private IntermediateCode PaParseDestructor() { Error Error = new Error(); IntermediateCode IC = new IntermediateCode(); ICMethodDeclaration MD = new ICMethodDeclaration(); MD.LineNumber = PaLexemeStream[PaPositionEnd].LineNumber; // PaPositionEnd -> ~ PaPositionEnd += 1; // Assert the next lexeme is an id if (PaPositionEnd == PaLexemeStream.Count || PaLexemeStream[PaPositionEnd].Type != LexemeType.ID) { Error.ID = ErrorID.C0010; Error.ErrorDetail = "The name of the class is expected."; Error.LineNo = PaLexemeStream[PaPositionNow - 1].LineNumber; ErrorHandler.ErrorHandler.EhErrorOutput(Error); PaStopParsing = true; return(IC); } MD.Type = 6; MD.TypeName = (string)PaLexemeStream[PaPositionEnd].Value; PaPositionEnd += 1; // Destructor does not have parameters if (PaPositionEnd + 1 >= PaLexemeStream.Count || PaLexemeStream[PaPositionEnd].Type != LexemeType.LEFT_BRACKET || PaLexemeStream[PaPositionEnd + 1].Type != LexemeType.RIGHT_BRACKET) { Error.ID = ErrorID.C0010; Error.ErrorDetail = "\"()\" expected and no parameter allowed for a destructor."; Error.LineNo = PaLexemeStream[PaPositionNow - 1].LineNumber; ErrorHandler.ErrorHandler.EhErrorOutput(Error); PaStopParsing = true; return(IC); } PaPositionEnd += 2; // Assert the next lexeme is a code block if (PaPositionEnd >= PaLexemeStream.Count || PaLexemeStream[PaPositionEnd].Type != LexemeType.CODE_BLOCK) { Error.ID = ErrorID.C0010; Error.ErrorDetail = "The definition of the destructor is expected."; Error.LineNo = PaLexemeStream[PaPositionNow - 1].LineNumber; ErrorHandler.ErrorHandler.EhErrorOutput(Error); PaStopParsing = true; return(IC); } Scanner ScanMethodContents = new Scanner((string)PaLexemeStream[PaPositionEnd].Value); ScanMethodContents.ScSetInitialLineCount(PaLexemeStream[PaPositionEnd].LineNumber); Parser ParseMethodContents = new Parser(ScanMethodContents.ScScan()); MD.Definition = ParseMethodContents.PaParse(); PaPositionEnd += 1; // PaPositionEnd += 1 -> STATEMENT_END_MARK IC.StatementContent = MD; IC.Type = ICStatementType.DESTRUCTOR_DECLARATION; return(IC); }
private IntermediateCode PaParseReturn() { IntermediateCode IC = new IntermediateCode(); Error Error = new Error(); PaPositionNow = PaPositionEnd; for (; PaPositionEnd < PaLexemeStream.Count && PaLexemeStream[PaPositionEnd].Type != LexemeType.STATEMENT_END_MARK; PaPositionEnd++) { ; } PaPositionNow += 1; if (PaPositionNow < PaPositionEnd) { IC.StatementContent = PaParseCommonExpression(PaPositionNow, PaPositionEnd); } else { Error.ID = ErrorID.C0012; Error.ErrorDetail = "Expect a return expression."; Error.LineNo = PaLexemeStream[PaPositionNow].LineNumber; ErrorHandler.ErrorHandler.EhErrorOutput(Error); PaStopParsing = true; return(IC); } if (PaStopParsing) { return(IC); } IC.Type = ICStatementType.RETURN; return(IC); }
private IntermediateCode PaParseCodeBlock(int Position) { Scanner CodeBlockScanner = new Scanner((string)PaLexemeStream[Position].Value); CodeBlockScanner.ScSetInitialLineCount(PaLexemeStream[Position].LineNumber); Parser CodeBlockParser = new Parser(CodeBlockScanner.ScScan()); IntermediateCode IC = new IntermediateCode(); IC.StatementContent = CodeBlockParser.PaParse(); IC.Type = ICStatementType.CODE_BLOCK; return(IC); }
/// <summary> /// A reference based expression parser /// </summary> /// <param name="StartPoint">Parser from.</param> /// <param name="EndPoint">Parse ends at. Usually ";", ")"</param> /// <returns></returns> public IntermediateCode PaParseCommonExpression(int StartPoint, int EndPoint) { /////////////////////////////////////////// // // Should parse until PaPositionEnd - 1 // as PaPositionEnd points to ';' or ')' // or some other stuff like that. // /////////////////////////////////////////// // // Shutting-yard Algorithm // /////////////////////////////////////////// Error Error = new Error(); IntermediateCode IC = new IntermediateCode(); IC.Type = ICStatementType.EXPRESSION; Stack <Lexeme> OperatorStack = new Stack <Lexeme>(); Stack <ICExpression> OutputStack = new Stack <ICExpression>(); Stack <bool> BracketIfFunction = new Stack <bool>(); #region Shutting-Yard Body int LastPosition = -1; for (; StartPoint < EndPoint; StartPoint++) { ICExpression ExpNow = new ICExpression(); ExpNow.LineNumber = PaLexemeStream[StartPoint].LineNumber; ExpNow.Operand1 = null; ExpNow.Operand2 = null; ExpNow.LValueName = null; switch (PaLexemeStream[StartPoint].Type) { // Values case LexemeType.CHAR_VALUE: ExpNow.Value = PaLexemeStream[StartPoint].Value; ExpNow.Operator = Operators.CHAR_VALUE; OutputStack.Push(ExpNow); LastPosition = StartPoint; break; case LexemeType.FLOAT_VALUE: ExpNow.Value = PaLexemeStream[StartPoint].Value; ExpNow.Operator = Operators.FLOAT_VALUE; OutputStack.Push(ExpNow); LastPosition = StartPoint; break; case LexemeType.INT_VALUE: ExpNow.Value = PaLexemeStream[StartPoint].Value; ExpNow.Operator = Operators.INT_VALUE; OutputStack.Push(ExpNow); LastPosition = StartPoint; break; case LexemeType.STRING_VALUE: ExpNow.Value = PaLexemeStream[StartPoint].Value; ExpNow.Operator = Operators.STRING_VALUE; OutputStack.Push(ExpNow); LastPosition = StartPoint; break; case LexemeType.TRUE: ExpNow.Value = true; ExpNow.Operator = Operators.BOOL_VALUE; OutputStack.Push(ExpNow); LastPosition = StartPoint; break; case LexemeType.FALSE: ExpNow.Value = false; ExpNow.Operator = Operators.BOOL_VALUE; OutputStack.Push(ExpNow); LastPosition = StartPoint; break; // ID -> 1. Variable. 2. Function. 3. Type cast case LexemeType.ID: ExpNow.Value = PaLexemeStream[StartPoint].Value; ExpNow.Operator = Operators.ID; OutputStack.Push(ExpNow); LastPosition = StartPoint; break; // Array case LexemeType.LEFT_SQUARE_BRACKET: OperatorStack.Push(PaLexemeStream[StartPoint]); LastPosition = StartPoint; break; case LexemeType.RIGHT_SQUARE_BRACKET: if (OperatorStack.Peek().Type == LexemeType.RIGHT_SQUARE_BRACKET) { ExpNow.Operator = Operators.ARRAY; OutputStack.Push(ExpNow); OperatorStack.Pop(); LastPosition = StartPoint; break; } while (OperatorStack.Count > 0 && OperatorStack.Peek().Type != LexemeType.LEFT_SQUARE_BRACKET) { if (OperatorStack.Peek().OperatorPriority > 2) { if (OutputStack.Count >= 2) { ExpNow = new ICExpression(); ExpNow.LineNumber = PaLexemeStream[StartPoint].LineNumber; ExpNow.Operand2 = OutputStack.Pop(); ExpNow.Operand1 = OutputStack.Pop(); ExpNow.Operator = (Operators)OperatorStack.Pop().Value; } else { Error.ID = ErrorID.C0012; Error.ErrorDetail = "Unexpected \"" + PaLexemeStream[StartPoint].Value.ToString() + "\"."; Error.LineNo = ExpNow.LineNumber; ErrorHandler.ErrorHandler.EhErrorOutput(Error); PaStopParsing = true; return(IC); } } else { if ((Operators)OperatorStack.Peek().Value == Operators.TYPE_CAST) { if (OutputStack.Count >= 2) { ExpNow = new ICExpression(); ExpNow.LineNumber = PaLexemeStream[StartPoint].LineNumber; ExpNow.Operand2 = OutputStack.Pop(); ExpNow.Operand1 = OutputStack.Pop(); ExpNow.Operator = (Operators)OperatorStack.Pop().Value; } else { Error.ID = ErrorID.C0012; Error.ErrorDetail = "Unexpected \"" + PaLexemeStream[StartPoint].Value.ToString() + "\"."; Error.LineNo = ExpNow.LineNumber; ErrorHandler.ErrorHandler.EhErrorOutput(Error); PaStopParsing = true; return(IC); } } else if (OutputStack.Count >= 1) { ExpNow = new ICExpression(); ExpNow.LineNumber = PaLexemeStream[StartPoint].LineNumber; ExpNow.Operand1 = OutputStack.Pop(); ExpNow.Operand2 = null; ExpNow.Operator = (Operators)OperatorStack.Pop().Value; } else { Error.ID = ErrorID.C0012; Error.ErrorDetail = "Unexpected \"" + PaLexemeStream[StartPoint].Value.ToString() + "\"."; Error.LineNo = ExpNow.LineNumber; ErrorHandler.ErrorHandler.EhErrorOutput(Error); PaStopParsing = true; return(IC); } } OutputStack.Push(ExpNow); } if (OperatorStack.Count == 0) { Error.ID = ErrorID.C0012; Error.ErrorDetail = "Unexpected \"]\"."; Error.LineNo = ExpNow.LineNumber; ErrorHandler.ErrorHandler.EhErrorOutput(Error); PaStopParsing = true; return(IC); } OperatorStack.Pop(); ExpNow = new ICExpression(); ExpNow.LineNumber = PaLexemeStream[StartPoint].LineNumber; ExpNow.Operator = Operators.ARRAY; ExpNow.Operand2 = OutputStack.Pop(); ExpNow.Operand1 = OutputStack.Pop(); OutputStack.Push(ExpNow); LastPosition = StartPoint; break; // Operators case LexemeType.LV1_OPERATOR: // case LexemeType.LV2_OPERATOR: case LexemeType.LV3_OPERATOR: case LexemeType.LV4_OPERATOR: case LexemeType.LV5_OPERATOR: case LexemeType.LV6_OPERATOR: case LexemeType.LV7_OPERATOR: case LexemeType.LV8_OPERATOR: case LexemeType.LV10_OPERATOR: while (OperatorStack.Count > 0 && OperatorStack.Peek().OperatorPriority <= PaLexemeStream[StartPoint].OperatorPriority) { if (OperatorStack.Peek().OperatorPriority > 2) { if (OutputStack.Count >= 2) { ExpNow = new ICExpression(); ExpNow.LineNumber = PaLexemeStream[StartPoint].LineNumber; ExpNow.Operand2 = OutputStack.Pop(); ExpNow.Operand1 = OutputStack.Pop(); ExpNow.Operator = (Operators)OperatorStack.Pop().Value; } else { Error.ID = ErrorID.C0012; Error.ErrorDetail = "Unexpected \"" + PaLexemeStream[StartPoint].Value.ToString() + "\"."; Error.LineNo = PaLexemeStream[StartPoint].LineNumber; ErrorHandler.ErrorHandler.EhErrorOutput(Error); PaStopParsing = true; return(IC); } } else { if ((Operators)OperatorStack.Peek().Value == Operators.TYPE_CAST || (Operators)OperatorStack.Peek().Value == Operators.GET_CHILD) { if (OutputStack.Count >= 2) { ExpNow = new ICExpression(); ExpNow.LineNumber = PaLexemeStream[StartPoint].LineNumber; ExpNow.Operand2 = OutputStack.Pop(); ExpNow.Operand1 = OutputStack.Pop(); ExpNow.Operator = (Operators)OperatorStack.Pop().Value; } else { Error.ID = ErrorID.C0012; Error.ErrorDetail = "Unexpected \"" + PaLexemeStream[StartPoint].Value.ToString() + "\"."; Error.LineNo = ExpNow.LineNumber; ErrorHandler.ErrorHandler.EhErrorOutput(Error); PaStopParsing = true; return(IC); } } else if (OutputStack.Count >= 1) { ExpNow = new ICExpression(); ExpNow.LineNumber = PaLexemeStream[StartPoint].LineNumber; ExpNow.Operand1 = OutputStack.Pop(); ExpNow.Operand2 = null; ExpNow.Operator = (Operators)OperatorStack.Pop().Value; } else { Error.ID = ErrorID.C0012; Error.ErrorDetail = "Unexpected \"" + PaLexemeStream[StartPoint].Value.ToString() + "\"."; Error.LineNo = PaLexemeStream[StartPoint].LineNumber; ErrorHandler.ErrorHandler.EhErrorOutput(Error); PaStopParsing = true; return(IC); } } OutputStack.Push(ExpNow); } OperatorStack.Push(PaLexemeStream[StartPoint]); LastPosition = StartPoint; break; case LexemeType.LV9_OPERATOR: case LexemeType.LV2_OPERATOR: while (OperatorStack.Count > 0 && OperatorStack.Peek().OperatorPriority < PaLexemeStream[StartPoint].OperatorPriority) { if (OperatorStack.Peek().OperatorPriority > 2) { if (OutputStack.Count >= 2) { ExpNow = new ICExpression(); ExpNow.LineNumber = PaLexemeStream[StartPoint].LineNumber; ExpNow.Operand2 = OutputStack.Pop(); ExpNow.Operand1 = OutputStack.Pop(); ExpNow.Operator = (Operators)OperatorStack.Pop().Value; } else { Error.ID = ErrorID.C0012; Error.ErrorDetail = "Unexpected \"" + PaLexemeStream[StartPoint].Value.ToString() + "\"."; Error.LineNo = PaLexemeStream[StartPoint].LineNumber; ErrorHandler.ErrorHandler.EhErrorOutput(Error); PaStopParsing = true; return(IC); } } else { if ((Operators)OperatorStack.Peek().Value == Operators.TYPE_CAST || (Operators)OperatorStack.Peek().Value == Operators.GET_CHILD) { if (OutputStack.Count >= 2) { ExpNow = new ICExpression(); ExpNow.LineNumber = PaLexemeStream[StartPoint].LineNumber; ExpNow.Operand2 = OutputStack.Pop(); ExpNow.Operand1 = OutputStack.Pop(); ExpNow.Operator = (Operators)OperatorStack.Pop().Value; } else { Error.ID = ErrorID.C0012; Error.ErrorDetail = "Unexpected \"" + PaLexemeStream[StartPoint].Value.ToString() + "\"."; Error.LineNo = ExpNow.LineNumber; ErrorHandler.ErrorHandler.EhErrorOutput(Error); PaStopParsing = true; return(IC); } } else if (OutputStack.Count >= 1) { ExpNow = new ICExpression(); ExpNow.LineNumber = PaLexemeStream[StartPoint].LineNumber; ExpNow.Operand1 = OutputStack.Pop(); ExpNow.Operand2 = null; ExpNow.Operator = (Operators)OperatorStack.Pop().Value; } else { Error.ID = ErrorID.C0012; Error.ErrorDetail = "Unexpected \"" + PaLexemeStream[StartPoint].Value.ToString() + "\"."; Error.LineNo = PaLexemeStream[StartPoint].LineNumber; ErrorHandler.ErrorHandler.EhErrorOutput(Error); PaStopParsing = true; return(IC); } } OutputStack.Push(ExpNow); } OperatorStack.Push(PaLexemeStream[StartPoint]); LastPosition = StartPoint; break; case LexemeType.LEFT_BRACKET: if (LastPosition >= 0 && PaLexemeStream[LastPosition].Type == LexemeType.ID) { BracketIfFunction.Push(true); } else { BracketIfFunction.Push(false); } OperatorStack.Push(PaLexemeStream[StartPoint]); LastPosition = StartPoint; break; case LexemeType.RIGHT_BRACKET: if (LastPosition > 0 && PaLexemeStream[LastPosition].Type == LexemeType.LEFT_BRACKET) { if (BracketIfFunction.Pop()) { ExpNow.Operator = Operators.FUNCTION_CALL; ExpNow.Operand2 = null; ExpNow.Operand1 = OutputStack.Pop(); OutputStack.Push(ExpNow); OperatorStack.Pop(); LastPosition = StartPoint; break; } else { Error.ID = ErrorID.C0012; Error.ErrorDetail = "Unexpected \")\"."; Error.LineNo = PaLexemeStream[StartPoint].LineNumber; ErrorHandler.ErrorHandler.EhErrorOutput(Error); PaStopParsing = true; return(IC); } } while (OperatorStack.Count > 0 && OperatorStack.Peek().Type != LexemeType.LEFT_BRACKET) { if (OperatorStack.Peek().OperatorPriority > 2) { if (OutputStack.Count >= 2) { ExpNow = new ICExpression(); ExpNow.LineNumber = PaLexemeStream[StartPoint].LineNumber; ExpNow.Operand2 = OutputStack.Pop(); ExpNow.Operand1 = OutputStack.Pop(); ExpNow.Operator = (Operators)OperatorStack.Pop().Value; } else { Error.ID = ErrorID.C0012; Error.ErrorDetail = "Unexpected \"" + PaLexemeStream[StartPoint].Value.ToString() + "\"."; Error.LineNo = PaLexemeStream[StartPoint].LineNumber; ErrorHandler.ErrorHandler.EhErrorOutput(Error); PaStopParsing = true; return(IC); } } else { if ((Operators)OperatorStack.Peek().Value == Operators.TYPE_CAST || (Operators)OperatorStack.Peek().Value == Operators.GET_CHILD) { if (OutputStack.Count >= 2) { ExpNow = new ICExpression(); ExpNow.LineNumber = PaLexemeStream[StartPoint].LineNumber; ExpNow.Operand2 = OutputStack.Pop(); ExpNow.Operand1 = OutputStack.Pop(); ExpNow.Operator = (Operators)OperatorStack.Pop().Value; } else { Error.ID = ErrorID.C0012; Error.ErrorDetail = "Unexpected \"" + PaLexemeStream[StartPoint].Value.ToString() + "\"."; Error.LineNo = ExpNow.LineNumber; ErrorHandler.ErrorHandler.EhErrorOutput(Error); PaStopParsing = true; return(IC); } } else if (OutputStack.Count >= 1) { ExpNow = new ICExpression(); ExpNow.LineNumber = PaLexemeStream[StartPoint].LineNumber; ExpNow.Operand1 = OutputStack.Pop(); ExpNow.Operand2 = null; ExpNow.Operator = (Operators)OperatorStack.Pop().Value; } else { Error.ID = ErrorID.C0012; Error.ErrorDetail = "Unexpected \"" + PaLexemeStream[StartPoint].Value.ToString() + "\"."; Error.LineNo = PaLexemeStream[StartPoint].LineNumber; ErrorHandler.ErrorHandler.EhErrorOutput(Error); PaStopParsing = true; return(IC); } } OutputStack.Push(ExpNow); } if (OperatorStack.Count == 0) { Error.ID = ErrorID.C0012; Error.ErrorDetail = "Unexpected \")\"."; Error.LineNo = PaLexemeStream[StartPoint].LineNumber; ErrorHandler.ErrorHandler.EhErrorOutput(Error); PaStopParsing = true; return(IC); } OperatorStack.Pop(); if (BracketIfFunction.Pop()) { ExpNow = new ICExpression(); ExpNow.LineNumber = PaLexemeStream[StartPoint].LineNumber; ExpNow.Operator = Operators.FUNCTION_CALL; ExpNow.Operand2 = OutputStack.Pop(); ExpNow.Operand1 = OutputStack.Pop(); OutputStack.Push(ExpNow); } else if (StartPoint + 1 < PaLexemeStream.Count && (PaLexemeStream[StartPoint + 1].Type != LexemeType.LV1_OPERATOR && PaLexemeStream[StartPoint + 1].Type != LexemeType.LV2_OPERATOR && PaLexemeStream[StartPoint + 1].Type != LexemeType.LV3_OPERATOR && PaLexemeStream[StartPoint + 1].Type != LexemeType.LV4_OPERATOR && PaLexemeStream[StartPoint + 1].Type != LexemeType.LV5_OPERATOR && PaLexemeStream[StartPoint + 1].Type != LexemeType.LV6_OPERATOR && PaLexemeStream[StartPoint + 1].Type != LexemeType.LV7_OPERATOR && PaLexemeStream[StartPoint + 1].Type != LexemeType.LV8_OPERATOR && PaLexemeStream[StartPoint + 1].Type != LexemeType.LV9_OPERATOR && PaLexemeStream[StartPoint + 1].Type != LexemeType.LV10_OPERATOR && PaLexemeStream[StartPoint + 1].Type != LexemeType.STATEMENT_END_MARK )) { Lexeme TypeCast = new Lexeme(); TypeCast.LineNumber = PaLexemeStream[StartPoint].LineNumber; TypeCast.Type = LexemeType.LV2_OPERATOR; TypeCast.OperatorPriority = 2; TypeCast.Value = Operators.TYPE_CAST; OperatorStack.Push(TypeCast); } LastPosition = StartPoint; break; case LexemeType.CODE_BLOCK: // Can and can only return an array Scanner CodeBlockScanner = new Scanner((string)PaLexemeStream[StartPoint].Value); CodeBlockScanner.ScSetInitialLineCount(PaLexemeStream[StartPoint].LineNumber); List <Lexeme> ScannedCodeBlock = CodeBlockScanner.ScScan(); Parser CodeBlockParser = new Parser(ScannedCodeBlock); OutputStack.Push((ICExpression)CodeBlockParser.PaParseCommonExpression(0, ScannedCodeBlock.Count).StatementContent); if (PaStopParsing) { return(IC); } LastPosition = StartPoint; break; case LexemeType.STATEMENT_END_MARK: Error.ID = ErrorID.C0012; Error.ErrorDetail = "Unexpeted \";\"."; Error.LineNo = PaLexemeStream[StartPoint].LineNumber; ErrorHandler.ErrorHandler.EhErrorOutput(Error); PaStopParsing = true; return(IC); default: Error.ID = ErrorID.C0012; Error.ErrorDetail = "Unexpeted \"" + PaLexemeStream[StartPoint].Type.ToString() + "\"."; Error.LineNo = PaLexemeStream[StartPoint].LineNumber; ErrorHandler.ErrorHandler.EhErrorOutput(Error); PaStopParsing = true; return(IC); } } #endregion Shutting-Yard Body while (OperatorStack.Count > 0) { ICExpression ExpNow = new ICExpression(); if (OperatorStack.Peek().OperatorPriority > 2) { if (OutputStack.Count >= 2) { ExpNow = new ICExpression(); ExpNow.LineNumber = OperatorStack.Peek().LineNumber; ExpNow.Operand2 = OutputStack.Pop(); ExpNow.Operand1 = OutputStack.Pop(); ExpNow.Operator = (Operators)OperatorStack.Pop().Value; } else { Error.ID = ErrorID.C0012; Error.ErrorDetail = "Unexpected \"" + PaLexemeStream[StartPoint].Value.ToString() + "\"."; Error.LineNo = OperatorStack.Peek().LineNumber; ErrorHandler.ErrorHandler.EhErrorOutput(Error); PaStopParsing = true; return(IC); } } else if (OperatorStack.Peek().Type == LexemeType.LEFT_BRACKET) { Error.ID = ErrorID.C0012; Error.ErrorDetail = "Unexpected \"(\"."; Error.LineNo = OperatorStack.Peek().LineNumber; ErrorHandler.ErrorHandler.EhErrorOutput(Error); PaStopParsing = true; return(IC); } else if (OperatorStack.Peek().Type == LexemeType.LEFT_SQUARE_BRACKET) { Error.ID = ErrorID.C0012; Error.ErrorDetail = "Unexpected \"[\"."; Error.LineNo = OperatorStack.Peek().LineNumber; ErrorHandler.ErrorHandler.EhErrorOutput(Error); PaStopParsing = true; return(IC); } else { if (OutputStack.Count >= 1) { ExpNow = new ICExpression(); ExpNow.LineNumber = OperatorStack.Peek().LineNumber; ExpNow.Operand1 = OutputStack.Pop(); ExpNow.Operand2 = null; ExpNow.Operator = (Operators)OperatorStack.Pop().Value; } else { Error.ID = ErrorID.C0012; Error.ErrorDetail = "Unexpected \"" + PaLexemeStream[StartPoint].Value.ToString() + "\"."; Error.LineNo = PaLexemeStream[StartPoint].LineNumber; ErrorHandler.ErrorHandler.EhErrorOutput(Error); PaStopParsing = true; return(IC); } } OutputStack.Push(ExpNow); } if (OutputStack.Count > 1) { Error.ID = ErrorID.C0012; Error.ErrorDetail = "\";\" expected."; Error.LineNo = OutputStack.Peek().LineNumber; ErrorHandler.ErrorHandler.EhErrorOutput(Error); PaStopParsing = true; return(IC); } else if (OutputStack.Count == 0) { return(IC); } else { IC.StatementContent = OutputStack.Pop(); } return(IC); }
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); }
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); } }
} // PaParse : List<IntermediateCode> /// <summary> /// Parser worker method. /// </summary> /// <returns>Parsed intermediate code list.</returns> private List <IntermediateCode> PaParseW() { List <IntermediateCode> ReturnList = new List <IntermediateCode>(); for (; PaPositionEnd < PaLexemeStream.Count && !PaStopParsing; PaPositionEnd++) { switch (PaLexemeStream[PaPositionEnd].Type) { #region Declaration // Parse Declaration case LexemeType.PUBLIC: case LexemeType.PROTECTED: case LexemeType.PRIVATE: case LexemeType.VIRTUAL: case LexemeType.OVERRIDE: case LexemeType.STATIC: case LexemeType.CONST: case LexemeType.FINAL: case LexemeType.BOOL: case LexemeType.INT: case LexemeType.FLOAT: case LexemeType.DOUBLE: case LexemeType.CHAR: case LexemeType.STRING: case LexemeType.VOID: case LexemeType.CLASS: case LexemeType.ENUM: ReturnList.Add(PaParseDeclaration()); break; case LexemeType.DESTRUCTOR_MARK: ReturnList.Add(PaParseDestructor()); break; #endregion Declaration #region StartsWithID // 1. Expression // 2. Declaration case LexemeType.ID: int IDPosition = PaPositionEnd + 1; if (IDPosition == PaLexemeStream.Count) { Error ErrorG = new Error(); ErrorG.ID = ErrorID.C0009; ErrorG.ErrorDetail = "\";\" expected."; ErrorG.LineNo = PaLexemeStream[PaPositionEnd].LineNumber; ErrorHandler.ErrorHandler.EhErrorOutput(ErrorG); PaStopParsing = true; break; } if (PaLexemeStream[IDPosition].Type == LexemeType.LV1_OPERATOR || PaLexemeStream[IDPosition].Type == LexemeType.LV2_OPERATOR || PaLexemeStream[IDPosition].Type == LexemeType.LV3_OPERATOR || PaLexemeStream[IDPosition].Type == LexemeType.LV4_OPERATOR || PaLexemeStream[IDPosition].Type == LexemeType.LV5_OPERATOR || PaLexemeStream[IDPosition].Type == LexemeType.LV6_OPERATOR || PaLexemeStream[IDPosition].Type == LexemeType.LV7_OPERATOR || PaLexemeStream[IDPosition].Type == LexemeType.LV8_OPERATOR || PaLexemeStream[IDPosition].Type == LexemeType.LV9_OPERATOR || PaLexemeStream[IDPosition].Type == LexemeType.LV10_OPERATOR || PaLexemeStream[IDPosition].Type == LexemeType.LEFT_SQUARE_BRACKET) { ReturnList.Add(PaParseExpression()); } else if (PaLexemeStream[IDPosition].Type == LexemeType.LEFT_BRACKET) { if (PaForceTreatIDAsDeclaration) { ReturnList.Add(PaParseDeclaration()); } else { ReturnList.Add(PaParseExpression()); } } else if (PaLexemeStream[IDPosition].Type == LexemeType.COLON) { ReturnList.Add(PaParseGotoTarget()); } else if (PaLexemeStream[IDPosition].Type == LexemeType.STATEMENT_END_MARK) { Error ErrorG = new Error(); ErrorG.ID = ErrorID.C0009; ErrorG.ErrorDetail = "A statement is required."; ErrorG.LineNo = PaLexemeStream[PaPositionEnd].LineNumber; ErrorHandler.ErrorHandler.EhErrorOutput(ErrorG); PaStopParsing = true; break; } else { ReturnList.Add(PaParseDeclaration()); } break; #endregion StartWithID 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: ReturnList.Add(PaParseExpression()); break; case LexemeType.RIGHT_BRACKET: Error Error = new Error(); Error.ID = ErrorID.C0009; Error.ErrorDetail = "Unexpected \")\"."; Error.LineNo = PaLexemeStream[PaPositionEnd].LineNumber; ErrorHandler.ErrorHandler.EhErrorOutput(Error); PaStopParsing = true; break; case LexemeType.CODE_BLOCK: ReturnList.Add(PaParseCodeBlock(PaPositionEnd)); PaPositionEnd += 1; break; case LexemeType.IF: ReturnList.Add(PaParseIf()); break; case LexemeType.FOR: ReturnList.Add(PaParseFor()); break; case LexemeType.WHILE: ReturnList.Add(PaParseWhile()); break; case LexemeType.DO: ReturnList.Add(PaParseDoWhile()); break; case LexemeType.GOTO: ReturnList.Add(PaParseGoto()); break; case LexemeType.TRY: ReturnList.Add(PaParseTry()); break; case LexemeType.LABEL_NAME: break; case LexemeType.RETURN: ReturnList.Add(PaParseReturn()); break; case LexemeType.STATEMENT_END_MARK: IntermediateCode Empty = new IntermediateCode(); Empty.Type = ICStatementType.EMPTY_STATEMENT; ReturnList.Add(Empty); break; default: Error ErrorT = new Error(); ErrorT.ID = ErrorID.C0009; ErrorT.ErrorDetail = "Unexpected \"" + PaLexemeStream[PaPositionEnd].Type.ToString() + "\"."; ErrorT.LineNo = PaLexemeStream[PaPositionEnd].LineNumber; ErrorHandler.ErrorHandler.EhErrorOutput(ErrorT); PaStopParsing = true; break; } } return(ReturnList); } // PaParseW : List<IntermediateCode>