all:我正在尝试编写一个 antlr 解析器来解析一些文本,其格式如下:
RP NUCLEOTIDE SEQUENCE [GENOMIC DNA],
RP PROTEIN SEQUENCE OF 1-22; 2-17;
RP 240-256; 318-339 AND 381-390, AND CHARACTERIZATION.
基本上所有的行都有一个前导'RP '
来指示文本行的用途,最后一行应该以 a"."
结尾来指示这种类型的行的结尾。文本也可以是任何东西。我最终需要的是文本。
为此,我编写了一个 Antlr 语法:
grammar RefLine;
rp_line: RP_HEADER RP_TEXT;
RP_HEADER : 'RP ' -> pushMode(RP_FREE_TEXT_MODE);
mode RP_FREE_TEXT_MODE;
RP_HEADER_SKIP: '\nRP ' -> skip;
RP_TEXT: .+;
DOT_NEWLINE: '.\n' -> popMode;
这里的想法是当看到第一个 RP_HEADER 时,它会更改为 RP_FREE_TEXT_MODE 并因此跳过行之间的任何 RP_HEADER。当看到 DOT_NEWLINE 时,返回主模式。
然而,这个语法不能用 Antlr 4.1 编译,产生错误:
[ERROR] Message{errorType=MODE_NOT_IN_LEXER, args=[RP_FREE_TEXT_MODE, org.antlr.v4.tool.Grammar@5c0662], e=null, fileName='RefLine.g4', line=7, charPosition=5}
[WARNING] Message{errorType=IMPLICIT_TOKEN_DEFINITION, args=[RP_TEXT], e=null, fileName='RefLine.g4', line=3, charPosition=19}
我不太明白为什么会产生错误。谁能解释在 Antlr 中使用词法分析器模式的正确方法?另外,在模式中定义的 TOKEN 是否对解析器规则不可用?
编辑:
正如@auselen 建议的那样,我将词法分析器放在一个单独的文件 RefLineLex.g4 中:
lexer grammar RefLineLex;
RP_HEADER : 'RP ' -> pushMode(RP_FREE_TEXT_MODE);
mode RP_FREE_TEXT_MODE;
RP_HEADER_SKIP: '\nRP ' -> skip;
RP_TEXT: .+;
DOT_NEWLINE: '.\n' -> popMode;
在另一个组合语法 RefLine.g4 我有:
grammar RefLine;
import RefLineLex;
rp_line: RP_HEADER RP_TEXT ;
现在 Antlr 编译文件,但在它生成的 RefLineLexer.java 中:
private void RP_HEADER_action(RuleContext _localctx, int actionIndex) {
switch (actionIndex) {
case 0: pushMode(RP_FREE_TEXT_MODE); break;
}
}
常量: RP_FREE_TEXT_MODE
未在 RefLineLexer.java 中的任何位置定义。我还缺少什么吗?