3

次の非常に単純な(テスト)文法ファイルがあります

@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);
}

そして最後に、ログに次のメッセージが表示されます。

[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.

残念ながら、parsekit の doco は、その文法構文と、メソッドをトリガーする方法については存在しないようです。はい、私もソースコードをトロールしました:-)

誰も parsekit の経験があり、これに光を当てることができますか?

4

1 に答える 1

2

私は ParseKit の開発者ですが、これは実際には正しい動作です。これを解決するのに役立ついくつかのアイテムを次に示します。

  1. ParseKit がどのように機能するかを学ぶ最良の方法は、Steven John Metsker による「Building Parsers with Java」を購入することです。ParseKit は、そこに配置された設計にほぼ完全に基づいています。

  2. ParseKit のパーサー コンポーネントは非常に動的で、無限の先読み機能を備えています。これは、迅速な開発や小さな入力の簡単な解析には理想的ですが、大きなドキュメントを解析するときに ParseKit のパフォーマンスが極端に低下することも意味します。

  3. ParseKit の無限先読みにより、実装するアセンブラー メソッドは何度も呼び出されます。実際には、上で説明したように、何度も呼び出されるように見えます。これは正常です。ParseKit は、利用可能なすべての解析パスをいつでも探索しているため、「多すぎる」コールバックが発生します。

  4. 答えは、アセンブラーのコールバック メソッドで ivar を操作しないことです。アセンブラー メソッドでは、現在PKAssemblytargetivar で作業中の状態を常に保持する必要があります。

    標的

currentPKAssemblyは、コールバック メソッドに渡されるものです。

それが役立つことを願っています。

于 2011-06-04T16:00:07.053 に答える