示例#1
0
    def __init__(self, debug=False, optimize=True):
        self.lexer = VYPeLexer()
        self.lexer.build(
            optimize=optimize,
            debug=debug,
            lextab='vype.lextab'
        )
        self.tokens = self.lexer.tokens

        self.parser = yacc.yacc(
            module=self,
            start='program',
            optimize=optimize,
            debug=debug,
            tabmodule='vype.yacctab'
        )
示例#2
0
class VYPeParser(object):
    def __init__(self, debug=False, optimize=True):
        self.lexer = VYPeLexer()
        self.lexer.build(
            optimize=optimize,
            debug=debug,
            lextab='vype.lextab'
        )
        self.tokens = self.lexer.tokens

        self.parser = yacc.yacc(
            module=self,
            start='program',
            optimize=optimize,
            debug=debug,
            tabmodule='vype.yacctab'
        )

    def parse(self, text, filename='', debuglevel=0):
        self.lexer.filename = filename
        self.lexer.reset_lineno()
        return self.parser.parse(
            input=text,
            lexer=self.lexer,
            debug=debuglevel
        )

    # ==================================================================

    def p_empty(self, p):
        '''
        empty :
        '''
        p[0] = None

    # ==================================================================

    def p_program(self, p):
        '''
        program : declaration_list
        '''
        p[0] = ast.Program(p[1])

    def p_declaration_list_1(self, p):
        '''
        declaration_list : declaration
        '''
        p[0] = [p[1]]

    def p_declaration_list_2(self, p):
        '''
        declaration_list : declaration_list declaration
        '''
        if p[2] is not None:
            p[1].append(p[2])
        p[0] = p[1]

    def p_declaration(self, p):
        '''
        declaration : function_declaration
                    | function_definition
                    | variable_declaration
        '''
        p[0] = p[1]

    # ==================================================================

    def p_variable_declaration(self, p):
        '''
        variable_declaration : type variable_declaration_list SEMI
        '''
        p[0] = ast.VariableDeclaration(p[1], p[2])

    def p_variable_declaration_list_1(self, p):
        '''
        variable_declaration_list : variable_declaration_initialize
        '''
        p[0] = [p[1]]

    def p_variable_declaration_list_2(self, p):
        '''
        variable_declaration_list : variable_declaration_list COMMA variable_declaration_initialize
        '''
        if p[3] is not None:
            p[1].append(p[3])
        p[0] = p[1]

    def p_variable_declaration_initialize(self, p):
        '''
        variable_declaration_initialize : IDENTIFIER
                                        | IDENTIFIER EQUALS expression
        '''
        p[0] = ast.VariableInitialize(p[1], p[3] if len(p) == 4 else None)

    def p_type_1(self, p):
        '''
        type : INT
             | CHAR
             | STRING
        '''
        p[0] = ast.Type(p[1])

    def p_type_2(self, p):
        '''
        type : UNSIGNED INT
             | SHORT
             | UNSIGNED SHORT
        '''
        p[0] = None
        raise ParserError("unsupported type '%s'" % ' '.join(p[1:]))

    def p_void(self, p):
        '''
        void : VOID
        '''
        p[0] = ast.Type(p[1])

    # =====================================================================

    def p_function_definition_1(self, p):
        '''
        function_definition : void IDENTIFIER LPAREN params RPAREN compound_statement
                            | type IDENTIFIER LPAREN params RPAREN compound_statement
        '''
        p[0] = ast.FunctionDefinition(p[1], p[2], p[4], p[6])

    def p_function_definition_2(self, p):
        '''
        function_definition : void IDENTIFIER LPAREN void RPAREN compound_statement
                            | type IDENTIFIER LPAREN void RPAREN compound_statement
        '''
        p[0] = ast.FunctionDefinition(p[1], p[2], [ast.FunctionParam(p[4])], p[6])

    def p_params_1(self, p):
        '''
        params : param
        '''
        p[0] = [p[1]]

    def p_params_2(self, p):
        '''
        params : params COMMA param
        '''
        if p[3] is not None:
            p[1].append(p[3])
        p[0] = p[1]

    def p_param(self, p):
        '''
        param : type IDENTIFIER
        '''
        p[0] = ast.FunctionParam(p[1], p[2])

    def p_function_declaration_1(self, p):
        '''
        function_declaration : void IDENTIFIER LPAREN types RPAREN SEMI
                             | type IDENTIFIER LPAREN types RPAREN SEMI
        '''
        p[0] = ast.FunctionDefinition(p[1], p[2], p[4])

    def p_function_declaration_2(self, p):
        '''
        function_declaration : void IDENTIFIER LPAREN void RPAREN SEMI
                             | type IDENTIFIER LPAREN void RPAREN SEMI
        '''
        p[0] = ast.FunctionDefinition(p[1], p[2], [ast.FunctionParam(p[4])])

    def p_types_1(self, p):
        '''
        types : type
        '''
        p[0] = [ast.FunctionParam(p[1])]

    def p_types_2(self, p):
        '''
        types : types COMMA type
        '''
        if p[3] is not None:
            p[1].append(ast.FunctionParam(p[3]))
        p[0] = p[1]

    # ==================================================================

    def p_compound_statement(self, p):
        '''
        compound_statement : LBRACE RBRACE
                           | LBRACE block_item_list RBRACE
        '''
        p[0] = ast.Compound(p[2] if len(p) == 4 else [ast.Empty()])

    def p_block_item_list_1(self, p):
        '''
        block_item_list : block_item
        '''
        p[0] = [p[1]]

    def p_block_item_list_2(self, p):
        '''
        block_item_list : block_item_list block_item
        '''
        if p[2] is not None:
            p[1].append(p[2])
        p[0] = p[1]

    def p_block_item(self, p):
        '''
        block_item : variable_declaration
                   | statement
        '''
        p[0] = p[1]

    def p_statement(self, p):
        '''
        statement : expression_statement
                  | selection_statement
                  | iteration_statement
                  | jump_statement
                  | return_statement
        '''
        p[0] = p[1]

    def p_expression_statement(self, p):
        '''
        expression_statement : expression_opt SEMI
        '''
        if p[1] is not None:
            p[0] = p[1]
        else:
            p[0] = ast.Empty()

    def p_selection_statement(self, p):
        '''
        selection_statement : IF LPAREN expression RPAREN compound_statement
                            | IF LPAREN expression RPAREN compound_statement ELSE compound_statement
        '''
        p[0] = ast.If(p[3], p[5], p[7] if len(p) == 8 else ast.Empty())

    def p_iteration_statement_1(self, p):
        '''
        iteration_statement : WHILE LPAREN expression RPAREN compound_statement
        '''
        p[0] = ast.While(p[3], p[5])

    def p_iteration_statement_2(self, p):
        '''
        iteration_statement : FOR LPAREN expression_statement expression_statement expression_opt RPAREN compound_statement
        '''
        p[0] = ast.For(p[3], p[4], p[5], p[7])

    def p_jump_statement_1(self, p):
        '''
        jump_statement : CONTINUE SEMI
        '''
        p[0] = ast.Continue()

    def p_jump_statement_2(self, p):
        '''
        jump_statement : BREAK SEMI
        '''
        p[0] = ast.Break()

    def p_return_statement(self, p):
        '''
        return_statement : RETURN expression_opt SEMI
        '''
        p[0] = ast.Return(p[2])

    # ==================================================================

    def p_expression_opt(self, p):
        '''
        expression_opt : expression
                       | empty
        '''
        p[0] = p[1]

    def p_expression(self, p):
        '''
        expression : assignment_expression
        '''
        p[0] = p[1]

    def p_assignment_expression_1(self, p):
        '''
        assignment_expression : lor_expression
        '''
        p[0] = p[1]

    def p_assignment_expression_2(self, p):
        '''
        assignment_expression : IDENTIFIER EQUALS assignment_expression
        '''
        p[0] = ast.Assignment(p[1], p[3])

    def p_lor_expression_1(self, p):
        '''
        lor_expression : land_expression
        '''
        p[0] = p[1]

    def p_lor_expression_2(self, p):
        '''
        lor_expression : lor_expression OR land_expression
        '''
        p[0] = ast.BinaryOp(p[2], p[1], p[3])

    def p_land_expression_1(self, p):
        '''
        land_expression : equality_expression
        '''
        p[0] = p[1]

    def p_land_expression_2(self, p):
        '''
        land_expression : land_expression AND equality_expression
        '''
        p[0] = ast.BinaryOp(p[2], p[1], p[3])

    def p_equality_expression_1(self, p):
        '''
        equality_expression : relational_expression
        '''
        p[0] = p[1]

    def p_equality_expression_2(self, p):
        '''
        equality_expression : equality_expression EQ relational_expression
                            | equality_expression NE relational_expression
        '''
        p[0] = ast.BinaryOp(p[2], p[1], p[3])

    def p_relational_expression_1(self, p):
        '''
        relational_expression : additive_expression
        '''
        p[0] = p[1]

    def p_relational_expression_2(self, p):
        '''
        relational_expression : relational_expression LT additive_expression
                              | relational_expression LE additive_expression
                              | relational_expression GE additive_expression
                              | relational_expression GT additive_expression
        '''
        p[0] = ast.BinaryOp(p[2], p[1], p[3])

    def p_additive_expression_1(self, p):
        '''
        additive_expression : multiplicative_expression
        '''
        p[0] = p[1]

    def p_additive_expression_2(self, p):
        '''
        additive_expression : additive_expression PLUS multiplicative_expression
                            | additive_expression MINUS multiplicative_expression
        '''
        p[0] = ast.BinaryOp(p[2], p[1], p[3])

    def p_multiplicative_expression_1(self, p):
        '''
        multiplicative_expression : cast_expression
        '''
        p[0] = p[1]

    def p_multiplicative_expression_2(self, p):
        '''
        multiplicative_expression : multiplicative_expression TIMES cast_expression
                                  | multiplicative_expression DIVIDE cast_expression
                                  | multiplicative_expression MOD cast_expression
        '''
        p[0] = ast.BinaryOp(p[2], p[1], p[3])

    def p_cast_expression_1(self, p):
        '''
        cast_expression : unary_expression
        '''
        p[0] = p[1]

    def p_cast_expression_2(self, p):
        '''
        cast_expression : LPAREN type RPAREN cast_expression
        '''
        p[0] = ast.Cast(p[2], p[4])

    def p_unary_expression_1(self, p):
        '''
        unary_expression : factor
        '''
        p[0] = p[1]

    def p_unary_expression_2(self, p):
        '''
        unary_expression : unary_operator cast_expression
        '''
        p[0] = ast.UnaryOp(p[1], p[2])

    def p_unary_operator(self, p):
        '''
        unary_operator : PLUS
                       | MINUS
                       | NOT
        '''
        p[0] = p[1]

    def p_factor(self, p):
        '''
        factor : immutable
               | mutable
        '''
        p[0] = p[1]

    def p_mutable(self, p):
        '''
        mutable : IDENTIFIER
        '''
        p[0] = ast.Identifier(p[1])

    def p_immutable_1(self, p):
        '''
        immutable : LPAREN expression RPAREN
        '''
        p[0] = p[2]

    def p_immutable_2(self, p):
        '''
        immutable : call
                  | constant
        '''
        p[0] = p[1]

    def p_call(self, p):
        '''
        call : IDENTIFIER LPAREN args RPAREN
        '''
        p[0] = ast.FunctionCall(p[1], p[3])

    def p_args_1(self, p):
        '''
        args : arg_list
        '''
        p[0] = p[1]

    def p_args_2(self, p):
        '''
        args : empty
        '''
        p[0] = [p[1]]

    def p_arg_list_1(self, p):
        '''
        arg_list : expression
        '''
        p[0] = [p[1]]

    def p_arg_list_2(self, p):
        '''
        arg_list : arg_list COMMA expression
        '''
        if p[3] is not None:
            p[1].append(p[3])
        p[0] = p[1]

    def p_constant_1(self, p):
        '''
        constant : INT_CONSTANT
        '''
        p[0] = ast.Constant(ast.Type(VarType.Integer), p[1])

    def p_constant_2(self, p):
        '''
        constant : CHAR_CONSTANT
        '''
        p[0] = ast.Constant(ast.Type(VarType.Character), p[1])

    def p_constant_3(self, p):
        '''
        constant : STRING_LITERAL
        '''
        p[0] = ast.Constant(ast.Type(VarType.String), p[1])

    # ==================================================================

    def p_error(self, p):
        raise ParserError("unexpected token '%s' on line %s" % (p.value, p.lineno,))