ANTLR语法匹配不兼容的规则而不是抛出NoViableAltException

时间:2013-04-16 11:55:59

标签: c# antlr antlr3

我有以下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' 

然后将其解释为 propertyname 而不是常量。如果我在C#中编译它并在测试工具中运行它也会发生同样的情况,所以这对狡猾的解释器来说不是问题

我确定我错过了一些非常明显的东西......但为什么会这样呢?很明显字符串匹配器存在问题,但我至少会想到 IDENTIFIER 与'字符不匹配的事实意味着这会抛出NoViableAltException而不是仅仅掉落通过?

1 个答案:

答案 0 :(得分:1)

首先,ANTLRWorks和antlr-3.5-complete.jar都不能用于为C#目标生成代码。它们可能会生成以.cs结尾的文件,而这些文件甚至可能编译,但这些文件与ANTLR工具(Antlr3.exe)的C#端口生成的文件或者推荐MSBuild集成。确保您使用tested methods之一生成生成的解析器。

其次,INT永远不会匹配。由于IDENTIFIER出现在语法INT之前,并且所有序列'0'..'9'+都与IDENTIFIERINT匹配,因此词法分析器将始终采用出现的第一个选项( IDENTIFIER)。