private static int Compile(string filename) { filename = Path.GetFullPath(filename); ICharStream characters = new ANTLRFileStream(filename); var lexer = new TigerLexer(characters); ITokenStream tokens = new CommonTokenStream(lexer); var parser = new TigerParser(tokens); //parser.TraceDestination = Console.Out; var result = parser.program(); if (parser.NumberOfSyntaxErrors > 0 || lexer.Error) { return(1); } ((ProgramNode)result.Tree).CheckSemantics(Scope.DefaultGlobalScope, Scope.DefaultGlobalScope.Reporter); if (Scope.DefaultGlobalScope.Reporter.Errors.Count > 0) { Scope.DefaultGlobalScope.Reporter.PrintErrors(Console.Out); return(1); } var generator = new CodeGenerator(filename); generator.GenerateCode((ASTNode)result.Tree); generator.SaveBin(); return(0); }
protected AstNode ParseText(string text) { var s = new StreamReader(GenerateStreamFromString(text)); var stm = new AntlrInputStream(s);; var lexer = new TigerLexer(stm); var tokenStream = new CommonTokenStream(lexer); var parser = new TigerParser(tokenStream); var expContext = parser.program(); var contextVisitor = new BuildAstVisitor(); return(expContext.Accept(contextVisitor)); }
public static ProgramNode ParseInput(string inputPath) { try { ANTLRFileStream input = new ANTLRFileStream(inputPath); TigerLexer lexer = new TigerLexer(input); CommonTokenStream tokens = new CommonTokenStream(lexer); TigerParser parser = new TigerParser(tokens); parser.TreeAdaptor = new Adaptor(); var program = (ProgramNode)parser.program().Tree; return(program); } catch (ParsingException exc) { Console.WriteLine("({1},{2}): {0}", exc.Message, exc.RecognitionError.Line, exc.RecognitionError.CharPositionInLine); Environment.ExitCode = (int)ErrorCode.Error; return(null); } }
private static int Main(string[] args) { Console.WriteLine("Tiger Compiler version 1.0"); Console.WriteLine(@"Copyright (C) 2015-2016 Laila González Fernández & Mario César Muñiz Jiménez"); //Creating report, parser and lexer var arg = args[0]; var report = new Report(); var characters = new ANTLRFileStream(arg); var lexer = new TigerLexer(report, characters); var tokens = new CommonTokenStream(lexer); var parser = new TigerParser(report, tokens) { TraceDestination = Console.Out, TreeAdaptor = new TreeAdaptor() }; //Syntactic analysis var ret = (ProgramNode)parser.program().Tree; if (!report.IsOk) { foreach (var message in report) { Console.WriteLine($"({message.Line}, {message.Column}): {message.Text}"); } return(1); } //Preparing assembly var name = Path.GetFileNameWithoutExtension(arg); var filename = name + ".exe"; var assemblyName = new AssemblyName(name); var assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave); var moduleBuilder = assembly.DefineDynamicModule(name, filename); var programType = moduleBuilder.DefineType(name + ".Program", TypeAttributes.Public); var mainMethod = programType.DefineMethod("Main", MethodAttributes.Static | MethodAttributes.Public, typeof(void), Type.EmptyTypes); var generator = mainMethod.GetILGenerator(); assembly.SetEntryPoint(mainMethod); ProgramNode.Module = moduleBuilder; ProgramNode.Program = programType; //Semantic analysis ret.CheckSemantics(new TigerScope(programType), report); if (!report.IsOk) { foreach (var message in report) { Console.WriteLine($"({message.Line}, {message.Column}): {message.Text}"); } return(1); } generator.BeginExceptionBlock(); //Code generation ret.GenerateCode(generator); if (!TigerType.AreOfSameType(ret.TigerType, TigerType.Void)) { generator.Emit(OpCodes.Pop); } generator.BeginCatchBlock(typeof(Exception)); generator.BeginScope(); LocalBuilder exception = generator.DeclareLocal(typeof(Exception)); MethodInfo writeLineSO = typeof(TextWriter).GetMethod("WriteLine", new Type[] { typeof(string), typeof(object) }); MethodInfo writeLineS = typeof(TextWriter).GetMethod("WriteLine", new Type[] { typeof(string) }); MethodInfo standardErrorOutput = typeof(Console).GetProperty("Error").GetGetMethod(); generator.Emit(OpCodes.Stloc, exception); generator.Emit(OpCodes.Call, standardErrorOutput); generator.Emit(OpCodes.Ldstr, "Exception of type '{0}' was thrown."); generator.Emit(OpCodes.Ldloc, exception); generator.Emit(OpCodes.Callvirt, typeof(Exception).GetMethod("GetType", Type.EmptyTypes)); generator.Emit(OpCodes.Callvirt, typeof(Type).GetProperty("Name").GetGetMethod()); generator.Emit(OpCodes.Callvirt, writeLineSO); generator.Emit(OpCodes.Call, standardErrorOutput); generator.Emit(OpCodes.Ldloc, exception); generator.Emit(OpCodes.Callvirt, typeof(Exception).GetProperty("Message").GetGetMethod()); generator.Emit(OpCodes.Callvirt, writeLineS); generator.EndScope(); generator.Emit(OpCodes.Ldc_I4_1); generator.Emit(OpCodes.Call, typeof(Environment).GetMethod("Exit")); generator.EndExceptionBlock(); generator.Emit(OpCodes.Ret); programType.CreateType(); assembly.Save(filename); return(0); }
//filePathInput indica si input es el codigo fuente o la direccion del archivo donde este se encuentre public bool Compile(string input, string outputfileName, bool filePathInput = true) { Errors = Errors ?? new List<Error>(); Errors.Clear(); ICharStream source; try { source = filePathInput ? new ANTLRFileStream(input) : new ANTLRStringStream(input); //escoger la entrada } catch (Exception) { Errors.Add(new Error(new CommonTree {Line = 0, CharPositionInLine = 0}, "File '{0}' cannot be found",input)); return false; } TigerParser parser = new TigerParser(new CommonTokenStream(new TigerLexer(source, Errors)), Errors); //crear el parser a partir del lexer a partir del source parser.TreeAdaptor = new TigerTreeAdaptor();//setear el tree adaptor del parser para transformar los nodos del AST a nodos de la jerarquia //chequeo sintactico ASTNode ast = parser.program().Tree as ASTNode; if (Errors.Count > 0) { Errors.Sort(); return false; } //chequeo semantico Scope scope = new Scope(); Environment.ResetName(); scope.AddType("int", IntType.IntInstance); scope.AddType("string", StringType.StringInstance); FunctionDecNode printFunct, printiFunct, printlnFunct, getCharFunct, getlnFunct, chrFunct, sizeFunct, substringFunct, concatFunct, notFunct, exitFunct, flushFunct, ordFunct; BuiltInFunctions.DefineBuiltinFunctions(scope, out printFunct, out printiFunct, out printlnFunct, out getCharFunct, out getlnFunct, out chrFunct, out sizeFunct, out substringFunct, out concatFunct, out notFunct, out exitFunct, out flushFunct, out ordFunct); ast.CheckSemantic(scope, Errors); if (Errors.Count > 0) { Errors.Sort(); return false; } //generacion de codigo AssemblyName name = new AssemblyName("TigerProgram"); AssemblyBuilder asmBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.RunAndSave, Path.GetDirectoryName(outputfileName)); ModuleBuilder moduleBuilder = asmBuilder.DefineDynamicModule("TigerProgram", Path.GetFileName(outputfileName)); TypeBuilder typeBuilder = moduleBuilder.DefineType("Program"); MethodBuilder methodBuilder = typeBuilder.DefineMethod("Main", MethodAttributes.Public | MethodAttributes.Static, typeof(int), new Type[] { }); ILGenerator ilGenerator = methodBuilder.GetILGenerator(); LocalBuilder returnValue = ilGenerator.DeclareLocal(typeof(int)); ilGenerator.Emit(OpCodes.Ldc_I4_0); ilGenerator.Emit(OpCodes.Stloc, returnValue); BuiltInFunctions.GenerateBuiltinCode(printFunct, printiFunct, printlnFunct, getCharFunct, getlnFunct, chrFunct, sizeFunct, substringFunct, concatFunct, notFunct, exitFunct, flushFunct, ordFunct, typeBuilder); LocalBuilder varException = ilGenerator.DeclareLocal(typeof(Exception)); ilGenerator.BeginExceptionBlock(); ast.GenerateCode(ilGenerator, typeBuilder, moduleBuilder); if (ast is ExpressionNode && ((ExpressionNode)ast).ReturnType != VoidType.VoidInstance) ilGenerator.Emit(OpCodes.Pop); ilGenerator.BeginCatchBlock(typeof(Exception)); ilGenerator.Emit(OpCodes.Stloc, varException); ilGenerator.Emit(OpCodes.Ldstr, "Exception of type ‘{0}’ was thrown."); ilGenerator.Emit(OpCodes.Ldloc, varException); ilGenerator.EmitCall(OpCodes.Callvirt, typeof(Exception).GetMethod("GetType"), null); ilGenerator.EmitCall(OpCodes.Callvirt, varException.GetType().GetMethod("ToString"), null); ilGenerator.EmitCall(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string), typeof(object) }), null); ilGenerator.Emit(OpCodes.Ldc_I4_1); ilGenerator.Emit(OpCodes.Stloc, returnValue); ilGenerator.EndExceptionBlock(); ilGenerator.Emit(OpCodes.Ldloc, returnValue); ilGenerator.Emit(OpCodes.Ret); typeBuilder.CreateType(); asmBuilder.SetEntryPoint(methodBuilder); asmBuilder.Save(Path.GetFileName(outputfileName)); return true; }
/// <summary> /// Compiles a Tiger source code /// </summary> /// <param name="input">Source code input</param> /// <returns>True if compilation proccess succeded, False otherwise</returns> private static bool Compile(ICharStream input) { ///limpiamos los errores antes del proceso de compilación Errors = new List <CompileError>(); ///creamos el lexer Lexer = new TigerLexer(input); ///creamos los tokens Tokens = new CommonTokenStream(Lexer); ///creamos el parser Parser = new TigerParser(Tokens); Parser.TreeAdaptor = new TigerAdaptor(); try { ///análisis sintáctico Lexer.OnLexicalErrorOcurrence += NotifyLexicError; Parser.OnParsingErrorOcurrence += NotifySyntacticError; Ast = Parser.program().Tree as ExpressionNode; ///en caso de que no fuera un ExpressionNode if (Ast == null) { throw new Exception("A parsing error ocurred"); } ///en caso de haber errores sintácticos if (Errors.Count > 0) { return(false); } ///creamos la tabla de símbolos SemanticSymbolTable = new SymbolTable(); ///análisis semántico Ast.CheckSemantic(SemanticSymbolTable, Errors); ///en caso de haber errores semánticos if (Errors.Count > 0) { return(false); } ///generamos código CodeGenerator = new ILCodeGenerator(ExecutableFileName, ParentDirectory); CodeGenerator.OnBuildingErrorOcurrence += NotifyBuildError; Ast.GenerateCode(CodeGenerator); ///si el Ast retorna valor, lo sacamos de la pila if (Ast.NodeInfo.BuiltInType.IsReturnType()) { CodeGenerator.ILGenerator.Emit(OpCodes.Pop); } ///salvamos el ejecutable return(CodeGenerator.SaveExecutable()); } catch (RecognitionException re) { ///elaboramos el mensaje de error string errorMessage = Lexer.GetErrorMessage(re, Lexer.TokenNames); ///agregamos el error sintáctico(aunque esto es en caso de que el parser explote) Errors.Add(new CompileError { Line = re.Line, Column = re.CharPositionInLine, ErrorMessage = errorMessage, Kind = ErrorKind.Lexic }); return(false); } catch (Exception e) { //change Errors.Add(new CompileError { Line = 0, Column = 0, ErrorMessage = "Compile process terminated due to unexpected error", Kind = ErrorKind.Build }); return(false); } }