private AST_assignment Parse_assignment(TokenKind followSet) { IncrementDepth(); AST_assignment assignment; AST_identifier identifier; AST_expression expression = null; identifier = Parse_identifier(Assignment); if (!Match(Assignment)) { Error("':=' expected.", lastReadToken); if (LookAheadToken().Kind != Semicolon) { // Assume an incorrect assignment symbol and skip over it GetNextToken(); } } expression = Parse_expression(Semicolon); assignment = new AST_assignment(identifier, expression); DecrementDepth(); return(assignment); }
override public void Visit(AST_variable_declaration variable_declaration) { if (variable_declaration.Type != null) { variable_declaration.Type.Accept(this); } string name = variable_declaration.Identifier.Name; if (variables.ContainsKey(name)) { Error("Variable '" + name + "' has already been declared.", variable_declaration.Identifier); } else { AST_expression expr = variable_declaration.Expression; if (expr != null) { expr.Accept(this); if (expr.DataType != variable_declaration.Type.Kind) { Error("Variable and initial value must be same type.", variable_declaration.Expression); } } variables.Add(name, variable_declaration); } variable_declaration.Identifier.Accept(this); }
private AST_variable_declaration Parse_variable_declaration() { IncrementDepth(); AST_variable_declaration variable_declaration; AST_identifier name; AST_type type = null; AST_expression expression = null; Match(var_Keyword); name = Parse_identifier(Colon | Semicolon); if (!Match(Colon)) { Error("':' expected.", lastReadToken); SkipUntilFollow(Semicolon); } else { type = Parse_type(Assignment | Semicolon); switch (LookAheadToken().Kind) { case Assignment: Match(Assignment); expression = Parse_expression(Semicolon); break; case Semicolon: break; default: Error("':=' or ';' expected.", LookAheadToken()); SkipUntilFollow(Semicolon); break; } } variable_declaration = new AST_variable_declaration(name, type, expression); DecrementDepth(); return(variable_declaration); }
private AST_for_statement Parse_for_statement() { IncrementDepth(); DebugPrint("for_statement"); AST_for_statement for_statement = null; AST_expression from = null; AST_expression to = null; AST_statement_list statement_list = null; Match(for_Keyword); AST_identifier identifier = Parse_identifier(in_Keyword); bool skipForDo = false; bool skipAll = false; if (!Match(in_Keyword)) { Error("'in' expected.", lastReadToken); // Prefer to skip for .. do and still process the statement_list, // worst case is to skip everything until 'end for' SkipUntilFollow(do_Keyword | end_Keyword); if (LookAheadToken().Kind == end_Keyword) { Match(end_Keyword); Match(for_Keyword); skipAll = true; } else { Match(do_Keyword); skipForDo = true; } } if (!skipAll) { if (!skipForDo) { from = Parse_expression(RangeDots); if (!Match(RangeDots)) { SkipUntilFollow(do_Keyword | end_Keyword); if (LookAheadToken().Kind == end_Keyword) { Match(end_Keyword); Match(for_Keyword); skipAll = true; } else { Match(do_Keyword); skipForDo = true; } } if (!skipAll && !skipForDo) { to = Parse_expression(do_Keyword | end_Keyword); if (!Match(do_Keyword)) { Error("'do' expected.", lastReadToken); ReuseToken(); } } } if (!skipAll) { statement_list = Parse_statement_list(); if (!Match(end_Keyword)) { Error("'end for' or a statement expected.", lastReadToken); SkipUntilFollow(Semicolon); } else { if (!Match(for_Keyword)) { Error("'end for' expected.", lastReadToken); SkipUntilFollow(Semicolon); } } } } for_statement = new AST_for_statement(identifier, from, to, statement_list); DecrementDepth(); return(for_statement); }
public virtual void Visit(AST_expression expression) { }