ANTLR4如何根据规则更改隐藏字符?

ANTLR4 how do change hidden characters based on rule?

我正在尝试解析结构错误的输入文件,因为通常会跳过换行符,但在某些情况下它用于终止语句,因此有时必须匹配它。然而在这种情况下,换行符似乎变成了一般的普通标记,不能跳过。

为了说明我的问题,请考虑以下语法:

text
    : (line '\n')+
    ;

line
    : ( ID )+
    | '(' ID* ')'
    ;

ID  : [a-zA-Z]+
    ;

WS  : [ \t\n\r]+ -> skip
    ;

在这个语法中,我想解析如下语句:

a b
c d
(e
f)

但我收到以下错误:

line 3:2 extraneous input '\n' expecting {')', ID}

因为没有跳过括号里面的换行符。语法本身要复杂得多,因此不可能简单地输入“'\n'?”无处不在。

处理此问题的最佳方法是什么?

对于我的两个建议,您需要将空白设置为隐藏频道(而不是跳过它)。

要灵活控制空格(或换行符),您可以应用以下解决方案 。您可以 enable/disable 语法中每个点的空格。

另一种方法是将 \n 设置为隐藏通道,但不将其作为标记而是作为语义谓词包含在规则中。

text
  : (line {/*check that the last whitespace contained a newline*/}?)+
  ;

对于实现,您可以使用 BufferedTokenStream#getHiddenTokensToRightBufferedTokenStream#getHiddenTokensToLeft(两者都允许读取隐藏的通道外令牌)。