Exemple #1
0
def type_check_relational(node1, node2, op, token, is_bool=False):
    allowed_class = {'BasicType'}
    allowed_base = {'int', 'long', 'char', 'double', 'float'}
    if node1.type == "error" or node2.type == "error":
        return Node(type="error")
    if node1.type.class_type not in allowed_class or node2.type.class_type not in allowed_class:
        Errors(errorType='TypeError',
               errorText=op + ' not support type ' + node1.type.stype + ',' +
               node2.type.stype,
               token_object=token)
        return Node(type="error")
    if is_bool:
        if node1.type.type == "bool" and node2.type.type == "bool":
            return Node(name="binary_op",
                        value="bool" + op,
                        children=[node1, node2],
                        type=BasicType('bool'))
    if node1.type.type not in allowed_base or node2.type.type not in allowed_base:
        Errors(errorType='TypeError',
               errorText=op + ' not support type ' + node1.type.stype + ',' +
               node2.type.stype,
               token_object=token)
        return Node(type="error")

    node1, node2, typ = implicit_casting(node1, node2)
    return Node(name="binary_op",
                value=typ.stype + op,
                children=[node1, node2],
                type=BasicType('bool'))
Exemple #2
0
def type_check_multi(node1, node2, op, token, decimal=True):
    allowed_class = {'BasicType'}
    allowed_base = {'int', 'long', 'char'}
    if decimal: allowed_base = {'int', 'long', 'char', 'float', 'double'}
    if node1.type == "error" or node2.type == "error":
        return Node(type="error")
    if node1.type.class_type not in allowed_class or node2.type.class_type not in allowed_class:
        Errors(errorType='TypeError',
               errorText=op + ' not support type ' + node1.type.stype + ',' +
               node2.type.stype,
               token_object=token)
        return Node(type="error")

    if node1.type.type not in allowed_base or node2.type.type not in allowed_base:
        Errors(errorType='TypeError',
               errorText=op + ' not support type ' + node1.type.stype + ',' +
               node2.type.stype,
               token_object=token)
        return Node(type="error")

    node1, node2, typ = implicit_casting(node1, node2)
    return Node(name="binary_op",
                value=typ.stype + op,
                children=[node1, node2],
                type=typ)
def p_postfix_expression(p):
    '''
    postfix_expression : primary_expression
                       | postfix_expression INCREMENT
                       | postfix_expression DECREMENT

    '''
    if len(p) == 2:
        p[0] = p[1]
    else:
        allowed_base = {'int', 'float', 'double', 'char', 'long'}
        allowed_class = {'PointerType'}
        if p[1].type == 'error':
            p[0] = p[1]
        elif p[1].type.class_type == 'BasicType' and p[
                1].type.type in allowed_base:
            p[0] = Node(name="unary_op",
                        value=str(p[1].type) + ': p' + p[2],
                        children=[p[1]],
                        type=p[1].type)
        elif p[1].type.class_type in allowed_class:
            p[0] = Node(name="unary_op",
                        value=str(p[1].type) + ': p' + p[2],
                        children=[p[1]],
                        type=p[1].type)
        else:
            p[0] = p[1]
            p[0].type = 'error'
            Errors(errorType='TypeError',
                   errorText='increment/decrement not possible',
                   token_object=p.slice[-1])
def p_postfix_expression_4(p):
    # struct ref
    ''' 
    postfix_expression : postfix_expression ARROW IDENTIFIER
    
    '''
    if p[1].type == "error":
        p[0] = Node(type="error")
        return
    if p[1].type.class_type != "PointerType" or p[
            1].type.type.class_type != "StructType":
        p[0] = Node(type="error")
        Errors(errorType='TypeError',
               errorText='not pointer of struct type',
               token_object=p.slice[-1])
        return

    # arg_dict = p[1].type.type.arg_dict
    # success = arg_dict.get(p[3])
    struct_sym = p[1].type.type.symbol_table
    success = struct_sym._look_up(p[3],
                                  token_object=p.slice[3],
                                  in_struct=True,
                                  no_error=True)
    if success == None:
        Errors(errorType='DeclarationError',
               errorText='variable ' + p[3] + ' not declared in struct',
               token_object=p.slice[-1])
        p[0] = Node(type="error")
        return
    p[3] = Node(name="id", value=p[3])
    p[0] = Node(name="struct ref",
                value=p[2],
                type=success.type,
                children=[p[1], p[3]])
