ANTLR4解析不一致

  • 本文关键字:不一致 ANTLR4 antlr4
  • 更新时间 :
  • 英文 :


在我刚写的一个小测试范围内,我遇到了一个奇怪的问题,我不太了解。

将其剥离为显示问题的最小示例,让我们从以下语法开始:

testing.g4:

grammar Testing;
cscript                           // This is the construct I shortened
    : (statement_list)* ;
statement_list
    : statement ';' statement_list?
    | block
    ;
statement
    : assignment_statement
    ;
block : '{' statement_list? '}' ;
expression
    : left=expression op=('*'|'/') right=expression              # arithmeticExpression
    | left=expression op=('+'|'-') right=expression              # arithmeticExpression
    | left=expression op=Comparison_operator right=expression    # comparisonExpression
    | ID                                                         # variableValueExpression
    | constant                                                   # ignore  // will be executed with the rule name
    ;
assignment_statement
    : ID op=Assignment_operator expression
    ;
constant
    : INT
    | REAL;
Assignment_operator : ('=' | '+=' | '-=') ;
Comparison_operator : ('<' | '>' | '==' | '!=') ;
Comment : '//' .*? 'n' -> skip;
fragment NUM : [0-9];
INT : NUM+;
REAL
    : NUM* '.' NUM+
    | '.' NUM+
    | INT
    ; 
ID : [a-zA-Z_] [a-zA-Z_0-9]*;
WS : [ trn]+ -> skip;

使用输入

z = x + y;

一切都很好,我们得到了一个解析树,该树从cscript到statement_list,statement,spectment_statement,id和expression。太好了!

现在,如果我添加了声明变量的可能性,所有这些都会下降:

这是语法的变化:

cscript
    : (statement_list | variable_declaration ';')* ;
variable_declaration
    : type ID ('=' expression)?
    ;
type
    : 'int'
    | 'real'
    ;
statement_list
    : statement ';' statement_list?
    | block
    ;
statement
    : assignment_statement
    ;
// (continue as before)

突然之间,相同的测试输入被错误地分解为两个语句_lists,每个语句继续带有"缺失';'"警告,第一个将转到" z ="的不完整sizhtment_statement_ statement_statement_statement_stater。到不完整的sigsment_statement" x "。

我试图以文本形式显示解析树:

cscript
    statement_list
        statement
            assignment_statement
                'z'
                '=' [marked as error]
        [warning: missing ';']
    statement_list
        statement
            assignment_statement
                'x'
                '+' [marked as error]
        'y' [marked as error]
        ';'

谁能告诉我问题是什么?(以及如何修复它?; - ))


在2016-12-26上进行编辑,在Mike的评论之后:

用显式声明替换所有隐式Lexer规则后,突然间,输入" z = x y"工作了。(大拇指

我接下来要做的就是恢复更多我想到的原始示例,并添加新的输入行

int x = 22;

输入(以前有效,但没有将其归入最小示例)。现在,线路失败。这是测试钻机的输出输出:

[@0,0:2='int',<4>,1:0]
[@1,4:4='x',<22>,1:4]
[@2,6:6='=',<1>,1:6]
[@3,8:9='22',<20>,1:8]
[@4,10:10=';',<12>,1:10]
[@5,13:13='z',<22>,2:0]
[@6,15:15='=',<1>,2:2]
[@7,17:17='x',<22>,2:4]
[@8,19:19='+',<18>,2:6]
[@9,21:21='y',<22>,2:8]
[@10,22:22=';',<12>,2:9]
[@11,25:24='<EOF>',<-1>,3:0]
line 1:6 mismatched input '=' expecting '='

由于问题似乎在变量_declaration部分中,我什至试图将其分为两个解析规则:

cscript
    : (statement_list | variable_declaration_and_assignment SEMICOLON | variable_declaration SEMICOLON)* ;
variable_declaration_and_assignment
    : type ID EQUAL expression
    ;
variable_declaration
    : type ID
    ;

结果:

line 1:6 no viable alternative at input 'intx='

仍然卡住:-(顺便说一句:拆分" int x = 22;"进入" int x;"one_answers" x = 22;"作品。叹气


在2016-12-26上进行编辑,在Mike的下一个评论之后:

仔细检查,一切都是Lexer规则。尽管如此," ='and'='之间的不匹配(不幸的是,我再也无法重建)给了我检查令牌类型的想法。当前状态是:

(缩短语法)

cscript
    : (statement_list | variable_declaration)* ;
...
variable_declaration
    : type ID (EQUAL expression)? SEMICOLON
    ;
...
Assignment_operator : (EQUAL | PLUS_EQ | MINUS_EQ) ;
// among others
PLUS_EQ : '+=';
MINUS_EQ : '-=';
EQUAL: '=';
...

缩短输出:

[@0,0:2='int',<4>,1:0]
[@1,4:4='x',<22>,1:4]
[@2,6:6='=',<1>,1:6]
...
line 1:6 mismatched input '=' expecting ';'

在这里,如果我正确理解了这一点,则" ="是将令牌类型1解析,根据lexer.tokens的输出 - 是sistizent_operator,而预期相等的是13。

这可能是问题吗?

好的,似乎主要的收入是:考虑您的定义以及如何定义它们。为您的文字创建明确的Lexer规则,而不是在解析器规则中隐式定义它们。如果解析器给您奇怪的错误,请检查您从Lexer获得的令牌值,因为它们必须首先是正确的,否则您的解析没有机会完成工作。

相关内容

  • 没有找到相关文章

最新更新