import ply.yacc as yacc from Lexer import Lexer from nodes import * class Parser(object): def __init__(self, input): self.input = input self.lexer = Lexer() self.tokens = self.lexer.tokens self.parser = yacc.yacc(module = self, outputdir = 'parser') self.saw_error = False def p_unit(self, p): 'unit : unit_items' if self.saw_error: p[0] = None else: p[0] = UnitNode([p[1]]) def p_unit_items(self, p): 'unit_items : unit_item unit_items' p[0] = Node([p[1]] + p[2].children) def p_unit_items_empty(self, p): 'unit_items : empty' p[0] = p[1] def p_unit_item_c_stmt(self, p): 'unit_item : c_expr SEMICOLON' p[0] = p[1] def p_statement(self, p): 'statement : expr SEMICOLON' p[0] = StatementNode([p[1]]) def p_expr(self, p): 'expr : c_expr' p[0] = p[1] def p_c_expr(self, p): 'c_expr : C LPAREN STRING RPAREN' p[0] = CExprNode(p[3]) def p_empty(self, p): 'empty :' p[0] = Node() def p_error(self, p): self.saw_error = True def parse(self): return self.parser.parse(self.input, lexer = self.lexer)