我使用以下简单的语法来了解ANTLR。
grammar Example;
options {
language=Java;
}
ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
;
INT : '0'..'9'+
;
PLUS : '+';
ADDNUM :
INT PLUS INT;
prog : ADDNUM;当我尝试在ANTLRWorks中为输入1+2运行语法时,控制台中会出现以下错误:
16:54:08口译..。16:54:08问题匹配令牌2:0 NoViableAltException(‘'@1:1:令牌:( ID : INT + ADDNUM);)
有谁能帮我理解我哪里出了问题吗?
发布于 2012-02-13 22:11:22
您可能没有将prog作为ANTLRWorks中的起始规则。如果你这么做了,一切都会好起来的。
但是,您真的不应该像在ADDNUM中那样创建一个与表达式匹配的lexer规则:这应该是一个解析器规则:
grammar Example;
prog : addExpr EOF;
addExpr : INT PLUS INT;
ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*;
INT : '0'..'9'+;
PLUS : '+';反规则
在使用解析器
lexer规则
词汇规则通常是语言中最小的部分(字符串、数字、标识符、注释等)。试图从像1+2这样的输入中创建一个lexer规则会导致问题,因为:
1 + 2。表达式1+2是三个标记:INT、PLUS和另一个INT。
碎片规则
当您不希望这个规则因为一个“真实的”令牌而被永远使用时,就会使用片段规则。例如,以下列lexer规则为例:
ID : ('a'..'z' | 'A'..'Z' | '_') ('a'..'z' | 'A'..'Z' | '_' | '0'..'9')*
FLOAT : '0'..'9'+ '.' '0'..'9'+;
INT : '0'..'9'+;在上面的规则中,您要使用'0'..'9'四次,所以可以将它放在单独的规则中
ID : ('a'..'z' | 'A'..'Z' | '_') ('a'..'z' | 'A'..'Z' | '_' | DIGIT)*
FLOAT : DIGIT+ '.' DIGIT+;
INT : DIGIT+;
DIGIT : '0'..'9';但是,您不希望创建一个DIGIT令牌:您只想让其他DIGIT规则使用它。在这种情况下,您可以创建一个fragment规则:
ID : ('a'..'z' | 'A'..'Z' | '_') ('a'..'z' | 'A'..'Z' | '_' | DIGIT)*
FLOAT : DIGIT+ '.' DIGIT+;
INT : DIGIT+;
fragment DIGIT : '0'..'9';这将确保永远不会有DIGIT令牌:为此,永远不要在解析器规则中使用它!
解析器规则
解析器规则将标记粘合在一起:它们确保语言是句法有效(a.a.(解析)。需要强调的是,解析器规则可以使用其他解析器规则或词法规则,但不能使用片段规则。
另见:有一个简单的例子吗?
https://stackoverflow.com/questions/9268651
复制相似问题