def p_conditional_expression(p):
    '''
    conditional_expression : logical_or_expression
	                       | logical_or_expression QUES_MARK expression COLON conditional_expression
    '''

    if len(p) == 2:
        p[0] = p[1]
    else:
        if p[1].type == "error" or p[3].type == "error" or p[5].type == "error":
            p[0] = Node(type="error")
            return
        allowed_class = {'BasicType'}
        allowed_base = {'int', 'long', 'char', 'bool', 'double', 'float'}
        if p[1].type.class_type not in allowed_class or p[
                1].type.type not in allowed_base:
            Errors(errorType='TypeError',
                   errorText=p[2] + ' not support type ' + p[1].type.stype,
                   token_object=p.slice[2])
            p[0] = Node(type="error")
            return
        if p[3].type != p[5].type:
            Errors(errorType='TypeError',
                   errorText='type should be same',
                   token_object=p.slice[2])
            p[0] = Node(type="error")
        p[1] = Node(name="type_cast",
                    value='bool',
                    children=[p[1]],
                    type=BasicType('bool'))
        p[0] = Node("ternary_op", children=[p[1], p[3], p[5]], type=p[3].type)
def p_type_specifier(p):
    '''
    type_specifier : VOID
                   | CHAR
                   | INT
                   | LONG
                   | FLOAT
                   | DOUBLE
                   | STRUCT IDENTIFIER
                   | ENUM IDENTIFIER
                   | BOOL
    '''
    if p[1] == 'enum':
        pass
    elif p[1] == 'struct':
        success = sym_table.look_up_struct(name=p[2], token_object=p.slice[-1])
        if success:
            p[0] = Node(type=success)
        else:
            p[0] = Node(type="error")
    else:
        if p[1] == 'void':
            p[0] = Node(type=Type())
        else:
            p[0] = Node(type=BasicType(type=p[1]))

    assert isinstance(p[0], Node), "return object is not Node"
    assert p[0].type == 'error' or isinstance(
        p[0].type, Type), "unexpected type attribute of return object"
def p_pointer(p):
    '''
    pointer : MULTIPLY
            | pointer MULTIPLY
    '''
    # | MULTIPLY type_qualifier_list
    # | MULTIPLY type_qualifier_list pointer
    # p[0] = [Node("pointer_ref",p[1])]
    # for i in range(2,len(p)):
    #     p[0] += p[i]
    if len(p) == 2:
        type_specifier_symbol = None
        for symbol in reversed(p.stack):
            if symbol.type in ['type_specifier', 'pointer', 'no_pointer']:
                type_specifier_symbol = symbol
                break
        if type_specifier_symbol.value.type == "error":
            p[0] = Node(type="error")
        else:
            p[0] = Node(type=PointerType(
                type=type_specifier_symbol.value.type))
        #p[0] = Node(PointerType(type = p.stack[-1].value.type))
    else:
        p[0] = p[1]
        if p[0].type != "error":
            p[0].type = PointerType(type=p[1].type)

    assert isinstance(p[0], Node), "return object is not Node"
    assert p[0].type == 'error' or isinstance(
        p[0].type, Type), "unexpected type attribute of return object"
Exemple #8
0
def type_check_bit(node1, node2, op, token):
    allowed_class = {'BasicType'}
    allowed_base = {'int', 'long', 'char', 'bool'}
    if node1.type == "error" or node2.type == "error":
        return Node(type="error")
    if node1.type.class_type not in allowed_class or node2.type.class_type not in allowed_class:
        Errors(errorType='TypeError',
               errorText=op + ' not support type ' + node1.type.stype + ',' +
               node2.type.stype,
               token_object=token)
        return Node(type="error")

    if node1.type.type not in allowed_base or node2.type.type not in allowed_base:
        Errors(errorType='TypeError',
               errorText=op + ' not support type ' + node1.type.stype + ',' +
               node2.type.stype,
               token_object=token)
        return Node(type="error")

    node1, node2, typ = implicit_casting(node1, node2)
    node = Node(name="binary_op",
                value=typ.stype + op,
                children=[node1, node2],
                type=typ)
    node.code = node1.code + node2.code
    tmp, code = get_opcode(op=typ.stype + op,
                           place1=node1.place,
                           place2=node2.place,
                           type=typ)
    node.code += [code]
    node.place = tmp
    return node
