示例#1
0
def parse_vars(tokens, idx):
    # <id> "[" <exp> "]"
    old_idx = idx
    try:

        idx, tok = utils.match_type(tokens, idx, IDENTIFIER)
        id_name = tok.value
        idx, tok = utils.match(tokens, idx, OPERATOR, '[')

        idx, index_expression = parse_expression(tokens, idx)
        idx, tok = utils.match(tokens, idx, OPERATOR, ']')

        return idx, ArrayVariable(id_name=id_name,
                                  index_expression=index_expression)
    except:
        idx = old_idx

    # <id>
    try:
        idx, tok = utils.match_type(tokens, idx, IDENTIFIER)
        return idx, Variable(id_name=tok.value)
    except:
        pass

    assert False
示例#2
0
def parse_single_declaration(tokens, idx):
    # <single_declaration> ::= <id> "[" <exp>(a num) "]" | <id> [ '=' <exp> ]
    old_idx = idx
    try:
        idx, tok = utils.match_type(tokens, idx, IDENTIFIER)
        id_name = tok.value

        idx, tok = utils.match(tokens, idx, OPERATOR, '[')
        idx, tok = utils.match_type(tokens, idx, INT)
        index_expression = Number(num=int(tok.value))
        idx, tok = utils.match(tokens, idx, OPERATOR, ']')

        return idx, SingleArrayDeclaration(id_name=id_name,
                                           index_expression=index_expression)
    except:
        idx = old_idx

    old_idx = idx
    try:
        idx, tok = utils.match_type(tokens, idx, IDENTIFIER)
        id_name = tok.value

        try:
            idx, tok = utils.match(tokens, idx, OPERATOR, '=')
            idx, expression = parse_subexpression(tokens, idx)
            return idx, SingleDeclaration(id_name=id_name,
                                          expression=expression)
        except:
            pass

        return idx, SingleDeclaration(id_name=id_name, expression=None)
    except:
        idx = old_idx

    assert False
示例#3
0
def parse_function(tokens, idx):
    # <function> ::= "int" <id> "(" [ "int" <id> { "," "int" <id> } ] ")" ( "{" { <block-item> } "}" | ";" )
    idx, tok = utils.match(tokens, idx, RESERVED, 'int')
    rtype = tok.value
    idx, tok = utils.match_type(tokens, idx, IDENTIFIER)
    fname = tok.value

    idx, tok = utils.match(tokens, idx, OPERATOR, '(')
    idx, parameters = parse_parameter_list(tokens, idx)
    idx, tok = utils.match(tokens, idx, OPERATOR, ')')

    # if it is declaration
    try:
        idx, tok = utils.match(tokens, idx, OPERATOR, ';')
        return idx, Function_Declaration(fname=fname,
                                         rtype=rtype,
                                         parameters=parameters,
                                         function=None)
    except:
        pass

    # else it is defination
    idx, tok = utils.match(tokens, idx, OPERATOR, '{')

    # sub statement
    idx, statement = parse_block_item(tokens, idx)
    function = Function(fname=fname,
                        rtype=rtype,
                        statement=statement,
                        parameters=parameters,
                        function=None)

    # more statement
    while True:
        if tokens[idx].value == '}':
            break
        # print(idx, tokens[idx])
        idx, statement = parse_block_item(tokens, idx)
        function = Function(fname=fname,
                            rtype=rtype,
                            statement=statement,
                            parameters=parameters,
                            function=function)

    idx, tok = utils.match(tokens, idx, OPERATOR, '}')

    # add default return
    if 'astnodes.Return' not in str(type(function.statement)):
        function = Function(fname=fname,
                            rtype=rtype,
                            statement=Return(),
                            parameters=parameters,
                            function=function)

    return idx, function
示例#4
0
def parse_parameter_list(tokens, idx):
    # [ "int" <id> { "," "int" <id> } ]
    ret = []
    try:
        idx, tok1 = utils.match(tokens, idx, RESERVED, 'int')
        idx, tok2 = utils.match_type(tokens, idx, IDENTIFIER)
        ret.append([tok1, tok2])

        old_idx = None
        try:
            while True:
                old_idx = idx
                idx, tok = utils.match(tokens, idx, OPERATOR, ',')
                idx, tok1 = utils.match(tokens, idx, RESERVED, 'int')
                idx, tok2 = utils.match_type(tokens, idx, IDENTIFIER)
                ret.append([tok1, tok2])
        except:
            idx = old_idx

    except:
        pass
    return idx, ret
示例#5
0
def parse_global_declaration(tokens, idx):
    # <declaration> ::= "int" <id> [ = <exp> ] ";"
    try:
        idx, tok = utils.match(tokens, idx, RESERVED, 'int')
        type_name = tok.value
        idx, tok = utils.match_type(tokens, idx, IDENTIFIER)
        id_name = tok.value

        try:
            idx, tok = utils.match(tokens, idx, OPERATOR, '=')
            idx, tok = utils.match_type(tokens, idx, INT)
            val = tok.value
            idx, tok = utils.match(tokens, idx, OPERATOR, ';')
            return idx, GlobalDeclaration(type_name=type_name,
                                          id_name=id_name,
                                          val=val)
        except:
            pass

        idx, tok = utils.match(tokens, idx, OPERATOR, ';')
        return idx, Declaration(type_name=type_name, id_name=id_name)
    except:
        pass
    assert False
