parsing - 类香料语言识别器的语法

标签 parsing antlr grammar antlr3

我正在尝试使用 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/

相关文章:

java - 如何让Antlr支持更多数据类型的符号表?

java - Antlr AST 树构建

c# - ISO 语法是否遵循特定格式

grammar - 上下文相关语法可以有空字符串吗?

python - 使用 ANTLR 在 Python 中解析时如何获取 AST 树而不是列表?

c - yacc 中的左值语法不正确地归约

python - 使用 Python 解析和重新格式化 CSV/文本数据

Javascript:将var中的文本解析为一个集合

php - Facebook 点赞或分享来自其他页面的计数

python - 捕获花括号内的内容