Beispiel #1
0
 def parse_global_statement(self):
     token = self.get_current_token()
     if token.is_type():
         look_forward_2 = self.lookup_for_n(2)
         if look_forward_2.word == ';':
             return self.parse_var_decl()
         elif look_forward_2.word == '[':
             look_forward_5 = self.lookup_for_n(5)
             if look_forward_5.word == ';':
                 return self.parse_array_decl()
             else:
                 return self.parse_array_decl_and_assign()
         elif look_forward_2.word == '=':
             return self.parse_var_decl_and_assign()
         else:
             raise cmexception.SyntaxException(look_forward_2,
                                               [';', '[', '='])
     elif token.word == 'extern':
         self.move_for_n(1)
         prototype = self.parse_func_prototype()
         current = self.get_current_token()
         if current.word == ';':
             self.move_for_n(1)
             return prototype
         else:
             raise cmexception.SyntaxException(token, [';'])
     else:
         raise cmexception.SyntaxException(
             token, ['int', 'double', 'String', 'char'])
Beispiel #2
0
    def parse_array_assign(self):
        var_token = self.get_current_token()

        left_bracket = self.lookup_for_n(1)
        if left_bracket.word == '[':
            self.move_for_n(2)
            index_expr_node = self.parse_expr()
            right_bracket = self.get_current_token()
            if right_bracket.word == ']':
                equal = self.lookup_for_n(1)
                if equal.word == '=':
                    self.move_for_n(2)
                    value_expr_node = self.parse_expr_or_string()
                    node = ast.ArrayAssignNode(self.context, var_token,
                                               index_expr_node,
                                               value_expr_node)
                    semicolon = self.get_current_token()
                    if semicolon.word == ';':
                        self.move_for_n(1)
                        return node
                    else:
                        raise cmexception.SyntaxException(semicolon, [';'])
                else:
                    raise cmexception.SyntaxException(equal, ['='])
            else:
                raise cmexception.SyntaxException(right_bracket, [']'])
        else:
            raise cmexception.SyntaxException(left_bracket, ['['])
Beispiel #3
0
 def parse_func_prototype(self):
     ret_type_token = self.get_current_token()
     if ret_type_token.is_type() or ret_type_token.word == 'void':
         func_name_token = self.lookup_for_n(1)
         if func_name_token.lexme_type == LexmeType.Variable:
             self.move_for_n(3)
             args = self.parse_paramlist()
             right_bracket = self.get_current_token()
             if right_bracket.word == ')':
                 self.move_for_n(1)
                 temp = self.context
                 self.context = ASTContext(temp)
                 # for arg in args:
                 #     self.context.type_table[arg[0]] = arg[1]
                 return ast.FuncPrototypeNode(self.context, func_name_token,
                                              ret_type_token, args)
             else:
                 raise cmexception.SyntaxException(right_bracket,
                                                   ['<legal identifier>'])
         else:
             raise cmexception.SyntaxException(func_name_token,
                                               ['<legal identifier>'])
     else:
         raise cmexception.SyntaxException(
             ret_type_token, ['int', 'double', 'String', 'void', 'char'])
