Beispiel #1
0
        private List <ICVariableDeclaration> PaParseArgumentList()
        {
            List <ICVariableDeclaration> ReturnList = new List <ICVariableDeclaration>();

            int EndOfArgumentList = PaPositionNow;

            for (int BracketCount = 1; BracketCount > 0 && EndOfArgumentList < PaLexemeStream.Count; EndOfArgumentList++)
            {
                if (PaLexemeStream[EndOfArgumentList].Type == LexemeType.LEFT_BRACKET)
                {
                    BracketCount += 1;
                }
                else if (PaLexemeStream[EndOfArgumentList].Type == LexemeType.RIGHT_BRACKET)
                {
                    BracketCount -= 1;
                }
            }
            EndOfArgumentList -= 1;


            if (PaLexemeStream[EndOfArgumentList].Type != LexemeType.RIGHT_BRACKET)
            {
                Error Error = new Error();
                Error.ID          = ErrorID.C0010;
                Error.ErrorDetail = "A \')\' is expected.";
                Error.LineNo      = PaLexemeStream[EndOfArgumentList].LineNumber;
                ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                PaStopParsing = true;
                return(ReturnList);
            }

            for (; PaPositionNow < EndOfArgumentList;)
            {
                ICVariableDeclaration VD = new ICVariableDeclaration();

                // If no more arguments, return.
                if (PaPositionNow == EndOfArgumentList)
                {
                    return(ReturnList);
                }

                #region ParseType

                switch (PaLexemeStream[PaPositionNow].Type)
                {
                case LexemeType.ID:
                    VD.Type     = 7;
                    VD.TypeName = (string)PaLexemeStream[PaPositionNow].Value;
                    break;

                case LexemeType.BOOL:
                    VD.Type = 0;
                    break;

                case LexemeType.INT:
                    VD.Type = 1;
                    break;

                case LexemeType.FLOAT:
                    VD.Type = 2;
                    break;

                case LexemeType.DOUBLE:
                    VD.Type = 3;
                    break;

                case LexemeType.CHAR:
                    VD.Type = 4;
                    break;

                case LexemeType.STRING:
                    VD.Type = 5;
                    break;

                default:
                    Error Error = new Error();
                    Error.ID          = ErrorID.C0010;
                    Error.ErrorDetail = "Argument declaration is not valid. No modifier is allowed and a type is required.";
                    Error.LineNo      = PaLexemeStream[PaPositionNow].LineNumber;
                    ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                    PaStopParsing = true;
                    break;
                }

                VD.LineNumber  = PaLexemeStream[PaPositionNow].LineNumber;
                PaPositionNow += 1;

                #region LineJumpAndOutOfRangeProcess

                if (PaPositionNow >= EndOfArgumentList)
                {
                    Error Error = new Error();
                    Error.ID          = ErrorID.C0010;
                    Error.ErrorDetail = "Argument declaration is not finished. A name is expected.";
                    Error.LineNo      = PaLexemeStream[EndOfArgumentList].LineNumber;
                    ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                    PaStopParsing = true;
                    break;
                }

                #endregion LineJumpAndOutOfRangeProcess

                #endregion ParseType
                // PaPositionNow points to the lexeme after the type

                if (PaLexemeStream[PaPositionNow].Type == LexemeType.LEFT_SQUARE_BRACKET)
                {
                    VD.IsArray = true;
                    if (PaPositionNow >= EndOfArgumentList)
                    {
                        Error Error = new Error();
                        Error.ID          = ErrorID.C0010;
                        Error.ErrorDetail = "A \']\' is expected.";
                        Error.LineNo      = PaLexemeStream[EndOfArgumentList].LineNumber;
                        ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                        PaStopParsing = true;
                        break;
                    }
                    else if (PaLexemeStream[PaPositionNow + 1].Type != LexemeType.RIGHT_SQUARE_BRACKET)
                    {
                        Error Error = new Error();
                        Error.ID          = ErrorID.C0010;
                        Error.ErrorDetail = "The length of array cannot be declared here.";
                        Error.LineNo      = PaLexemeStream[PaPositionNow].LineNumber;
                        ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                        PaStopParsing = true;
                        break;
                    }
                    PaPositionNow += 2;
                }

                #region LineJumpAndOutOfRangeProcess

                if (PaPositionNow >= EndOfArgumentList)
                {
                    Error Error = new Error();
                    Error.ID          = ErrorID.C0010;
                    Error.ErrorDetail = "Argument declaration is not finished. A name is expected.";
                    Error.LineNo      = PaLexemeStream[EndOfArgumentList].LineNumber;
                    ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                    PaStopParsing = true;
                    break;
                }

                #endregion LineJumpAndOutOfRangeProcess

                if (PaLexemeStream[PaPositionNow].Type == LexemeType.ID)
                {
                    VD.Name        = (string)PaLexemeStream[PaPositionNow].Value;
                    PaPositionNow += 1;
                }
                else
                {
                    Error Error = new Error();
                    Error.ID          = ErrorID.C0010;
                    Error.ErrorDetail = "Argument declaration is not valid. A name is expected.";
                    Error.LineNo      = PaLexemeStream[PaPositionNow].LineNumber;
                    ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                    PaStopParsing = true;
                    break;
                }

                ReturnList.Add(VD);

                // If IndexNow is larger than LabelTokens.Count, that means every label is scanned
                // and no more ',' is required.
                if (PaPositionNow < EndOfArgumentList && PaLexemeStream[PaPositionNow].Type != LexemeType.LV10_OPERATOR)
                {
                    Error Error = new Error();
                    Error.ID          = ErrorID.C0010;
                    Error.ErrorDetail = "The declaration of arguments is not legal. A ',' is expected.";
                    Error.LineNo      = PaLexemeStream[PaPositionNow].LineNumber;
                    ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                    PaStopParsing = true;
                    break;
                }
                PaPositionNow += 1;
            }

            return(ReturnList);
        }
