示例#1
0
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}')
示例#2
0
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()
示例#3
0
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))
示例#4
0
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')
示例#5
0
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}")
示例#6
0
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]}")
示例#7
0
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')
示例#8
0
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}')
示例#9
0
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]}')
示例#10
0
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")
示例#11
0
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")
示例#12
0
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")
示例#13
0
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()
示例#14
0
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}')
示例#15
0
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}")
示例#16
0
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}')
示例#17
0
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()
示例#18
0
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}
示例#19
0
def p_error(p):
    print("Syntax error on the Input", p)
    raise CompilerError(f"Syntax error on the Input {p}")
示例#20
0
 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}")
示例#21
0
def t_error(t):
    print("Illegal character '%s'" % t.value[0])
    t.lexer.skip(1)
    raise CompilerError("Illegal character '%s'" % t.value[0])