package parsing.C.Functions.builder; import org.antlr.v4.runtime.ParserRuleContext; import ast.ASTNode; import ast.expressions.Expression; import ast.statements.BlockStarter; import ast.statements.CompoundStatement; import ast.statements.DoStatement; import ast.statements.ElseStatement; import ast.statements.ExpressionHolder; import ast.statements.IfStatement; import ast.statements.WhileStatement; public class NestingReconstructor { ContentBuilderStack stack; public NestingReconstructor(ContentBuilderStack aStack) { stack = aStack; } protected void addItemToParent(ASTNode expression) { ASTNode topOfStack = stack.peek(); topOfStack.addChild(expression); } protected void consolidateSubExpression(ParserRuleContext ctx) { Expression expression = (Expression) stack.pop(); expression.initializeFromContext(ctx); if (!(expression instanceof ExpressionHolder)) expression = pullUpOnlyChild(expression); addItemToParent(expression); } private Expression pullUpOnlyChild(Expression expression) { if (expression.getChildCount() == 1) expression = (Expression) expression.getChild(0); return expression; } protected void consolidate() { ASTNode stmt = stack.pop(); ASTNode topOfStack = null; if (stack.size() > 0) topOfStack = stack.peek(); if (topOfStack instanceof CompoundStatement) { CompoundStatement compound = (CompoundStatement) topOfStack; compound.addStatement(stmt); } else { consolidateBlockStarters(stmt); } } // Joins consecutive BlockStarters on the stack protected void consolidateBlockStarters(ASTNode node) { while (true) { try { BlockStarter curBlockStarter = (BlockStarter) stack.peek(); curBlockStarter = (BlockStarter) stack.pop(); curBlockStarter.addChild(node); node = curBlockStarter; if (curBlockStarter instanceof IfStatement) { if (stack.size() > 0 && stack.peek() instanceof ElseStatement) { // This is an if inside an else, e.g., 'else if' // handling BlockStarter elseItem = (BlockStarter) stack.pop(); elseItem.addChild(curBlockStarter); IfStatement lastIf = (IfStatement) stack .getIfInElseCase(); if (lastIf != null) { lastIf.setElseNode((ElseStatement) elseItem); } return; } } else if (curBlockStarter instanceof ElseStatement) { // add else statement to the previous if-statement, // which has already been consolidated so we can return IfStatement lastIf = (IfStatement) stack.getIf(); if (lastIf != null) lastIf.setElseNode((ElseStatement) curBlockStarter); else throw new RuntimeException( "Warning: cannot find if for else"); return; } else if (curBlockStarter instanceof WhileStatement) { // add while statement to the previous do-statement // if that exists. Otherwise, do nothing special. DoStatement lastDo = stack.getDo(); if (lastDo != null) { lastDo.addChild(((WhileStatement) curBlockStarter) .getCondition()); return; } } } catch (ClassCastException ex) { break; } } // Finally, add chain to top compound-item ASTNode root = stack.peek(); root.addChild(node); } }