Beispiel #2
0
        private IntermediateCode PaParseTry()
        {
            IntermediateCode IC = new IntermediateCode();

            IC.Type = ICStatementType.TRY_STATEMENT;
            ICTryStatement TS = new ICTryStatement();

            TS.LineNumber = PaLexemeStream[PaPositionEnd].LineNumber;
            Error Error = new Error();

            // PaPositionEnd -> try
            PaPositionNow = ++PaPositionEnd;
            if (PaPositionEnd == PaLexemeStream.Count)
            {
                Error.ID          = ErrorID.C0011;
                Error.ErrorDetail = "\";\" expected.";
                Error.LineNo      = PaLexemeStream[PaPositionEnd - 1].LineNumber;
                ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                PaStopParsing = true;
                return(IC);
            }
            switch (PaLexemeStream[PaPositionNow].Type)
            {
            case LexemeType.ID:
                int IDStart = PaPositionNow;
                PaPositionNow += 1;
                if (PaLexemeStream[PaPositionNow].Type == LexemeType.LV1_OPERATOR ||
                    PaLexemeStream[PaPositionNow].Type == LexemeType.LV2_OPERATOR ||
                    PaLexemeStream[PaPositionNow].Type == LexemeType.LV3_OPERATOR ||
                    PaLexemeStream[PaPositionNow].Type == LexemeType.LV4_OPERATOR ||
                    PaLexemeStream[PaPositionNow].Type == LexemeType.LV5_OPERATOR ||
                    PaLexemeStream[PaPositionNow].Type == LexemeType.LV6_OPERATOR ||
                    PaLexemeStream[PaPositionNow].Type == LexemeType.LV7_OPERATOR ||
                    PaLexemeStream[PaPositionNow].Type == LexemeType.LV8_OPERATOR ||
                    PaLexemeStream[PaPositionNow].Type == LexemeType.LV9_OPERATOR ||
                    PaLexemeStream[PaPositionNow].Type == LexemeType.LV10_OPERATOR ||
                    PaLexemeStream[PaPositionNow].Type == LexemeType.LEFT_BRACKET)
                {
                    PaPositionEnd = PaPositionNow;
                    for (; PaPositionEnd < PaLexemeStream.Count && PaLexemeStream[PaPositionEnd].Type != LexemeType.STATEMENT_END_MARK; PaPositionEnd++)
                    {
                        ;
                    }
                    TS.Statements = PaParseCommonExpression(IDStart, PaPositionEnd);
                    break;
                }
                else
                {
                    Error.ID          = ErrorID.C0011;
                    Error.ErrorDetail = "Cannot declear here.";
                    Error.LineNo      = PaLexemeStream[PaPositionNow].LineNumber;
                    ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                    PaStopParsing = true;
                    return(IC);
                }

            case LexemeType.CHAR_VALUE:
            case LexemeType.FLOAT_VALUE:
            case LexemeType.INT_VALUE:
            case LexemeType.LV2_OPERATOR:
            case LexemeType.NEW:
            case LexemeType.STRING_VALUE:
            case LexemeType.TRUE:
            case LexemeType.FALSE:
            case LexemeType.LEFT_BRACKET:
                for (; PaPositionEnd < PaLexemeStream.Count && PaLexemeStream[PaPositionEnd].Type != LexemeType.STATEMENT_END_MARK; PaPositionEnd++)
                {
                    ;
                }
                TS.Statements = PaParseCommonExpression(PaPositionNow, PaPositionEnd);
                break;

            case LexemeType.CODE_BLOCK:
                TS.Statements  = PaParseCodeBlock(PaPositionNow);
                PaPositionNow += 1;
                PaPositionEnd  = PaPositionNow;
                break;

            case LexemeType.IF:
                TS.Statements = PaParseIf();
                break;

            case LexemeType.FOR:
                TS.Statements = PaParseFor();
                break;

            case LexemeType.WHILE:
                TS.Statements = PaParseWhile();
                break;

            case LexemeType.DO:
                TS.Statements = PaParseDoWhile();
                break;

            case LexemeType.TRY:
                TS.Statements = PaParseTry();
                break;

            case LexemeType.STATEMENT_END_MARK:
                TS.Statements = new IntermediateCode();;
                break;

            default:
                Error.ID          = ErrorID.C0013;
                Error.ErrorDetail = "Cannot declear here.";
                Error.LineNo      = PaLexemeStream[PaPositionNow].LineNumber;
                ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                PaStopParsing = true;
                return(IC);
            }

            // PaPositionEnd -> STATEMENT_END_MARK
            PaPositionEnd += 1;

            // Assert the next lexeme must be "catch"
            if (PaPositionEnd == PaLexemeStream.Count || PaLexemeStream[PaPositionEnd].Type != LexemeType.CATCH)
            {
                Error.ID          = ErrorID.C0013;
                Error.ErrorDetail = "\"catch\" expected.";
                Error.LineNo      = PaLexemeStream[PaPositionNow].LineNumber;
                ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                PaStopParsing = true;
                return(IC);
            }

            List <ICCatchStatement> CSList = new List <ICCatchStatement>();

            while (PaPositionEnd < PaLexemeStream.Count && PaLexemeStream[PaPositionEnd].Type == LexemeType.CATCH)
            {
                ICCatchStatement CS = new ICCatchStatement();
                CS.LineNumber  = PaLexemeStream[PaPositionEnd].LineNumber;
                PaPositionEnd += 1;
                // Assert the next lexeme must be "("
                if (PaPositionEnd == PaLexemeStream.Count || PaLexemeStream[PaPositionEnd].Type != LexemeType.LEFT_BRACKET)
                {
                    Error.ID          = ErrorID.C0013;
                    Error.ErrorDetail = "\"(\" expected.";
                    Error.LineNo      = PaLexemeStream[PaPositionNow].LineNumber;
                    ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                    PaStopParsing = true;
                    return(IC);
                }

                PaPositionEnd += 1;
                PaPositionNow  = PaPositionEnd;
                for (int BracketCount = 1; BracketCount > 0 && PaPositionEnd < PaLexemeStream.Count; PaPositionEnd++)
                {
                    if (PaLexemeStream[PaPositionEnd].Type == LexemeType.LEFT_BRACKET)
                    {
                        BracketCount += 1;
                    }
                    else if (PaLexemeStream[PaPositionEnd].Type == LexemeType.RIGHT_BRACKET)
                    {
                        BracketCount -= 1;
                    }
                }
                PaPositionEnd -= 1;

                if (PaPositionEnd >= PaLexemeStream.Count || PaLexemeStream[PaPositionEnd].Type != LexemeType.RIGHT_BRACKET)
                {
                    Error.ID          = ErrorID.C0013;
                    Error.ErrorDetail = "A \")\" is expected.";
                    Error.LineNo      = PaLexemeStream[PaPositionEnd - 1].LineNumber;
                    ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                    PaStopParsing = true;
                    return(IC);
                }
                // PaPositionNow -> the lexeme after (, PaPositionEnd -> )
                ICVariableDeclaration Exception = new ICVariableDeclaration();
                // Assert PaLexemeStream[PaPositionEnd].Type == LexemeType.ID
                if (PaPositionNow == PaPositionEnd || PaLexemeStream[PaPositionNow].Type != LexemeType.ID)
                {
                    Error.ID          = ErrorID.C0013;
                    Error.ErrorDetail = "An expection name is expected.";
                    Error.LineNo      = PaLexemeStream[PaPositionEnd - 1].LineNumber;
                    ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                    PaStopParsing = true;
                    return(IC);
                }
                Exception.Type     = 6;
                Exception.TypeName = (string)PaLexemeStream[PaPositionNow].Value;
                PaPositionNow     += 1;

                // Assert PaLexemeStream[PaPositionENd].Type == LexemeType.ID
                if (PaPositionNow == PaPositionEnd || PaLexemeStream[PaPositionNow].Type != LexemeType.ID)
                {
                    Error.ID          = ErrorID.C0013;
                    Error.ErrorDetail = "The name of the expection is expected.";
                    Error.LineNo      = PaLexemeStream[PaPositionEnd - 1].LineNumber;
                    ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                    PaStopParsing = true;
                    return(IC);
                }
                Exception.Name = (string)PaLexemeStream[PaPositionNow].Value;
                CS.Exception   = Exception;
                if (PaPositionNow + 1 != PaPositionEnd)
                {
                    Error.ID          = ErrorID.C0013;
                    Error.ErrorDetail = "\";\" expected.";
                    Error.LineNo      = PaLexemeStream[PaPositionEnd - 1].LineNumber;
                    ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                    PaStopParsing = true;
                    return(IC);
                }

                PaPositionEnd += 1;

                // Assert PaLexemeStream still have lexemes
                if (PaPositionEnd == PaLexemeStream.Count)
                {
                    Error.ID          = ErrorID.C0013;
                    Error.ErrorDetail = "Statements are expected.";
                    Error.LineNo      = PaLexemeStream[PaPositionEnd - 1].LineNumber;
                    ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                    PaStopParsing = true;
                    return(IC);
                }

                PaPositionNow = PaPositionEnd;

                switch (PaLexemeStream[PaPositionNow].Type)
                {
                case LexemeType.ID:
                    int IDStart = PaPositionNow;
                    PaPositionNow += 1;
                    if (PaLexemeStream[PaPositionNow].Type == LexemeType.LV1_OPERATOR ||
                        PaLexemeStream[PaPositionNow].Type == LexemeType.LV2_OPERATOR ||
                        PaLexemeStream[PaPositionNow].Type == LexemeType.LV3_OPERATOR ||
                        PaLexemeStream[PaPositionNow].Type == LexemeType.LV4_OPERATOR ||
                        PaLexemeStream[PaPositionNow].Type == LexemeType.LV5_OPERATOR ||
                        PaLexemeStream[PaPositionNow].Type == LexemeType.LV6_OPERATOR ||
                        PaLexemeStream[PaPositionNow].Type == LexemeType.LV7_OPERATOR ||
                        PaLexemeStream[PaPositionNow].Type == LexemeType.LV8_OPERATOR ||
                        PaLexemeStream[PaPositionNow].Type == LexemeType.LV9_OPERATOR ||
                        PaLexemeStream[PaPositionNow].Type == LexemeType.LV10_OPERATOR ||
                        PaLexemeStream[PaPositionNow].Type == LexemeType.LEFT_BRACKET)
                    {
                        PaPositionEnd = PaPositionNow;
                        for (; PaPositionEnd < PaLexemeStream.Count && PaLexemeStream[PaPositionEnd].Type != LexemeType.STATEMENT_END_MARK; PaPositionEnd++)
                        {
                            ;
                        }
                        CS.Actions = PaParseCommonExpression(IDStart, PaPositionEnd);
                        break;
                    }
                    else
                    {
                        Error.ID          = ErrorID.C0011;
                        Error.ErrorDetail = "Cannot declear here.";
                        Error.LineNo      = PaLexemeStream[PaPositionNow].LineNumber;
                        ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                        PaStopParsing = true;
                        return(IC);
                    }

                case LexemeType.CHAR_VALUE:
                case LexemeType.FLOAT_VALUE:
                case LexemeType.INT_VALUE:
                case LexemeType.LV2_OPERATOR:
                case LexemeType.NEW:
                case LexemeType.STRING_VALUE:
                case LexemeType.TRUE:
                case LexemeType.FALSE:
                case LexemeType.LEFT_BRACKET:
                    for (; PaPositionEnd < PaLexemeStream.Count && PaLexemeStream[PaPositionEnd].Type != LexemeType.STATEMENT_END_MARK; PaPositionEnd++)
                    {
                        ;
                    }
                    CS.Actions = PaParseCommonExpression(PaPositionNow, PaPositionEnd);
                    break;

                case LexemeType.CODE_BLOCK:
                    CS.Actions     = PaParseCodeBlock(PaPositionNow);
                    PaPositionNow += 1;
                    PaPositionEnd  = PaPositionNow;
                    break;

                case LexemeType.IF:
                    CS.Actions = PaParseIf();
                    break;

                case LexemeType.FOR:
                    CS.Actions = PaParseFor();
                    break;

                case LexemeType.WHILE:
                    CS.Actions = PaParseWhile();
                    break;

                case LexemeType.DO:
                    CS.Actions = PaParseDoWhile();
                    break;

                case LexemeType.TRY:
                    CS.Actions = PaParseTry();
                    break;

                case LexemeType.STATEMENT_END_MARK:
                    CS.Actions = new IntermediateCode();;
                    break;

                default:
                    Error.ID          = ErrorID.C0013;
                    Error.ErrorDetail = "Cannot declear here.";
                    Error.LineNo      = PaLexemeStream[PaPositionNow].LineNumber;
                    ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                    PaStopParsing = true;
                    return(IC);
                }
                CSList.Add(CS);
                PaPositionEnd += 1;
            }

            TS.Catches = CSList;


            // Parse final
            // Check if there is a "final"
            if (PaPositionEnd < PaLexemeStream.Count && PaLexemeStream[PaPositionEnd].Type == LexemeType.FINALLY)
            {
                PaPositionEnd += 1;
                // Assert PaLexemeStream still have lexemes
                if (PaPositionEnd == PaLexemeStream.Count)
                {
                    Error.ID          = ErrorID.C0013;
                    Error.ErrorDetail = "Statements are expected.";
                    Error.LineNo      = PaLexemeStream[PaPositionEnd - 1].LineNumber;
                    ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                    PaStopParsing = true;
                    return(IC);
                }

                PaPositionNow = PaPositionEnd;

                switch (PaLexemeStream[PaPositionNow].Type)
                {
                case LexemeType.ID:
                    int IDStart = PaPositionNow;
                    PaPositionNow += 1;
                    if (PaLexemeStream[PaPositionNow].Type == LexemeType.LV1_OPERATOR ||
                        PaLexemeStream[PaPositionNow].Type == LexemeType.LV2_OPERATOR ||
                        PaLexemeStream[PaPositionNow].Type == LexemeType.LV3_OPERATOR ||
                        PaLexemeStream[PaPositionNow].Type == LexemeType.LV4_OPERATOR ||
                        PaLexemeStream[PaPositionNow].Type == LexemeType.LV5_OPERATOR ||
                        PaLexemeStream[PaPositionNow].Type == LexemeType.LV6_OPERATOR ||
                        PaLexemeStream[PaPositionNow].Type == LexemeType.LV7_OPERATOR ||
                        PaLexemeStream[PaPositionNow].Type == LexemeType.LV8_OPERATOR ||
                        PaLexemeStream[PaPositionNow].Type == LexemeType.LV9_OPERATOR ||
                        PaLexemeStream[PaPositionNow].Type == LexemeType.LV10_OPERATOR ||
                        PaLexemeStream[PaPositionNow].Type == LexemeType.LEFT_BRACKET)
                    {
                        PaPositionEnd = PaPositionNow;
                        for (; PaPositionEnd < PaLexemeStream.Count && PaLexemeStream[PaPositionEnd].Type != LexemeType.STATEMENT_END_MARK; PaPositionEnd++)
                        {
                            ;
                        }
                        TS.FinalActions = PaParseCommonExpression(IDStart, PaPositionEnd);
                        break;
                    }
                    else
                    {
                        Error.ID          = ErrorID.C0011;
                        Error.ErrorDetail = "Cannot declear here.";
                        Error.LineNo      = PaLexemeStream[PaPositionNow].LineNumber;
                        ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                        PaStopParsing = true;
                        return(IC);
                    }

                case LexemeType.CHAR_VALUE:
                case LexemeType.FLOAT_VALUE:
                case LexemeType.INT_VALUE:
                case LexemeType.LV2_OPERATOR:
                case LexemeType.NEW:
                case LexemeType.STRING_VALUE:
                case LexemeType.TRUE:
                case LexemeType.FALSE:
                case LexemeType.LEFT_BRACKET:
                    for (; PaPositionEnd < PaLexemeStream.Count && PaLexemeStream[PaPositionEnd].Type != LexemeType.STATEMENT_END_MARK; PaPositionEnd++)
                    {
                        ;
                    }
                    TS.FinalActions = PaParseCommonExpression(PaPositionNow, PaPositionEnd);
                    break;

                case LexemeType.CODE_BLOCK:
                    TS.FinalActions = PaParseCodeBlock(PaPositionNow);
                    PaPositionNow  += 1;
                    PaPositionEnd   = PaPositionNow;
                    break;

                case LexemeType.IF:
                    TS.FinalActions = PaParseIf();
                    break;

                case LexemeType.FOR:
                    TS.FinalActions = PaParseFor();
                    break;

                case LexemeType.WHILE:
                    TS.FinalActions = PaParseWhile();
                    break;

                case LexemeType.DO:
                    TS.FinalActions = PaParseDoWhile();
                    break;

                case LexemeType.TRY:
                    TS.FinalActions = PaParseTry();
                    break;

                case LexemeType.STATEMENT_END_MARK:
                    TS.FinalActions = new IntermediateCode();;
                    break;

                default:
                    Error.ID          = ErrorID.C0013;
                    Error.ErrorDetail = "Cannot declear here.";
                    Error.LineNo      = PaLexemeStream[PaPositionNow].LineNumber;
                    ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                    PaStopParsing = true;
                    return(IC);
                }
            }

            IC.StatementContent = TS;
            return(IC);
        }
