我有以下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而不是仅仅掉落通过?
答案 0 :(得分:1)
首先,ANTLRWorks和antlr-3.5-complete.jar都不能用于为C#目标生成代码。它们可能会生成以.cs结尾的文件,而这些文件甚至可能编译,但这些文件与ANTLR工具(Antlr3.exe)的C#端口生成的文件或者推荐MSBuild集成。确保您使用tested methods之一生成生成的解析器。
其次,INT
永远不会匹配。由于IDENTIFIER
出现在语法INT
之前,并且所有序列'0'..'9'+
都与IDENTIFIER
和INT
匹配,因此词法分析器将始终采用出现的第一个选项( IDENTIFIER
)。