/// <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); } }