在典型的解析器生成器情况(例如 ANTLR 或 Beaver)中,如何处理以下情况:
0051A2B3C4D5E
0031G2T3H
它是一个 3 个字符的数字字段,它告诉您重复字段的迭代次数。
我知道有后期处理的可能性,但在某些情况下不会有用,所以我试图找出解析器是否有某种方法来处理它。如果有一个解决方案涉及在解析器读取数字字段时与它进行交互 - 不知何故告诉它根据某个产生式读取下一个 N 项。
在典型的解析器生成器情况(例如 ANTLR 或 Beaver)中,如何处理以下情况:
0051A2B3C4D5E
0031G2T3H
它是一个 3 个字符的数字字段,它告诉您重复字段的迭代次数。
我知道有后期处理的可能性,但在某些情况下不会有用,所以我试图找出解析器是否有某种方法来处理它。如果有一个解决方案涉及在解析器读取数字字段时与它进行交互 - 不知何故告诉它根据某个产生式读取下一个 N 项。
这是否可能取决于解析器生成器。
您的词法分析器将需要了解其周围环境(上下文敏感)。您只想Num
在一行的开头创建一个标记。在 ANTLR 中,您可以通过getCharPositionInLine()==0
在规则前面添加谓词来做到这一点Num
。
然后在您的解析器规则中,只要计数器大于零(计数器的值) line
,您就需要继续使用令牌(您的双字符)。Block
Num
一个快速的 ANTLR 演示:
grammar T;
parse
: line* EOF
;
line
@init{int n = 0;}
: Num {n = Integer.valueOf($Num.text);} ({n > 0}?=> Block {n--;})*
;
Num
: {getCharPositionInLine()==0}?=> Digit Digit Digit
;
Block
: AlphaNum AlphaNum
;
Space
: (' ' | '\t' | '\r' | '\n')+ {skip();}
;
fragment Digit : '0'..'9';
fragment Letter : 'a'..'z' | 'A'..'Z';
fragment AlphaNum : Letter | Digit;
将解析您的输入:
0051A2B3C4D5E
0031G2T3H
如下: