我正在尝试使用 Antlr-3.1.3 为类香料语言的识别器构建语法(由于 Python 目标,我使用此版本)。我没有解析器的经验。我找到了一篇硕士论文,其中学生对SPICE 2G6语言进行了句法分析,并使用LEX和YACC编译器编写工具构建了一个解析器。 ( http://digitool.library.mcgill.ca/R/?func=dbin-jump-full&object_id=60667&local_base=GEN01-MCG02 ) 在第 4 章中,他描述了 SPICE 2G6 语言的 Backus-Naur 形式的语法,并将解析器的 LEX 和 YACC 代码文件附加到工作中。
我致力于这项工作,为更严格的香料语言的识别器创建一个更简单的语法。
我阅读了 Antlr 手册,但无法弄清楚如何解决下面的代码片段所示的两个问题。
grammar Najm_teste;
resistor
: RES NODE NODE VALUE 'G2'? COMMENT? NEWLINE
;
// START:tokens
RES : ('R'|'r') DIG+;
NODE : DIG+; // non-negative integer
VALUE : REAL; // non-negative real
fragment
SIG : '+'|'-';
fragment
DIG : '0'..'9';
fragment
EXP : ('E'|'e') SIG? DIG+;
fragment
FLT : (DIG+ '.' DIG+)|('.' DIG+)|(DIG+ '.');
fragment
REAL : (DIG+ EXP?)|(FLT EXP?);
COMMENT : '%' ( options {greedy=false;} : . )* NEWLINE;
NEWLINE : '\r'? '\n';
WS : (' '|'\t')+ {$channel=HIDDEN;};
// END:tokens
在上面的语法中,标记 NODE 是 VALUE 标记表示的集合的子集。该语法可以正确解释“R1 5 0 1.1/n”等输入,但无法解释“R1 5 0 1/n”等输入,因为它将“1”映射到标记 NODE,而不是将其映射到标记 VALUE ,因为在标记部分中 NODE 位于 VALUE 之前。给定这样的输入,是否有人知道如何将“1”映射到正确的标记值,或者建议如何更改语法以便我可以正确解释输入?
第二个问题是行尾存在注释。因为 NEWLINE 标记分隔: (1) 注释的结束; (2) 一行代码的结尾。当我在一行代码末尾添加注释时,解析器需要两个换行符才能正确识别该代码行,否则只需要一个换行符。我该如何改进?
谢谢!
最佳答案
问题 1
词法分析器不会“监听”解析器。词法分析器只是创建包含尽可能多的字符的标记。如果两个标记匹配相同数量的字符,则首先定义的标记将“获胜”。换句话说,"1"
将始终被标记为 NODE
,即使解析器尝试匹配 VALUE
。
你可以这样做:
resistor
: RES NODE NODE value 'G2'? COMMENT? NEWLINE
;
value : NODE | REAL;
// START:tokens
RES : ('R'|'r') DIG+;
NODE : DIG+;
REAL : (DIG+ EXP?) | (FLT EXP?);
...
例如,我从 REAL
中删除了 VALUE
、添加了 value
并删除了 fragment
问题2
不要让注释与换行符匹配:
COMMENT : '%' ~('\r' | '\n')*;
其中 ~('\r' | '\n')*
匹配除换行符之外的零个或多个字符。
关于parsing - 类香料语言识别器的语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22698684/