def p_add_id(p): '''add_id : ''' global current_id, current_type, current_func, global_var_table, local_var_table, address, counter current_id = p[-1] if context == 'global': if current_id not in global_var_table: global_var_table[current_id] = [ current_id, current_type, address['global'][current_type] + counter['global'][current_type], [] ] counter['global'][current_type] += 1 else: print('ERROR: Variable already defined', current_id) raise CompilerError( f'ERROR: Variable already defined {current_id}') else: if current_id not in local_var_table: local_var_table[current_id] = [ current_id, current_type, address['local'][current_type] + counter['local'][current_type], [] ] counter['local'][current_type] += 1 else: print('ERROR: Variable already defined', current_id) raise CompilerError( f'ERROR: Variable already defined {current_id}')
def p_call_func_exp(p): '''call_func_exp : AMP ID call_func_era L_P args R_P''' global current_call, dir_func, k current_call = func_call_stack.peek() if len(dir_func[current_call]['param_types']) == 0 or k == ( len(dir_func[current_call]['param_types']) - 1): quadruples.append([ 'goSub', current_call, None, dir_func[current_call]['start_quad'] ]) if current_call in global_var_table: func_var = global_var_table[current_call] func_temp_add = address['temp'][func_var[1]] + \ counter['temp'][func_var[1]] counter['temp'][func_var[1]] += 1 quadruples.append(['=', func_var[2], None, func_temp_add]) elements_stack.push(func_temp_add) types_stack.push(func_var[1]) else: print('ERROR: Cannot call void function on expresion', current_call) raise CompilerError( f'ERROR: Cannot call void function on expresion {current_call}' ) else: r = len(dir_func[current_call]['param_types']) - 1 print('ERROR: Missing arguments', k, len(dir_func[current_call]['param_types']) - 1) raise CompilerError(f'ERROR: Missing arguments {k}, {r}') func_call_stack.pop()
def p_for_statement(p): '''for_statement : FOR id for_id EQUAL expression for_id_quad TO breadcrumb expression exp_type do_statement''' global jumps_stack, quadruples, local_var_table, global_var_table, constant_var_table, current_for_id end = jumps_stack.pop() element = None return_jump = jumps_stack.pop() current_for_id = for_id_stack.pop() if current_for_id in local_var_table: element = local_var_table[current_for_id][2] id_type = local_var_table[current_for_id][1] elif current_for_id in global_var_table: element = global_var_table[current_for_id][2] id_type = global_var_table[current_for_id][1] if element != None: result_type = semantic_cube[id_type]['+']['int'] if result_type != None: quadruples.append( ['+', element, constant_var_table[1][2], element]) else: print("ERROR: Type mismatch") raise CompilerError( f"ERROR: Type mismatch, {element}, '+', {constant_var_table[1][2]}" ) else: print('ERROR: Undeclared variable', current_for_id) raise CompilerError(f'ERROR: Undeclared variable {current_for_id}') quadruples.append(['goto', None, None, return_jump]) fill(end, len(quadruples))
def p_verify_dim(p): '''verify_dim : ''' global global_var_table, local_var_table, current_id, current_arr_id, dim_stack current_arr_id = current_id dim_stack.push({'id': current_arr_id, 'DIM': 1}) if current_arr_id in local_var_table: if len(local_var_table[current_id][3]) == 0: print(f'ERROR: Variable {current_id} has not dimensions') raise CompilerError( f'ERROR: Variable {current_id} has not dimensions') elif current_arr_id in global_var_table: if len(global_var_table[current_id][3]) == 0: print(f'ERROR: Variable {current_id} has not dimensions') raise CompilerError( f'ERROR: Variable {current_id} has not dimensions')
def p_verify_quad_2(p): '''verify_quad_2 : ''' global global_var_table, local_var_table, elements_stack, quadruples, current_arr_id, dim_stack, constant_var_table dims = [] second_dim = 0 current_arr_id = dim_stack.peek()['id'] if current_arr_id in local_var_table: dims = local_var_table[current_arr_id][3] second_dim = dims[1] quadruples.append(['ver', elements_stack.peek(), None, second_dim]) elif current_arr_id in global_var_table: dims = global_var_table[current_arr_id][3] second_dim = dims[1] quadruples.append(['ver', elements_stack.peek(), None, second_dim]) aux2 = elements_stack.pop() type_aux2 = types_stack.pop() aux1 = elements_stack.pop() type_aux1 = types_stack.pop() result_type = semantic_cube[type_aux2]['+'][type_aux1] if result_type != None: result = address['temp'][result_type] + counter['temp'][result_type] counter['temp'][result_type] += 1 quadruples.append(['+', aux1, aux2, result]) elements_stack.push(result) types_stack.push(result_type) else: print("ERROR: Type mismatch", aux1, '+', aux2) raise CompilerError(f"ERROR: Type mismatch, {aux1}, '+', {aux2}")
def p_verify_quad_1(p): '''verify_quad_1 : ''' global global_var_table, local_var_table, elements_stack, quadruples, current_arr_id, dim_stack, constant_var_table dims = [] first_dim = 0 current_arr_id = dim_stack.peek()['id'] if current_arr_id in local_var_table: dims = local_var_table[current_arr_id][3] first_dim = dims[0] quadruples.append(['ver', elements_stack.peek(), None, first_dim]) elif current_arr_id in global_var_table: dims = global_var_table[current_arr_id][3] first_dim = dims[0] quadruples.append(['ver', elements_stack.peek(), None, first_dim]) if len(dims) > 1: element_op = elements_stack.pop() element_type = types_stack.pop() result_type = semantic_cube[element_type]['*']['int'] if result_type != None: result = address['temp'][result_type] + \ counter['temp'][result_type] counter['temp'][result_type] += 1 quadruples.append( ['*', element_op, constant_var_table[dims[1]][2], result]) elements_stack.push(result) types_stack.push(result_type) else: print("ERROR: Type mismatch", element_op, '*', dims[1]) raise CompilerError( f"ERROR: Type mismatch {element_op}, '*', {dims[1]}")
def p_return_func(p): '''return_func : RETURN L_P expression R_P SEMICOLON''' global quadruples, elements_stack, types_stack, current_func element = elements_stack.pop() if types_stack.pop() == dir_func[current_func]['type']: quadruples.append(['return', None, current_func, element]) else: print('ERROR: Return type mismatch') raise CompilerError('ERROR: Return type mismatch')
def p_param_check(p): '''param_check : ''' global elements_stack, types_stack, k, dir_func, current_call, counter arg_element = elements_stack.pop() arg_type = types_stack.pop() current_call = func_call_stack.peek() if k < len(dir_func[current_call]['param_types']): if dir_func[current_call]['param_types'][k] == arg_type: quadruples.append(['param', arg_element, k, current_call]) else: print('ERROR: Type mismatch on argument on call function', current_call) raise CompilerError( f'ERROR: Type mismatch on argument on call function {current_call}' ) else: print('ERROR: Incorrect number of arguments', current_call) raise CompilerError( f'ERROR: Incorrect number of arguments {current_call}')
def p_call_func_era(p): '''call_func_era : ''' global dir_func, quadruples, k, current_call if p[-1] in dir_func: current_call = p[-1] func_call_stack.push(current_call) quadruples.append(['ERA', current_call, None, None]) k = 0 else: print('ERROR: Undeclared function', p[-1]) raise CompilerError(f'ERROR: Undeclared function {p[-1]}')
def p_exp_type(p): '''exp_type : ''' global types_stack, elements_stack, jumps_stack, quadruples exp_type = types_stack.pop() if exp_type == 'int': result = elements_stack.pop() quadruples.append(['gotoF', result, None, None]) jumps_stack.push(len(quadruples) - 1) else: print('ERROR: Type mismatch') raise CompilerError("ERROR: Type mismatch on bool")
def p_assignation(p): '''assignation : id EQUAL expression SEMICOLON''' global quadruples, address, counter, elements_stack, types_stack right_op = elements_stack.pop() right_type = types_stack.pop() left_op = elements_stack.pop() left_type = types_stack.pop() result_type = semantic_cube[left_type]['='][right_type] if result_type != None: quadruples.append(['=', right_op, None, left_op]) else: print("ERROR: Type mismatch in assignation") raise CompilerError("ERROR: Type mismatch in assignation")
def p_for_id_quad(p): '''for_id_quad : ''' global quadruples, address, counter, elements_stack, types_stack, current_id, current_for_id right_op = elements_stack.pop() right_type = types_stack.pop() left_op = elements_stack.pop() left_type = types_stack.pop() result_type = semantic_cube[left_type]['='][right_type] if result_type != None: quadruples.append(['=', right_op, None, left_op]) else: print("ERROR: Type mismatch on loop id") raise CompilerError("ERROR: Type mismatch on loop id")
def p_call_func(p): '''call_func : AMP ID call_func_era L_P args R_P SEMICOLON''' global current_call, dir_func, k, quadruples current_call = func_call_stack.peek() if len(dir_func[current_call]['param_types']) == 0 or k == ( len(dir_func[current_call]['param_types']) - 1): quadruples.append([ 'goSub', current_call, None, dir_func[current_call]['start_quad'] ]) else: r = len(dir_func[current_call]['param_types']) - 1 print('ERROR: Missing arguments', k, len(dir_func[current_call]['param_types']) - 1) raise CompilerError(f'ERROR: Missing arguments {k}, {r}') func_call_stack.pop()
def p_register_func(p): 'register_func : ' global current_func, current_type, dir_func, address, counter current_func = p[-1] if current_func not in dir_func: dir_func[current_func] = {'name': current_func, 'type': current_type} if (current_type != 'void'): memory_address = address['global'][current_type] + counter[ 'global'][current_type] global_var_table[current_func] = [ current_func, current_type, memory_address, [] ] counter['global'][current_type] += 1 dir_func[current_func]['memory_address'] = memory_address else: print('ERROR: Function already defined', current_func) raise CompilerError(f'ERROR: Function already defined {current_func}')
def generate_quadruple(): global quadruples, address, counter, elements_stack, types_stack, operators_stack right_op = elements_stack.pop() right_type = types_stack.pop() left_op = elements_stack.pop() left_type = types_stack.pop() op = operators_stack.pop() result_type = semantic_cube[left_type][op][right_type] if result_type != None: result = address['temp'][result_type] + counter['temp'][result_type] counter['temp'][result_type] += 1 quadruples.append([op, left_op, right_op, result]) elements_stack.push(result) types_stack.push(result_type) else: print("ERROR: Type mismatch", right_op, op, left_op) raise CompilerError( f"ERROR: Type mismatch, {right_op}, {op}, {left_op}")
def p_id_quad(p): ''' id_quad : ''' global elements_stack, types_stack, local_var_table, global_var_table, current_id element = None element_type = None is_array = False if current_id in local_var_table: element = local_var_table[current_id][2] element_type = local_var_table[current_id][1] is_array = False if len(local_var_table[current_id][3]) == 0 else True elif current_id in global_var_table: element = global_var_table[current_id][2] element_type = global_var_table[current_id][1] is_array = False if len(global_var_table[current_id][3]) == 0 else True if element != None: if not is_array: elements_stack.push(element) types_stack.push(element_type) else: print('ERROR: Undeclared variable', current_id) raise CompilerError(f'ERROR: Undeclared variable {current_id}')
def p_add_base(p): '''add_base : ''' global elements_stack, types_stack, address, counter, current_arr_id, global_var_table, local_var_table, current_id element_op = elements_stack.pop() element_type = types_stack.pop() result_type = semantic_cube[element_type]['+']['int'] base_address = 0 if result_type != None: result = address['pointer'] + counter['pointer'] counter['pointer'] += 1 if current_arr_id in local_var_table: base_address = local_var_table[current_arr_id][2] elif current_arr_id in global_var_table: base_address = global_var_table[current_arr_id][2] if base_address not in constant_var_table: constant_var_table[base_address] = (base_address, 'int', address['constant']['int'] + counter['constant']['int']) counter['constant']['int'] += 1 quadruples.append( ['+', element_op, constant_var_table[base_address][2], result]) elements_stack.push(result) types_stack.push(result_type) current_id = current_arr_id else: print("ERROR: Type mismatch", element_op, '+', base_address) raise CompilerError( f"ERROR: Type mismatch, {element_op}, '+', {base_address}") if not dim_stack.is_empty(): dim_stack.pop()
def p_main(p): '''main : MAIN L_P params R_P var_declaration L_B main_start statements R_B''' global local_var_table, param_types, counter, dir_func current_func = 'main' if current_func not in dir_func: dir_func[current_func] = { 'name': current_func, 'type': 'void', 'param_types': param_types, 'variable_counter': { 'local': counter['local'], 'temp': counter['temp'] } } else: print('ERROR: Function already defined', current_func) raise CompilerError(f'ERROR: Function already defined {current_func}') print(local_var_table) quadruples.append(['ENDFunc', None, None, None]) local_var_table = {} param_types = [] counter['local'] = {'int': 0, 'float': 0, 'char': 0} counter['temp'] = {'int': 0, 'float': 0, 'char': 0}
def p_error(p): print("Syntax error on the Input", p) raise CompilerError(f"Syntax error on the Input {p}")
def get_value(self, address): if address in self.addresses: return self.addresses[address] print("ERROR: Address not found", address, self.addresses) raise CompilerError(f"ERROR: Address not found {address}")
def t_error(t): print("Illegal character '%s'" % t.value[0]) t.lexer.skip(1) raise CompilerError("Illegal character '%s'" % t.value[0])