public ArrayTokenStream LexWithFixes(string str)
        {
            str = OBScriptFixer.FixScriptErrors(str);
            ArrayTokenStream tokens = Lex(str);

            return(tokens);
        }
Beispiel #2
0
        public object ParseWithFixLogic(ITokenStream stream)
        {
            //WTM:  Change:  If the script is just a comment, resulting in only an EOF token, parser.ParseWithFixLogic fails.
            //The below check works around that.
            IToken[] firstTwoTokens = stream.Take(2).ToArray();
            if (firstTwoTokens.Length == 1 && firstTwoTokens[0].Type == EOF_TOKEN_TYPE)
            {
                throw new EOFOnlyException();
            }
            try
            {
                return(base.Parse(stream));
            }
            catch (UnexpectedTokenException ex) when(ex.Token.Value == "endif")
            {
                bool          isFixed = false;
                int           nesting = 0;
                List <IToken> tokens  = new List <IToken>();

                foreach (var token in stream)
                {
                    if (token.Type == "BranchStartToken")
                    {
                        ++nesting;
                        tokens.Add(token);
                    }
                    else
                    {
                        if (token.Type == "BranchEndToken")
                        {
                            nesting = nesting - 1;
                            if (nesting > -1)
                            {
                                tokens.Add(token);
                            }
                            else
                            {
                                isFixed = true;
                                nesting = 0; //Clear up the token and nesting will be again 0
                            }
                        }
                        else
                        {
                            tokens.Add(token);
                        }
                    }
                }

                if (!isFixed)
                {
                    throw;
                }

                ArrayTokenStream newTokenStream = new ArrayTokenStream(tokens);
                object           newAST         = this.Parse(newTokenStream);

                return(newAST);
            }
        }
        public T Parse(string scriptPath)
        {
            OBScriptLexer          lexer      = this.lexerLazy.Value;
            string                 sourceText = File.ReadAllText(scriptPath);
            ArrayTokenStream       tokens     = lexer.LexWithFixes(sourceText);
            SyntaxErrorCleanParser parser     = this.parserLazy.Value;
            T result = (T)parser.ParseWithFixLogic(tokens);

            return(result);
        }
