ANTLR4 词法分析器规则不匹配正确的文本块
ANTLR4 lexer rules not matching correct block of text
我试图了解 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' 匹配文本 'start'?我还收到错误消息“无关输入 'start' 期望 NUM”
如果我对我的语法进行以下更改
OTHER : [a-z]+ ->skip;
错误消失了。除了上图中的文字 '55 其他文字
another text' 将表达式匹配为 AST 中的节点。为什么会这样?
以上所有内容都与词法分析器匹配输入的方式有关吗?我知道词法分析器寻找第一个最长的匹配规则,但我如何更改我的语法以便只匹配添加的内容?
Why does rule 'expr' matches the text 'start'?
没有。当标记在树中显示为红色时,表示出现错误。该标记与任何可能的替代项都不匹配,因此产生了一个错误,解析器继续使用下一个标记。
In addition in the image above text '55 other text another text' matches the expression as a node in the AST. Why is this happening?
跳过 OTHER
个标记后,您的输入基本上如下所示:
4 + 5 + 22 + 1 55 2 + 4 + 255 44
4 + 5 + 22 + 1
可以解析为表达式,没问题。之后,解析器需要一个 +
(继续表达式)或一个数字(开始一个新表达式)。所以当它看到 55
时,表示新表达式的开始。现在它需要 +
(因为语法规定 PLUS NUM
必须在表达式中的第一个数字之后至少出现一次)。它实际得到的是数字2
。因此它会产生错误并忽略该标记。然后它看到 +
,这是它所期望的。然后它继续这种方式直到 44
,它再次开始一个新的表达式。因为后面没有 +
,这是另一个错误。
All the above have to do with the way lexer matches an input?
不是真的。 "start 4 + 5" 的标记序列是 OTHER NUM PLUS NUM
,如果您跳过 OTHER
,则只是 NUM PLUS NUM
。 “55 skippedtext 2 + 4”的标记序列是 NUM NUM PLUS NUM
。我想这正是您所期望的。
相反,似乎让您感到困惑的是 ANTLR 如何从错误中恢复(或者 它是如何从错误中恢复的)。
我试图了解 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' 匹配文本 'start'?我还收到错误消息“无关输入 'start' 期望 NUM”
如果我对我的语法进行以下更改
OTHER : [a-z]+ ->skip;
错误消失了。除了上图中的文字 '55 其他文字 another text' 将表达式匹配为 AST 中的节点。为什么会这样?
以上所有内容都与词法分析器匹配输入的方式有关吗?我知道词法分析器寻找第一个最长的匹配规则,但我如何更改我的语法以便只匹配添加的内容?
Why does rule 'expr' matches the text 'start'?
没有。当标记在树中显示为红色时,表示出现错误。该标记与任何可能的替代项都不匹配,因此产生了一个错误,解析器继续使用下一个标记。
In addition in the image above text '55 other text another text' matches the expression as a node in the AST. Why is this happening?
跳过 OTHER
个标记后,您的输入基本上如下所示:
4 + 5 + 22 + 1 55 2 + 4 + 255 44
4 + 5 + 22 + 1
可以解析为表达式,没问题。之后,解析器需要一个 +
(继续表达式)或一个数字(开始一个新表达式)。所以当它看到 55
时,表示新表达式的开始。现在它需要 +
(因为语法规定 PLUS NUM
必须在表达式中的第一个数字之后至少出现一次)。它实际得到的是数字2
。因此它会产生错误并忽略该标记。然后它看到 +
,这是它所期望的。然后它继续这种方式直到 44
,它再次开始一个新的表达式。因为后面没有 +
,这是另一个错误。
All the above have to do with the way lexer matches an input?
不是真的。 "start 4 + 5" 的标记序列是 OTHER NUM PLUS NUM
,如果您跳过 OTHER
,则只是 NUM PLUS NUM
。 “55 skippedtext 2 + 4”的标记序列是 NUM NUM PLUS NUM
。我想这正是您所期望的。
相反,似乎让您感到困惑的是 ANTLR 如何从错误中恢复(或者 它是如何从错误中恢复的)。