我是一个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
;
有两个问题:
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中消除它的歧义(使用name
S和AA
不相同的前缀或使用lexer模式)。
标准的TestCase之一是,lexer应该从中生成令牌流。不幸的是,由于ANTLR优先匹配较长的令牌,它生成令牌流,这将导致解析器引发错误。 是否可以先让ANTLR4 lexer尝试使用较短的令牌进行匹配?向添加lookahead-type规则并不是一个很好的解决方案,因为我需要考虑各种潜在的词法冲突(例如,被命名为,而不是,等等)。 编辑: 但这并不是一个真正的可扩展或可维护的解决方案,而且还
我是ANTLR的新手。我想写一个语法来解析下面的输入: 语法如下:: 当我尝试使用语法解析上述输入时,它会引发以下异常:: 第1行:0不匹配的输入'commit a1b2c3d4',应为'commit' 我已经引用了ANTLR4:不匹配的输入链接,但仍然不清楚发生了什么。
效果很好。但是我也想匹配包含关键字的句子,这些关键字不会被期望终止ID+块。例如 fist显示为,然后作为第一个ID+的一部分。按照上面链接的问题的例子,我可以这样修复它: 它起作用了,而且做的正是我想要的。在我的真实语言中,我有数百个关键字列表,用于不同类型的句子,所以如果我尝试这种方法,我肯定会犯错误,当我在我的语言中创建新的结构时,我必须返回并编辑所有其他结构。 最好是从列表中进行非贪婪匹配
我刚刚开始学习ANTLR4 lexer规则。我的目标是为Java属性文件创建一个简单的语法。以下是我目前掌握的信息:
我需要编写一个Java程序,使用,在给定一个源文件和一个方法的情况下,可以计算变量、运算符、标点符号和保留字的数量。 如何使用根据标记的类型对其计数?