import sys 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) 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].children) 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_unit_item_function(self, p): 'unit_item : function' 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_function(self, p): 'function : type ID LPAREN RPAREN LCURLY function_items RCURLY' p[0] = FunctionNode(p[2], p[1], None, p[6].children) def p_function_items(self, p): 'function_items : function_item function_items' p[0] = Node([p[1]] + p[2].children) def p_function_items_empty(self, p): 'function_items : empty' p[0] = p[1] def p_function_item_stmt(self, p): 'function_item : statement' p[0] = p[1] def p_type(self, p): '''type : CHAR | SHORT | INT | LONG''' p[0] = p[1] def p_empty(self, p): 'empty :' p[0] = Node() def p_error(self, p): self.saw_error = True col = p.lexpos - max(0, self.input.rfind('\n', 0, p.lexpos)) sys.stdout.write('Error: Unexpected %s at line %d, col %d\n' % ( p.type, p.lineno, col)) def parse(self): return self.parser.parse(self.input, lexer = self.lexer)