0

より大きな式パーサーの一部を形成する次の ANTLR 文法があります。

grammar ProblemTest;

atom    :   constant
    |   propertyname;

constant:   (INT+ | BOOL | STRING | DATETIME);

propertyname
    :   IDENTIFIER  ('/' IDENTIFIER)*;

IDENTIFIER 
    :   ('a'..'z'|'A'..'Z'|'0'..'9'|'_')+;

INT 
    :   '0'..'9'+;

BOOL    :   ('true' | 'false');

DATETIME
    :   'datetime\'' '0'..'9'+ '-' '0'..'9'+ '-' + '0'..'9'+ 'T' '0'..'9'+ ':' '0'..'9'+ (':' '0'..'9'+ ('.' '0'..'9'+)*)* '\'';

STRING
    :  '\'' ( ESC_SEQ | ~('\\'|'\'') )* '\''
    ;

fragment
HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ;

fragment
ESC_SEQ
    :   '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
    |   UNICODE_ESC
    |   OCTAL_ESC
    ;

fragment
OCTAL_ESC
    :   '\\' ('0'..'3') ('0'..'7') ('0'..'7')
    |   '\\' ('0'..'7') ('0'..'7')
    |   '\\' ('0'..'7')
    ;

fragment
UNICODE_ESC
    :   '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
    ;

ANTLR内からインタープリターでこれを呼び出すと、

'Hello\\World' 

次に、これは定数ではなくプロパティ名として解釈されます。これを C# でコンパイルしてテスト ハーネスで実行しても同じことが起こるので、危険なインタープリターでは問題になりません。

本当に明らかな何かが欠けていると確信しています...しかし、なぜこれが起こっているのですか? 文字列マッチャーに問題があることは明らかですが、少なくともIDENTIFIERが ' 文字と一致しないという事実は、これが単に失敗するのではなく NoViableAltException をスローすることを意味すると思いましたか?

4

1 に答える 1

1

まず、ANTLRWorks も antlr-3.5-complete.jar も、C# ターゲットのコードを生成するために使用できません。それらは .cs で終わるファイルを生成する可能性があり、それらのファイルはコンパイルされる可能性もありますが、それらのファイルは、ANTLR ツール (Antlr3.exe) の C# ポートまたは推奨される MSBuild 統合によって生成されるファイルと同じではありません。テスト済みのいずれかの方法で、生成されたパーサーを生成していることを確認してください。

第二に、INT一致することはありません。文法のIDENTIFIER前に出現し、すべてのシーケンスが と の両方に一致するため、レクサーは常に出現する最初のオプション ( ) を取ります。INT'0'..'9'+IDENTIFIERINTIDENTIFIER

于 2013-04-16T13:16:26.383 に答える