为什么解析器中的单独字符包含在令牌中?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么解析器中的单独字符包含在令牌中?相关的知识,希望对你有一定的参考价值。

我有一个用ANTLR编写的组合语法,如下:

names: NAME (',' NAME)*;

NAME: (REG_NAME | QUOTED_NAME);

fragment QUOTED_NAME:      '\\"' QUOTED_NAME_CHAR+ '\\"';
fragment REG_NAME:         REG_NAME_CHAR+;
fragment QUOTED_NAME_CHAR: (LETTER | ',');
fragment REG_NAME_CHAR:    LETTER+;
fragment LETTER:           ('a..z' | 'A..Z');

[基本上,名称只能包含字母,或者如果包含引号,则可以包含字母和逗号。在大多数情况下,这种语法可以正常运行,但是NAME标记存在问题,其中包括未加引号的','。例如,如果我输入类似:

Bob,John,Sally,"\"Smith,James\"","\"Zane,Grey\""

我得到的NAME代币是:"Bob", ",John", ",Sally", "\"Smith,James\"", "\"Zane,Grey\""

为什么将逗号分隔符(不是NAME标记的一部分,包含在结果的NAME标记中?如何修改语法以解决此问题?

我确实将REG_NAME重写为~(',')REG_NAME_CHAR+;,并且在令牌中不包含逗号,但是似乎不需要修改,因为在这种情况下逗号不是有效的字符。

答案

您在这里有很多错误。请研究此更正的语法。

grammar foobar;
names: NAME (',' NAME)*;
NAME: (REG_NAME | QUOTED_NAME);
fragment QUOTED_NAME:      '"' QUOTED_NAME_CHAR+ '"';
fragment REG_NAME:         REG_NAME_CHAR+;
fragment QUOTED_NAME_CHAR: (LETTER | ',');
fragment REG_NAME_CHAR:    LETTER;
fragment LETTER:           ('a'..'z' | 'A'..'Z');
WS : [ \r\n\t] + -> skip ;

以上是关于为什么解析器中的单独字符包含在令牌中?的主要内容,如果未能解决你的问题,请参考以下文章

GrapQHL Apollo Server,提取值并在解析器中使用它们

片段着色器中的球面映射

Javascript 中的 IP 地址解析器

片段着色器中的OpenGL点精灵旋转

为啥在 Metal 中不允许从片段着色器中写入缓冲区?

Javascript - 去掉 JSON 字符串中出现的 u',解析返回意外令牌