当前位置: 首页 > 知识库问答 >
问题:

用Antlr4匹配令牌

汪文光
2023-03-14

我是一个Antlr4新手,有一个相对简单的语法问题。语法在末尾的底部给出。(这是一个语法片段,用于分析生物序列变体的描述)。

在下面的单元测试中,我试图解析字符串“p.a3l”

@Test
public void testProteinSubtitutionWithoutRef() {
    ANTLRInputStream inputStream = new ANTLRInputStream("p.A3L");
    HGVSLexer l = new HGVSLexer(inputStream);
    HGVSParser p = new HGVSParser(new CommonTokenStream(l));
    p.setTrace(true);
    p.addErrorListener(new BaseErrorListener() {
        @Override
        public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line,
                int charPositionInLine, String msg, RecognitionException e) {
            throw new IllegalStateException("failed to parse at line " + line + " due to " + msg, e);
        }
    });
    p.hgvs();
}

这里出了什么问题?我在哪里可以学习如何解决这个问题?

grammar HGVS;

hgvs: protein_var
    ;

// Basix lexemes

AA: AA1
  | AA3
  | 'X';

AA1: 'A'
   | 'R'
   | 'N'
   | 'D'
   | 'C'
   | 'Q'
   | 'E'
   | 'G'
   | 'H'
   | 'I'
   | 'L'
   | 'K'
   | 'M'
   | 'F'
   | 'P'
   | 'S'
   | 'T'
   | 'W'
   | 'Y'
   | 'V';

AA3: 'Ala'
   | 'Arg'
   | 'Asn'
   | 'Asp'
   | 'Cys'
   | 'Gln'
   | 'Glu'
   | 'Gly'
   | 'His'
   | 'Ile'
   | 'Leu'
   | 'Lys'
   | 'Met'
   | 'Phe'
   | 'Pro'
   | 'Ser'
   | 'Thr'
   | 'Trp'
   | 'Tyr'
   | 'Val';

NUMBER: [0-9]+;

NAME: [a-zA-Z0-9_]+;

// Top-level Rule

/** Variant in a protein. */
protein_var: 'p.' AA NUMBER AA
           ;

共有1个答案

万俟招
2023-03-14

有两个问题:

  • 在lexer规则之前为protein_var定义规则(现在应该可以这样做,但不容易阅读,因为另一个解析器规则在前面)。
  • 删除名称的规则。A3L不是(如您所料)AA NUMBER AA,而是name<=ANTLR总是更喜欢最长的匹配lexer规则

得到的语法应该如下所示:

grammar HGVS;

hgvs
    : protein_var
    ;

protein_var
    : 'p.' AA NUMBER AA
    ;

AA: ...;

AA3: ...;

AA1: ...;

NUMBER: [0-9]+;

如果需要name用于其他目的,则必须在lexer中消除它的歧义(使用nameS和AA不相同的前缀或使用lexer模式)。

 类似资料:
  • 标准的TestCase之一是,lexer应该从中生成令牌流。不幸的是,由于ANTLR优先匹配较长的令牌,它生成令牌流,这将导致解析器引发错误。 是否可以先让ANTLR4 lexer尝试使用较短的令牌进行匹配?向添加lookahead-type规则并不是一个很好的解决方案,因为我需要考虑各种潜在的词法冲突(例如,被命名为,而不是,等等)。 编辑: 但这并不是一个真正的可扩展或可维护的解决方案,而且还

  • 我是ANTLR的新手。我想写一个语法来解析下面的输入: 语法如下:: 当我尝试使用语法解析上述输入时,它会引发以下异常:: 第1行:0不匹配的输入'commit a1b2c3d4',应为'commit' 我已经引用了ANTLR4:不匹配的输入链接,但仍然不清楚发生了什么。

  • 效果很好。但是我也想匹配包含关键字的句子,这些关键字不会被期望终止ID+块。例如 fist显示为,然后作为第一个ID+的一部分。按照上面链接的问题的例子,我可以这样修复它: 它起作用了,而且做的正是我想要的。在我的真实语言中,我有数百个关键字列表,用于不同类型的句子,所以如果我尝试这种方法,我肯定会犯错误,当我在我的语言中创建新的结构时,我必须返回并编辑所有其他结构。 最好是从列表中进行非贪婪匹配

  • 我刚刚开始学习ANTLR4 lexer规则。我的目标是为Java属性文件创建一个简单的语法。以下是我目前掌握的信息:

  • 我需要编写一个Java程序,使用,在给定一个源文件和一个方法的情况下,可以计算变量、运算符、标点符号和保留字的数量。 如何使用根据标记的类型对其计数?