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+;