package parsing.C.Modules; import java.util.Iterator; import java.util.List; import org.antlr.v4.runtime.ParserRuleContext; import parsing.ANTLRParserDriver; import parsing.CompoundItemAssembler; import parsing.C.ModuleFunctionParserInterface; import parsing.C.Modules.builder.FunctionDefBuilder; import parsing.C.Shared.builders.ClassDefBuilder; import parsing.C.Shared.builders.IdentifierDeclBuilder; import antlr.C.ModuleBaseListener; import antlr.C.ModuleParser; import antlr.C.ModuleParser.Class_defContext; import antlr.C.ModuleParser.DeclByClassContext; import antlr.C.ModuleParser.Init_declarator_listContext; import antlr.C.ModuleParser.Type_nameContext; import ast.declarations.IdentifierDecl; import ast.statements.CompoundStatement; import ast.statements.IdentifierDeclStatement; // Converts Parse Trees to ASTs for Modules public class CModuleParserTreeListener extends ModuleBaseListener { ANTLRParserDriver p; public CModuleParserTreeListener(ANTLRParserDriver aP) { p = aP; } @Override public void enterCode(ModuleParser.CodeContext ctx) { p.notifyObserversOfUnitStart(ctx); } @Override public void exitCode(ModuleParser.CodeContext ctx) { p.notifyObserversOfUnitEnd(ctx); } // ///////////////////////////////////////////////////////////// // This is where the ModuleParser invokes the FunctionParser // ///////////////////////////////////////////////////////////// // This function is invoked when a Function_Def parse tree node // is entered. This is where we hand over the function contents to // the function parser and connect the AST node created for the // function definition to the AST created by the function parser. // //////////////////////////////////////////////////////////////// @Override public void enterFunction_def(ModuleParser.Function_defContext ctx) { FunctionDefBuilder builder = new FunctionDefBuilder(); builder.createNew(ctx); p.builderStack.push(builder); CompoundStatement functionContent = ModuleFunctionParserInterface .parseFunctionContents(ctx); builder.setContent(functionContent); } @Override public void exitFunction_def(ModuleParser.Function_defContext ctx) { FunctionDefBuilder builder = (FunctionDefBuilder) p.builderStack.pop(); p.notifyObserversOfItem(builder.getItem()); } @Override public void enterReturn_type(ModuleParser.Return_typeContext ctx) { FunctionDefBuilder builder = (FunctionDefBuilder) p.builderStack.peek(); builder.setReturnType(ctx, p.builderStack); } @Override public void enterFunction_name(ModuleParser.Function_nameContext ctx) { FunctionDefBuilder builder = (FunctionDefBuilder) p.builderStack.peek(); builder.setName(ctx, p.builderStack); } @Override public void enterFunction_param_list( ModuleParser.Function_param_listContext ctx) { FunctionDefBuilder builder = (FunctionDefBuilder) p.builderStack.peek(); builder.setParameterList(ctx, p.builderStack); } @Override public void enterParameter_decl(ModuleParser.Parameter_declContext ctx) { FunctionDefBuilder builder = (FunctionDefBuilder) p.builderStack.peek(); builder.addParameter(ctx, p.builderStack); } // DeclByType @Override public void enterDeclByType(ModuleParser.DeclByTypeContext ctx) { Init_declarator_listContext decl_list = ctx.init_declarator_list(); Type_nameContext typeName = ctx.type_name(); emitDeclarations(decl_list, typeName, ctx); } private void emitDeclarations(ParserRuleContext decl_list, ParserRuleContext typeName, ParserRuleContext ctx) { IdentifierDeclBuilder builder = new IdentifierDeclBuilder(); List<IdentifierDecl> declarations = builder.getDeclarations(decl_list, typeName); IdentifierDeclStatement stmt = new IdentifierDeclStatement(); // stmt.initializeFromContext(ctx); Iterator<IdentifierDecl> it = declarations.iterator(); while (it.hasNext()) { IdentifierDecl decl = it.next(); stmt.addChild(decl); } p.notifyObserversOfItem(stmt); } // DeclByClass @Override public void enterDeclByClass(ModuleParser.DeclByClassContext ctx) { ClassDefBuilder builder = new ClassDefBuilder(); builder.createNew(ctx); p.builderStack.push(builder); } @Override public void exitDeclByClass(ModuleParser.DeclByClassContext ctx) { ClassDefBuilder builder = (ClassDefBuilder) p.builderStack.pop(); CompoundStatement content = parseClassContent(ctx); builder.setContent(content); p.notifyObserversOfItem(builder.getItem()); emitDeclarationsForClass(ctx); } @Override public void enterClass_name(ModuleParser.Class_nameContext ctx) { ClassDefBuilder builder = (ClassDefBuilder) p.builderStack.peek(); builder.setName(ctx); } private void emitDeclarationsForClass(DeclByClassContext ctx) { Init_declarator_listContext decl_list = ctx.init_declarator_list(); if (decl_list == null) return; ParserRuleContext typeName = ctx.class_def().class_name(); emitDeclarations(decl_list, typeName, ctx); } private CompoundStatement parseClassContent( ModuleParser.DeclByClassContext ctx) { ANTLRCModuleParserDriver shallowParser = createNewShallowParser(); CompoundItemAssembler generator = new CompoundItemAssembler(); shallowParser.addObserver(generator); restrictStreamToClassContent(ctx); shallowParser.parseAndWalkTokenStream(p.stream); p.stream.resetRestriction(); return generator.getCompoundItem(); } private void restrictStreamToClassContent( ModuleParser.DeclByClassContext ctx) { Class_defContext class_def = ctx.class_def(); int startIndex = class_def.OPENING_CURLY().getSymbol().getTokenIndex(); int stopIndex = class_def.stop.getTokenIndex(); p.stream.restrict(startIndex + 1, stopIndex); } private ANTLRCModuleParserDriver createNewShallowParser() { ANTLRCModuleParserDriver shallowParser = new ANTLRCModuleParserDriver(); shallowParser.setStack(p.builderStack); return shallowParser; } }