private void ParseFactor() { var token = CurrentToken(); switch (token.m_Type) { case PascalTokenType.Unsigned: int value = (int)token.m_Value; CodeGenerator.Emit(Operation.LoadLiteral, 0, value); ConsumeCurrentToken(); break; case PascalTokenType.Identifier: var result = m_SymbolTableStack.Lookup(token.m_Text); if (result == null) { //TODO: error ErrorReporter.RecordError(4, m_Scanner.m_CurrentToken.m_LineNumber); throw new Exception(); } var type = (result as SymbolTableEntry).GetAttribute(SymbolTableAttributeKeyType.Type); switch (type) { case SymbolTableEntryType.Constant: int const_value = (int)(result as SymbolTableEntry).GetAttribute(SymbolTableAttributeKeyType.ConstantValue); CodeGenerator.Emit(Operation.LoadLiteral, 0, const_value); break; case SymbolTableEntryType.Variable: var current_nesting_level = m_SymbolTableStack.GetCurrentNestingLevel(); var reference_nesting_level = result.GetSymbolTable().GetNestingLevel(); int offset = (int)(result as SymbolTableEntry).GetAttribute(SymbolTableAttributeKeyType.Offset); CodeGenerator.Emit(Operation.LoadVariable, current_nesting_level - reference_nesting_level, offset); break; default: break; } ConsumeCurrentToken(); break; case PascalTokenType.LeftParenthesis: ConsumeCurrentToken(); //skip ( var expression_parser = new ExpressionParser(this); expression_parser.ParseExpression(); token = CurrentToken(); if (token.m_Text != ")") { //TODO: error ErrorReporter.RecordError(5, m_Scanner.m_CurrentToken.m_LineNumber); throw new Exception(); } ConsumeCurrentToken(); //skip ) break; default: //TODO: error ErrorReporter.RecordError(0, m_Scanner.m_CurrentToken.m_LineNumber); throw new Exception(); } }
public override void Parse() { try { var token = CurrentToken(); switch (token.m_Type) { case PascalTokenType.Begin: var compound_parser = new CompoundParser(this); compound_parser.Parse(); break; case PascalTokenType.Identifier: var assignment_parser = new AssignmentParser(this); assignment_parser.Parse(); break; case PascalTokenType.If: var if_parser = new IfStatementParser(this); if_parser.Parse(); break; case PascalTokenType.Call: var procedure_parser = new ProcedureParser(this); procedure_parser.Parse(); break; case PascalTokenType.While: var while_parser = new WhileStatementParser(this); while_parser.Parse(); break; case PascalTokenType.Read: var read_parser = new ReadParser(this); read_parser.Parse(); break; case PascalTokenType.Write: var write_parser = new WriteParser(this); write_parser.Parse(); break; case PascalTokenType.Repeat: var repeat_parser = new RepeatStatementParser(this); repeat_parser.Parse(); break; //case PascalTokenType.Semicolon: // ConsumeCurrentToken(); // break; default: if (!FollowStatement.Contains(token.m_Text)) { //TODO: error ErrorReporter.RecordError(0, m_Scanner.m_CurrentToken.m_LineNumber, ",possibility: missing ;"); throw new Exception(); } break; } } catch (Exception) { } }