为什么我的antlr语法似乎正确地解析了这个输入?

为什么我的antlr语法似乎正确地解析了这个输入?,antlr,antlr3,Antlr,Antlr3,我已经使用python在ANTLR中创建了一个小语法(一个可以接受ID列表中的数字列表的语法),但是当我输入一个字符串,比如1965年12月12日的,,ANTLR将在文件上运行,并且不会显示以下代码的错误(我使用的所有python代码都是通过@main嵌入的): 语法分析器lang; 选择权{ 语言=Python; } @标题{ 导入系统 进口antlr3 从ParserAngleXer导入ParserAngleXer } @主{ def main(argv,其他arg=None): char_

我已经使用python在ANTLR中创建了一个小语法(一个可以接受ID列表中的数字列表的语法),但是当我输入一个字符串,比如1965年12月12日的
,ANTLR将在文件上运行,并且不会显示以下代码的错误(我使用的所有python代码都是通过@main嵌入的):

语法分析器lang;
选择权{
语言=Python;
}
@标题{
导入系统
进口antlr3
从ParserAngleXer导入ParserAngleXer
}
@主{
def main(argv,其他arg=None):
char_stream=antlr3.ANTLRInputStream(打开(sys.argv[1],'r'))
lexer=ParserLangLexer(字符流)
令牌=公共令牌流(lexer)
parser=ParserLangParser(令牌);
rule=parser.entry\u rule()
}
程序:idList EOF
|整数列EOF
;
idList:ID空白idList
|身份证
;
整数列表:整数空格整数列表
|整数
;
空白:(空白|注释)+;
ID:字母(数字|字母)*;
整数:(非零位*)|零;
空白:('\t'|'''|'\r'|'\n'|'\u000C')+{$channel=HIDDEN;};
注释:('/*'.'*/')|('//'.'.'\n'){$channel=HIDDEN;};
零片段:“0”;
片段数字:“0”…'9';
片段非零位:“1”…'9';
片段字母:“a”…'z’|‘A’…'Z′;
我做错什么了吗


编辑:当我使用与输入相同语法的ANTLRWorks时,会抛出NoViableAltException。如何通过代码获得该错误?

我无法重现该错误。当我在修复语法中的错误(
rule=parser.entry\u rule()
应该是:
rule=parser.program()
)后,从您的输入中生成一个lexer和parser,并将输入解析为
“1965年12月12日”
(作为文件输入或普通字符串),我会得到以下错误:

line 1:0 no viable alternative at input u'December'
这可能看起来很奇怪,因为这可能是一个
空闲列表的开始。事实上,您的语法还包含一个错误和一个可以改进的小问题:

  • 空白
    注释
    放在
    隐藏的
    通道上,因此在解析器规则中不可用(至少,在不更改解析器读取其标记的通道的情况下…)
  • 输入末尾的
    注释
    ,即末尾没有
    \n
    ,将无法正确标记。最好定义这样的单行注释:
    '/'~('\r'|'\n')*
    。毕竟,
    空白
    规则将捕获尾随换行符
由于
空白
规则,解析器无法匹配
idList
(或与此相关的
整数列表
),因此会产生指向第一个标记的错误(
'December'

下面是一个有效的语法(如预期的那样):

运行根据上述语法生成的解析器也会产生错误:

line 1:9 missing EOF at u'12'
但这是预期的:在
idList
之后,解析器预期
EOF
,但它遇到的是
'12'

line 1:9 missing EOF at u'12'