Beispiel #4
0
 def parse_atom(self):
     token = self.get_current_token()
     if token.lexme_type == LexmeType.Variable:
         if self.lookup_for_n(1).word == '[':
             self.move_for_n(2)
             index_expr_node = self.parse_expr()
             right_bracket = self.get_current_token()
             if right_bracket.word == ']':
                 self.move_for_n(1)
                 return ast.ArrayVariableNode(self.context, token,
                                              index_expr_node)
             else:
                 raise cmexception.SyntaxException(right_bracket, [']'])
         elif self.lookup_for_n(1).word == '(':
             self.move_for_n(2)
             valuelist = self.parse_array_value_list()
             right_brace = self.get_current_token()
             if right_brace.word == ')':
                 self.move_for_n(1)
                 return ast.FunctionCallNode(self.context, token, valuelist)
             else:
                 raise cmexception.SyntaxException(right_brace, [')'])
         else:
             self.move_for_n(1)
             return ast.VariableNode(self.context, token)
     elif token.word == '(':
         lookup1 = self.lookup_for_n(1)
         if lookup1.is_type():
             lookup2 = self.lookup_for_n(2)
             if lookup2.word == ')':
                 self.move_for_n(3)
                 expr_node = self.parse_expr()
                 return ast.CastExprNode(self.context, expr_node, lookup1)
         else:
             self.move_for_n(1)
             expr_node = self.parse_expr()
             right_brace = self.get_current_token()
             if right_brace.word == ')':
                 self.move_for_n(1)
                 return expr_node
             else:
                 raise cmexception.SyntaxException(right_brace, [')'])
     elif token.lexme_type == LexmeType.Double:
         self.move_for_n(1)
         return ast.ConstantNode(self.context, token)
     elif token.lexme_type == LexmeType.Integer:
         self.move_for_n(1)
         return ast.ConstantNode(self.context, token)
     elif token.lexme_type == LexmeType.Char:
         self.move_for_n(1)
         return ast.ConstantNode(self.context, token)
     else:
         raise cmexception.SyntaxException(token, [
             '<legal identifier>', '(', '<legal number>',
             '<ascii character>'
         ])
Beispiel #5
0
 def parse_array_initial_value(self):
     token = self.get_current_token()
     if token.word == '{':
         self.move_for_n(1)
         valuelist = self.parse_array_value_list()
         token = self.get_current_token()
         if token.word == '}':
             self.move_for_n(1)
             return valuelist
         else:
             raise cmexception.SyntaxException(token, ['}'])
     else:
         raise cmexception.SyntaxException(token, ['{'])
Beispiel #6
0
 def parse_var_decl_and_assign(self):
     type_token = self.get_current_token()
     var_token = self.lookup_for_n(1)
     if var_token.lexme_type == LexmeType.Variable:
         self.move_for_n(3)
         expr_node = self.parse_expr_or_string()
         semicolon = self.get_current_token()
         if semicolon.word == ';':
             self.move_for_n(1)
             return ast.VarDeclAndAssignNode(self.context, var_token,
                                             type_token, expr_node)
         else:
             raise cmexception.SyntaxException(semicolon, [';'])
     else:
         raise cmexception.SyntaxException(self.lookup_for_n(4),
                                           ['<legal identifier>'])
Beispiel #7
0
 def parse_function_call(self):
     token = self.get_current_token()
     left_brace = self.lookup_for_n(1)
     if left_brace.word == '(':
         self.move_for_n(2)
         valuelist = self.parse_array_value_list()
         right_brace = self.get_current_token()
         if right_brace.word == ')':
             semicolon = self.move_for_n(1)
             if semicolon.word == ';':
                 return ast.FunctionCallNode(self.context, token, valuelist)
             else:
                 raise cmexception.SyntaxException(semicolon, [';'])
         else:
             raise cmexception.SyntaxException(right_brace, [')'])
     else:
         raise cmexception.SyntaxException(left_brace, ['('])
Beispiel #8
0
    def parse_var_assign(self):
        var_token = self.get_current_token()
        assign = self.lookup_for_n(1)
        if assign.word == '=':
            self.move_for_n(2)

            # self.current_node.children.append(node)
            # self.current_node = node
            expr_or_string_node = self.parse_expr_or_string()
            semicolon = self.get_current_token()
            if semicolon.word == ';':
                node = ast.VarAssignNode(self.context, var_token,
                                         expr_or_string_node)
                self.move_for_n(1)
                return node
            else:
                raise cmexception.SyntaxException(semicolon, [';'])
        else:
            raise cmexception.SyntaxException(assign, ['='])
