这是我的XML解析器语法:
attribute : Name '=' STRING ;
和词法分析器:
STRING : '"' ~[<"]* '"'
| '\'' ~[<']* '\''
;
这有效,但是当我使用以下命令在C#代码中检索STRING位时:
context.STRING().ToString();
我将文本用引号引起来,例如:“ hello”,而不是hello。 所以我尝试将解析器语法更改为:
attribute : Name '=' '"' STRING ;
或
attribute : Name '="' STRING ;
我收到错误消息:“无法在非组合语法中为字符串文字创建隐式标记”
我很困惑为什么解析器语法中允许使用“ =”,但不允许使用引号,以及如何更改解析器以检索不带引号的文本。另外,该词法分析器似乎已经可以消除引号,因此我不理解为什么在解析时仍能得到引号。
答案 0 :(得分:1)
如果您有单独的词法分析器和解析器语法,则当且仅当您在词法分析器中使用该字符串文字定义了词法规则时,才允许在解析器中使用字符串文字。否则,词法分析器将永远不会产生与该字面值匹配的标记,因为该词法分析器不知道解析器中是否出现了哪些字符串文字(组合语法不是这种情况,这就是为什么错误消息会显示“ non-组合语法”)。
因此,您可以使用'='
,但不能使用'"'
,因为您有规则EQUALS: '=';
,但没有规则DQUOTE: '"';
。但是在继续添加这样的规则之前,让我们考虑一下该怎么做以及是否需要(不这样做):
如果您添加了这样的规则(或在没有语法的情况下使用了组合语法,则'"'
规则现在将与名称标记匹配,后跟{{1} }令牌,后跟attribute
令牌,后跟字符串令牌。由于字符串令牌已经在其开头和结尾都包含了引号,所以看起来像这样:
=
所以这不是您想要的。另外,即使您想要的是它也不起作用:上面输入中的第一引号不会被识别为"
令牌-而是SomeName = " "hello"
Name '=' '"' STRING
将被识别为字符串令牌,然后将'"'
作为" "
,最后将hello
作为Name
令牌(因为没有进一步的引用使它与"
规则匹配。>
所以这是错误的方向,您不应该这样做。
如果您要获取不带引号的字符串内容,则解决方案不是在语法中添加更多引号。您应该只在C#代码中使用'"'
从字符串中删除第一个和最后一个字符。