ANTLR Decaf语法无法正确匹配带参数方法调用的问题排查
问题根因
当前Decaf语法的expression规则中,location备选分支的优先级高于methodCall分支。ANTLR解析表达式时会按照规则书写顺序优先尝试匹配靠前的分支,当解析factorial(b)这类带参数的方法调用时,解析器会先匹配factorial为location规则中的ID,后续的参数部分因歧义被错误吸收,最终将整个方法调用识别为location;无参数时()结构辨识度高,location匹配失败后会回退到methodCall分支,因此表现正常。
修复方案
调整expression规则的备选分支顺序,将methodCall放到location之前,提高方法调用的匹配优先级:
expression : methodCall #expr_mcall | location #expr_loc | literal #expr_literal | '-' expression #expr_minus // Unary Minus Operation | '!' expression #expr_not // Unary NOT Operation | '('expression')' #expr_parenthesis | expression arith_op_fifth expression #expr_arith5 // * / % << >> | expression arith_op_fourth expression #expr_arith4 // + - | expression arith_op_third expression #expr_arith3 // == != < <= > >= | expression arith_op_second expression #expr_arith2 // && | expression arith_op_first expression #expr_arith1 // || ;
调整后,解析器遇到ID后紧跟(的结构时,会优先匹配方法调用规则;如果ID后不是(,methodCall分支匹配失败,会自动回退到location分支匹配变量/结构体成员,不会影响普通变量的解析逻辑。
额外可选优化(非必须)
为了进一步降低歧义,可以将基础原子表达式抽成独立的primary规则,逻辑更清晰:
primary : literal | '(' expression ')' | methodCall | location ; expression : primary #expr_primary | '-' expression #expr_minus | '!' expression #expr_not | expression arith_op_fifth expression #expr_arith5 | expression arith_op_fourth expression #expr_arith4 | expression arith_op_third expression #expr_arith3 | expression arith_op_second expression #expr_arith2 | expression arith_op_first expression #expr_arith1 ;
修改后重新生成语法解析器,a=factorial(b)即可被正确识别为location = expression -> methodCall结构。
内容的提问来源于stack exchange,提问作者Rodrigo Zea
相关产品推荐
相关产品推荐