Beispiel #4
0
        public ArrayTokenStream LexWithFixes(string str)
        {
            //WTM:  Change:  In tif__0101efc0 and other TGExpelledScripts, PayFine gets misunderstood as a function call instead of a variable.
            str = str.Replace("TGExpelled.PayFine", "TGExpelled.PayFineTemp");
            //WTM:  Change:  In tgcastout, the below replacement must be made so the variable name can stay in synch.
            if (str.StartsWith("ScriptName TGCastOut"))
            {
                str = str.Replace("Float PayFine", "Float PayFineTemp");
            }
            //WTM:  Change:  In darkperenniaghostscript, Disable gets misunderstood as a function call instead of a variable.
            if (str.StartsWith("Scriptname DarkPerenniaGhostScript"))
            {
                str = str.Replace("Disable", "DisableTemp");
            }
            //WTM:  Change:  In blade3script, Look gets misunderstood as a function call instead of a variable.
            if (str.StartsWith("Scriptname Blade3Script"))
            {
                str = str
                      .Replace("short Look", "short LookTemp")
                      .Replace("if Look == ", "if LookTemp == ")
                      .Replace("set Look to ", "set LookTemp to ");
            }
            //WTM:  Change:  In qf_tg03elven_01034ea2_100_0, a variable is apparently accidentally quoted.
            if (str.Contains("TG03LlathasasBustMarker.PlaceAtMe \"TG03LlathasasBust\""))
            {
                str = str.Replace("TG03LlathasasBustMarker.PlaceAtMe \"TG03LlathasasBust\"", "TG03LlathasasBustMarker.PlaceAtMe TG03LlathasasBust");
            }
            //WTM:  Change:  In sebruscusdannusitemscript, getstartingpos's arguments are not quoted.
            if (str.StartsWith("scn SEBruscusDannusItemSCRIPT"))
            {
                str = getStartingPosOrAngleUnquotedArguments.Replace(str, "$1 \"$2\"");
            }
            ArrayTokenStream tokens = Lex(str);

            return(tokens);
        }
        public void execute(string buildPath = Build.DEFAULT_BUILD_PATH, bool skipParsing = false, string mode = "strict")
        {
            set_time_limit(10800); // 3 hours is the maximum for this command. Need more? You really screwed something, full suite for all Oblivion vanilla data takes 20 minutes. :)
            float threshold;

            switch (mode)
            {
            case "sloppy":
            {
                threshold = 0.5f;
                break;
            }

            case "normal":
            {
                threshold = 0.85f;
                break;
            }

            case "strict":
            default:
            {
                threshold = 0.95f;
                break;
            }

            case "perfect":
            {
                threshold = 1;
                break;
            }
            }

            if (!skipParsing)
            {
                SyntaxErrorCleanParser parser = new SyntaxErrorCleanParser(new TES4ObscriptCodeGrammar());
                //parser = new Parser(new TES4OBScriptGrammar());
                TES4ToTES5ASTTIFFragmentConverter converter = TES4ToTES5ASTTIFFragmentConverterFactory.GetConverter(new Build(buildPath));
                string   inputFolder = "./Fragments/TIF/fragments/";
                string   outputFolder = "./Fragments/TIF/PapyrusFragments/";
                string[] scandir = Directory.GetFiles(inputFolder);
                int      success = 0, total = 0;
                Dictionary <string, TES5MultipleScriptsScope> ASTTable = new Dictionary <string, TES5MultipleScriptsScope>();
                Console.WriteLine("Lexing and parsing..");
                int totalNumber = scandir.Length;
                foreach (var scriptPath in scandir)
                {
                    if (!scriptPath.EndsWith(".txt"))
                    {
                        continue;
                    }

                    if ((total % 10) == 0)
                    {
                        Console.WriteLine(total + "/" + totalNumber + "...");
                    }

                    string scriptFileName   = scriptPath.Substring(0, scriptPath.Length - 4);
                    string outputScriptPath = scriptFileName + ".psc";
                    total++;
                    try
                    {
                        Console.WriteLine(scriptFileName + "...");
                        FragmentLexer               lexer        = new FragmentLexer();
                        ArrayTokenStream            tokens       = lexer.lex(File.ReadAllText(path));
                        TES4VariableDeclarationList variableList = this.fragmentsReferencesBuilder.buildVariableDeclarationList(inputFolder + scriptFileName + ".references");
                        TES5MultipleScriptsScope    AST          = (TES5MultipleScriptsScope)parser.ParseWithFixLogic(tokens);
                        ASTTable[scriptPath] = AST;
                        TES5Target TES5AST      = converter.convert(scriptFileName, variableList, AST);
                        string     outputScript = TES5AST.output();
                        File.WriteAllText(outputFolder + outputScriptPath, outputScript);
                        Process.Start("lua", "\"Utilities/beautifier.lua\" \"" + outputFolder + outputScriptPath + "\"");
                        success++;
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(scriptPath + "\r\n" + e.GetType().FullName + ":  " + e.Message + "\r\n");
                        continue;
                    }
                }

                float successRate = (float)success / total;
                if (successRate < threshold)
                {
                    float percent = (float)Math.Round(successRate * 100);
                    Console.WriteLine("ERROR: Build failed on parsing step in " + mode + " mode. The rate is " + success + "/" + total + " (" + percent + " %)");
                    return;
                }

                Console.WriteLine("Parsing in " + mode + " mode succedeed (rate " + success + "/" + total + ").  Copying Skyrim scripts and parsed papyrus fragments to build folder...");
            }

            Console.WriteLine("Build in " + mode + " mode succeeded!");
        }