Beispiel #1
0
        /// <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);
            }
        }