parsekit 意外调用选择器 [英] parsekit gives unexpected calls to selectors

查看:60
本文介绍了parsekit 意外调用选择器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下非常简单的(测试)语法文件

I have the following very simple (test) grammar file

@start = expression+;
expression = keyword | otherWord;
otherWord = Word;
keyword = a | the;
a = 'a';
the = 'the';

然后我运行以下代码:

// Grammar contains the contents of the above grammar file.
PKParser *parser = [[PKParserFactory factory] parserFromGrammar:grammar assembler:self];
NSString *s = @"The parrot";
[parser parse:s];
PKReleaseSubparserTree(parser);

以及以下方法:

- (void)didMatchA:(PKAssembly *)a{
    [self log:a type:@"didMatchA          "];
}
- (void)didMatchThe:(PKAssembly *)a{
    [self log:a type:@"didMatchThe        "];
}
- (void)didMatchKeyword:(PKAssembly *)a{
    [self log:a type:@"didMatchKeyword    "];
}
- (void)didMatchExpression:(PKAssembly *)a{
    [self log:a type:@"didMatchExpression "];
}
- (void)didMatchOtherWord:(PKAssembly *)a{
    [self log:a type:@"didMatchOtherWord  "];
}

-(void) log:(PKAssembly *) assembly type:(NSString *) type{
    PKToken * token = [assembly top];
    NSLog(@"Method: [%@], token: %@, assembly: %@", type, token, assembly);
}

最后我在日志中收到这些消息:

And finally I get these messages in the log:

[1] Method: [didMatchThe        ], token: The, assembly: [The]The^parrot
[2] Method: [didMatchKeyword    ], token: The, assembly: [The]The^parrot
[3] Method: [didMatchOtherWord  ], token: The, assembly: [The]The^parrot
[4] Method: [didMatchExpression ], token: The, assembly: [The]The^parrot
[5] Method: [didMatchExpression ], token: The, assembly: [The]The^parrot
[6] Method: [didMatchOtherWord  ], token: parrot, assembly: [The, parrot]The/parrot^
[7] Method: [didMatchExpression ], token: parrot, assembly: [The, parrot]The/parrot^

这是有道理的,但我不明白为什么会出现 %5.我真的很希望能够删除双重匹配,以便像The"这样的关键字被删除.只触发 didMatchThe 而不是 didMatchKeyword.

This sort of makes sense, but I cannot see why %5 occurs. I'd really like to be able to remove the double matching so that keywords such as "The" only trigger didMatchThe and not didMatchKeyword.

不幸的是,parsekit 上的 doco 似乎不存在其语法语法以及它如何决定触发方法.是的,我也偷看了源代码 :-)

Unfortunately the doco on parsekit seems to be non-existant on its grammar syntax and how it decides to trigger methods. Yes, I've trolled the source code too :-)

有没有人有使用 parsekit 的经验并且可以对此有所了解?

Has anyone got experience with parsekit and can shed some light on this?

推荐答案

我是 ParseKit 的开发者,这实际上是正确的行为.以下是一些有助于解决此问题的项目:

I'm the developer of ParseKit, and this is actually correct behavior. Here's a few items to help clear this up:

  1. 了解 ParseKit 工作原理的最佳方式是购买 使用 Java 构建解析器" 作者:Steven John Metsker.ParseKit 几乎完全基于那里的设计.

  1. The best way to learn about how ParseKit works is to buy "Building Parsers with Java" by Steven John Metsker. ParseKit is based almost entirely on the designs laid out there.

ParseKit 的解析器组件非常动态,并具有无限前瞻功能.这使得它非常适合快速开发或轻松解析小输入,但这也意味着 ParseKit 在解析大文档时表现出极差的性能.

ParseKit's parser component is extremely dynamic and features Infinite look-ahead. This makes it ideal for quick development or easily parsing small input, but it also means ParseKit exhibits extremely poor performance when parsing large documents.

由于 ParseKit 的无限前瞻,您实现的汇编器方法将被多次调用.实际上,正如您在上面描述的那样,它们似乎会被调用太多次.这是正常的.ParseKit 会随时探索所有可用的解析路径,因此您会收到太多"回调.

Due to ParseKit's infinite look-ahead, the assembler methods you implement will be called many times. Actually, it will appear they will be called too many times as you've described above. This is normal. ParseKit is exploring every possible parse path available to it at any time, so you get "too many" callbacks.

答案是永远不要在汇编器回调方法中使用 ivars.在您的 Assembler 方法中,您应该始终在当前 PKAssemblytarget ivar 中保持您正在处理的状态.

The answer is to never work on ivars in your assembler callback methods. In your Assembler methods, you should instead always keep the state of what you are working on in the current PKAssembly's target ivar.

a.target

当前的 PKAssembly 是传递给回调方法的那个.

The current PKAssembly is the one passed into your callback method.

希望有所帮助.

这篇关于parsekit 意外调用选择器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