Exemple #9
0
def convert(tree):
    """tree as triples"""
    corefs, temps, modals = [], [], []
    modal_vars = []
    for tree_triple in tree:
        rel = tree_triple.rel
        chain_triples = tree_triple.tgt

        if rel == COREF:
            for chain_triple in chain_triples.value:
                src_var = split_var(chain_triple.src)
                tgt_var = split_var(chain_triple.tgt)

                found_chain = None
                for coref_chain in corefs:
                    if src_var in coref_chain or tgt_var in coref_chain:
                        found_chain = coref_chain
                        break

                if not found_chain:
                    corefs.append([src_var, tgt_var])
                else:
                    if src_var not in found_chain:
                        found_chain.append(src_var)
                    if tgt_var not in found_chain:
                        found_chain.append(tgt_var)

        elif rel == TEMP:
            """TODO (Nov 3, 2019)"""
            pass
        elif rel == MODAL:
            for chain_triple in chain_triples.value:
                chain_rel = chain_triple.rel
                src_var = Node(split_var(chain_triple.src))
                tgt_var = Node(split_var(chain_triple.tgt))

                if src_var not in modal_vars:
                    modal_vars.append(src_var)
                else:
                    src_var = [v for v in modal_vars if src_var == v][0]

                if tgt_var not in modal_vars:
                    modal_vars.append(tgt_var)
                else:
                    tgt_var = [v for v in modal_vars if tgt_var == v][0]

                new_chain_triple = Triple(chain_rel, src_var, tgt_var)
                add_to_tree(modals, new_chain_triple)

    root = tree[0].src
    assert root.is_root()
    new_tree = [
        Triple(rel=COREF, src=root, tgt=Node(corefs)),
        Triple(rel=TEMP, src=root, tgt=Node(temps)),
        Triple(rel=MODAL, src=root, tgt=Node(modals))
    ]

    return new_tree
def p_compound_statement(p):
    '''
    compound_statement : L_BRACES R_BRACES
	                   | L_BRACES add_sym block_item_list pop_sym R_BRACES
    '''
    if len(p) == 3:
        p[0] = Node("compound_statement", "{}", type="ok")
    else:
        p[0] = Node("compound_statement", "{}", children=p[3], type="ok")
def p_function_body(p):
    '''
    function_body : L_BRACES R_BRACES
	              | L_BRACES block_item_list R_BRACES
    '''
    if len(p) == 3:
        p[0] = Node("compound_statement", "{}", type="ok")
    else:
        p[0] = Node("compound_statement", "{}", children=p[2], type="ok")
def p_function_definition(p):
    '''
    function_definition : type_specifier declarator func_scope parameter_type_list func_rparen_1 function_body pop_sym
                        | type_specifier declarator func_scope func_rparen_2 function_body pop_sym
    '''

    if len(p) == 8:
        p[0] = Node("function", p[2].value, children=[p[6]])
    else:
        p[0] = Node("function", p[2].value, children=[p[5]])
    p[0] = [p[0]]
Exemple #13
0
def typecast(node1, type, token=None, hard=False):
    node1 = load_place(node1)
    assert isinstance(type, Type), "not of class Type"
    assert type.class_type in {"BasicType", "PointerType",
                               "StructType"}, "not valid type"
    # assert node1.type.class_type in {"BasicType","PointerType"}, "not valid type"
    # assert "sconst@" not in node1.place, "string in typecast"
    if node1.type.stype == type.stype:
        if hard: node1.type = type
        return node1
    elif "sconst@" in node1.place:
        # print(str(node1.type.stype),str(type.stype))
        if token:
            Errors(errorType='TypeError',
                   errorText="cannot assign string constant to type " +
                   type.stype,
                   token_object=token)
            return Node(type="error")
        else:
            assert "string in typecast"
    else:
        node = Node(name="type_cast",
                    value=type.stype,
                    children=[node1],
                    type=type)
        node.code = node1.code
        node.place = node1.place
        if type.class_type == 'PointerType':
            type1 = 'long'
        else:
            type1 = type.type
        if node1.type.class_type == 'PointerType':
            type2 = 'long'
        else:
            type2 = node1.type.type

        if type1 == type2:
            return node
        if type1 in {"long", "int"} and type2 in {"long", "int"}:
            return node
        if "const@" in node1.place:
            node.place = get_const(const=get_const_value(node1.place),
                                   type=BasicType(type1))
            return node
        node.place = get_newtmp(type=BasicType(type1))
        node.code += [
            gen(op=type2 + "_to_" + type1,
                place1=node1.place,
                place3=node.place,
                code=node.place + " = " + type2 + "_to_" + type1 + " " +
                node1.place)
        ]
    return node
