我试图了解ANTLR4如何基于词法分析器和解析器规则工作,但是在以下示例中缺少内容:
我正在尝试分析文件并匹配所有数学加法(例如1 + 2 + 3等)。我的文件包含以下文本:
start
4 + 5 + 22 + 1
other text other text test test
test test other text
55 other text
another text 2 + 4 + 255
number 44
end
我想匹配
4 + 5 + 22 + 1
和
2 + 4 + 255
我的语法如下:
grammar Hello;
hi : expr+ EOF;
expr : NUM (PLUS NUM)+;
PLUS : '+' ;
NUM : [0-9]+ ;
SPACE : [\n\r\t ]+ ->skip;
OTHER : [a-z]+ ;
我的抽象语法树显示为
为什么规则“ expr”与文本“开始”匹配?我还收到错误消息“ 外部输入'开始',期望NUM ”
如果我对语法进行了以下更改
OTHER : [a-z]+ ->skip;
错误消失了。另外在上图中的文字'55其他文字 另一个文本”将该表达式与AST中的节点匹配。为什么会这样呢?
以上所有与lexer匹配输入的方式有关吗?我知道lexer会寻找第一个最长的匹配规则,但是如何更改语法以仅匹配添加项?
答案 0 :(得分:2)
为什么规则“ expr”与文本“开始”匹配?
不是。当令牌在树中显示为红色时,表明存在错误。该令牌与任何可能的替代方案都不匹配,因此产生了错误,并且解析器继续使用下一个令牌。
此外,在文字'55其他文字上方的图片中,该文字与该表达式匹配,是AST中的一个节点。为什么会这样?
跳过OTHER
标记后,您的输入基本上如下所示:
4 + 5 + 22 + 1 55 2 + 4 + 255 44
4 + 5 + 22 + 1
可以解析为表达式,没问题。之后,解析器将期望+
(继续表达式)或数字(开始新表达式)。因此,当它看到55
时,表示新表达式的开始。现在它需要一个+
(因为语法说PLUS NUM
必须在表达式中的第一个数字之后至少出现一次)。它实际上得到的是数字2
。因此它产生一个错误并忽略该令牌。然后,它会看到一个+
,它是预期的。然后,它将继续这种方式,直到44
为止,后者再次启动一个新表达式。由于后面没有+
,因此这是另一个错误。
以上所有内容都与词法分析器匹配输入的方式有关?
不是。 “开始4 + 5”的令牌顺序为OTHER NUM PLUS NUM
,如果跳过NUM PLUS NUM
,则仅为OTHER
。 “ 55 skippedtext 2 + 4”的令牌序列为NUM NUM PLUS NUM
。我认为这正是您所期望的。
相反,似乎让您感到困惑的是ANTLR如何从错误中恢复(或者那从错误中恢复)。