为什么令牌显示为 'end' 类型而不是 STRING?
Why the token is displayed as 'end' type instead of STRING?
我的目标是保存以任何单词开头并以 "end" 单词结尾的评论,如下所示
ANYWORD bla bla bla end
我有这个语法:
lexer grammar JunkLexer;
WS : [ \r\t\n]+ -> skip ;
LQUOTE : 'start' -> more, mode(START) ;
mode START;
STRING : 'end' -> mode(DEFAULT_MODE) ; // token we want parser to see
TEXT : . -> more ; // collect more text for string
但不知道为什么,词法分析器生成语法中不存在的标记:
当我检查词法分析器标记时,是一样的:
WS=1
STRING=2
LQUOTE=3
'start'=3
'end'=2
提前致谢
当您使用单个字符串文字定义词法分析器规则时,该字符串文字将成为该规则的替代名称。因此,当您在词法分析器语法中定义 FOO: 'foo';
时,您可以在解析器语法中互换使用 FOO
和 'foo'
。这允许您在语法中使用字符串文字,即使您将其拆分为解析器和词法分析器语法。所以即使你必须在词法分析器中写 PLUS: '+';
,你仍然可以在语法中写 exp '+' exp
而不是 exp PLUS exp
。字符串文字名称也是显示令牌时使用的名称,因为它往往更具可读性。
当然这在 PLUS
示例中有意义,但在您的示例中并没有真正意义,因为,由于 more
,您的 STRING
规则不实际上只是匹配end
,而是一个完整的字符串。因此,在解析器语法中编写 'end'
以匹配完整的开始-结束部分将完全令人困惑(尽管它会起作用),它被用作标记名称的事实也是如此。然而 ANTLR 没有意识到这一点,因为它没有意识到 STRING
只能通过调用 more
.
的规则来实现
请注意,您仍然可以使用 STRING
来引用标记,因此这实际上不会以任何方式破坏您的语法。但是,这会导致错误消息令人困惑("missing 'end'",而它应该是 "missing STRING")。
要解决此问题,您可以将 STRING
规则更改为不仅包含单个字符串文字:
STRING: 'e' 'n' 'd';
除了 'end'
不再是 STRING
的别名并且不再用作令牌的显示名称外,这在各个方面都是等效的。
我的目标是保存以任何单词开头并以 "end" 单词结尾的评论,如下所示
ANYWORD bla bla bla end
我有这个语法:
lexer grammar JunkLexer;
WS : [ \r\t\n]+ -> skip ;
LQUOTE : 'start' -> more, mode(START) ;
mode START;
STRING : 'end' -> mode(DEFAULT_MODE) ; // token we want parser to see
TEXT : . -> more ; // collect more text for string
但不知道为什么,词法分析器生成语法中不存在的标记:
当我检查词法分析器标记时,是一样的:
WS=1
STRING=2
LQUOTE=3
'start'=3
'end'=2
提前致谢
当您使用单个字符串文字定义词法分析器规则时,该字符串文字将成为该规则的替代名称。因此,当您在词法分析器语法中定义 FOO: 'foo';
时,您可以在解析器语法中互换使用 FOO
和 'foo'
。这允许您在语法中使用字符串文字,即使您将其拆分为解析器和词法分析器语法。所以即使你必须在词法分析器中写 PLUS: '+';
,你仍然可以在语法中写 exp '+' exp
而不是 exp PLUS exp
。字符串文字名称也是显示令牌时使用的名称,因为它往往更具可读性。
当然这在 PLUS
示例中有意义,但在您的示例中并没有真正意义,因为,由于 more
,您的 STRING
规则不实际上只是匹配end
,而是一个完整的字符串。因此,在解析器语法中编写 'end'
以匹配完整的开始-结束部分将完全令人困惑(尽管它会起作用),它被用作标记名称的事实也是如此。然而 ANTLR 没有意识到这一点,因为它没有意识到 STRING
只能通过调用 more
.
请注意,您仍然可以使用 STRING
来引用标记,因此这实际上不会以任何方式破坏您的语法。但是,这会导致错误消息令人困惑("missing 'end'",而它应该是 "missing STRING")。
要解决此问题,您可以将 STRING
规则更改为不仅包含单个字符串文字:
STRING: 'e' 'n' 'd';
除了 'end'
不再是 STRING
的别名并且不再用作令牌的显示名称外,这在各个方面都是等效的。