def p_expression(p):
    '''
    expression : assignment_expression
	           | expression COMMA assignment_expression
    '''
    if len(p) == 2:
        p[0] = p[1]
    else:
        if p[1].type == "error" or p[3].type == "error":
            p[0] = Node(type="error")
        if isinstance(p[1], Node) and p[1].name == "expression":
            p[1].addChild(p[3])
            p[0] = p[1]
        else:
            p[0] = Node(name="expression", children=[p[1], p[3]], type="ok")
Exemple #15
0
 def __init__(self,name):
     self.name=name
     self.dom=Node()
     self.nodes=[self.dom]
     self.stack=[self.dom]
     self.elements=self._prepare(name)
     self._parse()
def p_jump_statement(p):
    '''
    jump_statement : CONTINUE SEMI_COLON
	               | BREAK SEMI_COLON
	                 
    '''
    p[0] = Node(name=p[1], type="ok")
def p_labeled_statement(p):
    '''
    labeled_statement : CASE constant_expression COLON statement
	                  | DEFAULT COLON statement
    '''

    if p.slice[1].type == 'CASE':
        if p[2].type == "error" or p[4].type == "error":
            p[0] = Node(type="error")
            return
        p[0] = Node("case", children=[p[2], p[4]], type="ok")
    else:
        if p[3].type == "error":
            p[0] = Node(type="error")
            return
        p[0] = Node("default", children=[p[3]], type="ok")
def p_init_declarator(p):
    '''
    init_declarator : declarator
	                | declarator ASSIGNMENT initializer
    '''
    if p[1].type == "error":
        p[0] = [None]
        return
    if len(p) == 2:
        success = sym_table.add_entry(name=p[1].value,
                                      type=p[1].type,
                                      token_object=p[1].data['token'])
        p[0] = [None]

    else:
        # type checking
        # check for initliazer
        init = type_check_init(p[3], p[1].type, p.slice[2])
        if init.type == "error":
            p[0] = [None]
            return
        success = sym_table.add_entry(name=p[1].value,
                                      type=p[1].type,
                                      token_object=p[1].data['token'])
        if success:
            p[0] = [
                Node(name="initialization", children=[p[1], init], type="ok")
            ]
        else:
            p[0] = [None]
 def create_node(parent=None):
     """Creating node with random value."""
     return Node(
         # some random value to be unique
         # in real case uniqueness must be supplied by the user
         value=randrange(10000),
         parent=parent)
def p_selection_statement(p):
    '''
    selection_statement : IF L_PAREN expression R_PAREN statement
	                    | IF L_PAREN expression R_PAREN statement ELSE statement
	                    | SWITCH L_PAREN expression R_PAREN L_BRACES add_sym labeled_statement_list pop_sym R_BRACES
    '''
    if p[1] == "if":
        if len(p) == 6:
            if p[3].type == "error" or p[5].type == "error":
                p[0] = Node(type="error")
                return
            p[0] = Node(name="if", children=[p[3], p[5]], type="ok")

        else:
            if p[3].type == "error" or p[5].type == "error" or p[
                    7].type == "error":
                p[0] = Node(type="error")
                return
            p[0] = Node(name="if_else", children=[p[3], p[5], p[7]], type="ok")

    else:
        if p[3].type == "error":
            p[0] = Node(type="error")
            return
        label_list = Node(name="labeled list",
                          value="{}",
                          children=p[7],
                          type="ok")
        p[0] = Node(name="switch", children=[p[3], label_list], type="ok")
Exemple #21
0
def tree_search(problem, mode):
    frontier = AQueue(mode)
    frontier([Node(state=problem.initial)])
    while frontier.empty():
        node = frontier.pop()
        if problem.goal_test(node.state):
            return node
        frontier.extend(node.expand(problem))
    return None
