如何解决如何在Antlr中的不同词法分析器模式下使用相同的令牌?
我有一个基于SQL Antlr4的词法分析器,它也可以从SQL注释中解析特定的标签:
OPEN_COMMENT: '/*' -> mode(COMMENT);
mode COMMENT;
NAME_TAG : '@name';
CLOSE_COMMENT: '*/' -> mode(DEFAULT_MODE);
此词法分析器能够读取以下内容:
/* @name GetAllUsers */
但是,我也希望能够阅读行注释:
-- @name @GetAllUsers
我不能使用相同的模式,因为CLOSE_COMMENT的工作方式有所不同:块注释应为*/
,行注释应为\n
。但是,无论是行注释还是块注释,我都希望解析器获得相同的标记。
我该如何实现?还是使用词法分析器模式根本不是正确的方法?
(出于这个问题的目的,我将代码仅修整为必要的部分,因此更易于阅读和推理。您可以找到有问题的here中的整个代码。)
解决方法
您必须将某些内容复制到2种不同的模式中。您可以定义通用令牌,例如语法NAME
块内的tokens { ... }
令牌,以便可以在展位模式下共享它。
快速演示:
lexer grammar TestLexer;
tokens {
NAME
}
ID
: [a-zA-Z_] [a-zA-Z_0-9]*
;
LINE_COMMENT_START
: '--' -> skip,mode(LINE_COMMENT_MODE)
;
BLOCK_COMMENT_START
: '/*' -> skip,mode(BLOCK_COMMENT_MODE)
;
mode LINE_COMMENT_MODE;
LINE_COMMENT_MODE_ID
: ID -> type(ID)
;
LINE_COMMENT_NAME
: '@name' -> type(NAME)
;
LINE_COMMENT_END
: [\r\n]+ -> skip,mode(DEFAULT_MODE)
;
LINE_COMMENT_OTHER
: . -> skip
;
mode BLOCK_COMMENT_MODE;
BLOCK_COMMENT_MODE_ID
: ID -> type(ID)
;
BLOCK_COMMENT_NAME
: '@name' -> type(NAME)
;
BLOCK_COMMENT_END
: '*/' -> skip,mode(DEFAULT_MODE)
;
BLOCK_COMMENT_OTHER
: . -> skip
;
如果将输入标记化:
-- @name GetAllUsers
/* @name GetAllUsers */
您将获得以下令牌:
NAME `@name`
ID `GetAllUsers`
NAME `@name`
ID `GetAllUsers`
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。