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