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' )
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,))