4

私は次の文法を持っています:

rule: 'aaa' | 'a' 'a';

文字列「aaa」は正常に解析できますが、「aa」の解析に失敗し、次のエラーが発生します。

line 1:2 mismatched character '<EOF>' expecting 'a'

参考までに、パーサーとは呼ばないので、パーサーの問題ではなく、レクサーの問題です。主な機能は次のようになります。

@members {
  public static void main(String[] args) throws Exception {
    RecipeLexer lexer = new RecipeLexer(new ANTLRInputStream(System.in));
    for (Token t = lexer.nextToken(); t.getType() != EOF; t = lexer.nextToken())
      System.out.println(t.getType());
  }
}

結果は、より明白なバージョンと同じです。

rule: AAA | A A;
AAA: 'aaa';
A: 'a';

明らかに、ANTLRレクサーは入力'aa'をルールAAAと一致させようとしますが失敗します。ANTLRがLL(*)パーサーなどであることは別として、レクサーはパーサーとは別に機能する必要があり、あいまいさを解決できる必要があります。文法は古き良きlex(またはflex)ではうまく機能しますが、ANTLRでは機能しません。では、ここでの問題は何ですか?

助けてくれてありがとう!

4

1 に答える 1

6

ANTLRで生成されたパーサーは、そのレクサーではなく、LL(*)です(またはそうなる可能性があります)。

レクサー入力"aa"を確認すると、トークンとの照合を試みますAAA。そうしないと、一致する他のトークンと一致しようとします"aa"(レクサーは一致するようにバックトラックしませんA!)。これは不可能であるため、エラーが発生します。

実際には、ある種の識別子ルール"aa"がフォールバックできることが多いため、これは通常問題にはなりません。それで、あなたはどのような実際の問題を解決しようとしていますか、それとも内部の仕組みにのみ興味がありましたか?初めての場合は、質問を編集して実際の問題を説明してください。

于 2012-08-30T06:44:54.240 に答える