Beispiel #3
0
        private IntermediateCode PaParseDeclaration()
        {
            int Accessibility = 0;                  // 0: private; 1: protected; 2: public. Private in default.
            // bool AccessbilityEdited = false;
            int AccessbilityAssignmentLine = 0;

            int Inherit = 0;                        // 0: N/A; 1: virtual; 2: override. Normal in default.
            // bool InheritEdited = false;
            int InheritAssignmentLine = 0;

            int EditControl = 0;                    // 0: N/A; 1: static; 2: const; 3: final.  Normal in default
            // bool EditControlEdited = false;
            int EditControlAssignmentLine = 0;

            int    Type;                            // 0: bool; 1: int; 2: float; 3: double; 4: char; 5: string; 6: id(an instanced class); 7:enmu; 8: class;
            string TypeName           = "";
            int    TypeAssignmentLine = 0;          // For future use(abstract classes). Now it makes no sense.

            bool IsArray = false;                   // To show if the declared variable or method is an array.
            bool IfArrayLengthDefined = false;
            int  ArrayLength          = 0;

            string Name = "";
            int    Mode = 0;                        // 0: Variable; 1: Method; 2. Class; 3. Enum; 4. Array.

            int LineNumber = PaLexemeStream[PaPositionEnd].LineNumber;

            bool IsConstructor = false;

            IntermediateCode IC = new IntermediateCode();

            try
            {
                // During the 'for' in PaParse, the PaPositionEnd is automatically added one so that it points to the first lexeme of the next statement.
                // Set PaPositionNow to the first lexeme of the current statement.
                PaPositionNow = PaPositionEnd;

                #region ParseModifier

                // Not necessary. The method is called based on the first lexeme so that it can't be Line_Marker.
                // PaJumpLineMarksNow();

                // Access control
                if (PaLexemeStream[PaPositionNow].Type == LexemeType.PRIVATE)
                {
                    PaPositionNow += 1;
                    // AccessbilityEdited = true;
                    AccessbilityAssignmentLine = PaLexemeStream[PaPositionNow].LineNumber;
                }
                else if (PaLexemeStream[PaPositionNow].Type == LexemeType.PROTECTED)
                {
                    Accessibility  = 1;
                    PaPositionNow += 1;
                    // AccessbilityEdited = true;
                    AccessbilityAssignmentLine = PaLexemeStream[PaPositionNow].LineNumber;
                }
                else if (PaLexemeStream[PaPositionNow].Type == LexemeType.PUBLIC)
                {
                    Accessibility  = 2;
                    PaPositionNow += 1;
                    // AccessbilityEdited = true;
                    AccessbilityAssignmentLine = PaLexemeStream[PaPositionNow].LineNumber;
                }
                // else: fall through

                // InheriteControl
                // N/A needs nothing to do.
                if (PaLexemeStream[PaPositionNow].Type == LexemeType.VIRTUAL)
                {
                    Inherit        = 1;
                    PaPositionNow += 1;
                    // InheritEdited = true;
                    InheritAssignmentLine = PaLexemeStream[PaPositionNow].LineNumber;
                }
                else if (PaLexemeStream[PaPositionNow].Type == LexemeType.OVERRIDE)
                {
                    Inherit        = 2;
                    PaPositionNow += 1;
                    // InheritEdited = true;
                    EditControlAssignmentLine = PaLexemeStream[PaPositionNow].LineNumber;
                }
                // else: fall through

                // EditControl
                // N/A needs nothing to do.
                if (PaLexemeStream[PaPositionNow].Type == LexemeType.STATIC)
                {
                    EditControl    = 1;
                    PaPositionNow += 1;
                    // EditControlEdited = true;
                    EditControlAssignmentLine = PaLexemeStream[PaPositionNow].LineNumber;
                }
                else if (PaLexemeStream[PaPositionNow].Type == LexemeType.CONST)
                {
                    EditControl    = 2;
                    PaPositionNow += 1;
                    // EditControlEdited = true;
                    EditControlAssignmentLine = PaLexemeStream[PaPositionNow].LineNumber;
                }
                else if (PaLexemeStream[PaPositionNow].Type == LexemeType.FINAL)
                {
                    EditControl    = 3;
                    PaPositionNow += 1;
                    // EditControlEdited = true;
                    EditControlAssignmentLine = PaLexemeStream[PaPositionNow].LineNumber;
                }
                // else: fall through

                #endregion ParseModifier
                // PaPositionNow points to the lexeme after all modifiers which should be type.

                #region ParseType

                // Type
                // If not, throw bug.
                switch (PaLexemeStream[PaPositionNow].Type)
                {
                case LexemeType.BOOL:
                    Type           = 0;
                    PaPositionNow += 1;
                    break;

                case LexemeType.INT:
                    Type           = 1;
                    PaPositionNow += 1;
                    break;

                case LexemeType.FLOAT:
                    Type           = 2;
                    PaPositionNow += 1;
                    break;

                case LexemeType.DOUBLE:
                    Type           = 3;
                    PaPositionNow += 1;
                    break;

                case LexemeType.CHAR:
                    Type           = 4;
                    PaPositionNow += 1;
                    break;

                case LexemeType.STRING:
                    Type           = 5;
                    PaPositionNow += 1;
                    break;

                case LexemeType.ID:
                    Type           = 6;
                    TypeName       = (string)PaLexemeStream[PaPositionNow].Value;
                    PaPositionNow += 1;
                    break;

                case LexemeType.ENUM:
                    Type           = 7;
                    Mode           = 3;
                    PaPositionNow += 1;
                    break;

                case LexemeType.CLASS:
                    Type           = 7;
                    Mode           = 2; // CAN BE DETERMINED NOW.
                    PaPositionNow += 1;
                    break;


                // Modifier position error:
                case LexemeType.PUBLIC:
                case LexemeType.PRIVATE:
                case LexemeType.PROTECTED:
                case LexemeType.VIRTUAL:
                case LexemeType.OVERRIDE:
                case LexemeType.STATIC:
                case LexemeType.CONST:
                case LexemeType.FINAL:
                    Error ErrorMod = new Error();
                    ErrorMod.ID          = ErrorID.C0010;
                    ErrorMod.ErrorDetail = "Invalid \"" + PaLexemeStream[PaPositionNow].Value.ToString() + "\". Modifier must be declared in order.";
                    ErrorMod.LineNo      = PaLexemeStream[PaPositionNow].LineNumber;
                    ErrorHandler.ErrorHandler.EhErrorOutput(ErrorMod);
                    PaStopParsing = true;
                    return(IC);

                default:
                    Error Error = new Error();
                    Error.ID          = ErrorID.C0010;
                    Error.ErrorDetail = "A declaration must have a type.";
                    Error.LineNo      = PaLexemeStream[PaPositionNow].LineNumber;
                    ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                    PaStopParsing = true;
                    return(IC);
                }
                // else: Must throw error

                TypeAssignmentLine = PaLexemeStream[PaPositionNow - 1].LineNumber;

                #endregion ParseType
                // PaPositionNow points to the lexeme after type which should be ID.

                if (PaPositionNow < PaLexemeStream.Count && PaLexemeStream[PaPositionNow].Type == LexemeType.LEFT_BRACKET)
                {
                    IsConstructor = true;
                    goto ParseMethod;
                }

                // ArrayParsing.
                #region ArrayParsing

                if (PaLexemeStream[PaPositionNow].Type == LexemeType.LEFT_SQUARE_BRACKET)
                {
                    IsArray = true;

                    #region ArrayLengthParsing

                    PaPositionNow += 1;

                    if (PaLexemeStream[PaPositionNow].Type == LexemeType.RIGHT_SQUARE_BRACKET)
                    {
                        IfArrayLengthDefined = false;
                    }
                    else if (PaLexemeStream[PaPositionNow].Type == LexemeType.INT_VALUE)
                    {
                        IfArrayLengthDefined = true;
                        ArrayLength          = (int)PaLexemeStream[PaPositionNow].Value;

                        PaPositionNow += 1;

                        // Pair two square bracket. If not, return error.
                        if (PaLexemeStream[PaPositionNow].Type != LexemeType.RIGHT_SQUARE_BRACKET)
                        {
                            Error Error = new Error();
                            Error.ID          = ErrorID.C0010;
                            Error.ErrorDetail = "Array's length must be only one constant integer.";
                            Error.LineNo      = PaLexemeStream[PaPositionNow].LineNumber;
                            ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                            PaStopParsing = true;
                            return(IC);
                        }
                    }
                    else
                    {
                        Error Error = new Error();
                        Error.ID          = ErrorID.C0010;
                        Error.ErrorDetail = "Array's length must be only one constant integer.";
                        Error.LineNo      = PaLexemeStream[PaPositionNow].LineNumber;
                        ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                        PaStopParsing = true;
                        return(IC);
                    }

                    #endregion ArrayLengthParsing

                    PaPositionNow += 1;
                }

                #endregion ArrayParsing
                // Continue or error

                // Parse Name
                #region ParseName

                if (PaPositionNow >= PaLexemeStream.Count || PaLexemeStream[PaPositionNow].Type != LexemeType.ID)
                {
                    Error Error = new Error();
                    Error.ID          = ErrorID.C0010;
                    Error.ErrorDetail = "A declaration must have a name comes after the type.";
                    Error.LineNo      = PaLexemeStream[PaPositionNow - 1].LineNumber;
                    ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                    PaStopParsing = true;
                    return(IC);
                }
                else
                {
                    Name = (string)PaLexemeStream[PaPositionNow].Value;
                    PaPositionNow++;
                }

                #endregion ParseID
                // PaPositionNow points to the lexeme after ID.


                #region ClassParsing

                if (Mode == 2)
                {
                    ICClassDeclaration CD = new ICClassDeclaration();
                    CD.Accessbility = Accessibility;
                    CD.Name         = Name;
                    CD.LineNumber   = LineNumber;
                    // Process inheritive
                    if (PaPositionNow < PaLexemeStream.Count && PaLexemeStream[PaPositionNow].Type == LexemeType.COLON)
                    {
                        PaPositionNow += 1;
                        while (PaPositionNow < PaLexemeStream.Count && PaLexemeStream[PaPositionNow].Type == LexemeType.ID)
                        {
                            CD.Ancestors.Add(PaLexemeStream[PaPositionNow]);
                            PaPositionNow += 1;
                            // Assert the next lexeme is a comma. If not, break;
                            if (PaPositionNow < PaLexemeStream.Count && PaLexemeStream[PaPositionNow].Type != LexemeType.LV10_OPERATOR)
                            {
                                break;
                            }
                            else
                            {
                                PaPositionNow += 1;
                            }
                        }
                    }

                    if (PaPositionNow >= PaLexemeStream.Count || PaLexemeStream[PaPositionNow].Type != LexemeType.CODE_BLOCK /*  || PaLexemeStream[PaPositionNow + 1].Type != LexemeType.STATEMENT_END_MARK Assert that
                                                                                                                              *  it must have been ended. The statement end mark is automatically added to the stream by the Scanner */
                        )
                    {
                        Error Error = new Error();
                        Error.ID          = ErrorID.C0010;
                        Error.ErrorDetail = "The declaration of class is illegal. '{' is expected.";
                        Error.LineNo      = PaLexemeStream[PaPositionNow - 1].LineNumber;
                        ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                        PaStopParsing = true;
                        return(IC);
                    }
                    else
                    {
                        if (EditControl != 0)
                        {
                            Error Error = new Error();
                            Error.ID          = ErrorID.C0010;
                            Error.ErrorDetail = "The declaration of class cannot setup an edit control level.";
                            Error.LineNo      = EditControlAssignmentLine;
                            ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                            PaStopParsing = true;
                            return(IC);
                        }
                        if (Inherit != 0)
                        {
                            Error Error = new Error();
                            Error.ID          = ErrorID.C0010;
                            Error.ErrorDetail = "The declaration of class cannot setup an inheriting modifier.";
                            Error.LineNo      = InheritAssignmentLine;
                            ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                            PaStopParsing = true;
                            return(IC);
                        }
                        if (IsArray)
                        {
                            Error Error = new Error();
                            Error.ID          = ErrorID.C0010;
                            Error.ErrorDetail = "The declaration of class is illegal.";
                            Error.LineNo      = PaLexemeStream[PaPositionNow].LineNumber;
                            ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                            PaStopParsing = true;
                            return(IC);
                        }

                        CD.Declarations = new List <IntermediateCode>();

                        Scanner ScanClassContents = new Scanner((string)PaLexemeStream[PaPositionNow].Value);
                        ScanClassContents.ScSetInitialLineCount(PaLexemeStream[PaPositionNow].LineNumber);

                        Parser ParseClassContents = new Parser(ScanClassContents.ScScan());
                        ParseClassContents.PaForceTreatIDAsDeclaration = true;
                        CD.Declarations = ParseClassContents.PaParse();

                        foreach (IntermediateCode CheckingIC in CD.Declarations)
                        {
                            if (CheckingIC.Type == ICStatementType.CONSTRUCTOR_DECLARATION)
                            {
                                CD.Constructors.Add((ICMethodDeclaration)CheckingIC.StatementContent);
                            }
                            else if (CheckingIC.Type == ICStatementType.DESTRUCTOR_DECLARATION)
                            {
                                if (CD.Destructor == null)
                                {
                                    CD.Destructor = (ICMethodDeclaration)CheckingIC.StatementContent;
                                }
                                else
                                {
                                    Error Error = new Error();
                                    Error.ID          = ErrorID.C0010;
                                    Error.ErrorDetail = "A class can only have one destructor.";
                                    Error.LineNo      = ((ICMethodDeclaration)CheckingIC.StatementContent).LineNumber;
                                    ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                                    PaStopParsing = true;
                                    return(IC);
                                }
                            }
                            else if (CheckingIC.Type != ICStatementType.VARIABLE_DECLARATION && CheckingIC.Type != ICStatementType.METHOD_DECLARATION && CheckingIC.Type != ICStatementType.ENUM_DECLARATION)
                            {
                                Error Error = new Error();
                                Error.ID          = ErrorID.C0010;
                                Error.ErrorDetail = "A class can only consist of variables and methods.";
                                Error.LineNo      = CD.LineNumber;
                                ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                                PaStopParsing = true;
                                return(IC);
                            }
                        }
                        IC.StatementContent = CD;
                        IC.Type             = ICStatementType.CLASS_DECLARATION;
                        PaPositionEnd       = PaPositionNow + 1;
                        return(IC);
                    }
                }

                #endregion ClassParsing
                // Returned or error.

                // EnumParsing.
                #region EnumParsing

                if (Mode == 3)
                {
                    if (PaPositionNow >= PaLexemeStream.Count || PaLexemeStream[PaPositionNow].Type != LexemeType.CODE_BLOCK)
                    {
                        Error Error = new Error();
                        Error.ID          = ErrorID.C0010;
                        Error.ErrorDetail = "The declaration of enum is not legal. '{' is expected.";
                        Error.LineNo      = PaLexemeStream[PaPositionNow].LineNumber;
                        ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                        PaStopParsing = true;
                        return(IC);
                    }
                    else
                    {
                        ICEnumDeclaration ED = new ICEnumDeclaration();
                        ED.Accessbility = Accessibility;
                        ED.Name         = Name;
                        ED.LineNumber   = LineNumber;

                        if (EditControl != 0)
                        {
                            Error Error = new Error();
                            Error.ID          = ErrorID.C0010;
                            Error.ErrorDetail = "The declaration of enum cannot setup an edit control level.";
                            Error.LineNo      = EditControlAssignmentLine;
                            ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                            PaStopParsing = true;
                            return(IC);
                        }
                        if (Inherit != 0)
                        {
                            Error Error = new Error();
                            Error.ID          = ErrorID.C0010;
                            Error.ErrorDetail = "The declaration of enum cannot setup an inheriting modifier.";
                            Error.LineNo      = InheritAssignmentLine;
                            ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                            PaStopParsing = true;
                            return(IC);
                        }
                        if (IsArray)
                        {
                            Error Error = new Error();
                            Error.ID          = ErrorID.C0010;
                            Error.ErrorDetail = "The declaration of enum is illegal.";
                            Error.LineNo      = PaLexemeStream[PaPositionNow].LineNumber;
                            ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                            PaStopParsing = true;
                            return(IC);
                        }


                        ED.Items = new List <string>();
                        Scanner       ScanEnumContents = new Scanner((string)PaLexemeStream[PaPositionNow].Value);
                        List <Lexeme> LabelTokens      = new List <Lexeme>();
                        ScanEnumContents.ScSetInitialLineCount(PaLexemeStream[PaPositionNow].LineNumber);
                        LabelTokens = ScanEnumContents.ScScan();
                        for (int i = 0; i < LabelTokens.Count; i++)
                        {
                            if (i < LabelTokens.Count && LabelTokens[i].Type == LexemeType.ID)
                            {
                                ED.Items.Add((string)LabelTokens[i].Value);
                                i += 1;

                                //   If i is larger than LabelTokens.Count, that means every label is scanned
                                // and no more ',' is required.
                                if (i < LabelTokens.Count && LabelTokens[i].Type != LexemeType.LV10_OPERATOR)
                                {
                                    Error Error = new Error();
                                    Error.ID          = ErrorID.C0010;
                                    Error.ErrorDetail = "The declaration of enum is not legal. A ',' is expected.";
                                    Error.LineNo      = PaLexemeStream[PaPositionNow].LineNumber;
                                    ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                                    PaStopParsing = true;
                                    return(IC);
                                }
                            }
                            else
                            {
                                Error Error = new Error();
                                Error.ID          = ErrorID.C0010;
                                Error.ErrorDetail = "The declaration of enum is not legal. A label is expected.";
                                Error.LineNo      = PaLexemeStream[PaPositionNow].LineNumber;
                                ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                                PaStopParsing = true;
                                return(IC);
                            }
                        }
                        PaPositionEnd       = PaPositionNow + 1;
                        IC.StatementContent = ED;
                        IC.Type             = ICStatementType.ENUM_DECLARATION;
                        return(IC);
                    }
                }

                #endregion EnumParsing
                // Returned or error.

ParseMethod:

                // MethodParsing. Only defiened methods are valid now. Need Improvement
                #region MethodParsing

                if (PaLexemeStream[PaPositionNow].Type == LexemeType.LEFT_BRACKET)
                {
                    ICMethodDeclaration MD = new ICMethodDeclaration();
                    MD.Accessbility = Accessibility;
                    MD.EditControl  = EditControl;
                    MD.Inherit      = Inherit;
                    MD.Type         = Type;
                    MD.LineNumber   = LineNumber;
                    if (Type == 6)
                    {
                        MD.TypeName = TypeName;
                    }
                    MD.Name         = Name;
                    PaPositionNow  += 1;
                    MD.ArgumentList = PaParseArgumentList();
                    MD.IsArray      = IsArray;
                    if (IsArray && IfArrayLengthDefined)
                    {
                        Error Error = new Error();
                        Error.ID          = ErrorID.C0010;
                        Error.ErrorDetail = "The length cannot be declared here.";
                        Error.LineNo      = EditControlAssignmentLine;
                        ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                        PaStopParsing = true;
                        return(IC);
                    }
                    if (PaPositionNow >= PaLexemeStream.Count || PaLexemeStream[PaPositionNow].Type != LexemeType.CODE_BLOCK)
                    {
                        Error Error = new Error();
                        Error.ID          = ErrorID.C0010;
                        Error.ErrorDetail = "The declaration of method is illegal. Need and only need a code block.";
                        Error.LineNo      = PaLexemeStream[PaPositionNow - 1].LineNumber;
                        ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                        PaStopParsing = true;
                        return(IC);
                    }
                    else
                    {
                        // PaPositionNow -> CodeBlock
                        MD.IfDefined  = true;
                        MD.Definition = new List <IntermediateCode>();

                        Scanner ScanMethodContents = new Scanner((string)PaLexemeStream[PaPositionNow].Value);
                        ScanMethodContents.ScSetInitialLineCount(PaLexemeStream[PaPositionNow].LineNumber);

                        Parser ParseMethodContents = new Parser(ScanMethodContents.ScScan());
                        MD.Definition       = ParseMethodContents.PaParse();
                        PaPositionEnd       = PaPositionNow + 1; // PaPositionEnd = PaPositionNow + 1 -> STATEMENT_END_MARK
                        IC.StatementContent = MD;
                        if (IsConstructor)
                        {
                            IC.Type = ICStatementType.CONSTRUCTOR_DECLARATION;
                        }
                        else
                        {
                            IC.Type = ICStatementType.METHOD_DECLARATION;
                        }
                        return(IC);
                    }
                }

                #endregion MethodParsing
                // Returned or error

                ICVariableDeclaration VD = new ICVariableDeclaration();

                IC.Type         = ICStatementType.VARIABLE_DECLARATION;
                VD.Accessbility = Accessibility;
                VD.EditControl  = EditControl;
                VD.Inherit      = Inherit;
                VD.Type         = Type;
                VD.LineNumber   = LineNumber;
                if (VD.Type == 6)
                {
                    VD.TypeName = TypeName;
                }

                VD.Name    = Name;
                VD.IsArray = IsArray;
                VD.IfArrayLengthDefined = IfArrayLengthDefined;
                VD.ArrayLength          = ArrayLength;



                if (PaLexemeStream[PaPositionNow].Type == LexemeType.STATEMENT_END_MARK)
                {
                    IC.StatementContent = (object)VD;
                    return(IC);
                }
                else if (PaLexemeStream[PaPositionNow].Type == LexemeType.LV9_OPERATOR && (Operators)PaLexemeStream[PaPositionNow].Value == Operators.ASSIGN)
                {
                    PaPositionNow += 1;
                    VD.IfDefined   = true;
                    PaPositionEnd  = PaPositionNow;
                    for (; PaPositionEnd < PaLexemeStream.Count && PaLexemeStream[PaPositionEnd].Type != LexemeType.STATEMENT_END_MARK; PaPositionEnd++)
                    {
                        ;
                    }
                    VD.Definition       = PaParseCommonExpression(PaPositionNow, PaPositionEnd);
                    IC.StatementContent = (object)VD;
                    return(IC);
                }
                else
                {
                    Error Error = new Error();
                    Error.ID          = ErrorID.C0010;
                    Error.ErrorDetail = "Unexpected character \"" + PaLexemeStream[PaPositionNow].Value.ToString() + "\".";
                    Error.LineNo      = PaLexemeStream[PaPositionNow].LineNumber;
                    ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                    PaStopParsing = true;
                    return(IC);
                }

                /////////////////////////////////////////////
                //
                //   Assert: The code will never get here.
                //
                /////////////////////////////////////////////
            }
            catch (System.Exception)
            {
                Error Error = new Error();
                Error.ID          = ErrorID.C0010;
                Error.ErrorDetail = "The declaration parsing now meets an unhandled problem. Please contact the developer of Cimplex for bug reporting.";
                Error.LineNo      = PaLexemeStream[PaPositionNow].LineNumber;
                ErrorHandler.ErrorHandler.EhErrorOutput(Error);
                PaStopParsing = true;
                return(IC);
            }
        }