ANTLR4:如何用相同的规则匹配 kv 表达式

ANTLR4: how to match kv expression with same rule

我想解析以下语句:

键=值

解析器总是混淆,因为键和值具有相同的规则。

我的错误语法:

grammar MatchExpr;
prog: stat ;

stat: expr
    ;

expr : kv JOINER kv #joiner
     | kv #condition
     ;

kv: KEY OP VALUE;

JOINER: '&';
KEY : [a-zA-Z] ([a-zA-Z0-9])*;
OP : '=';
VALUE : [a-zA-Z0-9];
WS : [ \t]+ -> skip ; // toss out whitespace

但另一种语法可以 运行 :

grammar MatchExpr;

prog: stat ;

stat: expr
    ;

expr : kv JOINER kv #joiner
     | kv #condition
     ; kv: KV;

KV: [a-zA-Z] ([a-zA-Z0-9_-])* '=' [a-zA-Z0-9] ([a-zA-Z0-9._-])*;
JOINER: '&'; 
WS : [ \t]+ -> skip ; // toss out whitespace

为什么?

ANTLR 将始终为输入 foo 创建一个 KEY 标记。无论输入是否为 mu = foo,也会创建 2 个 KEY 令牌(中间有一个 OP 令牌)。

这就是 ANTLR 词法分析器的工作原理。词法分析器不是由解析器“驱动”的。解析器是否尝试匹配 VALUE 标记并不重要,输入 foo 将始终是 KEY 标记。

这些是词法分析器创建标记的 2 条规则:

  1. 创建尽可能长的匹配项
  2. 如果有 2 个或更多的词法分析器规则匹配相同的字符,让第一个定义的“赢”

由于规则 2,您可以看到为什么 KEY 将为 foo 而不是 VALUE 创建。

要解决此问题,请执行以下操作:

kv     : KEY OP value;
value  : KEY | VALUE;

JOINER : '&';
KEY    : [a-zA-Z] [a-zA-Z0-9]*;
VALUE  : [a-zA-Z0-9]+ // matches an ID starting with a digit
OP     : '=';