Click here to Skip to main content
15,891,409 members
Articles / Programming Languages / C#

Lua Interpreter

Rate me:
Please Sign up or sign in to vote.
4.89/5 (32 votes)
22 Sep 2012MIT4 min read 99.5K   3K   85  
A Lua interpreter is implemented in C#. It allows to write Lua extensions in C# and call the extensions in Lua code.
using System;
using System.Collections.Generic;
using System.Text;

namespace Language.Lua
{
    public partial class Parser
    {
        public Chunk ParseChunk(ParserInput<char> input, out bool success)
        {
            this.SetInput(input);
            Chunk chunk = ParseChunk(out success);
            if (this.Position < input.Length)
            {
                success = false;
                Error("Failed to parse remaining input.");
            }
            return chunk;
        }

        private Chunk ParseChunk(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "Chunk");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as Chunk;
            }

            int errorCount = Errors.Count;
            Chunk chunk = new Chunk();
            int start_position = position;

            ParseSpOpt(out success);

            while (true)
            {
                while (true)
                {
                    int seq_start_position1 = position;
                    Statement statement = ParseStatement(out success);
                    if (success) { chunk.Statements.Add(statement); }
                    else { break; }

                    while (true)
                    {
                        int seq_start_position2 = position;
                        MatchTerminal(';', out success);
                        if (!success) { break; }

                        ParseSpOpt(out success);
                        break;
                    }
                    success = true;
                    break;
                }
                if (!success) { break; }
            }
            success = true;

