예제 #1
0
    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)
예제 #2
0
    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)
예제 #3
0
 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
예제 #4
0
 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
예제 #5
0
 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)
예제 #6
0
 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)
예제 #7
0
 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
예제 #8
0
 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)
예제 #9
0
 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
예제 #10
0
 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)
예제 #11
0
 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()
예제 #12
0
    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
예제 #13
0
    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)
예제 #14
0
 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)
예제 #15
0
    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()
예제 #16
0
 def variable(self):
     self.must_next(Type.Word)
     result = Node.Var(self.token)
     self.next_token()
     return result
예제 #17
0
 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)