parsekit给了选择器意外调用 [英] parsekit given unexpected calls to selectors

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

问题描述

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

I have the following very simple (test) grammer file

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

然后我运行以下代码:

// Grammer contains the contents of the above grammer file.
PKParser *parser = [[PKParserFactory factory] parserFromGrammar:grammer 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 it's grammer 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的工作方式的最佳方法是购买,作者:史蒂芬·约翰·梅茨克(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天全站免登陆