4

私はこの問題に約4時間取り組んできました。これは、可能な限り単純な例になるように簡略化した ANTLR V4 文法ファイルです。

grammar Cfscript;

component
    : (statement)*
    ;

statement
    : 'return' expression? ';'
    | statementExpression ';'
    ;

statementExpression
    : expression
    ;

expression
    : primary
    | expression '.' Identifier
    ;

primary
    : Identifier
    ;

Identifier
    : [a-zA-Z0-9_]+
    ;

WS
    : [ \t\r\n]+ -> skip 
    ;

私のファイルには

local.return;

で入力してこのファイルを解析しようとするとcomponent、次のエラーが表示されます: mismatched input 'return' expecting Identifier. このエラーが発生する理由がわかりません。

アップデート

私の理解が正しければ、これはreturnJava の予約語であり、そのため文法がそのように構造化されているためです。私の言語では、Coldfusion Cfscriptは、スコープが, ,returnである限り有効です。これは、 、、および他の多くの単語にも当てはまります。これらはすべてスコープ内でのみ有効ですが、変数または式の最初の項としては有効ではありません:無効ですが、有効です。これは、それらを取得するパーサー規則と競合するため、これらの用語のすべてで同じ問題に遭遇することを意味します。local.returnvariables.returnlocal["return"]ifelsesavecontentif.blah = "something"blah.if = "something"

バートが述べたことを総合すると、これはこの問題を解決するためのクリーンな方法ですか?

grammar Cfscript;

component
    : (statement)*
    ;

statement
    : K_Return expression? ';'
    | expression ';'
    ;

expression
    : primary
    | expression '.' secondary
    ;

primary
    : Identifier
    ;

secondary
    : K_Return
    | K_If
    | K_Else
    | Identifier
    ;

K_Return : 'return' ;
K_If : 'if' ;
K_Else : 'else' ;

Identifier
    : [a-zA-Z0-9_]+
    ;

WS
    : [ \t\r\n]+ -> skip 
    ;
4

1 に答える 1

4

で行ったように、パーサールール内にリテラルトークンを追加しても、レクサーがルール内の2番目の選択肢として文字列と一致することを意味する'return'わけではありません。"return"Identifierexpression

expression '.' Identifier

"return"キーワードおよび言語の識別子として一致させる場合は、 Identifiersとキーワードの両方に一致するパーサールールを作成する必要があります。

expression
    : primary
    | expression '.' id
    ;

primary
    : id
    ;

id
    : Identifier
    | K_Return
    ;

// Better explicitly define them instead of litering keywords inside parser rules
K_Return
    : 'return'
    ;

Identifier
    : [a-zA-Z0-9_]+
    ;
于 2013-03-11T07:51:59.197 に答える