5

私の質問は、ANTLRWorks で次の文法を実行することに関するものです。

INT :('0'..'9')+;
SEMICOLON: ';';
NEWLINE: ('\r\n'|'\n'|'\r');
STMTEND: (SEMICOLON (NEWLINE)*|NEWLINE+);

statement
    : STMTEND
    | INT STMTEND
    ;

program: statement+;

選択した改行NL(CR/LF/CRLF)または整数に関係なく、次の入力(開始ルールとしてプログラムを使用)で次の結果が得られます。

"; NL " または "32; NL " はエラーなしで解析されます。";" または「45;」(改行なし) EarlyExecution が発生します。" NL " 自体はエラーなしで解析します。セミコロンなしの"456 NL " は、MismatchedTokenException になります。

私が望むのは、ステートメントが改行、セミコロン、またはセミコロンとそれに続く改行で終了することであり、パーサーが終了時にできるだけ多くの連続した改行を食べるようにしたいので、 "; NL NL NL NL " はちょうど4つまたは5つではなく、1つの終端。また、ファイルの終わりの場合も有効な終了にしたいのですが、その方法はまだわかりません。

では、これの何が問題なのですか? どうすればこれを EOF でうまく終了させることができますか? 私は解析、ANTLR、および EBNF のすべてに完全に慣れていないため、簡単な電卓の例とリファレンスの間のどこかのレベルで読む資料はあまり見つかりませんでした (The Definitive ANTLR Reference を持っていますが、 ANTLRWorks の外ではまだ実行していないクイック スタートを前面に出しており、実際にはリファレンスです)、読書の提案 (Wirth の 1977 年の ACM 論文以外) も役に立ちます。ありがとう!

4

1 に答える 1

6

";"またはのような入力の場合"45;"、トークンSTMTENDは作成されません。

";"単一のトークンを作成します:SEMICOLON、および"45;"生成します:INT SEMICOLON

あなたが(おそらく)望んでいるのはそれSEMICOLONでありNEWLINE、実際のトークン自体には決して到達しませんが、それらは常にSTMTENDです。それらをいわゆる「フラグメント」ルールにすることで、それを行うことができます。

program: statement+;

statement
 : STMTEND
 | INT STMTEND
 ;

INT     : '0'..'9'+;
STMTEND : SEMICOLON NEWLINE* | NEWLINE+;

fragment SEMICOLON : ';';
fragment NEWLINE   : '\r' '\n' | '\n' | '\r';

フラグメントルールは他のレクサールールでのみ使用できるため、パーサー(本番)ルールになることはありません。INT強調するために:上記の文法は、またはSTMTENDトークンのいずれかのみを作成します。

于 2011-04-17T22:10:42.663 に答える