无法在非组合语法中为字符串文字创建隐式标记:

时间:2018-11-29 14:40:39

标签: antlr4

这是我的XML解析器语法:

attribute   :   Name '=' STRING ;

和词法分析器:

STRING      :   '"' ~[<"]* '"'
            |   '\'' ~[<']* '\''
            ;

这有效,但是当我使用以下命令在C#代码中检索STRING位时:

context.STRING().ToString();

我将文本用引号引起来,例如:“ hello”,而不是hello。 所以我尝试将解析器语法更改为:

attribute   :   Name '=' '"' STRING ;

attribute   :   Name '="' STRING ;

我收到错误消息:“无法在非组合语法中为字符串文字创建隐式标记”

我很困惑为什么解析器语法中允许使用“ =”,但不允许使用引号,以及如何更改解析器以检索不带引号的文本。另外,该词法分析器似乎已经可以消除引号,因此我不理解为什么在解析时仍能得到引号。

1 个答案:

答案 0 :(得分:1)

如果您有单独的词法分析器和解析器语法,则当且仅当您在词法分析器中使用该字符串文字定义了词法规则时,才允许在解析器中使用字符串文字。否则,词法分析器将永远不会产生与该字面值匹配的标记,因为该词法分析器不知道解析器中是否出现了哪些字符串文字(组合语法不是这种情况,这就是为什么错误消息会显示“ non-组合语法”)。

因此,您可以使用'=',但不能使用'"',因为您有规则EQUALS: '=';,但没有规则DQUOTE: '"';。但是在继续添加这样的规则之前,让我们考虑一下该怎么做以及是否需要(不这样做):

如果您添加了这样的规则(或在没有语法的情况下使用了组合语法,则'"'规则现在将与名称标记匹配,后跟{{1} }令牌,后跟attribute令牌,后跟字符串令牌。由于字符串令牌已经在其开头和结尾都包含了引号,所以看起来像这样:

=

所以这不是您想要的。另外,即使您想要的是它也不起作用:上面输入中的第一引号不会被识别为"令牌-而是SomeName = " "hello" Name '=' '"' STRING 将被识别为字符串令牌,然后将'"'作为" ",最后将hello作为Name令牌(因为没有进一步的引用使它与"规则匹配。

所以这是错误的方向,您不应该这样做。


如果您要获取不带引号的字符串内容,则解决方案不是在语法中添加更多引号。您应该只在C#代码中使用'"'从字符串中删除第一个和最后一个字符。