Beispiel #9
0
 def parse_var_decl(self):
     type_token = self.get_current_token()
     var_token = self.lookup_for_n(1)
     if var_token.lexme_type == LexmeType.Variable:
         node = ast.VarDeclNode(self.context, var_token, type_token)
         self.move_for_n(3)
         return node
     else:
         raise cmexception.SyntaxException(var_token,
                                           ['<legal identifier>'])
Beispiel #10
0
 def parse_paramlistrest(self):
     nodes = []
     token = self.get_current_token()
     if token.word == ',':
         type_token = self.lookup_for_n(1)
         if type_token.is_type():
             var_token = self.lookup_for_n(2)
             if var_token.lexme_type == LexmeType.Variable:
                 self.move_for_n(3)
                 nodes.append((var_token.word, type_token.word))
                 nodes.extend(self.parse_paramlistrest())
                 return nodes
             else:
                 raise cmexception.SyntaxException(var_token,
                                                   ['<legal identifier>'])
         else:
             raise cmexception.SyntaxException(type_token,
                                               ['<argument type>'])
     elif token.word == ')':
         return nodes
Beispiel #11
0
 def parse_array_decl_and_assign(self):
     type_token = self.get_current_token()
     var_token = self.lookup_for_n(1)
     if var_token.lexme_type == LexmeType.Variable:
         length_token = self.lookup_for_n(3)
         if length_token.lexme_type == LexmeType.Integer:
             self.move_for_n(6)
             initial_value = self.parse_array_initial_value()
             semicolon = self.get_current_token()
             if semicolon.word == ';':
                 self.move_for_n(1)
                 return ast.ArrayDeclAndAssignNode(self.context, var_token,
                                                   type_token, length_token,
                                                   initial_value)
             else:
                 raise cmexception.SyntaxException(self.lookup_for_n(4),
                                                   [';'])
         else:
             raise cmexception.SyntaxException(self.lookup_for_n(4),
                                               ['<positive integer>'])
     else:
         raise cmexception.SyntaxException(self.lookup_for_n(4),
                                           ['<legal identifier>'])
Beispiel #12
0
 def parse_array_decl(self):
     type_token = self.get_current_token()
     var_token = self.lookup_for_n(1)
     length_token = self.lookup_for_n(3)
     if var_token.lexme_type == LexmeType.Variable:
         if length_token.lexme_type == LexmeType.Integer:
             if self.lookup_for_n(4).word == ']':
                 if self.lookup_for_n(5).word == ';':
                     node = ast.ArrayDeclNode(self.context, var_token,
                                              type_token, length_token)
                     self.move_for_n(6)
                     return node
                 else:
                     raise cmexception.SyntaxException(
                         self.lookup_for_n(5), [';'])
             else:
                 raise cmexception.SyntaxException(self.lookup_for_n(4),
                                                   [']'])
         else:
             raise cmexception.SyntaxException(length_token,
                                               ['<an positive Integer>'])
     else:
         raise cmexception.SyntaxException(var_token,
                                           ['<legal identifier>'])
Beispiel #13
0
 def parse_global(self):
     look_forward2 = self.lookup_for_n(2)
     if look_forward2.word == '(':
         prototype_node = self.parse_func_prototype()
         current = self.get_current_token()
         if current.word == ';':
             self.context = self.context.parent_context
             self.move_for_n(1)
             return prototype_node
         elif current.word == '{':
             body = self.parse_statement()
             self.context = self.context.parent_context
             return ast.FunctionNode(self.context, prototype_node, body)
         else:
             raise cmexception.SyntaxException(current, ['{', ';'])
     else:
         return self.parse_global_statement()
