由于自顶向下解析的性质,ANTLR在到达表达式内的叶子之前生成具有一些长重复结构的解析树,其中包含许多多余的节点。
例如,在以下代码中使用C.g4语法(https://github.com/antlr/grammars-v4/tree/master/c):
main(){
int a=5, b=10;
for(int i =0;i<b;i++){
b=a--;
}
}
生成的树是:
(compilationUnit(translationUnit(externalDeclaration (functionDefinition(declarator(directDeclarator(directDeclarator。) main)()))(compoundStatement {(blockItemList(blockItemList (blockItem(声明(declarationSpecifiers)(declarationSpecifier (typeSpecifier int)))(initDeclaratorList(initDeclaratorList (initDeclarator(declarator(directDeclarator a))=(初始化器 (assignmentExpression(conditionalExpression(logicalOrExpression (logicalAndExpression(inclusiveOrExpression(exclusiveOrExpression (andExpression(equalityExpression(relationalExpression (shiftExpression(additiveExpression(multiplicativeExpression (castExpression(unaryExpression(postfixExpression(primaryExpression 5))))))))))))))))))),(initDeclarator(声明者(directDeclarator) b))=(初始化器(assignmentExpression(conditionalExpression (logicalOrExpression(logicalAndExpression(inclusiveOrExpression (exclusiveOrExpression(andExpression(equalityExpression (relationalExpression(shiftExpression(additiveExpression (multiplicativeExpression(castExpression(unaryExpression (postfixExpression(primaryExpression 10)))))))))))))))))));))) (blockItem(statement(iterationStatement for((声明 (declarationSpecifiers(declarationSpecifier(typeSpecifier int))) (initDeclaratorList(initDeclarator(declarator(directDeclarator i)) =(初始化器(assignmentExpression):conditionalExpression(logicalOrExpression(logicalAndExpression(inclusiveOrExpression) (exclusiveOrExpression(andExpression(equalityExpression (relationalExpression(shiftExpression(additiveExpression (multiplicativeExpression(castExpression(unaryExpression (postfixExpression(primaryExpression 0)))))))))))))))))));) (表达式(assignmentExpression(conditionalExpression (logicalOrExpression(logicalAndExpression(inclusiveOrExpression (exclusiveOrExpression(andExpression(equalityExpression (relationalExpression(relationalExpression(shiftExpression (additiveExpression(multiplicativeExpression(castExpression (unaryExpression(postfixExpression(primaryExpression i)))))))))&lt; (shiftExpression(additiveExpression(multiplicativeExpression (castExpression(unaryExpression(postfixExpression(primaryExpression b))))))))))))))))); (表达式(assignmentExpression (conditionalExpression(logicalOrExpression(logicalAndExpression (inclusiveOrExpression(exclusiveOrExpression(andExpression。) (equalityExpression(relationalExpression(shiftExpression (additiveExpression(multiplicativeExpression(castExpression (unaryExpression(postfixExpression(postfixExpression (primaryExpression i))++)))))))))))))))))(声明 (compoundStatement {(blockItemList(blockItem(statement (expressionStatement(expression(assignmentExpression。) (unaryExpression(postfixExpression(primaryExpression b))) (assignmentOperator =)(assignmentExpression(conditionalExpression (logicalOrExpression(logicalAndExpression(inclusiveOrExpression (exclusiveOrExpression(andExpression(equalityExpression (relationalExpression(shiftExpression(additiveExpression (multiplicativeExpression(castExpression(unaryExpression (postfixExpression(postfixExpression(primaryExpression a)) - )))))))))))))))));))))}))))))})))))
其中树的子结构与代码存根匹配&#34; int a = 5&#34;是:
(声明(declarationSpecifiers(declarationSpecifier (typeSpecifier int)))(initDeclaratorList(initDeclaratorList (initDeclarator(declarator(directDeclarator a))=(初始化器 (assignmentExpression(conditionalExpression(logicalOrExpression (logicalAndExpression(inclusiveOrExpression(exclusiveOrExpression (andExpression(equalityExpression(relationalExpression (shiftExpression(additiveExpression(multiplicativeExpression (castExpression(unaryExpression(postfixExpression(primaryExpression 5)))))))))))))))))))
我们清楚地看到,这大致可以简化为:
(声明(declarationSpecifiers(declarationSpecifier (typeSpecifier int)))(initDeclaratorList(initDeclaratorList (initDeclarator(declarator(directDeclarator a))=(初始化器 (assignmentExpression(postfixExpression(primaryExpression 5))))))
我正在使用解析树来执行某些静态分析,并且由于上面显示的多余节点,我需要在系统的侦听器端执行大量检查以访问感兴趣的正确树节点。
所以我想知道是否有一种简单的方法可以通过使用一组转换规则修改解析树来删除多余的节点和/或减少长重复结构。