def procedure_definition(self): # eating procedure keyword self.must_next(Type.Reserved.Procedure) self.next_token() # eating name of procedure self.must_next(Type.Word) procedure_name = self.token.value self.next_token() #eating procedure params if have procedure_params = self.procedure_or_function_params() # eating ; self.must_next(Type.Lang.Semi) self.next_token() vars_declarations = self.declarations() main_function = self.compound_statement() self.must_next(Type.Lang.Semi) self.next_token() self.must_next(Type.Reserved.End) self.next_token() self.must_next(Type.Lang.Semi) self.next_token() return Node.Procedure(procedure_name, procedure_params, vars_declarations, main_function)
def function_definition(self): # eating procedure keyword self.must_next(Type.Reserved.Function) self.next_token() # eating name of procedure self.must_next(Type.Word) function_name = self.token.value self.next_token() # eating procedure params if have function_params = self.procedure_or_function_params() # eating return type self.must_next(Type.Lang.Colon) self.next_token() function_return_type = self.type_spec() # eating ; self.must_next(Type.Lang.Semi) self.next_token() vars_declarations = self.declarations() main_function = self.compound_statement() self.must_next(Type.Lang.Semi) self.next_token() self.must_next(Type.Reserved.End) self.next_token() self.must_next(Type.Lang.Semi) self.next_token() return Node.Function(function_name, function_params, function_return_type, vars_declarations, main_function)
def expr(self): node = self.term() if self.is_next(Type.BinaryOperation.Or): while self.token.type in (Type.BinaryOperation.Or): operation_token = self.token self.next_token() new_node = self.term() node = Node.BinaryOperation(node, new_node, operation_token) else: while self.token.type in (Type.BinaryOperation.Plus, Type.BinaryOperation.Minus): operation_token = self.token self.next_token() new_node = self.term() node = Node.BinaryOperation(node, new_node, operation_token) return node
def compound_statement(self): self.must_next(Type.Reserved.Begin) self.next_token() node = Node.Compound(self.statement_list()) self.must_next(Type.Reserved.End) self.next_token() return node
def var_declarations(self): vars = self.vars_names() self.must_next(Type.Lang.Colon) self.next_token() cur_type = self.type_spec() self.must_next(Type.Lang.Semi) self.next_token() return Node.VarsDeclatrations(vars, cur_type)
def while_statement(self): self.must_next(Type.Reserved.While) self.next_token() expression = self.comparing_expr() self.must_next(Type.Reserved.Do) self.next_token() code = self.statement() return Node.WhileBlock(expression, code)
def assign_statement(self): node = self.variable() while self.token.type == Type.BinaryOperation.Assign: operation_token = self.token self.next_token() new_node = self.comparing_expr() node = Node.AssignOperation(node.value, new_node) return node
def program(self): program_name = self.program_init() procedures = self.procedures_and_functions() vars_declarations = self.declarations() main_function = self.compound_statement() self.must_next(Type.Lang.Dot) return Node.Program(program_name, procedures, vars_declarations, main_function)
def term(self): node = self.factor() if self.is_next(Type.BinaryOperation.And): while self.token.type in (Type.BinaryOperation.And): operation_token = self.token self.next_token() new_node = self.factor() node = Node.BinaryOperation(node, new_node, operation_token) else: while self.token.type in (Type.BinaryOperation.Mul, Type.BinaryOperation.Div, Type.BinaryOperation.Mod, Type.BinaryOperation.DivInt): operation_token = self.token self.next_token() new_node = self.factor() node = Node.BinaryOperation(node, new_node, operation_token) return node
def if_statement(self): self.must_next(Type.Reserved.If) self.next_token() if_expression = self.comparing_expr() self.must_next(Type.Reserved.Then) self.next_token() if_code = self.statement() else_code = None if self.is_next(Type.Reserved.Else): self.next_token() else_code = self.statement() return Node.IfBlock(if_expression, if_code, else_code)
def factor(self): result = None if self.is_next([ Type.BinaryOperation.Plus, Type.BinaryOperation.Minus, Type.UnaryOperation.Not ]): op_token = self.token self.next_token() result = Node.UnaryOperation(self.factor(), op_token) return result elif self.is_next(available_var_types): result = Node.Number(self.token) self.next_token() return result elif self.is_next(Type.Lang.LeftBracket): self.next_token() result = self.comparing_expr() self.must_next(Type.Lang.RightBracket) self.next_token() return result elif self.is_next(Type.Word) and self.is_nth(Type.Lang.LeftBracket, 1): return self.procedure_or_function_call() elif self.is_next(Type.Word): return self.variable()
def comparing_expr(self): handle_operations = [ Type.BinaryOperation.Equal, Type.BinaryOperation.NotEqual, Type.BinaryOperation.Less, Type.BinaryOperation.LessEqual, Type.BinaryOperation.Bigger, Type.BinaryOperation.BiggerEqual, ] node = self.expr() if self.is_next(handle_operations): operation_token = self.token self.next_token() new_node = self.expr() node = Node.BinaryOperation(node, new_node, operation_token) return node
def procedure_params_vars(self): referenced = False # check if params are passed by reference if self.is_next(Type.Reserved.Var): referenced = True self.next_token() vars = [self.variable()] while self.token.type == Type.Lang.Comma: self.next_token() vars.append(self.variable()) self.must_next(Type.Lang.Colon) self.next_token() cur_type = self.type_spec() return Node.ProcedureOrFunctionVarsDeclatrations( vars, cur_type, referenced)
def for_statement(self): self.must_next(Type.Reserved.For) self.next_token() assign_statement = self.assign_statement() plus = True if self.is_next(Type.Reserved.To): self.must_next(Type.Reserved.To) self.next_token() plus = True else: self.must_next(Type.Reserved.DownTo) self.next_token() plus = False to_value = self.comparing_expr() self.must_next(Type.Reserved.Do) self.next_token() code = self.statement() return Node.ForBlock(assign_statement, plus, to_value, code)
def statement(self): # assign_statement or compound_statement or empty if self.is_next(Type.Reserved.Begin): return self.compound_statement() if self.is_next(Type.Word) and self.is_nth(Type.BinaryOperation.Assign, 1): return self.assign_statement() if self.is_next(Type.Word) and (self.is_nth(Type.Lang.Semi, 1) or self.is_nth(Type.Lang.LeftBracket, 1)): return self.procedure_or_function_call() if self.is_next(Type.Reserved.If): return self.if_statement() if self.is_next(Type.Reserved.While): return self.while_statement() if self.is_next(Type.Reserved.For): return self.for_statement() return Node.NoOperation()
def variable(self): self.must_next(Type.Word) result = Node.Var(self.token) self.next_token() return result
def procedure_or_function_call(self): self.must_next(Type.Word) name_of_proc = self.token.value self.next_token() passed_params = self.procedure_or_function_passed_params() return Node.ProcedureOrFunctionCall(name_of_proc, passed_params)