def p_expression_statement(p):
    '''
    expression_statement : SEMI_COLON
	                     | expression SEMI_COLON
    '''
    if len(p) == 2:
        p[0] = Node(value=p[1], type="ok")
    else:
        p[0] = p[1]
Exemple #23
0
def type_check_assign(node1, node2, token):
    if node1.type == "error" or node2.type == "error":
        return Node(type="error")
    if node2.type.is_convertible_to(node1.type):
        if str(node2.type) != str(node1.type):
            node2 = Node(name="type_cast",
                         value=node1.type.stype,
                         children=[node2],
                         type=node1.type)
        return Node("binary_op",
                    node1.type.stype + "=",
                    children=[node1, node2],
                    type=node1.type)
    Errors(errorType='TypeError',
           errorText="cannot assign " + node2.type.stype + " to " +
           node1.type.stype,
           token_object=token)
    return Node(type="error")
Exemple #24
0
def type_check_add(node1, node2, op, token):
    allowed_class = [('PointerType', 'BasicType'),
                     ('BasicType', 'PointerType'), ('BasicType', 'BasicType')]
    allowed_base = [{'int', 'long', 'char'}, {'int', 'long', 'char'},
                    {'int', 'long', 'char', 'double', 'float'}]
    if node1.type == "error" or node2.type == "error":
        return Node(type="error")
    class1 = node1.type.class_type
    class2 = node2.type.class_type
    if (class1, class2) not in allowed_class:
        Errors(errorType='TypeError',
               errorText=op + ' not support type ' + node1.type.stype + ',' +
               node2.type.stype,
               token_object=token)
        return Node(type="error")
    i = allowed_class.index((class1, class2))
    if i == 0:
        if node2.type.type not in allowed_base[i]:
            Errors(errorType='TypeError',
                   errorText=op + ' not support type ' + node1.type.stype +
                   ',' + node2.type.stype,
                   token_object=token)
            return Node(type="error")
        return Node(name="binary_op",
                    value=node1.type.stype + op,
                    type=node1.type,
                    children=[node1, node2])

    if i == 1:
        if node1.type.type not in allowed_base[i]:
            Errors(errorType='TypeError',
                   errorText=op + ' not support type ' + node1.type.stype +
                   ',' + node2.type.stype,
                   token_object=token)
            return Node(type="error")
        return Node(name="binary_op",
                    value=node2.type.stype + op,
                    type=node2.type,
                    children=[node2, node1])
    if i == 2:
        if node1.type.type not in allowed_base[
                i] or node2.type.type not in allowed_base[i]:
            Errors(errorType='TypeError',
                   errorText=op + ' not support type ' + node1.type.stype +
                   ',' + node2.type.stype,
                   token_object=token)
            return Node(type="error")
        node1, node2, typ = implicit_casting(node1, node2)
        return Node(name="binary_op",
                    value=typ.stype + op,
                    children=[node1, node2],
                    type=typ)
Exemple #25
0
def type_check_assign_op(node1, node2, op, token):
    if node1.type == "error" or node2.type == "error":
        return Node(type="error")
    if op == "=":
        return type_check_assign(node1, node2, token)
    op = op[:-1]
    if op == "+" or op == "-":
        node = type_check_add(node1, node2, op, token)
    elif op == "/" or op == "*":
        node = type_check_multi(node1, node2, op, token)
    elif op == "%":
        node = type_check_multi(node1, node2, op, token, decimal=False)
    elif op == "^" or op == "&" or op == "|":
        node = type_check_bit(node1, node2, op, token)
    else:
        Errors(errorType='SyntaxError',
               errorText="invalid " + op + "=",
               token_object=token)
        return Node(type="error")
    return type_check_assign(node1, node, token)