            ParsingResults[reskey] = new Tuple<object, bool, int>(chunk, success, position);
            return chunk;
        }

        private Statement ParseStatement(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "Statement");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as Statement;
            }

            int errorCount = Errors.Count;
            Statement statement = null;

            statement = ParseAssignment(out success);
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(statement, success, position);return statement; }

            statement = ParseFunction(out success);
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(statement, success, position);return statement; }

            statement = ParseLocalVar(out success);
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(statement, success, position);return statement; }

            statement = ParseLocalFunc(out success);
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(statement, success, position);return statement; }

            statement = ParseReturnStmt(out success);
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(statement, success, position);return statement; }

            statement = ParseBreakStmt(out success);
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(statement, success, position);return statement; }

            statement = ParseDoStmt(out success);
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(statement, success, position);return statement; }

            statement = ParseIfStmt(out success);
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(statement, success, position);return statement; }

            statement = ParseForStmt(out success);
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(statement, success, position);return statement; }

            statement = ParseForInStmt(out success);
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(statement, success, position);return statement; }

            statement = ParseWhileStmt(out success);
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(statement, success, position);return statement; }

            statement = ParseRepeatStmt(out success);
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(statement, success, position);return statement; }

            statement = ParseExprStmt(out success);
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(statement, success, position);return statement; }

            return statement;
        }

        private Assignment ParseAssignment(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "Assignment");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as Assignment;
            }

            int errorCount = Errors.Count;
            Assignment assignment = new Assignment();
            int start_position = position;

            assignment.VarList = ParseVarList(out success);
            if (!success)
            {
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(assignment, success, position);return assignment;
            }

            ParseSpOpt(out success);

            MatchTerminal('=', out success);
            if (!success)
            {
                Error("Failed to parse '=' of Assignment.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(assignment, success, position);return assignment;
            }

            ParseSpOpt(out success);

            assignment.ExprList = ParseExprList(out success);
            if (!success)
            {
                Error("Failed to parse ExprList of Assignment.");
                position = start_position;
            }

            if (success) { ClearError(errorCount); }
            ParsingResults[reskey] = new Tuple<object, bool, int>(assignment, success, position);
            return assignment;
        }

        private Function ParseFunction(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "Function");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as Function;
            }

            int errorCount = Errors.Count;
            Function function = new Function();
            int start_position = position;

            MatchTerminalString("function", out success);
            if (!success)
            {
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(function, success, position);return function;
            }

            ParseSpReq(out success);
            if (!success)
            {
                Error("Failed to parse SpReq of Function.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(function, success, position);return function;
            }

            function.Name = ParseFunctionName(out success);
            if (!success)
            {
                Error("Failed to parse Name of Function.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(function, success, position);return function;
            }

            ParseSpOpt(out success);

            function.Body = ParseFunctionBody(out success);
            if (!success)
            {
                Error("Failed to parse Body of Function.");
                position = start_position;
            }

            if (success) { ClearError(errorCount); }
            ParsingResults[reskey] = new Tuple<object, bool, int>(function, success, position);
            return function;
        }

        private LocalVar ParseLocalVar(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "LocalVar");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as LocalVar;
            }

            int errorCount = Errors.Count;
            LocalVar localVar = new LocalVar();
            int start_position = position;

            MatchTerminalString("local", out success);
            if (!success)
            {
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(localVar, success, position);return localVar;
            }

            ParseSpReq(out success);
            if (!success)
            {
                Error("Failed to parse SpReq of LocalVar.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(localVar, success, position);return localVar;
            }

            localVar.NameList = ParseNameList(out success);
            if (!success)
            {
                Error("Failed to parse NameList of LocalVar.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(localVar, success, position);return localVar;
            }

            ParseSpOpt(out success);

            while (true)
            {
                int seq_start_position1 = position;
                MatchTerminal('=', out success);
                if (!success) { break; }

                ParseSpOpt(out success);

                localVar.ExprList = ParseExprList(out success);
                if (!success)
                {
                    Error("Failed to parse ExprList of LocalVar.");
                    position = seq_start_position1;
                }
                break;
            }
            success = true;

            ParsingResults[reskey] = new Tuple<object, bool, int>(localVar, success, position);
            return localVar;
        }

        private LocalFunc ParseLocalFunc(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "LocalFunc");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as LocalFunc;
            }

            int errorCount = Errors.Count;
            LocalFunc localFunc = new LocalFunc();
            int start_position = position;

            MatchTerminalString("local", out success);
            if (!success)
            {
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(localFunc, success, position);return localFunc;
            }

            ParseSpReq(out success);
            if (!success)
            {
                Error("Failed to parse SpReq of LocalFunc.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(localFunc, success, position);return localFunc;
            }

            MatchTerminalString("function", out success);
            if (!success)
            {
                Error("Failed to parse 'function' of LocalFunc.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(localFunc, success, position);return localFunc;
            }

            ParseSpReq(out success);
            if (!success)
            {
                Error("Failed to parse SpReq of LocalFunc.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(localFunc, success, position);return localFunc;
            }

            localFunc.Name = ParseName(out success);
            if (!success)
            {
                Error("Failed to parse Name of LocalFunc.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(localFunc, success, position);return localFunc;
            }

            ParseSpOpt(out success);

            localFunc.Body = ParseFunctionBody(out success);
            if (!success)
            {
                Error("Failed to parse Body of LocalFunc.");
                position = start_position;
            }

            if (success) { ClearError(errorCount); }
            ParsingResults[reskey] = new Tuple<object, bool, int>(localFunc, success, position);
            return localFunc;
        }

        private ExprStmt ParseExprStmt(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "ExprStmt");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as ExprStmt;
            }

            int errorCount = Errors.Count;
            ExprStmt exprStmt = new ExprStmt();

            exprStmt.Expr = ParseExpr(out success);
            if (success) { ClearError(errorCount); }
            else { Error("Failed to parse Expr of ExprStmt."); }
            ParsingResults[reskey] = new Tuple<object, bool, int>(exprStmt, success, position);
            return exprStmt;
        }

        private ReturnStmt ParseReturnStmt(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "ReturnStmt");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as ReturnStmt;
            }

            int errorCount = Errors.Count;
            ReturnStmt returnStmt = new ReturnStmt();
            int start_position = position;

            MatchTerminalString("return", out success);
            if (!success)
            {
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(returnStmt, success, position);return returnStmt;
            }

            ParseSpReq(out success);
            if (!success)
            {
                Error("Failed to parse SpReq of ReturnStmt.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(returnStmt, success, position);return returnStmt;
            }

            returnStmt.ExprList = ParseExprList(out success);
            success = true;

            ParsingResults[reskey] = new Tuple<object, bool, int>(returnStmt, success, position);
            return returnStmt;
        }

        private BreakStmt ParseBreakStmt(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "BreakStmt");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as BreakStmt;
            }

            int errorCount = Errors.Count;
            BreakStmt breakStmt = new BreakStmt();
            int start_position = position;

            MatchTerminalString("break", out success);
            if (!success)
            {
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(breakStmt, success, position);return breakStmt;
            }

            ParseSpOpt(out success);

            if (success) { ClearError(errorCount); }
            ParsingResults[reskey] = new Tuple<object, bool, int>(breakStmt, success, position);
            return breakStmt;
        }

        private DoStmt ParseDoStmt(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "DoStmt");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as DoStmt;
            }

            int errorCount = Errors.Count;
            DoStmt doStmt = new DoStmt();
            int start_position = position;

            MatchTerminalString("do", out success);
            if (!success)
            {
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(doStmt, success, position);return doStmt;
            }

            ParseSpReq(out success);
            if (!success)
            {
                Error("Failed to parse SpReq of DoStmt.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(doStmt, success, position);return doStmt;
            }

            doStmt.Body = ParseChunk(out success);
            if (!success)
            {
                Error("Failed to parse Body of DoStmt.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(doStmt, success, position);return doStmt;
            }

            MatchTerminalString("end", out success);
            if (!success)
            {
                Error("Failed to parse 'end' of DoStmt.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(doStmt, success, position);return doStmt;
            }

            ParseSpReq(out success);
            if (!success)
            {
                Error("Failed to parse SpReq of DoStmt.");
                position = start_position;
            }

            if (success) { ClearError(errorCount); }
            ParsingResults[reskey] = new Tuple<object, bool, int>(doStmt, success, position);
            return doStmt;
        }

        private IfStmt ParseIfStmt(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "IfStmt");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as IfStmt;
            }

            int errorCount = Errors.Count;
            IfStmt ifStmt = new IfStmt();
            int start_position = position;

            MatchTerminalString("if", out success);
            if (!success)
            {
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(ifStmt, success, position);return ifStmt;
            }

            ParseSpReq(out success);
            if (!success)
            {
                Error("Failed to parse SpReq of IfStmt.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(ifStmt, success, position);return ifStmt;
            }

            ifStmt.Condition = ParseExpr(out success);
            if (!success)
            {
                Error("Failed to parse Condition of IfStmt.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(ifStmt, success, position);return ifStmt;
            }

            MatchTerminalString("then", out success);
            if (!success)
            {
                Error("Failed to parse 'then' of IfStmt.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(ifStmt, success, position);return ifStmt;
            }

            ParseSpReq(out success);
            if (!success)
            {
                Error("Failed to parse SpReq of IfStmt.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(ifStmt, success, position);return ifStmt;
            }

            ifStmt.ThenBlock = ParseChunk(out success);
            if (!success)
            {
                Error("Failed to parse ThenBlock of IfStmt.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(ifStmt, success, position);return ifStmt;
            }

            while (true)
            {
                ElseifBlock elseifBlock = ParseElseifBlock(out success);
                if (success) { ifStmt.ElseifBlocks.Add(elseifBlock); }
                else { break; }
            }
            success = true;

            while (true)
            {
                int seq_start_position1 = position;
                MatchTerminalString("else", out success);
                if (!success) { break; }

                ParseSpReq(out success);
                if (!success)
                {
                    Error("Failed to parse SpReq of IfStmt.");
                    position = seq_start_position1;
                    break;
                }

                ifStmt.ElseBlock = ParseChunk(out success);
                if (!success)
                {
                    Error("Failed to parse ElseBlock of IfStmt.");
                    position = seq_start_position1;
                }
                break;
            }
            success = true;

            MatchTerminalString("end", out success);
            if (!success)
            {
                Error("Failed to parse 'end' of IfStmt.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(ifStmt, success, position);return ifStmt;
            }

            ParseSpReq(out success);
            if (!success)
            {
                Error("Failed to parse SpReq of IfStmt.");
                position = start_position;
            }

            if (success) { ClearError(errorCount); }
            ParsingResults[reskey] = new Tuple<object, bool, int>(ifStmt, success, position);
            return ifStmt;
        }

        private ElseifBlock ParseElseifBlock(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "ElseifBlock");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as ElseifBlock;
            }

            int errorCount = Errors.Count;
            ElseifBlock elseifBlock = new ElseifBlock();
            int start_position = position;

            MatchTerminalString("elseif", out success);
            if (!success)
            {
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(elseifBlock, success, position);return elseifBlock;
            }

            ParseSpReq(out success);
            if (!success)
            {
                Error("Failed to parse SpReq of ElseifBlock.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(elseifBlock, success, position);return elseifBlock;
            }

            elseifBlock.Condition = ParseExpr(out success);
            if (!success)
            {
                Error("Failed to parse Condition of ElseifBlock.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(elseifBlock, success, position);return elseifBlock;
            }

            MatchTerminalString("then", out success);
            if (!success)
            {
                Error("Failed to parse 'then' of ElseifBlock.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(elseifBlock, success, position);return elseifBlock;
            }

            ParseSpReq(out success);
            if (!success)
            {
                Error("Failed to parse SpReq of ElseifBlock.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(elseifBlock, success, position);return elseifBlock;
            }

            elseifBlock.ThenBlock = ParseChunk(out success);
            if (!success)
            {
                Error("Failed to parse ThenBlock of ElseifBlock.");
                position = start_position;
            }

            if (success) { ClearError(errorCount); }
            ParsingResults[reskey] = new Tuple<object, bool, int>(elseifBlock, success, position);
            return elseifBlock;
        }

        private ForStmt ParseForStmt(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "ForStmt");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as ForStmt;
            }

            int errorCount = Errors.Count;
            ForStmt forStmt = new ForStmt();
            int start_position = position;

            MatchTerminalString("for", out success);
            if (!success)
            {
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(forStmt, success, position);return forStmt;
            }

            ParseSpReq(out success);
            if (!success)
            {
                Error("Failed to parse SpReq of ForStmt.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(forStmt, success, position);return forStmt;
            }

            forStmt.VarName = ParseName(out success);
            if (!success)
            {
                Error("Failed to parse VarName of ForStmt.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(forStmt, success, position);return forStmt;
            }

            ParseSpOpt(out success);

            MatchTerminal('=', out success);
            if (!success)
            {
                Error("Failed to parse '=' of ForStmt.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(forStmt, success, position);return forStmt;
            }

            ParseSpOpt(out success);

            forStmt.Start = ParseExpr(out success);
            if (!success)
            {
                Error("Failed to parse Start of ForStmt.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(forStmt, success, position);return forStmt;
            }

            MatchTerminal(',', out success);
            if (!success)
            {
                Error("Failed to parse ',' of ForStmt.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(forStmt, success, position);return forStmt;
            }

            ParseSpOpt(out success);

            forStmt.End = ParseExpr(out success);
            if (!success)
            {
                Error("Failed to parse End of ForStmt.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(forStmt, success, position);return forStmt;
            }

            while (true)
            {
                int seq_start_position1 = position;
                MatchTerminal(',', out success);
                if (!success) { break; }

                ParseSpOpt(out success);

                forStmt.Step = ParseExpr(out success);
                if (!success)
                {
                    Error("Failed to parse Step of ForStmt.");
                    position = seq_start_position1;
                }
                break;
            }
            success = true;

            MatchTerminalString("do", out success);
            if (!success)
            {
                Error("Failed to parse 'do' of ForStmt.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(forStmt, success, position);return forStmt;
            }

            ParseSpReq(out success);
            if (!success)
            {
                Error("Failed to parse SpReq of ForStmt.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(forStmt, success, position);return forStmt;
            }

            forStmt.Body = ParseChunk(out success);
            if (!success)
            {
                Error("Failed to parse Body of ForStmt.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(forStmt, success, position);return forStmt;
            }

            MatchTerminalString("end", out success);
            if (!success)
            {
                Error("Failed to parse 'end' of ForStmt.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(forStmt, success, position);return forStmt;
            }

            ParseSpReq(out success);
            if (!success)
            {
                Error("Failed to parse SpReq of ForStmt.");
                position = start_position;
            }

            if (success) { ClearError(errorCount); }
            ParsingResults[reskey] = new Tuple<object, bool, int>(forStmt, success, position);
            return forStmt;
        }

        private ForInStmt ParseForInStmt(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "ForInStmt");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as ForInStmt;
            }

            int errorCount = Errors.Count;
            ForInStmt forInStmt = new ForInStmt();
            int start_position = position;

            MatchTerminalString("for", out success);
            if (!success)
            {
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(forInStmt, success, position);return forInStmt;
            }

            ParseSpReq(out success);
            if (!success)
            {
                Error("Failed to parse SpReq of ForInStmt.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(forInStmt, success, position);return forInStmt;
            }

            forInStmt.NameList = ParseNameList(out success);
            if (!success)
            {
                Error("Failed to parse NameList of ForInStmt.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(forInStmt, success, position);return forInStmt;
            }

            ParseSpReq(out success);
            if (!success)
            {
                Error("Failed to parse SpReq of ForInStmt.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(forInStmt, success, position);return forInStmt;
            }

            MatchTerminalString("in", out success);
            if (!success)
            {
                Error("Failed to parse 'in' of ForInStmt.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(forInStmt, success, position);return forInStmt;
            }

            ParseSpReq(out success);
            if (!success)
            {
                Error("Failed to parse SpReq of ForInStmt.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(forInStmt, success, position);return forInStmt;
            }

            forInStmt.ExprList = ParseExprList(out success);
            if (!success)
            {
                Error("Failed to parse ExprList of ForInStmt.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(forInStmt, success, position);return forInStmt;
            }

            MatchTerminalString("do", out success);
            if (!success)
            {
                Error("Failed to parse 'do' of ForInStmt.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(forInStmt, success, position);return forInStmt;
            }

            ParseSpReq(out success);
            if (!success)
            {
                Error("Failed to parse SpReq of ForInStmt.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(forInStmt, success, position);return forInStmt;
            }

            forInStmt.Body = ParseChunk(out success);
            if (!success)
            {
                Error("Failed to parse Body of ForInStmt.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(forInStmt, success, position);return forInStmt;
            }

            MatchTerminalString("end", out success);
            if (!success)
            {
                Error("Failed to parse 'end' of ForInStmt.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(forInStmt, success, position);return forInStmt;
            }

            ParseSpReq(out success);
            if (!success)
            {
                Error("Failed to parse SpReq of ForInStmt.");
                position = start_position;
            }

            if (success) { ClearError(errorCount); }
            ParsingResults[reskey] = new Tuple<object, bool, int>(forInStmt, success, position);
            return forInStmt;
        }

        private WhileStmt ParseWhileStmt(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "WhileStmt");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as WhileStmt;
            }

            int errorCount = Errors.Count;
            WhileStmt whileStmt = new WhileStmt();
            int start_position = position;

            MatchTerminalString("while", out success);
            if (!success)
            {
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(whileStmt, success, position);return whileStmt;
            }

            ParseSpReq(out success);
            if (!success)
            {
                Error("Failed to parse SpReq of WhileStmt.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(whileStmt, success, position);return whileStmt;
            }

            whileStmt.Condition = ParseExpr(out success);
            if (!success)
            {
                Error("Failed to parse Condition of WhileStmt.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(whileStmt, success, position);return whileStmt;
            }

            MatchTerminalString("do", out success);
            if (!success)
            {
                Error("Failed to parse 'do' of WhileStmt.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(whileStmt, success, position);return whileStmt;
            }

            ParseSpReq(out success);
            if (!success)
            {
                Error("Failed to parse SpReq of WhileStmt.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(whileStmt, success, position);return whileStmt;
            }

            whileStmt.Body = ParseChunk(out success);
            if (!success)
            {
                Error("Failed to parse Body of WhileStmt.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(whileStmt, success, position);return whileStmt;
            }

            MatchTerminalString("end", out success);
            if (!success)
            {
                Error("Failed to parse 'end' of WhileStmt.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(whileStmt, success, position);return whileStmt;
            }

            ParseSpReq(out success);
            if (!success)
            {
                Error("Failed to parse SpReq of WhileStmt.");
                position = start_position;
            }

            if (success) { ClearError(errorCount); }
            ParsingResults[reskey] = new Tuple<object, bool, int>(whileStmt, success, position);
            return whileStmt;
        }

        private RepeatStmt ParseRepeatStmt(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "RepeatStmt");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as RepeatStmt;
            }

            int errorCount = Errors.Count;
            RepeatStmt repeatStmt = new RepeatStmt();
            int start_position = position;

            MatchTerminalString("repeat", out success);
            if (!success)
            {
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(repeatStmt, success, position);return repeatStmt;
            }

            ParseSpReq(out success);
            if (!success)
            {
                Error("Failed to parse SpReq of RepeatStmt.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(repeatStmt, success, position);return repeatStmt;
            }

            repeatStmt.Body = ParseChunk(out success);
            if (!success)
            {
                Error("Failed to parse Body of RepeatStmt.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(repeatStmt, success, position);return repeatStmt;
            }

            MatchTerminalString("until", out success);
            if (!success)
            {
                Error("Failed to parse 'until' of RepeatStmt.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(repeatStmt, success, position);return repeatStmt;
            }

            ParseSpReq(out success);
            if (!success)
            {
                Error("Failed to parse SpReq of RepeatStmt.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(repeatStmt, success, position);return repeatStmt;
            }

            repeatStmt.Condition = ParseExpr(out success);
            if (!success)
            {
                Error("Failed to parse Condition of RepeatStmt.");
                position = start_position;
            }

            if (success) { ClearError(errorCount); }
            ParsingResults[reskey] = new Tuple<object, bool, int>(repeatStmt, success, position);
            return repeatStmt;
        }

        private List<Var> ParseVarList(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "VarList");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as List<Var>;
            }

            int errorCount = Errors.Count;
            List<Var> list_Var = new List<Var>();
            int start_position = position;

            Var var = ParseVar(out success);
            if (success) { list_Var.Add(var); }
            else
            {
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(list_Var, success, position);return list_Var;
            }

            while (true)
            {
                while (true)
                {
                    int seq_start_position1 = position;
                    ParseSpOpt(out success);

                    MatchTerminal(',', out success);
                    if (!success)
                    {
                        Error("Failed to parse ',' of VarList.");
                        position = seq_start_position1;
                        break;
                    }

                    ParseSpOpt(out success);

                    var = ParseVar(out success);
                    if (success) { list_Var.Add(var); }
                    else
                    {
                        Error("Failed to parse Var of VarList.");
                        position = seq_start_position1;
                    }
                    break;
                }
                if (!success) { break; }
            }
            success = true;

            ParsingResults[reskey] = new Tuple<object, bool, int>(list_Var, success, position);
            return list_Var;
        }

        private List<Expr> ParseExprList(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "ExprList");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as List<Expr>;
            }

            int errorCount = Errors.Count;
            List<Expr> list_Expr = new List<Expr>();
            int start_position = position;

            Expr expr = ParseExpr(out success);
            if (success) { list_Expr.Add(expr); }
            else
            {
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(list_Expr, success, position);return list_Expr;
            }

            while (true)
            {
                while (true)
                {
                    int seq_start_position1 = position;
                    ParseSpOpt(out success);

                    MatchTerminal(',', out success);
                    if (!success)
                    {
                        Error("Failed to parse ',' of ExprList.");
                        position = seq_start_position1;
                        break;
                    }

                    ParseSpOpt(out success);

                    expr = ParseExpr(out success);
                    if (success) { list_Expr.Add(expr); }
                    else
                    {
                        Error("Failed to parse Expr of ExprList.");
                        position = seq_start_position1;
                    }
                    break;
                }
                if (!success) { break; }
            }
            success = true;

            ParsingResults[reskey] = new Tuple<object, bool, int>(list_Expr, success, position);
            return list_Expr;
        }

        private Expr ParseExpr(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "Expr");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as Expr;
            }

            int errorCount = Errors.Count;
            Expr expr = null;

            expr = ParseOperatorExpr(out success);
            if (success) { return expr.Simplify(); }

            expr = ParseTerm(out success);
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(expr, success, position);return expr; }

            return expr;
        }

        private Term ParseTerm(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "Term");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as Term;
            }

            int errorCount = Errors.Count;
            Term term = null;

            term = ParseNilLiteral(out success);
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(term, success, position);return term; }

            term = ParseBoolLiteral(out success);
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(term, success, position);return term; }

            term = ParseNumberLiteral(out success);
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(term, success, position);return term; }

            term = ParseStringLiteral(out success);
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(term, success, position);return term; }

            term = ParseFunctionValue(out success);
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(term, success, position);return term; }

            term = ParseTableConstructor(out success);
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(term, success, position);return term; }

            term = ParseVariableArg(out success);
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(term, success, position);return term; }

            term = ParsePrimaryExpr(out success);
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(term, success, position);return term; }

            return term;
        }

        private NilLiteral ParseNilLiteral(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "NilLiteral");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as NilLiteral;
            }

            int errorCount = Errors.Count;
            NilLiteral nilLiteral = new NilLiteral();

            MatchTerminalString("nil", out success);
            if (success) { ClearError(errorCount); }
            else { Error("Failed to parse 'nil' of NilLiteral."); }
            ParsingResults[reskey] = new Tuple<object, bool, int>(nilLiteral, success, position);
            return nilLiteral;
        }

        private BoolLiteral ParseBoolLiteral(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "BoolLiteral");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as BoolLiteral;
            }

            int errorCount = Errors.Count;
            ErrorStack.Push(errorCount); errorCount = Errors.Count;
            BoolLiteral boolLiteral = new BoolLiteral();

            while (true)
            {
                boolLiteral.Text = MatchTerminalString("true", out success);
                if (success) { ClearError(errorCount); break; }

                boolLiteral.Text = MatchTerminalString("false", out success);
                if (success) { ClearError(errorCount); break; }

                break;
            }
            errorCount = ErrorStack.Pop();
            if (success) { ClearError(errorCount); }
            else { Error("Failed to parse Text of BoolLiteral."); }
            ParsingResults[reskey] = new Tuple<object, bool, int>(boolLiteral, success, position);
            return boolLiteral;
        }

        private NumberLiteral ParseNumberLiteral(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "NumberLiteral");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as NumberLiteral;
            }

            int errorCount = Errors.Count;
            NumberLiteral numberLiteral = new NumberLiteral();

            numberLiteral.HexicalText = ParseHexicalNumber(out success);
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(numberLiteral, success, position);return numberLiteral; }

            numberLiteral.Text = ParseFloatNumber(out success);
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(numberLiteral, success, position);return numberLiteral; }

            return numberLiteral;
        }

        private StringLiteral ParseStringLiteral(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "StringLiteral");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as StringLiteral;
            }

            int errorCount = Errors.Count;
            StringLiteral stringLiteral = new StringLiteral();

            while (true)
            {
                int seq_start_position1 = position;
                MatchTerminal('"', out success);
                if (!success) { break; }

                stringLiteral.Text = ParseDoubleQuotedText(out success);

                MatchTerminal('"', out success);
                if (!success)
                {
                    Error("Failed to parse '\\\"' of StringLiteral.");
                    position = seq_start_position1;
                }
                break;
            }
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(stringLiteral, success, position);return stringLiteral; }

            while (true)
            {
                int seq_start_position2 = position;
                MatchTerminal('\'', out success);
                if (!success) { break; }

                stringLiteral.Text = ParseSingleQuotedText(out success);

                MatchTerminal('\'', out success);
                if (!success)
                {
                    Error("Failed to parse ''' of StringLiteral.");
                    position = seq_start_position2;
                }
                break;
            }
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(stringLiteral, success, position);return stringLiteral; }

            stringLiteral.Text = ParseLongString(out success);
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(stringLiteral, success, position);return stringLiteral; }

            return stringLiteral;
        }

        private VariableArg ParseVariableArg(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "VariableArg");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as VariableArg;
            }

            int errorCount = Errors.Count;
            VariableArg variableArg = new VariableArg();

            variableArg.Name = MatchTerminalString("...", out success);
            if (success) { ClearError(errorCount); }
            else { Error("Failed to parse Name of VariableArg."); }
            ParsingResults[reskey] = new Tuple<object, bool, int>(variableArg, success, position);
            return variableArg;
        }

        private FunctionValue ParseFunctionValue(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "FunctionValue");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as FunctionValue;
            }

            int errorCount = Errors.Count;
            FunctionValue functionValue = new FunctionValue();
            int start_position = position;

            MatchTerminalString("function", out success);
            if (!success)
            {
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(functionValue, success, position);return functionValue;
            }

            ParseSpOpt(out success);

            functionValue.Body = ParseFunctionBody(out success);
            if (!success)
            {
                Error("Failed to parse Body of FunctionValue.");
                position = start_position;
            }

            if (success) { ClearError(errorCount); }
            ParsingResults[reskey] = new Tuple<object, bool, int>(functionValue, success, position);
            return functionValue;
        }

        private FunctionBody ParseFunctionBody(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "FunctionBody");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as FunctionBody;
            }

            int errorCount = Errors.Count;
            FunctionBody functionBody = new FunctionBody();
            int start_position = position;

            MatchTerminal('(', out success);
            if (!success)
            {
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(functionBody, success, position);return functionBody;
            }

            ParseSpOpt(out success);

            while (true)
            {
                int seq_start_position1 = position;
                functionBody.ParamList = ParseParamList(out success);
                if (!success) { break; }

                ParseSpOpt(out success);
                break;
            }
            success = true;

            MatchTerminal(')', out success);
            if (!success)
            {
                Error("Failed to parse ')' of FunctionBody.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(functionBody, success, position);return functionBody;
            }

            functionBody.Chunk = ParseChunk(out success);
            if (!success)
            {
                Error("Failed to parse Chunk of FunctionBody.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(functionBody, success, position);return functionBody;
            }

            MatchTerminalString("end", out success);
            if (!success)
            {
                Error("Failed to parse 'end' of FunctionBody.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(functionBody, success, position);return functionBody;
            }

            ParseSpOpt(out success);

            if (success) { ClearError(errorCount); }
            ParsingResults[reskey] = new Tuple<object, bool, int>(functionBody, success, position);
            return functionBody;
        }

        private Access ParseAccess(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "Access");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as Access;
            }

            int errorCount = Errors.Count;
            Access access = null;

            access = ParseNameAccess(out success);
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(access, success, position);return access; }

            access = ParseKeyAccess(out success);
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(access, success, position);return access; }

            access = ParseMethodCall(out success);
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(access, success, position);return access; }

            access = ParseFunctionCall(out success);
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(access, success, position);return access; }

            return access;
        }

        private BaseExpr ParseBaseExpr(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "BaseExpr");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as BaseExpr;
            }

            int errorCount = Errors.Count;
            BaseExpr baseExpr = null;

            baseExpr = ParseGroupExpr(out success);
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(baseExpr, success, position);return baseExpr; }

            baseExpr = ParseVarName(out success);
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(baseExpr, success, position);return baseExpr; }

            return baseExpr;
        }

        private KeyAccess ParseKeyAccess(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "KeyAccess");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as KeyAccess;
            }

            int errorCount = Errors.Count;
            KeyAccess keyAccess = new KeyAccess();
            int start_position = position;

            MatchTerminal('[', out success);
            if (!success)
            {
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(keyAccess, success, position);return keyAccess;
            }

            ParseSpOpt(out success);

            keyAccess.Key = ParseExpr(out success);
            if (!success)
            {
                Error("Failed to parse Key of KeyAccess.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(keyAccess, success, position);return keyAccess;
            }

            MatchTerminal(']', out success);
            if (!success)
            {
                Error("Failed to parse ']' of KeyAccess.");
                position = start_position;
            }

            if (success) { ClearError(errorCount); }
            ParsingResults[reskey] = new Tuple<object, bool, int>(keyAccess, success, position);
            return keyAccess;
        }

        private NameAccess ParseNameAccess(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "NameAccess");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as NameAccess;
            }

            int errorCount = Errors.Count;
            NameAccess nameAccess = new NameAccess();
            int start_position = position;

            MatchTerminal('.', out success);
            if (!success)
            {
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(nameAccess, success, position);return nameAccess;
            }

            ParseSpOpt(out success);

            nameAccess.Name = ParseName(out success);
            if (!success)
            {
                Error("Failed to parse Name of NameAccess.");
                position = start_position;
            }

            if (success) { ClearError(errorCount); }
            ParsingResults[reskey] = new Tuple<object, bool, int>(nameAccess, success, position);
            return nameAccess;
        }

        private MethodCall ParseMethodCall(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "MethodCall");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as MethodCall;
            }

            int errorCount = Errors.Count;
            MethodCall methodCall = new MethodCall();
            int start_position = position;

            MatchTerminal(':', out success);
            if (!success)
            {
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(methodCall, success, position);return methodCall;
            }

            ParseSpOpt(out success);

            methodCall.Method = ParseName(out success);
            if (!success)
            {
                Error("Failed to parse Method of MethodCall.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(methodCall, success, position);return methodCall;
            }

            ParseSpOpt(out success);

            methodCall.Args = ParseArgs(out success);
            if (!success)
            {
                Error("Failed to parse Args of MethodCall.");
                position = start_position;
            }

            if (success) { ClearError(errorCount); }
            ParsingResults[reskey] = new Tuple<object, bool, int>(methodCall, success, position);
            return methodCall;
        }

        private FunctionCall ParseFunctionCall(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "FunctionCall");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as FunctionCall;
            }

            int errorCount = Errors.Count;
            FunctionCall functionCall = new FunctionCall();

            functionCall.Args = ParseArgs(out success);
            if (success) { ClearError(errorCount); }
            else { Error("Failed to parse Args of FunctionCall."); }
            ParsingResults[reskey] = new Tuple<object, bool, int>(functionCall, success, position);
            return functionCall;
        }

        private Var ParseVar(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "Var");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as Var;
            }

            int errorCount = Errors.Count;
            Var var = new Var();
            int start_position = position;

            var.Base = ParseBaseExpr(out success);
            if (!success)
            {
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(var, success, position);return var;
            }

            while (true)
            {
                ErrorStack.Push(errorCount); errorCount = Errors.Count;
                while (true)
                {
                    while (true)
                    {
                        int seq_start_position1 = position;
                        ParseSpOpt(out success);

                        NameAccess nameAccess = ParseNameAccess(out success);
                        if (success) { var.Accesses.Add(nameAccess); }
                        else
                        {
                            Error("Failed to parse NameAccess of Var.");
                            position = seq_start_position1;
                        }
                        break;
                    }
                    if (success) { ClearError(errorCount); break; }

                    while (true)
                    {
                        int seq_start_position2 = position;
                        ParseSpOpt(out success);

                        KeyAccess keyAccess = ParseKeyAccess(out success);
                        if (success) { var.Accesses.Add(keyAccess); }
                        else
                        {
                            Error("Failed to parse KeyAccess of Var.");
                            position = seq_start_position2;
                        }
                        break;
                    }
                    if (success) { ClearError(errorCount); break; }

                    break;
                }
                errorCount = ErrorStack.Pop();
                if (!success) { break; }
            }
            success = true;

            ParsingResults[reskey] = new Tuple<object, bool, int>(var, success, position);
            return var;
        }

        private PrimaryExpr ParsePrimaryExpr(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "PrimaryExpr");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as PrimaryExpr;
            }

            int errorCount = Errors.Count;
            PrimaryExpr primaryExpr = new PrimaryExpr();
            int start_position = position;

            primaryExpr.Base = ParseBaseExpr(out success);
            if (!success)
            {
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(primaryExpr, success, position);return primaryExpr;
            }

            while (true)
            {
                while (true)
                {
                    int seq_start_position1 = position;
                    ParseSpOpt(out success);

                    Access access = ParseAccess(out success);
                    if (success) { primaryExpr.Accesses.Add(access); }
                    else
                    {
                        Error("Failed to parse Access of PrimaryExpr.");
                        position = seq_start_position1;
                    }
                    break;
                }
                if (!success) { break; }
            }
            success = true;

            ParsingResults[reskey] = new Tuple<object, bool, int>(primaryExpr, success, position);
            return primaryExpr;
        }

        private VarName ParseVarName(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "VarName");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as VarName;
            }

            int errorCount = Errors.Count;
            VarName varName = new VarName();

            varName.Name = ParseName(out success);
            if (success) { ClearError(errorCount); }
            else { Error("Failed to parse Name of VarName."); }
            ParsingResults[reskey] = new Tuple<object, bool, int>(varName, success, position);
            return varName;
        }

        private FunctionName ParseFunctionName(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "FunctionName");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as FunctionName;
            }

            int errorCount = Errors.Count;
            FunctionName functionName = new FunctionName();
            int start_position = position;

            functionName.FullName = ParseFullName(out success);
            if (!success)
            {
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(functionName, success, position);return functionName;
            }

            while (true)
            {
                int seq_start_position1 = position;
                ParseSpOpt(out success);

                MatchTerminal(':', out success);
                if (!success)
                {
                    Error("Failed to parse ':' of FunctionName.");
                    position = seq_start_position1;
                    break;
                }

                ParseSpOpt(out success);

                functionName.MethodName = ParseName(out success);
                if (!success)
                {
                    Error("Failed to parse MethodName of FunctionName.");
                    position = seq_start_position1;
                }
                break;
            }
            success = true;

            ParsingResults[reskey] = new Tuple<object, bool, int>(functionName, success, position);
            return functionName;
        }

        private GroupExpr ParseGroupExpr(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "GroupExpr");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as GroupExpr;
            }

            int errorCount = Errors.Count;
            GroupExpr groupExpr = new GroupExpr();
            int start_position = position;

            MatchTerminal('(', out success);
            if (!success)
            {
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(groupExpr, success, position);return groupExpr;
            }

            ParseSpOpt(out success);

            groupExpr.Expr = ParseExpr(out success);
            if (!success)
            {
                Error("Failed to parse Expr of GroupExpr.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(groupExpr, success, position);return groupExpr;
            }

            MatchTerminal(')', out success);
            if (!success)
            {
                Error("Failed to parse ')' of GroupExpr.");
                position = start_position;
            }

            if (success) { ClearError(errorCount); }
            ParsingResults[reskey] = new Tuple<object, bool, int>(groupExpr, success, position);
            return groupExpr;
        }

        private TableConstructor ParseTableConstructor(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "TableConstructor");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as TableConstructor;
            }

            int errorCount = Errors.Count;
            TableConstructor tableConstructor = new TableConstructor();
            int start_position = position;

            MatchTerminal('{', out success);
            if (!success)
            {
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(tableConstructor, success, position);return tableConstructor;
            }

            ParseSpOpt(out success);

            tableConstructor.FieldList = ParseFieldList(out success);
            success = true;

            MatchTerminal('}', out success);
            if (!success)
            {
                Error("Failed to parse '}' of TableConstructor.");
                position = start_position;
            }

            if (success) { ClearError(errorCount); }
            ParsingResults[reskey] = new Tuple<object, bool, int>(tableConstructor, success, position);
            return tableConstructor;
        }

        private List<Field> ParseFieldList(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "FieldList");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as List<Field>;
            }

            int errorCount = Errors.Count;
            List<Field> list_Field = new List<Field>();
            int start_position = position;

            Field field = ParseField(out success);
            if (success) { list_Field.Add(field); }
            else
            {
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(list_Field, success, position);return list_Field;
            }

            while (true)
            {
                while (true)
                {
                    int seq_start_position1 = position;
                    ParseFieldSep(out success);
                    if (!success) { break; }

                    ParseSpOpt(out success);

                    field = ParseField(out success);
                    if (success) { list_Field.Add(field); }
                    else
                    {
                        Error("Failed to parse Field of FieldList.");
                        position = seq_start_position1;
                    }
                    break;
                }
                if (!success) { break; }
            }
            success = true;

            while (true)
            {
                int seq_start_position2 = position;
                ParseFieldSep(out success);
                if (!success) { break; }

                ParseSpOpt(out success);
                break;
            }
            success = true;

            ParsingResults[reskey] = new Tuple<object, bool, int>(list_Field, success, position);
            return list_Field;
        }

        private Field ParseField(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "Field");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as Field;
            }

            int errorCount = Errors.Count;
            Field field = null;

            field = ParseKeyValue(out success);
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(field, success, position);return field; }

            field = ParseNameValue(out success);
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(field, success, position);return field; }

            field = ParseItemValue(out success);
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(field, success, position);return field; }

            return field;
        }

        private KeyValue ParseKeyValue(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "KeyValue");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as KeyValue;
            }

            int errorCount = Errors.Count;
            KeyValue keyValue = new KeyValue();
            int start_position = position;

            MatchTerminal('[', out success);
            if (!success)
            {
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(keyValue, success, position);return keyValue;
            }

            ParseSpOpt(out success);

            keyValue.Key = ParseExpr(out success);
            if (!success)
            {
                Error("Failed to parse Key of KeyValue.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(keyValue, success, position);return keyValue;
            }

            MatchTerminal(']', out success);
            if (!success)
            {
                Error("Failed to parse ']' of KeyValue.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(keyValue, success, position);return keyValue;
            }

            ParseSpOpt(out success);

            MatchTerminal('=', out success);
            if (!success)
            {
                Error("Failed to parse '=' of KeyValue.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(keyValue, success, position);return keyValue;
            }

            ParseSpOpt(out success);

            keyValue.Value = ParseExpr(out success);
            if (!success)
            {
                Error("Failed to parse Value of KeyValue.");
                position = start_position;
            }

            if (success) { ClearError(errorCount); }
            ParsingResults[reskey] = new Tuple<object, bool, int>(keyValue, success, position);
            return keyValue;
        }

        private NameValue ParseNameValue(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "NameValue");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as NameValue;
            }

            int errorCount = Errors.Count;
            NameValue nameValue = new NameValue();
            int start_position = position;

            nameValue.Name = ParseName(out success);
            if (!success)
            {
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(nameValue, success, position);return nameValue;
            }

            ParseSpOpt(out success);

            MatchTerminal('=', out success);
            if (!success)
            {
                Error("Failed to parse '=' of NameValue.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(nameValue, success, position);return nameValue;
            }

            ParseSpOpt(out success);

            nameValue.Value = ParseExpr(out success);
            if (!success)
            {
                Error("Failed to parse Value of NameValue.");
                position = start_position;
            }

            if (success) { ClearError(errorCount); }
            ParsingResults[reskey] = new Tuple<object, bool, int>(nameValue, success, position);
            return nameValue;
        }

        private ItemValue ParseItemValue(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "ItemValue");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as ItemValue;
            }

            int errorCount = Errors.Count;
            ItemValue itemValue = new ItemValue();

            itemValue.Value = ParseExpr(out success);
            if (success) { ClearError(errorCount); }
            else { Error("Failed to parse Value of ItemValue."); }
            ParsingResults[reskey] = new Tuple<object, bool, int>(itemValue, success, position);
            return itemValue;
        }

        private OperatorExpr ParseOperatorExpr(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "OperatorExpr");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as OperatorExpr;
            }

            int errorCount = Errors.Count;
            OperatorExpr operatorExpr = new OperatorExpr();
            int start_position = position;

            while (true)
            {
                int seq_start_position1 = position;
                string unaryOper = ParseUnaryOperator(out success);
                if (success) { operatorExpr.Add(unaryOper); }
                else { break; }

                ParseSpOpt(out success);
                break;
            }
            success = true;

            Term firstTerm = ParseTerm(out success);
            if (success) { operatorExpr.Add(firstTerm); }
            else
            {
                Error("Failed to parse firstTerm of OperatorExpr.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(operatorExpr, success, position);return operatorExpr;
            }

            ParseSpOpt(out success);

            while (true)
            {
                while (true)
                {
                    int seq_start_position2 = position;
                    string binaryOper = ParseBinaryOperator(out success);
                    if (success) { operatorExpr.Add(binaryOper); }
                    else { break; }

                    ParseSpOpt(out success);

                    Term nextTerm = ParseTerm(out success);
                    if (success) { operatorExpr.Add(nextTerm); }
                    else
                    {
                        Error("Failed to parse nextTerm of OperatorExpr.");
                        position = seq_start_position2;
                        break;
                    }

                    ParseSpOpt(out success);
                    break;
                }
                if (!success) { break; }
            }
            success = true;

            ParsingResults[reskey] = new Tuple<object, bool, int>(operatorExpr, success, position);
            return operatorExpr;
        }

        private Args ParseArgs(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "Args");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as Args;
            }

            int errorCount = Errors.Count;
            Args args = new Args();

            args.ArgList = ParseArgList(out success);
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(args, success, position);return args; }

            args.String = ParseStringLiteral(out success);
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(args, success, position);return args; }

            args.Table = ParseTableConstructor(out success);
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(args, success, position);return args; }

            return args;
        }

        private List<Expr> ParseArgList(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "ArgList");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as List<Expr>;
            }

            int errorCount = Errors.Count;
            List<Expr> list_Expr = new List<Expr>();
            int start_position = position;

            MatchTerminal('(', out success);
            if (!success)
            {
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(list_Expr, success, position);return list_Expr;
            }

            ParseSpOpt(out success);

            while (true)
            {
                int seq_start_position1 = position;
                list_Expr = ParseExprList(out success);
                if (!success) { break; }

                ParseSpOpt(out success);
                break;
            }
            success = true;

            MatchTerminal(')', out success);
            if (!success)
            {
                Error("Failed to parse ')' of ArgList.");
                position = start_position;
            }

            if (success) { ClearError(errorCount); }
            ParsingResults[reskey] = new Tuple<object, bool, int>(list_Expr, success, position);
            return list_Expr;
        }

        private ParamList ParseParamList(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "ParamList");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as ParamList;
            }

            int errorCount = Errors.Count;
            ParamList paramList = new ParamList();

            while (true)
            {
                int seq_start_position1 = position;
                paramList.NameList = ParseNameList(out success);
                if (!success) { break; }

                while (true)
                {
                    int seq_start_position2 = position;
                    MatchTerminal(',', out success);
                    if (!success) { break; }

                    ParseSpOpt(out success);

                    MatchTerminalString("...", out success);
                    if (!success)
                    {
                        Error("Failed to parse '...' of ParamList.");
                        position = seq_start_position2;
                    }
                    break;
                }
                paramList.HasVarArg = success;
                success = true;
                break;
            }
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(paramList, success, position);return paramList; }

            paramList.IsVarArg = MatchTerminalString("...", out success);
            if (success) { ClearError(errorCount); ParsingResults[reskey] = new Tuple<object, bool, int>(paramList, success, position);return paramList; }

            return paramList;
        }

        private List<string> ParseFullName(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "FullName");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as List<string>;
            }

            int errorCount = Errors.Count;
            List<string> list_string = new List<string>();
            int start_position = position;

            string str = ParseName(out success);
            if (success) { list_string.Add(str); }
            else
            {
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(list_string, success, position);return list_string;
            }

            while (true)
            {
                while (true)
                {
                    int seq_start_position1 = position;
                    ParseSpOpt(out success);

                    MatchTerminal('.', out success);
                    if (!success)
                    {
                        Error("Failed to parse '.' of FullName.");
                        position = seq_start_position1;
                        break;
                    }

                    ParseSpOpt(out success);

                    str = ParseName(out success);
                    if (success) { list_string.Add(str); }
                    else
                    {
                        Error("Failed to parse Name of FullName.");
                        position = seq_start_position1;
                    }
                    break;
                }
                if (!success) { break; }
            }
            success = true;

            ParsingResults[reskey] = new Tuple<object, bool, int>(list_string, success, position);
            return list_string;
        }

        private List<string> ParseNameList(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "NameList");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as List<string>;
            }

            int errorCount = Errors.Count;
            List<string> list_string = new List<string>();
            int start_position = position;

            string str = ParseName(out success);
            if (success) { list_string.Add(str); }
            else
            {
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(list_string, success, position);return list_string;
            }

            while (true)
            {
                while (true)
                {
                    int seq_start_position1 = position;
                    ParseSpOpt(out success);

                    MatchTerminal(',', out success);
                    if (!success)
                    {
                        Error("Failed to parse ',' of NameList.");
                        position = seq_start_position1;
                        break;
                    }

                    ParseSpOpt(out success);

                    str = ParseName(out success);
                    if (success) { list_string.Add(str); }
                    else
                    {
                        Error("Failed to parse Name of NameList.");
                        position = seq_start_position1;
                    }
                    break;
                }
                if (!success) { break; }
            }
            success = true;

            ParsingResults[reskey] = new Tuple<object, bool, int>(list_string, success, position);
            return list_string;
        }

        private string ParseName(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "Name");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as string;
            }

            int errorCount = Errors.Count;
            StringBuilder text = new StringBuilder();
            int start_position = position;

            int not_start_position1 = position;
            while (true)
            {
                ParseKeyword(out success);
                if (!success) { break; }

                ParseWordSep(out success);
                break;
            }
            position = not_start_position1;
            success = !success;
            if (!success)
            {
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(text.ToString(), success, position);return text.ToString();
            }

            char ch = ParseLetter(out success);
            if (success) { text.Append(ch); }
            else
            {
                Error("Failed to parse Letter of Name.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(text.ToString(), success, position);return text.ToString();
            }

            while (true)
            {
                ErrorStack.Push(errorCount); errorCount = Errors.Count;
                while (true)
                {
                    ch = ParseLetter(out success);
                    if (success)
                    {
                        ClearError(errorCount);
                        text.Append(ch);
                        break;
                    }

                    ch = ParseDigit(out success);
                    if (success)
                    {
                        ClearError(errorCount);
                        text.Append(ch);
                        break;
                    }

                    break;
                }
                errorCount = ErrorStack.Pop();
                if (!success) { break; }
            }
            success = true;

            ParsingResults[reskey] = new Tuple<object, bool, int>(text.ToString(), success, position);
            return text.ToString();
        }

        private string ParseFloatNumber(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "FloatNumber");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as string;
            }

            int errorCount = Errors.Count;
            StringBuilder text = new StringBuilder();
            int start_position = position;

            char ch = MatchTerminal('-', out success);
            if (success) { text.Append(ch); }
            success = true;

            int counter = 0;
            while (true)
            {
                ch = ParseDigit(out success);
                if (success) { text.Append(ch); }
                else { break; }
                counter++;
            }
            if (counter > 0) { success = true; }
            if (!success)
            {
                Error("Failed to parse (Digit)+ of FloatNumber.");
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(text.ToString(), success, position);return text.ToString();
            }

            while (true)
            {
                int seq_start_position1 = position;
                ch = MatchTerminal('.', out success);
                if (success) { text.Append(ch); }
                else { break; }

                counter = 0;
                while (true)
                {
                    ch = ParseDigit(out success);
                    if (success) { text.Append(ch); }
                    else { break; }
                    counter++;
                }
                if (counter > 0) { success = true; }
                if (!success)
                {
                    Error("Failed to parse (Digit)+ of FloatNumber.");
                    position = seq_start_position1;
                }
                break;
            }
            success = true;

            while (true)
            {
                ErrorStack.Push(errorCount); errorCount = Errors.Count;
                int seq_start_position2 = position;
                while (true)
                {
                    ch = MatchTerminal('e', out success);
                    if (success)
                    {
                        ClearError(errorCount);
                        text.Append(ch);
                        break;
                    }

                    ch = MatchTerminal('E', out success);
                    if (success)
                    {
                        ClearError(errorCount);
                        text.Append(ch);
                        break;
                    }

                    break;
                }
                errorCount = ErrorStack.Pop();
                if (!success) { break; }

                counter = 0;
                while (true)
                {
                    ch = ParseDigit(out success);
                    if (success) { text.Append(ch); }
                    else { break; }
                    counter++;
                }
                if (counter > 0) { success = true; }
                if (!success)
                {
                    Error("Failed to parse (Digit)+ of FloatNumber.");
                    position = seq_start_position2;
                }
                break;
            }
            success = true;

            ParsingResults[reskey] = new Tuple<object, bool, int>(text.ToString(), success, position);
            return text.ToString();
        }

        private string ParseHexicalNumber(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "HexicalNumber");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as string;
            }

            int errorCount = Errors.Count;
            StringBuilder text = new StringBuilder();
            int start_position = position;

            MatchTerminalString("0x", out success);
            if (!success)
            {
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(text.ToString(), success, position);return text.ToString();
            }

            int counter = 0;
            while (true)
            {
                char ch = ParseHexDigit(out success);
                if (success) { text.Append(ch); }
                else { break; }
                counter++;
            }
            if (counter > 0) { success = true; }
            if (!success)
            {
                Error("Failed to parse (HexDigit)+ of HexicalNumber.");
                position = start_position;
            }

            if (success) { ClearError(errorCount); }
            ParsingResults[reskey] = new Tuple<object, bool, int>(text.ToString(), success, position);
            return text.ToString();
        }

        private string ParseSingleQuotedText(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "SingleQuotedText");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as string;
            }

            int errorCount = Errors.Count;
            StringBuilder text = new StringBuilder();

            while (true)
            {
                ErrorStack.Push(errorCount); errorCount = Errors.Count;
                while (true)
                {
                    char ch = MatchTerminalSet("'\\", true, out success);
                    if (success)
                    {
                        ClearError(errorCount);
                        text.Append(ch);
                        break;
                    }

                    ch = ParseEscapeChar(out success);
                    if (success)
                    {
                        ClearError(errorCount);
                        text.Append(ch);
                        break;
                    }

                    break;
                }
                errorCount = ErrorStack.Pop();
                if (!success) { break; }
            }
            success = true;
            ParsingResults[reskey] = new Tuple<object, bool, int>(text.ToString(), success, position);
            return text.ToString();
        }

        private string ParseDoubleQuotedText(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "DoubleQuotedText");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as string;
            }

            int errorCount = Errors.Count;
            StringBuilder text = new StringBuilder();

            while (true)
            {
                ErrorStack.Push(errorCount); errorCount = Errors.Count;
                while (true)
                {
                    char ch = MatchTerminalSet("\"\\", true, out success);
                    if (success)
                    {
                        ClearError(errorCount);
                        text.Append(ch);
                        break;
                    }

                    ch = ParseEscapeChar(out success);
                    if (success)
                    {
                        ClearError(errorCount);
                        text.Append(ch);
                        break;
                    }

                    break;
                }
                errorCount = ErrorStack.Pop();
                if (!success) { break; }
            }
            success = true;
            ParsingResults[reskey] = new Tuple<object, bool, int>(text.ToString(), success, position);
            return text.ToString();
        }

        private string ParseLongString(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "LongString");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as string;
            }

            int errorCount = Errors.Count;
            StringBuilder text = new StringBuilder();
            int start_position = position;

            List<char> opening = new List<char>();
            while (true)
            {
                int seq_start_position1 = position;
                char ch = MatchTerminal('[', out success);
                if (success) { opening.Add(ch); }
                else { break; }

                while (true)
                {
                    ch = MatchTerminal('=', out success);
                    if (success) { opening.Add(ch); }
                    else { break; }
                }
                success = true;

                ch = MatchTerminal('[', out success);
                if (success) { opening.Add(ch); }
                else
                {
                    Error("Failed to parse '[' of LongString.");
                    position = seq_start_position1;
                }
                break;
            }
            if (!success)
            {
                position = start_position;
                ParsingResults[reskey] = new Tuple<object, bool, int>(text.ToString(), success, position);return text.ToString();
            }

            ParseEol(out success);
            string closing = new string(opening.ToArray()).Replace('[', ']');
            success = true;

            while (true)
            {
                MatchTerminalString(closing, out success);
                if (success) break;
                char ch = MatchTerminalSet("", true, out success);
                if (success) { text.Append(ch); }
                else { break; }
            }
            success = true;

            ParsingResults[reskey] = new Tuple<object, bool, int>(text.ToString(), success, position);
            return text.ToString();
        }

        private void ParseKeyword(out bool success)
        {
            int errorCount = Errors.Count;
            MatchTerminalString("and", out success);
            if (success) { ClearError(errorCount); return; }

            MatchTerminalString("break", out success);
            if (success) { ClearError(errorCount); return; }

            MatchTerminalString("do", out success);
            if (success) { ClearError(errorCount); return; }

            MatchTerminalString("elseif", out success);
            if (success) { ClearError(errorCount); return; }

            MatchTerminalString("else", out success);
            if (success) { ClearError(errorCount); return; }

            MatchTerminalString("end", out success);
            if (success) { ClearError(errorCount); return; }

            MatchTerminalString("false", out success);
            if (success) { ClearError(errorCount); return; }

            MatchTerminalString("for", out success);
            if (success) { ClearError(errorCount); return; }

            MatchTerminalString("function", out success);
            if (success) { ClearError(errorCount); return; }

            MatchTerminalString("if", out success);
            if (success) { ClearError(errorCount); return; }

            MatchTerminalString("in", out success);
            if (success) { ClearError(errorCount); return; }

            MatchTerminalString("local", out success);
            if (success) { ClearError(errorCount); return; }

            MatchTerminalString("nil", out success);
            if (success) { ClearError(errorCount); return; }

            MatchTerminalString("not", out success);
            if (success) { ClearError(errorCount); return; }

            MatchTerminalString("or", out success);
            if (success) { ClearError(errorCount); return; }

            MatchTerminalString("repeat", out success);
            if (success) { ClearError(errorCount); return; }

            MatchTerminalString("return", out success);
            if (success) { ClearError(errorCount); return; }

            MatchTerminalString("then", out success);
            if (success) { ClearError(errorCount); return; }

            MatchTerminalString("true", out success);
            if (success) { ClearError(errorCount); return; }

            MatchTerminalString("until", out success);
            if (success) { ClearError(errorCount); return; }

            MatchTerminalString("while", out success);
            if (success) { ClearError(errorCount); return; }

        }

        private char ParseDigit(out bool success)
        {
            int errorCount = Errors.Count;
            char ch = MatchTerminalRange('0', '9', out success);
            if (success) { ClearError(errorCount); }
            else { Error("Failed to parse '0'...'9' of Digit."); }
            
            return ch;
        }

        private char ParseHexDigit(out bool success)
        {
            int errorCount = Errors.Count;
            char ch = MatchTerminalSet("0123456789ABCDEFabcdef", false, out success);
            if (success) { ClearError(errorCount); }
            else { Error("Failed to parse \"0123456789ABCDEFabcdef\" of HexDigit."); }
            
            return ch;
        }

        private char ParseLetter(out bool success)
        {
            int errorCount = Errors.Count;
            char ch = default(char);

            ch = MatchTerminalRange('A', 'Z', out success);
            if (success) { ClearError(errorCount); return ch; }

            ch = MatchTerminalRange('a', 'z', out success);
            if (success) { ClearError(errorCount); return ch; }

            ch = MatchTerminal('_', out success);
            if (success) { ClearError(errorCount); return ch; }

            return ch;
        }

        private string ParseUnaryOperator(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "UnaryOperator");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as string;
            }

            int errorCount = Errors.Count;
            StringBuilder text = new StringBuilder();

            char ch = MatchTerminal('#', out success);
            if (success)
            {
                ClearError(errorCount);
                text.Append(ch);
                ParsingResults[reskey] = new Tuple<object, bool, int>(text.ToString(), success, position);return text.ToString();
            }

            ch = MatchTerminal('-', out success);
            if (success)
            {
                ClearError(errorCount);
                text.Append(ch);
                ParsingResults[reskey] = new Tuple<object, bool, int>(text.ToString(), success, position);return text.ToString();
            }

            string str = MatchTerminalString("not", out success);
            if (success)
            {
                ClearError(errorCount);
                text.Append(str);
                ParsingResults[reskey] = new Tuple<object, bool, int>(text.ToString(), success, position);return text.ToString();
            }

            return text.ToString();
        }

        private string ParseBinaryOperator(out bool success)
        {
            var reskey = new Tuple<int, string>(position, "BinaryOperator");
            if (ParsingResults.ContainsKey(reskey))
            {
                var parsingResult = ParsingResults[reskey];
                success = parsingResult.Item2;
                position = parsingResult.Item3;
                return parsingResult.Item1 as string;
            }

            int errorCount = Errors.Count;
            StringBuilder text = new StringBuilder();

            char ch = MatchTerminal('+', out success);
            if (success)
            {
                ClearError(errorCount);
                text.Append(ch);
                ParsingResults[reskey] = new Tuple<object, bool, int>(text.ToString(), success, position);return text.ToString();
            }

            ch = MatchTerminal('-', out success);
            if (success)
            {
                ClearError(errorCount);
                text.Append(ch);
                ParsingResults[reskey] = new Tuple<object, bool, int>(text.ToString(), success, position);return text.ToString();
            }

            ch = MatchTerminal('*', out success);
            if (success)
            {
                ClearError(errorCount);
                text.Append(ch);
                ParsingResults[reskey] = new Tuple<object, bool, int>(text.ToString(), success, position);return text.ToString();
            }

            ch = MatchTerminal('/', out success);
            if (success)
            {
                ClearError(errorCount);
                text.Append(ch);
                ParsingResults[reskey] = new Tuple<object, bool, int>(text.ToString(), success, position);return text.ToString();
            }

            ch = MatchTerminal('%', out success);
            if (success)
            {
                ClearError(errorCount);
                text.Append(ch);
                ParsingResults[reskey] = new Tuple<object, bool, int>(text.ToString(), success, position);return text.ToString();
            }

            ch = MatchTerminal('^', out success);
            if (success)
            {
                ClearError(errorCount);
                text.Append(ch);
                ParsingResults[reskey] = new Tuple<object, bool, int>(text.ToString(), success, position);return text.ToString();
            }

            string str = MatchTerminalString("..", out success);
            if (success)
            {
                ClearError(errorCount);
                text.Append(str);
                ParsingResults[reskey] = new Tuple<object, bool, int>(text.ToString(), success, position);return text.ToString();
            }

            str = MatchTerminalString("==", out success);
            if (success)
            {
                ClearError(errorCount);
                text.Append(str);
                ParsingResults[reskey] = new Tuple<object, bool, int>(text.ToString(), success, position);return text.ToString();
            }

            str = MatchTerminalString("~=", out success);
            if (success)
            {
                ClearError(errorCount);
                text.Append(str);
                ParsingResults[reskey] = new Tuple<object, bool, int>(text.ToString(), success, position);return text.ToString();
            }

            str = MatchTerminalString("<=", out success);
            if (success)
            {
                ClearError(errorCount);
                text.Append(str);
                ParsingResults[reskey] = new Tuple<object, bool, int>(text.ToString(), success, position);return text.ToString();
            }

            str = MatchTerminalString(">=", out success);
            if (success)
            {
                ClearError(errorCount);
                text.Append(str);
                ParsingResults[reskey] = new Tuple<object, bool, int>(text.ToString(), success, position);return text.ToString();
            }

            ch = MatchTerminal('<', out success);
            if (success)
            {
                ClearError(errorCount);
                text.Append(ch);
                ParsingResults[reskey] = new Tuple<object, bool, int>(text.ToString(), success, position);return text.ToString();
            }

            ch = MatchTerminal('>', out success);
            if (success)
            {
                ClearError(errorCount);
                text.Append(ch);
                ParsingResults[reskey] = new Tuple<object, bool, int>(text.ToString(), success, position);return text.ToString();
            }

            str = MatchTerminalString("and", out success);
            if (success)
            {
                ClearError(errorCount);
                text.Append(str);
                ParsingResults[reskey] = new Tuple<object, bool, int>(text.ToString(), success, position);return text.ToString();
            }

            str = MatchTerminalString("or", out success);
            if (success)
            {
                ClearError(errorCount);
                text.Append(str);
                ParsingResults[reskey] = new Tuple<object, bool, int>(text.ToString(), success, position);return text.ToString();
            }

            return text.ToString();
        }

        private void ParseWordSep(out bool success)
        {
            int errorCount = Errors.Count;
            MatchTerminalSet(" \t\r\n'\",;:={}[]()+-*/%^.~<>#", false, out success);
            if (success) { ClearError(errorCount); }
            else { Error("Failed to parse \" \t\r\n'\",;:={}[]()+-*/%^.~<>#\" of WordSep."); }
        }

        private void ParseFieldSep(out bool success)
        {
            int errorCount = Errors.Count;
            MatchTerminal(',', out success);
            if (success) { ClearError(errorCount); return; }

            MatchTerminal(';', out success);
            if (success) { ClearError(errorCount); return; }

        }

        private void ParseSpReq(out bool success)
        {
            int errorCount = Errors.Count;
            int counter = 0;
            while (true)
            {
                ErrorStack.Push(errorCount); errorCount = Errors.Count;
                while (true)
                {
                    MatchTerminalSet(" \t\r\n", false, out success);
                    if (success) { ClearError(errorCount); break; }

                    ParseComment(out success);
                    if (success) { ClearError(errorCount); break; }

                    break;
                }
                errorCount = ErrorStack.Pop();
                if (!success) { break; }
                counter++;
            }
            if (counter > 0) { success = true; }
            if (success) { ClearError(errorCount); return; }

            while (true)
            {
                int seq_start_position1 = position;
                ParseSpOpt(out success);

                ParseEof(out success);
                if (!success)
                {
                    Error("Failed to parse Eof of SpReq.");
                    position = seq_start_position1;
                }
                break;
            }
            if (success) { ClearError(errorCount); return; }

        }

        private void ParseSpOpt(out bool success)
        {
            int errorCount = Errors.Count;
            while (true)
            {
                ErrorStack.Push(errorCount); errorCount = Errors.Count;
                while (true)
                {
                    MatchTerminalSet(" \t\r\n", false, out success);
                    if (success) { ClearError(errorCount); break; }

                    ParseComment(out success);
                    if (success) { ClearError(errorCount); break; }

                    break;
                }
                errorCount = ErrorStack.Pop();
                if (!success) { break; }
            }
            success = true;
        }

        private void ParseComment(out bool success)
        {
            int errorCount = Errors.Count;
            int start_position = position;

            MatchTerminalString("--", out success);
            if (!success)
            {
                position = start_position;
                return;
            }

            ErrorStack.Push(errorCount); errorCount = Errors.Count;
            while (true)
            {
                ParseLongString(out success);
                if (success) { ClearError(errorCount); break; }

                while (true)
                {
                    int seq_start_position1 = position;
                    while (true)
                    {
                        MatchTerminalSet("\r\n", true, out success);
                        if (!success) { break; }
                    }
                    success = true;

                    ErrorStack.Push(errorCount); errorCount = Errors.Count;
                    while (true)
                    {
                        ParseEol(out success);
                        if (success) { ClearError(errorCount); break; }

                        ParseEof(out success);
                        if (success) { ClearError(errorCount); break; }

                        break;
                    }
                    errorCount = ErrorStack.Pop();
                    if (!success)
                    {
                        Error("Failed to parse (Eol / Eof) of Comment.");
                        position = seq_start_position1;
                    }
                    break;
                }
                if (success) { ClearError(errorCount); break; }

                break;
            }
            errorCount = ErrorStack.Pop();
            if (!success)
            {
                Error("Failed to parse (LongString / (-\"\r\n\")* (Eol / Eof)) of Comment.");
                position = start_position;
            }

            if (success) { ClearError(errorCount); }
        }

        private void ParseEol(out bool success)
        {
            int errorCount = Errors.Count;
            MatchTerminalString("\r\n", out success);
            if (success) { ClearError(errorCount); return; }

            MatchTerminal('\n', out success);
            if (success) { ClearError(errorCount); return; }

            MatchTerminal('\r', out success);
            if (success) { ClearError(errorCount); return; }

        }

        private void ParseEof(out bool success)
        {
            int errorCount = Errors.Count;
            success = !Input.HasInput(position);
            if (success) { ClearError(errorCount); }
            else { Error("Failed to parse end of Eof."); }
        }

        private char ParseEscapeChar(out bool success)
        {
            int errorCount = Errors.Count;
            char ch = default(char);

            MatchTerminalString("\\\\", out success);
            if (success) { return '\\'; }

            MatchTerminalString("\\'", out success);
            if (success) { return '\''; }

            MatchTerminalString("\\\"", out success);
            if (success) { return '\"'; }

            MatchTerminalString("\\r", out success);
            if (success) { return '\r'; }

            MatchTerminalString("\\n", out success);
            if (success) { return '\n'; }

            MatchTerminalString("\\t", out success);
            if (success) { return '\t'; }

            MatchTerminalString("\\v", out success);
            if (success) { return '\v'; }

            MatchTerminalString("\\a", out success);
            if (success) { return '\a'; }

            MatchTerminalString("\\b", out success);
            if (success) { return '\b'; }

            MatchTerminalString("\\f", out success);
            if (success) { return '\f'; }

            MatchTerminalString("\\0", out success);
            if (success) { return '\0'; }

            return ch;
        }

    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The MIT License


Written By
Architect YunCheDa Hangzhou
China China
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions