public override void EnterConstructor_declaration(CSharpParser.Constructor_declarationContext context) { Console.WriteLine("Entering constructor_declaration context."); // Getting the current class node from symbol table in scope: Node currentClassScopeNode = ast.GetNode(symbolTable.CurrentScopeNode); ClassType classType = (ClassType)(currentClassScopeNode.Type); ClassSymbol classSymbol = classType.Symbol; IToken classToken = currentClassScopeNode.Token; // Getting the destructor modifiers: Symbol.ModifierFlag modFlags = TreatModTokens(); modifiersTokens.Clear(); // Creating the destructor symbol: ConstructorSymbol constructorSymbol = new ConstructorSymbol(modFlags, classSymbol); // Creating the destructor AST node: BuiltInType constructorType = new BuiltInType(classToken, TypeTag.Constructor); Node constructorNode = new Node(classToken, Node.Kind.Constructor, constructorType, constructorSymbol); ast.AddNode(constructorNode); // Adding the new node as a child of the class node: currentClassScopeNode.AddChildIndex(ast.NodeIndex(constructorNode)); // Adding the destructor symbol to the symbol table: int constructorNodeIndex = ast.NodeIndex(constructorNode); symbolTable.EnterScope(constructorNodeIndex); symbolTable.AddSymbol(classToken, constructorSymbol); }
public override void EnterMethod_declaration(CSharpParser.Method_declarationContext context) { Console.WriteLine("Entering method_declaration context."); // Getting the current scope node and current modifiers: Symbol.ModifierFlag modFlags = TreatModTokens(); modifiersTokens.Clear(); Node currentScopeNode = ast.GetNode(symbolTable.CurrentScopeNode); ClassSymbol ownerSymbol = (ClassSymbol)(currentScopeNode.Data); MethodSymbol methodSymbol = new MethodSymbol(modFlags, ownerSymbol); IToken idToken = context.method_member_name().identifier(0).Start; symbolTable.AddSymbol(idToken, methodSymbol); // Creating the method AST node: Node methodNode = new Node(idToken, Node.Kind.MethodDeclaration, currentType, methodSymbol); ast.AddNode(methodNode); int methodIndex = ast.NodeIndex(methodNode); currentScopeNode.AddChildIndex(methodIndex); // Entering the method scope: symbolTable.EnterScope(methodIndex); // Creating a node for each parameter: CSharpParser.Formal_parameter_listContext parameters = context.formal_parameter_list(); if (parameters != null) { CSharpParser.Fixed_parameterContext[] fixedParams = parameters.fixed_parameters().fixed_parameter(); foreach (CSharpParser.Fixed_parameterContext parameter in fixedParams) { CSharpParser.Arg_declarationContext arg = parameter.arg_declaration(); if (arg != null) { CSharpParser.Type_Context typeContext = arg.type_(); IToken varToken = arg.identifier().Start; Type t = TreatTypeContext(typeContext); VariableSymbol varSymbol = new VariableSymbol(Symbol.ModifierFlag.None, methodSymbol); symbolTable.AddSymbol(varToken, varSymbol); Node varNode = new Node(varToken, Node.Kind.MethodParameter, t, null); ast.AddNode(varNode); int varIndex = ast.NodeIndex(varNode); methodNode.AddChildIndex(varIndex); } } } // Creating the subtree for the method implementation: CSharpParser.BlockContext blockContext = context.method_body().block(); if (blockContext != null) { TreatBlock(blockContext, methodNode); } }
public override void EnterConstant_declaration(CSharpParser.Constant_declarationContext context) { Console.WriteLine("Entering constant_declaration context."); // Getting the current scope parent node: Node parentNode = ast.GetNode(symbolTable.CurrentScopeNode); Node.Kind parentKind = parentNode.NodeKind; // Getting the constants' type: Type t = TreatTypeContext(context.type_()); // Getting all the modifiers: Symbol.ModifierFlag modFlags = TreatModTokens(); modifiersTokens.Clear(); modFlags |= Symbol.ModifierFlag.Const; // Getting the name of the constant(s): CSharpParser.Constant_declaratorContext[] declarators = context.constant_declarators().constant_declarator(); foreach (CSharpParser.Constant_declaratorContext declarator in declarators) { CSharpParser.IdentifierContext idCtx = declarator.identifier(); IToken idToken = idCtx.Start; // Creating the constant symbol: if (parentKind == Node.Kind.ClassBody) { // Getting the owner class symbol: ClassSymbol ownerClass = ((ClassType)(parentNode.Type)).Symbol; AttributeSymbol constantSymbol = new AttributeSymbol(modFlags, ownerClass); // Creating the constant member node: Node constMemberNode = new Node(idToken, Node.Kind.MemberVariableDeclaration, t, constantSymbol); ast.AddNode(constMemberNode); parentNode.AddChildIndex(ast.NodeIndex(constMemberNode)); // Adding the symbol to the table: symbolTable.AddSymbol(idToken, constantSymbol); } else { // Creating a method variable // Getting the owner method symbol: MethodSymbol ownerMethod = (MethodSymbol)(symbolTable.FindSymbol(parentNode.Token, ast)); VariableSymbol constantSymbol = new VariableSymbol(modFlags, ownerMethod); // Creating the constant variable node: Node constVarNode = new Node(idToken, Node.Kind.MethodVariableDeclaration, t, constantSymbol); ast.AddNode(constVarNode); parentNode.AddChildIndex(ast.NodeIndex(constVarNode)); // Adding the symbol to the table: symbolTable.AddSymbol(idToken, constantSymbol); } } }
public override void EnterType_(CSharpParser.Type_Context context) { Console.WriteLine("Entering type_ context."); // Getting the current modifiers: Symbol.ModifierFlag mods = TreatModTokens(); modifiersTokens.Clear(); // Defining the type that's being read: currentType = TreatTypeContext(context); }
public override void EnterEnum_definition(CSharpParser.Enum_definitionContext context) { Console.WriteLine("Entering enum_definition context."); // Getting the current scope node in the AST: Node parentNode = ast.GetNode(symbolTable.CurrentScopeNode); // Getting the modifier for the enumerator: Symbol.ModifierFlag modFlags = TreatModTokens(); modifiersTokens.Clear(); // Getting the base tokens for the enumeration: CSharpParser.Enum_baseContext enumBase = context.enum_base(); Type enumBaseType = null; if (enumBase != null) { enumBaseType = TreatTypeContext(enumBase.type_()); } // Accessing the enum's body values: List <IToken> values = new List <IToken>(); CSharpParser.Enum_member_declarationContext[] members = context.enum_body().enum_member_declaration(); foreach (CSharpParser.Enum_member_declarationContext member in members) { CSharpParser.IdentifierContext id = member.identifier(); values.Add(id.Start); } // Creating the enum symbol: EnumSymbol enumSymbol = new EnumSymbol(modFlags, values.ToArray(), enumBaseType); // Creating the enum type name: CSharpParser.IdentifierContext idContext = context.identifier(); IToken idToken = idContext.Start; // Creating the enum node and adding it to the AST: Type enumType = new Type(idToken); symbolTable.AddType(enumType); Node enumNode = new Node(idToken, Node.Kind.EnumDefinition, enumType, enumSymbol); parentNode.AddChildIndex(ast.NodeIndex(enumNode)); ast.AddNode(enumNode); }
private void TreatForStatement(CSharpParser.ForStatementContext statement, Node parentNode) { // Creating node indicating it's a for statement: IToken forToken = statement.FOR().Symbol; Node forNode = new Node(forToken, Node.Kind.ForStatement, null); ast.AddNode(forNode); int forIndex = ast.NodeIndex(forNode); parentNode.AddChildIndex(forIndex); symbolTable.EnterScope(forIndex); // Craeting sub tree for the initializer expression: CSharpParser.For_initializerContext initContext = statement.for_initializer(); if (initContext != null) { CSharpParser.Local_variable_declarationContext declContext = initContext.local_variable_declaration(); if (declContext != null) { // Getting the local variables modifiers: Symbol.ModifierFlag modFlags = Symbol.ModifierFlag.None; if (declContext.REF() != null) { modFlags |= Symbol.ModifierFlag.Ref; } if (declContext.READONLY() != null) { modFlags |= Symbol.ModifierFlag.ReadOnly; } // Creating the local variables symbols: IToken typeToken = declContext.local_variable_type().Start; Type t = symbolTable.FindType(typeToken); if (t == null) { Console.WriteLine("FATAL ERROR: Unidentified type found."); Environment.Exit(1); } MethodSymbol ownerMethod = (MethodSymbol)symbolTable.FindSymbol(parentNode.Token, ast); CSharpParser.Local_variable_declaratorContext[] declarators = declContext.local_variable_declarator(); foreach (CSharpParser.Local_variable_declaratorContext declarator in declarators) { // Creating the variable symbol: CSharpParser.IdentifierContext identifier = declarator.identifier(); IToken variableID = identifier.Start; VariableSymbol variableSymbol = new VariableSymbol(modFlags, ownerMethod); symbolTable.AddSymbol(variableID, variableSymbol); // Creating the variable node and adding it to the AST: Node variableNode = new Node(variableID, Node.Kind.MethodVariableDeclaration, t); ast.AddNode(variableNode); int varDeclIndex = ast.NodeIndex(variableNode); parentNode.AddChildIndex(varDeclIndex); // Treating the variable initialization: TreatVariableInitializer(declarator.local_variable_initializer(), variableNode); } } else { CSharpParser.ExpressionContext[] initExpressions = initContext.expression(); foreach (CSharpParser.ExpressionContext expression in initExpressions) { beginTreatExpression(expression, forNode); } } } // Creating sub tree for the condition expression: beginTreatExpression(statement.expression(), forNode); // Creating sub tree for the iterator: CSharpParser.For_iteratorContext iteratorContext = statement.for_iterator(); if (iteratorContext != null) { CSharpParser.ExpressionContext[] expressions = iteratorContext.expression(); foreach (CSharpParser.ExpressionContext expression in expressions) { beginTreatExpression(expression, forNode); } } // Craeting sub tree and scope for the list of statements: CSharpParser.Embedded_statementContext embedded = statement.embedded_statement(); CSharpParser.Simple_embedded_statementContext simpleStatement = embedded.simple_embedded_statement(); if (simpleStatement != null) { TreatSimpleEmbeddedStatement(simpleStatement, forNode); } else { TreatBlock(embedded.block(), forNode); } symbolTable.ExitScope(); }
private void TreatStatement(CSharpParser.StatementContext statement, Node parentNode) { CSharpParser.Labeled_StatementContext labeledStatement = statement.labeled_Statement(); if (labeledStatement != null) { // Getting the label token: CSharpParser.IdentifierContext label = labeledStatement.identifier(); IToken labelToken = label.Start; // Adding the label to the symbol table: Symbol labelSymbol = new Symbol(Symbol.ModifierFlag.None); symbolTable.AddSymbol(labelToken, labelSymbol); // Creating the label node and adding it to the AST: Node labelNode = new Node(labelToken, Node.Kind.Label, null); ast.AddNode(labelNode); int labelNodeIndex = ast.NodeIndex(labelNode); parentNode.AddChildIndex(labelNodeIndex); CSharpParser.StatementContext innerStatement = labeledStatement.statement(); // Treating the labeled statement: TreatStatement(innerStatement, labelNode); } else { CSharpParser.DeclarationStatementContext declaration = statement.declarationStatement(); if (declaration != null) { CSharpParser.Local_variable_declarationContext localVariable = declaration.local_variable_declaration(); if (localVariable != null) { // Getting the local variables modifiers: Symbol.ModifierFlag modFlags = Symbol.ModifierFlag.None; if (localVariable.REF() != null) { modFlags |= Symbol.ModifierFlag.Ref; } if (localVariable.READONLY() != null) { modFlags |= Symbol.ModifierFlag.ReadOnly; } // Creating the local variables symbols: IToken typeToken = localVariable.local_variable_type().Start; Type t = symbolTable.FindType(typeToken); if (t == null) { Console.WriteLine("FATAL ERROR: Unidentified type found."); Environment.Exit(1); } MethodSymbol ownerMethod = (MethodSymbol)symbolTable.FindSymbol(parentNode.Token, ast); CSharpParser.Local_variable_declaratorContext[] declarators = localVariable.local_variable_declarator(); foreach (CSharpParser.Local_variable_declaratorContext declarator in declarators) { // Creating the variable symbol: CSharpParser.IdentifierContext identifier = declarator.identifier(); IToken variableID = identifier.Start; VariableSymbol variableSymbol = new VariableSymbol(modFlags, ownerMethod); symbolTable.AddSymbol(variableID, variableSymbol); // Creating the variable node and adding it to the AST: Node variableNode = new Node(variableID, Node.Kind.MethodVariableDeclaration, t); ast.AddNode(variableNode); int varDeclIndex = ast.NodeIndex(variableNode); parentNode.AddChildIndex(varDeclIndex); // Treating the variable initialization: TreatVariableInitializer(declarator.local_variable_initializer(), variableNode); } } } else { CSharpParser.Embedded_statementContext embedded = statement.embedded_statement(); CSharpParser.Simple_embedded_statementContext simpleStatement = embedded.simple_embedded_statement(); if (simpleStatement != null) { TreatSimpleEmbeddedStatement(simpleStatement, parentNode); } else { TreatBlock(embedded.block(), parentNode); } } } }
public override void EnterClass_definition(CSharpParser.Class_definitionContext context) { Console.WriteLine("Entering class_definition context."); // Getting the current scope node: Node currentScopeNode = ast.GetNode(symbolTable.CurrentScopeNode); // Add class symbol to symbol table: parent class, owner class and other informations and add to node data: // Getting the parent classes: List <IToken> baseTokens = new List <IToken>(); // Will hold the base class tokens // Getting the base classes' names identifiers: CSharpParser.Class_baseContext classBaseCtx = context.class_base(); if (classBaseCtx != null) { CSharpParser.Class_typeContext classTypeCtx = classBaseCtx.class_type(); if (classTypeCtx != null) { CSharpParser.Namespace_or_type_nameContext typeNameCtx = classTypeCtx.namespace_or_type_name(); if (typeNameCtx != null) { CSharpParser.IdentifierContext[] typeIDCtxs = typeNameCtx.identifier(); foreach (CSharpParser.IdentifierContext id in typeIDCtxs) { baseTokens.Add(id.Start); } } else { baseTokens.Add(typeNameCtx.Start); } } } // Getting the base classes' symbols: Symbol[] baseSymbols = symbolTable.FindSymbols(baseTokens.ToArray(), ast); List <ClassSymbol> baseClassSymbols = new List <ClassSymbol>(); foreach (Symbol bs in baseSymbols) { baseClassSymbols.Add((ClassSymbol)bs); } // Getting the class' modifiers: Symbol.ModifierFlag modFlags = TreatModTokens(); modifiersTokens.Clear(); // Creating the class symbol: ClassSymbol classSymbol = new ClassSymbol(modFlags, baseClassSymbols.ToArray()); // Adding the class node as a child to the current scope's AST node: Type type = new Type(context.CLASS().Symbol); Node classNode = new Node(context.CLASS().Symbol, Node.Kind.ClassDefinition, type); int classNodeIndex = ast.NodeIndex(classNode); currentScopeNode.AddChildIndex(classNodeIndex); // Adding the class node: ast.AddNode(classNode); // Adding an identifier node as a class node child: CSharpParser.IdentifierContext idCtx = context.identifier(); IToken idToken = idCtx.Start; // Adding the class body node as a class node child: CSharpParser.Class_bodyContext bodyCtx = context.class_body(); ClassType classType = new ClassType(idToken, ClassTag.Class, classSymbol); symbolTable.AddType(classType); Node bodyNode = new Node(idToken, Node.Kind.ClassBody, classType); ast.AddNode(bodyNode); int bodyNodeIndex = ast.NodeIndex(bodyNode); classNode.AddChildIndex(bodyNodeIndex); // Enter scope in the symbol table symbolTable.EnterScope(bodyNodeIndex); symbolTable.AddSymbol(idToken, classSymbol); }
public override void EnterStruct_definition(CSharpParser.Struct_definitionContext context) { Console.WriteLine("Entering struct_definition context."); // Getting the current scope node: Node currentScopeNode = ast.GetNode(symbolTable.CurrentScopeNode); // Add class symbol to symbol table: parent class, owner class and other informations and add to node data: // Getting the parent classes: List <IToken> interfaceTokens = new List <IToken>(); // Will hold the base class tokens // Getting the interfaces' names identifiers: CSharpParser.Struct_interfacesContext interfaces = context.struct_interfaces(); if (interfaces != null) { CSharpParser.Interface_type_listContext typeListCtx = interfaces.interface_type_list(); if (typeListCtx != null) { CSharpParser.Namespace_or_type_nameContext[] types = typeListCtx.namespace_or_type_name(); foreach (CSharpParser.Namespace_or_type_nameContext name in types) { CSharpParser.IdentifierContext[] ids = name.identifier(); foreach (CSharpParser.IdentifierContext id in ids) { interfaceTokens.Add(id.Start); } } } } // Getting the base classes' symbols: Symbol[] interfaceSymbols = symbolTable.FindSymbols(interfaceTokens.ToArray(), ast); List <ClassSymbol> interfaceClassSymbols = new List <ClassSymbol>(); foreach (Symbol bs in interfaceSymbols) { interfaceClassSymbols.Add((ClassSymbol)bs); } // Getting the class' modifiers: Symbol.ModifierFlag modFlags = TreatModTokens(); modifiersTokens.Clear(); // Creating the class symbol: ClassSymbol structSymbol = new ClassSymbol(modFlags, interfaceClassSymbols.ToArray()); // Adding the class node as a child to the current scope's AST node: Type type = new Type(context.STRUCT().Symbol); Node structNode = new Node(context.STRUCT().Symbol, Node.Kind.ClassDefinition, type); int structNodeIndex = ast.NodeIndex(structNode); currentScopeNode.AddChildIndex(structNodeIndex); // Adding the struct node: ast.AddNode(structNode); // Adding an identifier node as a struct node child: CSharpParser.IdentifierContext idCtx = context.identifier(); IToken idToken = idCtx.Start; // Adding the struct body node as a class node child: CSharpParser.Struct_bodyContext bodyCtx = context.struct_body(); ClassType structType = new ClassType(idToken, ClassTag.Struct, structSymbol); symbolTable.AddType(structType); Node bodyNode = new Node(idToken, Node.Kind.ClassBody, structType); ast.AddNode(bodyNode); int bodyNodeIndex = ast.NodeIndex(bodyNode); structNode.AddChildIndex(bodyNodeIndex); // Enter scope in the symbol table symbolTable.EnterScope(bodyNodeIndex); symbolTable.AddSymbol(idToken, structSymbol); }