The second alternative ((1-9)(0-9)) of the following parser rule results in two nodes in the abstract syntax tree.
oneToHundred
: ('1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9')
| ('1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9')('0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9')
| '100'
;
( side node: "Lexing"数字到数字标记的数字不受影响) . )
所以对于15我得到两个节点一个和五个而不是十五个但我想把它作为一个节点所代表的一个数字 .
我不能用令牌级别的词法分析器来做这个,因为取决于上下文,例如15可能意味着两个非常不同的东西:"one-symbol and a five-symbol"(绝对应该是两个节点)或"fifteen"和according to this post上下文敏感性应留给解析器 .
(编辑澄清:)
上下文敏感的示例:
输入应该分开/由分号分隔
Input:
11;2102;34%;P11o
this would be split into four parts and
11 - would not be a number but one '1'-symbol and another '1'-symbol
2102 - would not be a number but: '2'-symbol '1'-symbol '0'-symbol '2'-symbol
34% - now here 34 would be the number thirtyfour
P11o: 'P'-symbol '1'-symbol '1'-symbol 'o'-symbol
在这四个块中,34%将被解析器规则识别为百分比块,其他块将被识别为符号块 . 所以AST看起来应该是这样的:
SYMBOL
1
1
SYMBOL
2
1
0
2
PERCENT
34
SYMBOL
P
1
1
o
目标是C#:
options {
language=CSharp3;
output=AST;
}
I'm an Antlr-noob, so is there a good way to merge these two nodes with the parser or am I better of adding an imaginary token and concatenating the two digits "manually" in C# after parsing?
1 回答
你的解析器规则:
在幕后隐式创建以下标记:
(不是那些规则名称,而是它们匹配的内容 are 已创建)
因此,如果您的词法分析器将获得输入
"11"
,则会创建两个D_1_9
标记,并且oneToHundred
规则中的第二个替代项将无法匹配(此替代方案需要两个标记:D_1_9 D_0_9
) .您必须意识到词法分析器独立于解析器运行 . 它没有't matter what type of token the parser 1574550 of the lexer: the lexer has it'自己的规则优先级,导致
'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9'
永远不会被D_0_9
规则匹配(因为它出现在D_1_9
规则之后) .编辑
让我们调用你的输入
11;2102;34%;P11o
,每个atoms
(其中atom
是字母或数字)的四个单位可能以'%'
结尾:如果它以
'%'
结尾,您只需使用重写规则创建一个以PERCENT
为根的树,否则只需创建一个以SYMBOL
为根的树:一个工作演示:
您可以使用以下类测试解析器:
这将产生对应于以下AST的DOT输出:
在上图中,所有叶子的类型均为
Letter
或Digit
,但"34"
除外,其类型为NUMBER
.