首页 > 解决方案 > ANTLR4 歧义语法

问题描述

我想实现以下行为:User:class应该解析为Object - User; Type - class,也Us:er:class应该结果Object - Us:er; Type - class。我无法使第二部分工作,只要我添加:为合法符号,WORD它将整个输入解析为 object Object - Us:er:class。我的语法:

grammar Sketch;

/*
 * Parser Rules
 */
input               : (object)+ EOF ;
object              : objectName objectType? NEWLINE ;
objectType          : ':' TYPE ;
objectName          : WORD ;

/*
 * Lexer Rules
 */ 
fragment LOWERCASE  : [a-z] ;
fragment UPPERCASE  : [A-Z] ;
fragment NUMBER     : [0-9] ;
fragment WHITESPACE : (' ') ;
fragment SYMBOLS    : [!-/:-@[-`] ;
fragment C          : [cC] ;
fragment L          : [lL] ;
fragment A          : [aA] ;
fragment S          : [sS] ;
fragment T          : [tT] ;
fragment U          : [uU] ;
fragment R          : [rR] ;

TYPE                : ((C L A S S) | (S T R U C T));

NEWLINE             : ('\r'? '\n' | '\r')+ ;

WORD                : (LOWERCASE | UPPERCASE | NUMBER | WHITESPACE | SYMBOLS)+ ;

每个字母的片段用于不区分大小写的解析。据我了解,词法分析器从上到下优先考虑规则,因此应该选择 TYPE 而不是 WORD,但我无法实现。我是 antlr4 的新手,也许我遗漏了一些明显的东西。

标签: antlrantlr4

解决方案


如果您只需要解析如此简单的内容,则无需使用 ANTLR 编写解析器。这是我建议只使用简单正则表达式的极少数情况之一。如果你想用 ANTLR 解决它,我会这样做:1)丑陋的解决方案:你尝试使用谓词或动作来欺骗和强制解析做你想要的 2)你只需定义两个标记:一个用于获取标识符和一个得到分号。然后,您稍后使用解析器在代码中进行组合。

例如,User:class你会得到 [[ID:"User"], [ID:"class"]] 而Us:er:class你会得到 [[ID:"Us"], [ID:"er"], [ID:" class"]] 然后你的代码你知道最后一个 ID 代表类型,所有其他 ID 的序列代表对象。

两者都不是很好的解决方案,但我认为 ANTLR 不是您想要做的事情的正确工具。


推荐阅读