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'])
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, ['['])
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'])
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>' ])
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, ['{'])
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>'])
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, ['('])
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, ['='])
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>'])
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
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>'])
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>'])
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()
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)
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>'])