具有非贪婪规则的 ANTLR

ANTLR with non-greedy rules

我想要以下语法(部分):

expression 
: 
expression 'AND' expression
| expression 'OR' expression
| StringSequence
;

StringSequence
: 
StringCharacters
;

fragment
StringCharacters
: StringCharacter+
;

fragment
StringCharacter
: ~["\]
| EscapeSequence
;

它应该匹配 "a b c d f" 之类的东西(不带引号),以及 "a AND b AND c".

之类的东西

问题是我的规则 StringSequence 是贪婪的,并且也消耗了 OR/AND。我尝试了不同的方法,但无法让我的语法以正确的方式工作。 ANTLR4 这可能吗?请注意,我不想在每个字符串周围加上引号。加上引号效果很好,因为规则变得不贪婪,即:

StringSequence
: '"' StringCharacters? '"'
;

然而一个天真的解决方案:

StringSequence : 
  (StringCharacter | NotAnd | NotOr)+
;
fragment NotAnd :
  'AN' ~'D'
| 'A' ~'N'
;
fragment NotOr:
  'O' ~('R')
;
fragment StringCharacter :
  ~('O'|'A')
;

使用空白规则变得有点复杂。另一种解决方案是使用语义谓词向前看并防止读取关键字。

您没有空格规则,因此 StringCharacter 匹配除引号和反斜杠字符(+ 转义序列)之外的所有字符。包含一个空格规则以使其与单个 AND/OR 标记匹配。此外,我建议为字符串文字 ('AND''OR') 定义词法分析器规则,而不是将它们嵌入(解析器)规则中。这样你不仅可以读出令牌的名字(而不是自动生成的),还可以更好地控制匹配顺序。