2

私はANTLRを使用し、分離されたJava6レクサーと文法に基づいてASTを構築しています。レクサー定義はJava6Lex.gに含まれており、文法が消費するトークンを生成します。パーサーはこれらを問題なく消費しますが、ASTを作成するときに、架空のトークンを導入したいと思います。ただし、ANTLRはこのモデルを好まないようです。

パーサー文法には、レクサーからのトークン語彙が含まれています。これは、文法で使用可能なトークンのベースラインを作成する必要があります。

parser grammar Java6Parse;

options {
    tokenVocab=Java6Lex;
    backtrack=true;
    memoize=true;
    output=AST;
    language = CSharp3;
}

ここで、fieldDeclarationを取得し、書き換えルールを使用してルート化されたノードに変換したいとします。私は(明らかに間違って)次のように架空のトークンをパーサー文法に直接導入できると仮定しました。

fieldDeclaration
    :   modifiers type variableDeclarator (COMMA variableDeclarator)* SEMI
            -> ^(FIELD modifiers type variableDeclarator+)
    ;

ただし、これにより、次のエラーが発生するだけです。

reference to undefined token in rewrite rule: FIELD

問題ありません、わかりました。定義しませんでした。そこで、パーサー文法のトークンセクションで定義しようとしています。繰り返しますが、間違って考えると、tokenVocabはベースラインを提供する必要があります。

tokens { FIELD; }

いいえ、トークンブロックを定義しても、EarlyExitExceptionが発生し、Java6Parse.gにルールがないことを示すエラーが発生するようです。私が考えたのは、パーサーの文法は、パーサーでトークンが定義されていることを単に好まないということです。それで、レクサーで定義しました。繰り返しますが、それは失敗しました。次に、レクサーとパーサーの両方ですべてのトークンを定義しました。これも失敗です。

だから、これが私が知る必要があることです。レクサーとパーサーが分離されているときに架空のトークンを定義する方法はありますか?その場合はその方法がありますか?そうでない場合、文法と字句解析を同じファイルに戻す唯一のオプションはありますか?

4

1 に答える 1

4

tokens{}ブロックを間違った場所に含めている可能性があります。ANTLR 3では、文法ヘッダー要素が特定の順序で表示される必要があります。正しい順序については、次のStackOverflowの回答を参照してください。

ANTLRで@headerを使用する

于 2013-03-25T15:02:49.427 に答える