Parsing ANTLR4-使令牌之间的空间可选

Parsing ANTLR4-使令牌之间的空间可选,parsing,antlr4,Parsing,Antlr4,我的语法如下: grammar Hello; prog: stat+ EOF; stat: DELIMITER_OPEN expr DELIMITER_CLOSE; expr: NOTES COMMA value=VAR_VALUE #delim_body; VAR_VALUE: ANBang*; NOTES: WS* 'notes' WS*; COMMA: ','; DELIMITER_OPEN: '<<!';DELIMITER_CLOSE: '!&g

我的语法如下:

grammar Hello;

prog:   stat+ EOF;

stat:   DELIMITER_OPEN expr DELIMITER_CLOSE;
expr:   NOTES COMMA value=VAR_VALUE #delim_body;

VAR_VALUE:  ANBang*;
NOTES:  WS* 'notes' WS*;
COMMA:  ',';
DELIMITER_OPEN: '<<!';DELIMITER_CLOSE:    '!>>';
fragment ANBang:    AlphaNum | Bang;
fragment AlphaNum:  [a-zA-Z0-9];
fragment Bang:  '!';

WS    : [ \t\r\n]+ -> skip ;
语法你好; 程序:stat+EOF; stat:DELIMITER\u OPEN expr DELIMITER\u CLOSE; expr:NOTES逗号值=VAR#u值#delim_体; VAR_值:安邦*; 注:WS*‘NOTES’WS*; 逗号:','; 分隔符_打开:“”; 安邦碎片:阿尔法纳姆|邦; 碎片AlphaNum:[a-zA-Z0-9]; 碎片爆炸:“!”; WS:[\t\r\n]+->跳过; 分析以下工作:

<<! notes, Test !>>

变量值为“Test”,但是,当我消除分隔符_OPEN和NOTES之间的空格时,解析器失败:

<<!notes, Test !>>

第1行:3不匹配的输入“注释”应为注释

这是另一个秩序混乱的lexer规则

当lexer扫描下一个令牌时,它首先尝试查找与最长令牌匹配的规则。如果多个规则匹配,它将通过按定义顺序选择第一个规则来消除歧义

将被标记为:
DELIMITER\u打开
注释
逗号
VAR\u值
WS
DELIMITER\u关闭

这是因为
NOTES
规则可以匹配以下内容:

<<! notes, Test !>>
   \____/
WS*
添加到其他规则没有多大意义,因为将跳过
WS
。并且将令牌声明为可能的零宽度
*
也是毫无意义的,因此请改用
+
。最后,对规则进行重新排序,使最具体的规则与第一个规则相匹配

这样,
notes
就成为语法中的关键词。如果不希望它成为关键字,请将
NOTES
规则一起删除,并将
VAR\u值
规则与谓词一起使用。或者,您可以使用lexer模式。

这是另一个lexer规则顺序错误的情况

当lexer扫描下一个令牌时,它首先尝试查找与最长令牌匹配的规则。如果多个规则匹配,它将通过按定义顺序选择第一个规则来消除歧义

将被标记为:
DELIMITER\u打开
注释
逗号
VAR\u值
WS
DELIMITER\u关闭

这是因为
NOTES
规则可以匹配以下内容:

<<! notes, Test !>>
   \____/
WS*
添加到其他规则没有多大意义,因为将跳过
WS
。并且将令牌声明为可能的零宽度
*
也是毫无意义的,因此请改用
+
。最后,对规则进行重新排序,使最具体的规则与第一个规则相匹配


这样,
notes
就成为语法中的关键词。如果不希望它成为关键字,请将
NOTES
规则一起删除,并将
VAR\u值
规则与谓词一起使用。或者,您也可以使用lexer模式。

既然您跳过空白,请在
NOTES
规则中尝试不使用
WS*
。既然您跳过空白,请在
NOTES
规则中尝试不使用
WS*
。谢谢。如果VAR_值标记可以包含类似“Test me”的内容,我是否必须停止忽略空格,或者如何捕获“notes”的值,该值可以是任何字符串,带有空格、标点符号等。我要么将所有内容放在一个
notes
标记中,要么在解析器阶段坚持将其拆分,最简单的方法是使用lexer模式。你能举个例子给我指出正确的方向吗?如果您愿意,我可以创建一个单独的问题。您只需在
!>>,这允许您更改某些构造中的lexer规则。谷歌的lexer模式,然后尝试实施一个解决方案,如果你仍然有一个问题,然后张贴另一个问题的具体问题。谢谢。如果VAR_值标记可以包含类似“Test me”的内容,我是否必须停止忽略空格,或者如何捕获“notes”的值,该值可以是任何字符串,带有空格、标点符号等。我要么将所有内容放在一个
notes
标记中,要么在解析器阶段坚持将其拆分,最简单的方法是使用lexer模式。你能举个例子给我指出正确的方向吗?如果您愿意,我可以创建一个单独的问题。您只需在
!>>,这允许您更改某些构造中的lexer规则。谷歌搜索lexer模式,然后尝试实现一个解决方案,如果你仍然有问题,然后发布另一个问题与具体问题。
NOTES:  'notes';
VAR_VALUE:  ANBang+;