def p_primary_expression(p):
    '''
    primary_expression : IDENTIFIER
                       | INT_CONSTANT
                       | HEX_CONSTANT
                       | OCTAL_CONSTANT
                       | EXPONENT_CONSTANT
                       | REAL_CONSTANT
                       | CHAR_CONSTANT
                       | STR_CONSTANT
                       | L_PAREN expression R_PAREN
                       | TRUE
                       | FALSE
                       | NULL
    '''
    if len(p) == 2:
        if p.slice[-1].type == "IDENTIFIER":
            #looking for id
            success = sym_table.look_up(name=p[1], token_object=p.slice[-1])
            if success:
                p[0] = Node(name="id", value=p[1], type=success.type)
            else:
                p[0] = Node(name="id", type='error')
            return

        if p.slice[-1].type in [
                "INT_CONSTANT", "HEX_CONSTANT", "OCTAL_CONSTANT"
        ]:
            p[0] = Node(name="constant", value=p[1], type=BasicType('int'))

        elif p.slice[-1].type in ["EXPONENT_CONSTANT", "REAL_CONSTANT"]:
            p[0] = Node(name="constant", value=p[1], type=BasicType('float'))

        elif p.slice[-1].type == "CHAR_CONSTANT":
            p[0] = Node(name="constant", value=p[1], type=BasicType('char'))

        elif p.slice[-1].type == "STR_CONSTANT":
            str_type = PointerType(type=BasicType('char'),
                                   array_size=[len(p[1])],
                                   array_type=BasicType('char'))
            p[0] = Node(name="constant", value=p[1], type=str_type)
        elif p.slice[-1].type == "NULL":
            p[0] = Node(name="constant",
                        value=p[1],
                        type=PointerType(type=Type()))
        else:
            p[0] = Node(name="constant", value=p[1], type=BasicType('bool'))
        p[0].constant = p[0].value

    else:
        p[0] = p[2]
def p_argument_expression_list(p):
    '''
    argument_expression_list : assignment_expression
	                         | argument_expression_list COMMA assignment_expression
    '''
    if len(p) == 2:
        p[0] = Node("argument_expression_list", children=[p[1]])
        p[0].data['args_type'] = [p[1].type]
    else:
        p[1].addChild(p[3])
        p[1].data['args_type'] += [p[3].type]
        p[0] = p[1]
Exemple #28
0
def type_check_logical(node1, node2, op, token):
    allowed_class = {'BasicType'}
    allowed_base = {'int', 'long', 'char', 'double', 'float', 'bool'}
    if node1.type == "error" or node2.type == "error":
        return Node(type="error")
    if node1.type.class_type not in allowed_class or node2.type.class_type not in allowed_class:
        Errors(errorType='TypeError',
               errorText=op + ' not support type ' + node1.type.stype + ',' +
               node2.type.stype,
               token_object=token)
        return Node(type="error")
    if node1.type.type not in allowed_base or node2.type.type not in allowed_base:
        Errors(errorType='TypeError',
               errorText=op + ' not support type ' + node1.type.stype + ',' +
               node2.type.stype,
               token_object=token)
        return Node(type="error")

    if node1.type.type != "bool":
        node1 = Node(name="type_cast",
                     value='bool',
                     children=[node1],
                     type=BasicType('bool'))
    if node2.type.type != "bool":
        node2 = Node(name="type_cast",
                     value='bool',
                     children=[node2],
                     type=BasicType('bool'))
    return Node(name="binary_op",
                value=op,
                children=[node1, node2],
                type=BasicType('bool'))
def p_cast_expression(p):
    '''
    cast_expression : unary_expression
	                | L_PAREN type_name R_PAREN cast_expression
    '''
    if len(p) == 2:
        p[0] = p[1]
    else:
        if p[2].type == 'error' or p[4].type == 'error':
            p[0] = Node(type='error')
        else:
            if p[4].type.is_convertible_to(p[2].type):
                p[0] = Node(name="type_cast",
                            value=p[2].type.stype,
                            type=p[2].type,
                            children=[p[4]])
            else:
                Errors(errorType='TypeError',
                       errorText="cannot typecast " + p[4].types.stype +
                       " to " + p[2].type.stype,
                       token_object=p.slice[1])
                p[0] = Node(type='error')
def p_no_pointer(p):
    '''
    no_pointer : 
    '''
    type_specifier_symbol = None
    for symbol in reversed(p.stack):
        if symbol.type in ['type_specifier', 'pointer', 'no_pointer']:
            type_specifier_symbol = symbol
            break
    p[0] = Node(type=type_specifier_symbol.value.type)

    assert isinstance(p[0], Node), "return object is not Node"
    assert p[0].type == 'error' or isinstance(
        p[0].type, Type), "unexpected type attribute of return object"