ANTLR:具有大写规则的语法将无法识别输入
ANTLR: Grammar with uppercase rules won't recognize input
我对 ANTLR 很陌生,我需要解释它在识别输入字符串时的行为。据我了解,以大写字母开头的规则是词法分析器规则,而以小写字母开头的规则是解析器规则。
我有以下语言,我需要相应地编写语法:
所以 L 应该接受由以下组成的所有字符串:
- 非空字符串 b and/or c
- d
- 带有 and/or c
的非空字符串
这是我写的第一个语法,在识别输入时我没有遇到问题bbbcbcbcbcdaaacacacaaaa
:
start : (alfa 'd' beta);
alfa : ('b'|'c') | ('b'|'c') alfa;
beta : ('a'|'c') | ('a'|'c') beta;
WS : (' '|'\n'|'\t'|'\r')->skip;
但是如果我像下面这样改变它,同样的字符串就不再被识别了(下面你可以看到ANTLRWorks的调试器结果):
start : (alfa 'd' beta);
alfa : ALFA_VALS | ALFA_VALS alfa;
beta : BETA_VALS | BETA_VALS beta;
ALFA_VALS: ('b'|'c');
BETA_VALS: ('a'|'c');
WS : (' '|'\n'|'\t'|'\r')->skip;
此外,如果我将ALFA_VALS
和BETA_VALS
分别更改为alfa_vals
和beta_vals
,则不会出现任何问题。
有人可以为我提供有关此行为的解释吗?因为我找不到解决这个问题的具体方法。
非常感谢!
ANTLR 词法分析器匹配输入的最长可能子序列,或者如果它可以使用多个词法分析器规则匹配相同的输入,它使用第一个匹配的规则。
词法分析器不知道上下文和解析器状态,仅根据输入的字符做出决定。
如果您以这种方式在词法分析器中定义 ALFA_VALS
和 BETA_VALS
,输入 'c'
将 始终 匹配为 ALFA_VALS
令牌。
我可以建议一个稍微不同的方法吗?您的正确递归定义对于 ANTLR 来说是相当不典型的(虽然在自下而上的解析器中经常使用)。而是使用您的语言中定义的更简单的表达式:
grammar Example;
start : (α D β) EOF;
α: (B | C)+;
β: (A | C)+;
A: 'a';
B: 'b';
C: 'c';
D: 'd';
WS: (' '|'\n'|'\t'|'\r') -> skip;
这为您提供了这个更简单、更自然的解析树:
我对 ANTLR 很陌生,我需要解释它在识别输入字符串时的行为。据我了解,以大写字母开头的规则是词法分析器规则,而以小写字母开头的规则是解析器规则。
我有以下语言,我需要相应地编写语法:
所以 L 应该接受由以下组成的所有字符串:
- 非空字符串 b and/or c
- d
- 带有 and/or c 的非空字符串
这是我写的第一个语法,在识别输入时我没有遇到问题bbbcbcbcbcdaaacacacaaaa
:
start : (alfa 'd' beta);
alfa : ('b'|'c') | ('b'|'c') alfa;
beta : ('a'|'c') | ('a'|'c') beta;
WS : (' '|'\n'|'\t'|'\r')->skip;
但是如果我像下面这样改变它,同样的字符串就不再被识别了(下面你可以看到ANTLRWorks的调试器结果):
start : (alfa 'd' beta);
alfa : ALFA_VALS | ALFA_VALS alfa;
beta : BETA_VALS | BETA_VALS beta;
ALFA_VALS: ('b'|'c');
BETA_VALS: ('a'|'c');
WS : (' '|'\n'|'\t'|'\r')->skip;
此外,如果我将ALFA_VALS
和BETA_VALS
分别更改为alfa_vals
和beta_vals
,则不会出现任何问题。
有人可以为我提供有关此行为的解释吗?因为我找不到解决这个问题的具体方法。
非常感谢!
ANTLR 词法分析器匹配输入的最长可能子序列,或者如果它可以使用多个词法分析器规则匹配相同的输入,它使用第一个匹配的规则。
词法分析器不知道上下文和解析器状态,仅根据输入的字符做出决定。
如果您以这种方式在词法分析器中定义 ALFA_VALS
和 BETA_VALS
,输入 'c'
将 始终 匹配为 ALFA_VALS
令牌。
我可以建议一个稍微不同的方法吗?您的正确递归定义对于 ANTLR 来说是相当不典型的(虽然在自下而上的解析器中经常使用)。而是使用您的语言中定义的更简单的表达式:
grammar Example;
start : (α D β) EOF;
α: (B | C)+;
β: (A | C)+;
A: 'a';
B: 'b';
C: 'c';
D: 'd';
WS: (' '|'\n'|'\t'|'\r') -> skip;
这为您提供了这个更简单、更自然的解析树: