Пример #1
0
def get_for_clauses(index):
    """Get the three clauses of a for-statement.

        index - Index of the beginning of the first clause.

        returns - Tuple (Node, Node, Node, index). Each Node is the corresponding clause, or None if that clause is
        empty The index is that of first token after the close paren terminating the for clauses.

    Raises exception on malformed input.
    """

    first, index = get_first_for_clause(index)

    if token_is(index, token_kinds.semicolon):
        second = None
        index += 1
    else:
        second, index = parse_expression(index)
        index = match_token(index, token_kinds.semicolon, ParserError.AFTER)

    if token_is(index, token_kinds.close_paren):
        third = None
        index += 1
    else:
        third, index = parse_expression(index)
        index = match_token(index, token_kinds.close_paren, ParserError.AFTER)

    return first, second, third, index
Пример #2
0
def parse_while_statement(index):
    """ Parse a while statement """
    index = match_token(index, token_kinds.while_kw, ParserError.GOT)
    index = match_token(index, token_kinds.open_paren, ParserError.AFTER)
    conditional, index = parse_expression(index)
    index = match_token(index, token_kinds.close_paren, ParserError.AFTER)
    statement, index = parse_statement(index)

    return nodes.WhileStatement(conditional, statement), index
Пример #3
0
def parse_expr_statement(index):
    """Parse a statement that is an expression.
        Ex: a = 3 + 4
    """
    if token_is(index, token_kinds.semicolon):
        return nodes.EmptyStatement(), index + 1

    node, index = parse_expression(index)
    index = match_token(index, token_kinds.semicolon, ParserError.AFTER)
    return nodes.ExprStatement(node), index
Пример #4
0
def parse_return(index):
    """ Parse a return statement.
        Ex: return 5;
    """
    index = match_token(index, token_kinds.return_kw, ParserError.GOT)
    if token_is(index, token_kinds.semicolon):
        return nodes.Return(None), index

    node, index = parse_expression(index)

    index = match_token(index, token_kinds.semicolon, ParserError.AFTER)
    return nodes.Return(node), index
Пример #5
0
def parse_if_statement(index):
    """ Parse an if statement """

    index = match_token(index, token_kinds.if_kw, ParserError.GOT)
    index = match_token(index, token_kinds.open_paren, ParserError.AFTER)
    conditional, index = parse_expression(index)
    index = match_token(index, token_kinds.close_paren, ParserError.AFTER)
    statement, index = parse_statement(index)

    # If there is an else that follows, parse that too.
    is_else = token_is(index, token_kinds.else_kw)
    if not is_else:
        else_statement = None
    else:
        index = match_token(index, token_kinds.else_kw, ParserError.GOT)
        else_statement, index = parse_statement(index)

    return nodes.IfStatement(conditional, statement, else_statement), index
Пример #6
0
def get_first_for_clause(index):
    """Get the first clause of a for-statement.

        index - Index of the beginning of the first clause in the for-statement.

        returns - Tuple. First element is a node if a clause is found and None if there is no clause (i.e. semicolon
        terminating the clause). Second element is an integer index where the next token begins.

    If malformed, raises exception.
    """
    if token_is(index, token_kinds.semicolon): return None, index + 1

    with log_error():
        return parse_declaration(index)

    clause, index = parse_expression(index)
    index = match_token(index, token_kinds.semicolon, ParserError.AFTER)
    return clause, index
Пример #7
0
def parse_declarator_raw(start, end, is_typedef):
    """Like _parse_declarator, but doesn't add `.r` range attribute."""

    if start == end: return decl_nodes.Identifier(None)

    elif start + 1 == end and p.tokens[start].kind == token_kinds.identifier:
        p.symbols.add_symbol(p.tokens[start], is_typedef)
        return decl_nodes.Identifier(p.tokens[start])

    elif p.tokens[start].kind == token_kinds.star:
        const, index = find_const(start + 1)
        return decl_nodes.Pointer(_parse_declarator(index, end, is_typedef),
                                  const)

    func_decl = try_parse_func_decl(start, end, is_typedef)
    if func_decl:
        return func_decl

        # First and last elements make a parenthesis pair
    elif p.tokens[start].kind == token_kinds.open_paren and find_pair_forward(
            start) == end - 1:
        return _parse_declarator(start + 1, end - 1, is_typedef)

    # Last element indicates an array type
    elif p.tokens[end - 1].kind == token_kinds.close_sq_brack:
        open_sq = find_pair_backward(
            end - 1, token_kinds.open_sq_brack, token_kinds.close_sq_brack,
            "mismatched square brackets in declaration")

        if open_sq == end - 2: num_elem = None
        else:
            num_elem, index = parse_expression(open_sq + 1)
            if index != end - 1:
                err = "unexpected token in array size"
                raise_error(err, index, ParserError.AFTER)

        return decl_nodes.Array(num_elem,
                                _parse_declarator(start, open_sq, is_typedef))

    raise_error("faulty declaration syntax", start, ParserError.AT)