【问题标题】:Lexer Mode in AntlrAntlr 中的词法分析器模式
【发布时间】:2013-08-14 22:19:30
【问题描述】:

全部: 我正在尝试编写一个 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 ' 来指示文本行的用途,最后一行应以"." 结尾以指示此类行的结束。文本也可以是任何东西。我到底需要的是文字。

为此我写了一个 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 中的任何位置定义。 我还缺少什么吗?

【问题讨论】:

  • 如果您只想提取连接的文本,Antlr 可能是矫枉过正。也许是一个简单的逐行 Java 程序,它查看第一个标记以选择行并将文本添加到 StringBuilder,直到找到以 '.' 结尾的行?
  • @JimGarrison,它只是大型平面文件解析器的一小部分..
  • 提出一个新问题,不要更改现有问题 - 这将永远存在。

标签: java antlr antlr4


【解决方案1】:

Lexer 模式仅在 Lexer 语法中可用,而在复合语法(Lexer + Parser)中不可用。请参阅 Lexer Rules 了解一些糟糕的文档,并查看 github 上的 XML Parser 实现以获取示例。

您应该能够在错误打印中的信息非常丰富的errorType=MODE_NOT_IN_LEXER 消息中理解这一点:)

【讨论】:

  • Lexer Rules 链接已损坏 :)
  • 它的几个功能在复合语法中停止工作太糟糕了。我发现如果导入我的 lexar 语法会出现一些问题,这迫使我使用复合语法。例如,item{} 和 after{} 操作似乎中断了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-25
相关资源
最近更新 更多