Beispiel #14
0
 def code_gen(self):
     length = int(self.length_token.word)
     if length < 0 or length > (1 << 31) - 1:
         raise cmexception.SyntaxException(
             self.length_token, ['<a integer between 0 and 2e31-1>'])
     if self.context.parent_context is None:
         if self.array_name_token.word in self.context.type_table:
             raise cmexception.RedefineException(self.array_name_token,
                                                 'Global Variable')
         else:
             t = Helper.get_array_type(self.typo.word, length)
             gv = GlobalVariable.new(g_llvm_module, t,
                                     self.array_name_token.word)
             self.context.type_table[self.array_name_token.word] = t
             self.context.value_table[self.array_name_token.word] = gv
     else:
         if not self.array_name_token.word in self.context.type_table:
             t = Helper.get_array_type(self.typo.word, length)
             var_addr = g_llvm_builder.alloca(
                 t, name=self.array_name_token.word)
             self.context.type_table[self.array_name_token.word] = t
             self.context.value_table[self.array_name_token.word] = var_addr
         else:
             raise cmexception.RedefineException(self.array_name_token)
Beispiel #15
0
 def parse_statement(self):
     token = self.get_current_token()
     if token.is_type():
         lookup2 = self.lookup_for_n(2)
         if lookup2.word == ';':
             return self.parse_var_decl()
         elif lookup2.word == '=':
             return self.parse_var_decl_and_assign()
         elif lookup2.word == '[':
             lookup5 = self.lookup_for_n(5)
             if lookup5.word == '=':
                 return self.parse_array_decl_and_assign()
             elif lookup5.word == ';':
                 return self.parse_array_decl()
             else:
                 raise cmexception.SyntaxException(lookup5, ['=', ';'])
         else:
             raise cmexception.SyntaxException(lookup2, [';', '=', '['])
     elif token.lexme_type == LexmeType.Variable:
         lookup1 = self.lookup_for_n(1)
         if lookup1.word == '[':
             return self.parse_array_assign()
         elif lookup1.word == '=':
             return self.parse_var_assign()
         elif lookup1.word == '(':
             node = self.parse_function_call()
             self.move_for_n(1)
             return node
         else:
             raise cmexception.SyntaxException(lookup1, ['=', '['])
     elif token.word == '{':
         self.move_for_n(1)
         nodes = self.parse_stmtlist()
         right_bracket = self.get_current_token()
         if right_bracket.word == '}':
             self.move_for_n(1)
             return nodes
         else:
             raise cmexception.SyntaxException(right_bracket, ['}'])
     elif token.word == 'if':
         left_brace = self.move_for_n(1)
         if left_brace.word == '(':
             self.move_for_n(1)
             condition_expr = self.parse_expr()
             right_brace = self.get_current_token()
             if right_brace.word == ')':
                 self.move_for_n(1)
                 if_node = ast.IfNode(self.context, self.parse_statement())
                 else_node = self.parse_else_statement()
                 return ast.IfElseNode(self.context, condition_expr,
                                       if_node, else_node)
             else:
                 raise cmexception.SyntaxException(right_brace, [')'])
         else:
             raise cmexception.SyntaxException(left_brace, ['('])
     elif token.word == 'while':
         left_brace = self.lookup_for_n(1)
         if left_brace.word == '(':
             self.move_for_n(2)
             expr_node = self.parse_expr()
             right_brace = self.get_current_token()
             if right_brace.word == ')':
                 self.move_for_n(1)
                 stmtnode = self.parse_statement()
                 return ast.WhileNode(self.context, expr_node, stmtnode)
             else:
                 raise cmexception.SyntaxException(right_brace, [')'])
         else:
             raise cmexception.SyntaxException(left_brace, ['('])
     elif token.word == 'return':
         s = self.move_for_n(1)
         if s.word == ';':
             self.move_for_n(1)
             return ast.ReturnNode(self.context, token, None)
         else:
             node = self.parse_expr_or_string()
             if self.get_current_token().word == ';':
                 self.move_for_n(1)
                 return ast.ReturnNode(self.context, token, node)
             else:
                 return cmexception.SyntaxException(
                     self.get_current_token(), [';'])
     else:
         raise cmexception.SyntaxException(
             token,
             ['<legal identifier>', 'while', 'return', 'if', '<type>'])