示例#6
0
def parse_func_call(tokens, idx):
    # <function-call> ::= id "(" [ <exp> { "," <exp> } ] ")"
    try:

        idx, tok = utils.match_type(tokens, idx, IDENTIFIER)

        fname = tok.value
        idx, tok = utils.match(tokens, idx, OPERATOR, '(')
        parameters = []

        try:
            idx, exp = parse_condition_expression(tokens, idx)
            parameters.append(exp)
            while True:
                old_idx = idx
                try:
                    old_idx = idx
                    idx, tok = utils.match(tokens, idx, OPERATOR, ',')
                    # idx, exp = parse_expression(tokens, idx)
                    idx, exp = parse_condition_expression(
                        tokens, idx)  # fix bugs, no assignment action
                    parameters.append(exp)
                except:
                    idx = old_idx
                    break
        except:
            pass

        # print(parameters[0])

        idx, tok = utils.match(tokens, idx, OPERATOR, ')')
        # print(parameters)
        # print(fname, tok)
        return idx, Func_Call(fname=fname, parameters=parameters)
    except:
        pass

    assert False
示例#7
0
def parse_subexpression(tokens, idx):
    # <exp> ::= <id> "=" <exp>
    old_idx = idx
    try:
        idx, tok = utils.match_type(tokens, idx, IDENTIFIER)
        f_name = tok.value

        idx, tok = utils.match_type_values(tokens, idx, OPERATOR,
                                           utils.assign_op)
        idx, expression = parse_subexpression(tokens, idx)  # b=1,a
        assignment = Assignment(id_name=f_name,
                                expression=expression,
                                op=tok.value)
        return idx, assignment
    except:
        idx = old_idx

    # <id> "[" <exp> "]" "=" <exp>
    old_idx = idx
    try:

        idx, tok = utils.match_type(tokens, idx, IDENTIFIER)
        f_name = tok.value

        idx, tok = utils.match(tokens, idx, OPERATOR, '[')
        idx, index_expression = parse_expression(tokens, idx)
        idx, tok = utils.match(tokens, idx, OPERATOR, ']')

        idx, tok = utils.match_type_values(tokens, idx, OPERATOR,
                                           utils.assign_op)

        idx, expression = parse_subexpression(tokens, idx)
        assignment = ArrayAssignment(id_name=f_name,
                                     expression=expression,
                                     op=tok.value,
                                     index_expression=index_expression)
        return idx, assignment
    except:
        idx = old_idx

    # <exp> ::= "*" <id> "=" <exp>
    old_idx = idx
    try:
        idx, tok = utils.match(tokens, idx, OPERATOR, '*')
        idx, tok = utils.match_type(tokens, idx, IDENTIFIER)
        f_name = tok.value

        idx, tok = utils.match_type_values(tokens, idx, OPERATOR,
                                           utils.assign_op)
        idx, expression = parse_subexpression(tokens, idx)  # b=1,a
        assignment = CiteAssignment(id_name=f_name,
                                    expression=expression,
                                    op=tok.value)
        return idx, assignment
    except:
        idx = old_idx

    # <id> "*" "[" <exp> "]" "=" <exp>
    old_idx = idx
    try:
        idx, tok = utils.match(tokens, idx, OPERATOR, '*')
        idx, tok = utils.match_type(tokens, idx, IDENTIFIER)
        f_name = tok.value

        idx, tok = utils.match(tokens, idx, OPERATOR, '[')
        idx, index_expression = parse_expression(tokens, idx)
        idx, tok = utils.match(tokens, idx, OPERATOR, ']')

        idx, tok = utils.match_type_values(tokens, idx, OPERATOR,
                                           utils.assign_op)

        idx, expression = parse_subexpression(tokens, idx)
        assignment = ArrayAssignment(id_name=f_name,
                                     expression=expression,
                                     op=tok.value,
                                     index_expression=index_expression)
        return idx, assignment
    except:
        idx = old_idx

    # <conditional-exp>
    try:
        idx, expression = parse_condition_expression(tokens, idx)
        expression = Expression(logical_or_expression=expression)
        return idx, expression
    except:
        pass

    assert False
示例#8
0
def parse_factor(tokens, idx):
    # <function-call>
    try:
        idx, expression = parse_func_call(tokens, idx)
        return idx, Factor(expression=expression)
    except:
        pass

    # "(" <exp> ")"
    old_idx = idx
    try:
        idx, tok = utils.match(tokens, idx, OPERATOR, '(')
        idx, expression = parse_expression(tokens, idx)
        idx, tok = utils.match(tokens, idx, OPERATOR, ')')
        return idx, Factor(expression=expression)
    except:
        idx = old_idx

    # <unary_op> <var>
    old_idx = idx
    try:
        idx, tok = utils.match_type_values(tokens, idx, OPERATOR,
                                           utils.unary_op)
        idx, var = parse_vars(tokens, idx)
        return idx, UnaryOP(op=tok.value, factor=var)
    except:
        idx = old_idx

    # <var> <unary_op>
    old_idx = idx
    try:
        idx, var = parse_vars(tokens, idx)
        idx, tok = utils.match_type_values(tokens, idx, OPERATOR,
                                           utils.post_unary_op)
        return idx, PostUnaryOP(op=tok.value, factor=var)
    except:
        idx = old_idx

    # <var>
    try:
        idx, var = parse_vars(tokens, idx)
        return idx, var
    except:
        idx = old_idx

    # <int>
    try:
        idx, tok = utils.match_type(tokens, idx, INT)
        return idx, Number(num=int(tok.value))
    except:
        pass

    # <char>
    try:
        idx, tok = utils.match_type(tokens, idx, CHAR)
        return idx, Number(num=ord(tok.value))
    except:
        pass

    # <string>
    try:
        idx, tok = utils.match_type(tokens, idx, STRING)
        return idx, String(string=tok.value)
    except:
        pass

    # print('error: parse_factor')
    assert False