无法解释 ANTLRWorks 输出
我使用以下简单的语法来了解 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 | PLUS | ADDNUM);])
任何人都可以帮我理解我哪里出错了。
I am using the following simple grammar to get an understanding of 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;
When I try running the grammar in ANTLRWorks for the input 1+2
, I get the following error in the console:
[16:54:08] Interpreting... [16:54:08] problem matching token at 2:0
NoViableAltException(' '@[1:1: Tokens : ( ID | INT | PLUS | ADDNUM);])
Can anyone please help me understand where I am going wrong.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可能没有将
prog
指定为 ANTLRWorks 中的起始规则。如果你这样做了,一切都会好起来的。但您确实不应该像在
ADDNUM
中那样创建与表达式匹配的词法分析器规则:这应该是解析器规则:ANTLR 规则
何时使用解析器、词法分析器或词法
分析器规则
通常是语言的最小部分(字符串、数字、标识符、注释等)。尝试从像
1+2
这样的输入创建词法分析器规则会导致问题,因为:1 + 2.
。表达式
1+2
是三个标记:INT
、PLUS
和另一个INT
。片段规则
当您不希望此规则成为“真实”令牌时,可以使用片段规则。例如,采用以下词法分析器规则:
在上面的规则中,您使用了
'0'..'9'
四次,因此您可以将其放在单独的规则中但是您没有想要创建一个
DIGIT
标记:您只希望其他词法分析器规则使用DIGIT
。在这种情况下,您可以创建一个fragment
规则:这将确保永远不会有
DIGIT
标记:因此永远不会在您的解析器规则中使用它!解析器规则
解析器规则将标记粘合在一起:它们确保语言语法有效(也称为解析)。需要强调的是,解析器规则可以使用其他解析器规则或词法分析器规则,但不能片段规则。
另请参阅:ANTLR:有一个简单的示例吗?
You probably didn't indicate
prog
as the starting rule in ANTLRWorks. If you do, it all goes okay.But you really shouldn't create a lexer rule that matches an expression like you do in
ADDNUM
: this should be a parser rule:ANTLR rules
There are no strict rules when to use parser-, lexer- or fragment rules, but here's what they're usually used for:
lexer rules
A lexer rule is usually the smallest part of a language (a string, a numbers, an identifier, a comment, etc.). Trying to create a lexer rule from input like
1+2
causes problems because:1 + 2
.The expression
1+2
are three tokens:INT
,PLUS
and anotherINT
.fragment rules
A fragment rule is used when you don't want this rule to ever because a "real" token. For example, take the following lexer rules:
In the rules above, you're using
'0'..'9'
four times, so you could place that in a separate ruleBut you don't want to ever create a
DIGIT
token: you only want theDIGIT
to be used by other lexer rules. In that case, you can create afragment
rule:This will make sure there will never be a
DIGIT
token: and can therefor never use this in your parser rule(s)!parser rules
Parser rules glue the tokens together: they make sure the language is syntactic valid (a.k.a. parsing). To emphasize, parser rules can use other parser rules or lexer rules, but not fragment rules.
Also see: ANTLR: Is there a simple example?