如何让 ANTLR4 语法在一行中解析而不需要在中间换行?

How to get ANTLR4 grammar to parse over a single line without requiring line break in the middle?

我目前正在重新学习 ANTLR,我的语法和解析有点问题。我正在使用 ANTLR 插件在 IntelliJ IDEA 中编辑它,我使用的是 ANTLR 4.9.2 版。

我的语法如下

grammar Pattern;
pattern:
    patternName
    patternMeaning
    patternMoves;

patternName     :   'Name:'     NAME            ;
patternMeaning  :   'Meaning:'  NAME            ;

patternMoves    :   'Moves:'    (patternStep)+  ;
patternStep     :   'Turn' angle stance;
stance          :   'Walking Stance';
angle   :   ('90'|'180'|'270'|'360') '°' 'anti-'? 'clockwise';

NAME    :   WORD (' ' WORD)*;
fragment WORD    :   [a-zA-Z]+;
WS: [ \t\r\n]+ -> skip;

现在,当我尝试解析以下文本时,出现以下错误 line 2:9 mismatched input 'clockwise Walking Stance' expecting {'anti-', 'clockwise'}

Name: Il Jang
Meaning: Heaven and light
Moves:
Turn 90° clockwise Walking Stance

但是,如果我将文本更改为下面的内容,它就可以正常工作。如何调整我的语法以允许我在一行中解析它?

Name: Il Jang
Meaning: Heaven and light
Moves:
Turn 90° clockwise 
Walking Stance

您的问题是 clockwise Walking Stance 是一个有效的 NAME,因此它被解释为有效的 NAME 而不是 clockwise 关键字后跟 NAME Walking Stance。添加换行符可以解决此问题,因为换行符不能出现在名称中。

要解决此问题,您应该将 WORD 变成词法分析器规则,将 NAME 变成解析器规则。这样 name 规则只会在解析器实际需要名称的地方尝试,因此它不会尝试将 clockwise 解释为名称的一部分。而 WORD 规则不会吃关键字,因为 WORD 规则产生的匹配不会比关键字长,所以关键字获胜。

如果这是您的整个语法,那么就没有定义 whaitespace 处理的词法分析器规则。事实上,没有明确的词法分析器规则。 (ANTLR 将为您的解析器规则中的任何文字字符串创建隐式词法分析器规则(除非匹配已经定义的语法规则。))

你的语法本质上是(在 ANTLR 看来)

grammar Pattern;

patternMoves    :   T_1    (patternStep)+  ;

patternStep     :   T_2 angle stance;

stance          :  T_3;

angle   :   (T_4|T_5|T_6|T_7) T_8 T_9? T_10;

T_1: ‘Moves:’;
T_2: ‘Turn’;
T_3: 'Walking Stance';
T_4: '90';
T_5: '180';
T_6: '270';
T_7: '360';
T_8: '°';
T_9: 'anti-';
T_10: 'clockwise';

ANTLR 处理字符流,将它们传递给词法分析器,词法分析器必须决定如何处理所有字符(甚至是空格)。词法分析器生成由解析器规则处理的标记流。

您需要一些词法分析器规则来规定如何处理 whatespace:

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

是一种常见的处理方式。它将所有空格标记为 WS 标记,然后 skip 将该标记传递给解析器。 (这非常方便,因为您不必在整个语法中需要空格的地方散布 WSWS? 项。

你的插件接受你的输入对我来说意味着它可能将每一行输入视为一个新的解析。