非片段词法分析器规则x可以匹配空字符串

时间:2016-08-31 03:13:32

标签: antlr4

以下antlr lexer出了什么问题?

我收到了错误

warning(146): MySQL.g4:5685:0: non-fragment lexer rule VERSION_COMMENT_TAIL can match the empty string

附加源代码

VERSION_COMMENT_TAIL:
{ VERSION_MATCHED == False }? // One level of block comment nesting is allowed for version comments.
    ((ML_COMMENT_HEAD MULTILINE_COMMENT) | . )*? ML_COMMENT_END { self.setType(MULTILINE_COMMENT); }
| { self.setType(VERSION_COMMENT); IN_VERSION_COMMENT = True; }

1 个答案:

答案 0 :(得分:1)

您是否正在尝试将我的ANTLR3语法转换为ANTLR4?删除词法分析器中的所有注释规则并改为插入:

// There are 3 types of block comments:
// /* ... */ - The standard multi line comment.
// /*! ... */ - A comment used to mask code for other clients. In MySQL the content is handled as normal code.
// /*!12345 ... */ - Same as the previous one except code is only used when the given number is a lower value
//                   than the current server version (specifying so the minimum server version the code can run with).
VERSION_COMMENT_START: ('/*!' DIGITS) (
  {checkVersion(getText())}? // Will set inVersionComment if the number matches.
  | .*? '*/'
) -> channel(HIDDEN)
;

// inVersionComment is a variable in the base lexer.
MYSQL_COMMENT_START: '/*!' { inVersionComment = true; setChannel(HIDDEN); };
VERSION_COMMENT_END: '*/' {inVersionComment}? { inVersionComment = false; setChannel(HIDDEN); };
BLOCK_COMMENT: '/*' ~[!] .*? '*/' -> channel(HIDDEN);

POUND_COMMENT: '#' ~([\n\r])*  -> channel(HIDDEN);
DASHDASH_COMMENT: DOUBLE_DASH ([ \t] (~[\n\r])* | LINEBREAK | EOF) -> channel(HIDDEN);

你的词法分析器中需要一个本地inVersionComment成员和一个函数checkVersion()(我在生成的词法分析器派生的基础词法分析器中有它),它返回true或false,具体取决于当前服务器版本等于或高于给定版本。

对于你的问题:你不能在替代方案中采取行动。操作只能出现在整个规则的末尾。这与ANTLR3不同。