首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法实现ANTLRWorks输出

无法实现ANTLRWorks输出
EN

Stack Overflow用户
提问于 2012-02-13 21:57:51
回答 1查看 158关注 0票数 0

我使用以下简单的语法来了解ANTLR。

代码语言:javascript
复制
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);)

有谁能帮我理解我哪里出了问题吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-02-13 22:11:22

您可能没有将prog作为ANTLRWorks中的起始规则。如果你这么做了,一切都会好起来的。

但是,您真的不应该像在ADDNUM中那样创建一个与表达式匹配的lexer规则:这应该是一个解析器规则:

代码语言:javascript
复制
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是三个标记:INTPLUS和另一个INT

碎片规则

当您不希望这个规则因为一个“真实的”令牌而被永远使用时,就会使用片段规则。例如,以下列lexer规则为例:

代码语言:javascript
复制
ID    : ('a'..'z' | 'A'..'Z' | '_') ('a'..'z' | 'A'..'Z' | '_' | '0'..'9')*
FLOAT : '0'..'9'+ '.' '0'..'9'+; 
INT   : '0'..'9'+;

在上面的规则中,您要使用'0'..'9'四次,所以可以将它放在单独的规则中

代码语言:javascript
复制
ID    : ('a'..'z' | 'A'..'Z' | '_') ('a'..'z' | 'A'..'Z' | '_' | DIGIT)*
FLOAT : DIGIT+ '.' DIGIT+; 
INT   : DIGIT+;
DIGIT : '0'..'9';

但是,您不希望创建一个DIGIT令牌:您只想让其他DIGIT规则使用它。在这种情况下,您可以创建一个fragment规则:

代码语言:javascript
复制
ID    : ('a'..'z' | 'A'..'Z' | '_') ('a'..'z' | 'A'..'Z' | '_' | DIGIT)*
FLOAT : DIGIT+ '.' DIGIT+; 
INT   : DIGIT+;
fragment DIGIT : '0'..'9';

这将确保永远不会有DIGIT令牌:为此,永远不要在解析器规则中使用它!

解析器规则

解析器规则将标记粘合在一起:它们确保语言是句法有效(a.a.(解析)。需要强调的是,解析器规则可以使用其他解析器规则或词法规则,但不能使用片段规则。

另见:有一个简单的例子吗?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9268651

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档