我希望让 antlr 解析/树尽可能多的输入,以便信息可用于智能感知。也许这是错误的方法,但当输入不是 100% 有效时,这似乎是获得体面信息的唯一方法。
语法有由分号分隔的语句。我特别想要的是让 antlr 尝试解析/树所有由分号分隔的内容。这意味着 1 个损坏的语句不应阻止解析其他语句。
我可以使用以下内容轻松地将其添加到解析器语法中。
statements
: (statement (a=semicolon statement)* b=semicolon?) -> ^(BLOCK statement ($a statement)* $b?)
;
semicolon //Consume invalid tokens until we find a SEMICOLON.
: { while(input.LA(1) != EOF && input.LA(1) != SEMICOLON) input.Consume(); } SEMICOLON
;
这很好用。这是我为消耗不起作用的树重写所尝试的。
block returns [Statement block = null]
@init{ var statements = new List<Statement>(); }
: ^(t=BLOCK (s=statement { statements.Add(s); }) (semicolon s=statement { statements.Add(s); }))* semicolon?) { block = new Statement(li(t), statements); }
;
semicolon
: { while(input.LA(1) != EOF && input.LA(1) != SEMICOLON) input.Consume(); } SEMICOLON
;
查看编译后的代码表明它在使用之前会查找分号。这不起作用,因为分号前有无效的标记。
这是我目前处理解析器规则错误的方式。
rule : (A B c) => A^ B c
| A B { c(); } //Calling c reports the error without throwing an exception.