basparse.py revision 4479
14479Sbinkertn@umich.edu# An implementation of Dartmouth BASIC (1964) 24479Sbinkertn@umich.edu# 34479Sbinkertn@umich.edu 44479Sbinkertn@umich.edufrom ply import * 54479Sbinkertn@umich.eduimport basiclex 64479Sbinkertn@umich.edu 74479Sbinkertn@umich.edutokens = basiclex.tokens 84479Sbinkertn@umich.edu 94479Sbinkertn@umich.eduprecedence = ( 104479Sbinkertn@umich.edu ('left', 'PLUS','MINUS'), 114479Sbinkertn@umich.edu ('left', 'TIMES','DIVIDE'), 124479Sbinkertn@umich.edu ('left', 'POWER'), 134479Sbinkertn@umich.edu ('right','UMINUS') 144479Sbinkertn@umich.edu) 154479Sbinkertn@umich.edu 164479Sbinkertn@umich.edu#### A BASIC program is a series of statements. We represent the program as a 174479Sbinkertn@umich.edu#### dictionary of tuples indexed by line number. 184479Sbinkertn@umich.edu 194479Sbinkertn@umich.edudef p_program(p): 204479Sbinkertn@umich.edu '''program : program statement 214479Sbinkertn@umich.edu | statement''' 224479Sbinkertn@umich.edu 234479Sbinkertn@umich.edu if len(p) == 2 and p[1]: 244479Sbinkertn@umich.edu p[0] = { } 254479Sbinkertn@umich.edu line,stat = p[1] 264479Sbinkertn@umich.edu p[0][line] = stat 274479Sbinkertn@umich.edu elif len(p) ==3: 284479Sbinkertn@umich.edu p[0] = p[1] 294479Sbinkertn@umich.edu if not p[0]: p[0] = { } 304479Sbinkertn@umich.edu if p[2]: 314479Sbinkertn@umich.edu line,stat = p[2] 324479Sbinkertn@umich.edu p[0][line] = stat 334479Sbinkertn@umich.edu 344479Sbinkertn@umich.edu#### This catch-all rule is used for any catastrophic errors. In this case, 354479Sbinkertn@umich.edu#### we simply return nothing 364479Sbinkertn@umich.edu 374479Sbinkertn@umich.edudef p_program_error(p): 384479Sbinkertn@umich.edu '''program : error''' 394479Sbinkertn@umich.edu p[0] = None 404479Sbinkertn@umich.edu p.parser.error = 1 414479Sbinkertn@umich.edu 424479Sbinkertn@umich.edu#### Format of all BASIC statements. 434479Sbinkertn@umich.edu 444479Sbinkertn@umich.edudef p_statement(p): 454479Sbinkertn@umich.edu '''statement : INTEGER command NEWLINE''' 464479Sbinkertn@umich.edu if isinstance(p[2],str): 474479Sbinkertn@umich.edu print p[2],"AT LINE", p[1] 484479Sbinkertn@umich.edu p[0] = None 494479Sbinkertn@umich.edu p.parser.error = 1 504479Sbinkertn@umich.edu else: 514479Sbinkertn@umich.edu lineno = int(p[1]) 524479Sbinkertn@umich.edu p[0] = (lineno,p[2]) 534479Sbinkertn@umich.edu 544479Sbinkertn@umich.edu#### Interactive statements. 554479Sbinkertn@umich.edu 564479Sbinkertn@umich.edudef p_statement_interactive(p): 574479Sbinkertn@umich.edu '''statement : RUN NEWLINE 584479Sbinkertn@umich.edu | LIST NEWLINE 594479Sbinkertn@umich.edu | NEW NEWLINE''' 604479Sbinkertn@umich.edu p[0] = (0, (p[1],0)) 614479Sbinkertn@umich.edu 624479Sbinkertn@umich.edu#### Blank line number 634479Sbinkertn@umich.edudef p_statement_blank(p): 644479Sbinkertn@umich.edu '''statement : INTEGER NEWLINE''' 654479Sbinkertn@umich.edu p[0] = (0,('BLANK',int(p[1]))) 664479Sbinkertn@umich.edu 674479Sbinkertn@umich.edu#### Error handling for malformed statements 684479Sbinkertn@umich.edu 694479Sbinkertn@umich.edudef p_statement_bad(p): 704479Sbinkertn@umich.edu '''statement : INTEGER error NEWLINE''' 714479Sbinkertn@umich.edu print "MALFORMED STATEMENT AT LINE", p[1] 724479Sbinkertn@umich.edu p[0] = None 734479Sbinkertn@umich.edu p.parser.error = 1 744479Sbinkertn@umich.edu 754479Sbinkertn@umich.edu#### Blank line 764479Sbinkertn@umich.edu 774479Sbinkertn@umich.edudef p_statement_newline(p): 784479Sbinkertn@umich.edu '''statement : NEWLINE''' 794479Sbinkertn@umich.edu p[0] = None 804479Sbinkertn@umich.edu 814479Sbinkertn@umich.edu#### LET statement 824479Sbinkertn@umich.edu 834479Sbinkertn@umich.edudef p_command_let(p): 844479Sbinkertn@umich.edu '''command : LET variable EQUALS expr''' 854479Sbinkertn@umich.edu p[0] = ('LET',p[2],p[4]) 864479Sbinkertn@umich.edu 874479Sbinkertn@umich.edudef p_command_let_bad(p): 884479Sbinkertn@umich.edu '''command : LET variable EQUALS error''' 894479Sbinkertn@umich.edu p[0] = "BAD EXPRESSION IN LET" 904479Sbinkertn@umich.edu 914479Sbinkertn@umich.edu#### READ statement 924479Sbinkertn@umich.edu 934479Sbinkertn@umich.edudef p_command_read(p): 944479Sbinkertn@umich.edu '''command : READ varlist''' 954479Sbinkertn@umich.edu p[0] = ('READ',p[2]) 964479Sbinkertn@umich.edu 974479Sbinkertn@umich.edudef p_command_read_bad(p): 984479Sbinkertn@umich.edu '''command : READ error''' 994479Sbinkertn@umich.edu p[0] = "MALFORMED VARIABLE LIST IN READ" 1004479Sbinkertn@umich.edu 1014479Sbinkertn@umich.edu#### DATA statement 1024479Sbinkertn@umich.edu 1034479Sbinkertn@umich.edudef p_command_data(p): 1044479Sbinkertn@umich.edu '''command : DATA numlist''' 1054479Sbinkertn@umich.edu p[0] = ('DATA',p[2]) 1064479Sbinkertn@umich.edu 1074479Sbinkertn@umich.edudef p_command_data_bad(p): 1084479Sbinkertn@umich.edu '''command : DATA error''' 1094479Sbinkertn@umich.edu p[0] = "MALFORMED NUMBER LIST IN DATA" 1104479Sbinkertn@umich.edu 1114479Sbinkertn@umich.edu#### PRINT statement 1124479Sbinkertn@umich.edu 1134479Sbinkertn@umich.edudef p_command_print(p): 1144479Sbinkertn@umich.edu '''command : PRINT plist optend''' 1154479Sbinkertn@umich.edu p[0] = ('PRINT',p[2],p[3]) 1164479Sbinkertn@umich.edu 1174479Sbinkertn@umich.edudef p_command_print_bad(p): 1184479Sbinkertn@umich.edu '''command : PRINT error''' 1194479Sbinkertn@umich.edu p[0] = "MALFORMED PRINT STATEMENT" 1204479Sbinkertn@umich.edu 1214479Sbinkertn@umich.edu#### Optional ending on PRINT. Either a comma (,) or semicolon (;) 1224479Sbinkertn@umich.edu 1234479Sbinkertn@umich.edudef p_optend(p): 1244479Sbinkertn@umich.edu '''optend : COMMA 1254479Sbinkertn@umich.edu | SEMI 1264479Sbinkertn@umich.edu |''' 1274479Sbinkertn@umich.edu if len(p) == 2: 1284479Sbinkertn@umich.edu p[0] = p[1] 1294479Sbinkertn@umich.edu else: 1304479Sbinkertn@umich.edu p[0] = None 1314479Sbinkertn@umich.edu 1324479Sbinkertn@umich.edu#### PRINT statement with no arguments 1334479Sbinkertn@umich.edu 1344479Sbinkertn@umich.edudef p_command_print_empty(p): 1354479Sbinkertn@umich.edu '''command : PRINT''' 1364479Sbinkertn@umich.edu p[0] = ('PRINT',[],None) 1374479Sbinkertn@umich.edu 1384479Sbinkertn@umich.edu#### GOTO statement 1394479Sbinkertn@umich.edu 1404479Sbinkertn@umich.edudef p_command_goto(p): 1414479Sbinkertn@umich.edu '''command : GOTO INTEGER''' 1424479Sbinkertn@umich.edu p[0] = ('GOTO',int(p[2])) 1434479Sbinkertn@umich.edu 1444479Sbinkertn@umich.edudef p_command_goto_bad(p): 1454479Sbinkertn@umich.edu '''command : GOTO error''' 1464479Sbinkertn@umich.edu p[0] = "INVALID LINE NUMBER IN GOTO" 1474479Sbinkertn@umich.edu 1484479Sbinkertn@umich.edu#### IF-THEN statement 1494479Sbinkertn@umich.edu 1504479Sbinkertn@umich.edudef p_command_if(p): 1514479Sbinkertn@umich.edu '''command : IF relexpr THEN INTEGER''' 1524479Sbinkertn@umich.edu p[0] = ('IF',p[2],int(p[4])) 1534479Sbinkertn@umich.edu 1544479Sbinkertn@umich.edudef p_command_if_bad(p): 1554479Sbinkertn@umich.edu '''command : IF error THEN INTEGER''' 1564479Sbinkertn@umich.edu p[0] = "BAD RELATIONAL EXPRESSION" 1574479Sbinkertn@umich.edu 1584479Sbinkertn@umich.edudef p_command_if_bad2(p): 1594479Sbinkertn@umich.edu '''command : IF relexpr THEN error''' 1604479Sbinkertn@umich.edu p[0] = "INVALID LINE NUMBER IN THEN" 1614479Sbinkertn@umich.edu 1624479Sbinkertn@umich.edu#### FOR statement 1634479Sbinkertn@umich.edu 1644479Sbinkertn@umich.edudef p_command_for(p): 1654479Sbinkertn@umich.edu '''command : FOR ID EQUALS expr TO expr optstep''' 1664479Sbinkertn@umich.edu p[0] = ('FOR',p[2],p[4],p[6],p[7]) 1674479Sbinkertn@umich.edu 1684479Sbinkertn@umich.edudef p_command_for_bad_initial(p): 1694479Sbinkertn@umich.edu '''command : FOR ID EQUALS error TO expr optstep''' 1704479Sbinkertn@umich.edu p[0] = "BAD INITIAL VALUE IN FOR STATEMENT" 1714479Sbinkertn@umich.edu 1724479Sbinkertn@umich.edudef p_command_for_bad_final(p): 1734479Sbinkertn@umich.edu '''command : FOR ID EQUALS expr TO error optstep''' 1744479Sbinkertn@umich.edu p[0] = "BAD FINAL VALUE IN FOR STATEMENT" 1754479Sbinkertn@umich.edu 1764479Sbinkertn@umich.edudef p_command_for_bad_step(p): 1774479Sbinkertn@umich.edu '''command : FOR ID EQUALS expr TO expr STEP error''' 1784479Sbinkertn@umich.edu p[0] = "MALFORMED STEP IN FOR STATEMENT" 1794479Sbinkertn@umich.edu 1804479Sbinkertn@umich.edu#### Optional STEP qualifier on FOR statement 1814479Sbinkertn@umich.edu 1824479Sbinkertn@umich.edudef p_optstep(p): 1834479Sbinkertn@umich.edu '''optstep : STEP expr 1844479Sbinkertn@umich.edu | empty''' 1854479Sbinkertn@umich.edu if len(p) == 3: 1864479Sbinkertn@umich.edu p[0] = p[2] 1874479Sbinkertn@umich.edu else: 1884479Sbinkertn@umich.edu p[0] = None 1894479Sbinkertn@umich.edu 1904479Sbinkertn@umich.edu#### NEXT statement 1914479Sbinkertn@umich.edu 1924479Sbinkertn@umich.edudef p_command_next(p): 1934479Sbinkertn@umich.edu '''command : NEXT ID''' 1944479Sbinkertn@umich.edu 1954479Sbinkertn@umich.edu p[0] = ('NEXT',p[2]) 1964479Sbinkertn@umich.edu 1974479Sbinkertn@umich.edudef p_command_next_bad(p): 1984479Sbinkertn@umich.edu '''command : NEXT error''' 1994479Sbinkertn@umich.edu p[0] = "MALFORMED NEXT" 2004479Sbinkertn@umich.edu 2014479Sbinkertn@umich.edu#### END statement 2024479Sbinkertn@umich.edu 2034479Sbinkertn@umich.edudef p_command_end(p): 2044479Sbinkertn@umich.edu '''command : END''' 2054479Sbinkertn@umich.edu p[0] = ('END',) 2064479Sbinkertn@umich.edu 2074479Sbinkertn@umich.edu#### REM statement 2084479Sbinkertn@umich.edu 2094479Sbinkertn@umich.edudef p_command_rem(p): 2104479Sbinkertn@umich.edu '''command : REM''' 2114479Sbinkertn@umich.edu p[0] = ('REM',p[1]) 2124479Sbinkertn@umich.edu 2134479Sbinkertn@umich.edu#### STOP statement 2144479Sbinkertn@umich.edu 2154479Sbinkertn@umich.edudef p_command_stop(p): 2164479Sbinkertn@umich.edu '''command : STOP''' 2174479Sbinkertn@umich.edu p[0] = ('STOP',) 2184479Sbinkertn@umich.edu 2194479Sbinkertn@umich.edu#### DEF statement 2204479Sbinkertn@umich.edu 2214479Sbinkertn@umich.edudef p_command_def(p): 2224479Sbinkertn@umich.edu '''command : DEF ID LPAREN ID RPAREN EQUALS expr''' 2234479Sbinkertn@umich.edu p[0] = ('FUNC',p[2],p[4],p[7]) 2244479Sbinkertn@umich.edu 2254479Sbinkertn@umich.edudef p_command_def_bad_rhs(p): 2264479Sbinkertn@umich.edu '''command : DEF ID LPAREN ID RPAREN EQUALS error''' 2274479Sbinkertn@umich.edu p[0] = "BAD EXPRESSION IN DEF STATEMENT" 2284479Sbinkertn@umich.edu 2294479Sbinkertn@umich.edudef p_command_def_bad_arg(p): 2304479Sbinkertn@umich.edu '''command : DEF ID LPAREN error RPAREN EQUALS expr''' 2314479Sbinkertn@umich.edu p[0] = "BAD ARGUMENT IN DEF STATEMENT" 2324479Sbinkertn@umich.edu 2334479Sbinkertn@umich.edu#### GOSUB statement 2344479Sbinkertn@umich.edu 2354479Sbinkertn@umich.edudef p_command_gosub(p): 2364479Sbinkertn@umich.edu '''command : GOSUB INTEGER''' 2374479Sbinkertn@umich.edu p[0] = ('GOSUB',int(p[2])) 2384479Sbinkertn@umich.edu 2394479Sbinkertn@umich.edudef p_command_gosub_bad(p): 2404479Sbinkertn@umich.edu '''command : GOSUB error''' 2414479Sbinkertn@umich.edu p[0] = "INVALID LINE NUMBER IN GOSUB" 2424479Sbinkertn@umich.edu 2434479Sbinkertn@umich.edu#### RETURN statement 2444479Sbinkertn@umich.edu 2454479Sbinkertn@umich.edudef p_command_return(p): 2464479Sbinkertn@umich.edu '''command : RETURN''' 2474479Sbinkertn@umich.edu p[0] = ('RETURN',) 2484479Sbinkertn@umich.edu 2494479Sbinkertn@umich.edu#### DIM statement 2504479Sbinkertn@umich.edu 2514479Sbinkertn@umich.edudef p_command_dim(p): 2524479Sbinkertn@umich.edu '''command : DIM dimlist''' 2534479Sbinkertn@umich.edu p[0] = ('DIM',p[2]) 2544479Sbinkertn@umich.edu 2554479Sbinkertn@umich.edudef p_command_dim_bad(p): 2564479Sbinkertn@umich.edu '''command : DIM error''' 2574479Sbinkertn@umich.edu p[0] = "MALFORMED VARIABLE LIST IN DIM" 2584479Sbinkertn@umich.edu 2594479Sbinkertn@umich.edu#### List of variables supplied to DIM statement 2604479Sbinkertn@umich.edu 2614479Sbinkertn@umich.edudef p_dimlist(p): 2624479Sbinkertn@umich.edu '''dimlist : dimlist COMMA dimitem 2634479Sbinkertn@umich.edu | dimitem''' 2644479Sbinkertn@umich.edu if len(p) == 4: 2654479Sbinkertn@umich.edu p[0] = p[1] 2664479Sbinkertn@umich.edu p[0].append(p[3]) 2674479Sbinkertn@umich.edu else: 2684479Sbinkertn@umich.edu p[0] = [p[1]] 2694479Sbinkertn@umich.edu 2704479Sbinkertn@umich.edu#### DIM items 2714479Sbinkertn@umich.edu 2724479Sbinkertn@umich.edudef p_dimitem_single(p): 2734479Sbinkertn@umich.edu '''dimitem : ID LPAREN INTEGER RPAREN''' 2744479Sbinkertn@umich.edu p[0] = (p[1],eval(p[3]),0) 2754479Sbinkertn@umich.edu 2764479Sbinkertn@umich.edudef p_dimitem_double(p): 2774479Sbinkertn@umich.edu '''dimitem : ID LPAREN INTEGER COMMA INTEGER RPAREN''' 2784479Sbinkertn@umich.edu p[0] = (p[1],eval(p[3]),eval(p[5])) 2794479Sbinkertn@umich.edu 2804479Sbinkertn@umich.edu#### Arithmetic expressions 2814479Sbinkertn@umich.edu 2824479Sbinkertn@umich.edudef p_expr_binary(p): 2834479Sbinkertn@umich.edu '''expr : expr PLUS expr 2844479Sbinkertn@umich.edu | expr MINUS expr 2854479Sbinkertn@umich.edu | expr TIMES expr 2864479Sbinkertn@umich.edu | expr DIVIDE expr 2874479Sbinkertn@umich.edu | expr POWER expr''' 2884479Sbinkertn@umich.edu 2894479Sbinkertn@umich.edu p[0] = ('BINOP',p[2],p[1],p[3]) 2904479Sbinkertn@umich.edu 2914479Sbinkertn@umich.edudef p_expr_number(p): 2924479Sbinkertn@umich.edu '''expr : INTEGER 2934479Sbinkertn@umich.edu | FLOAT''' 2944479Sbinkertn@umich.edu p[0] = ('NUM',eval(p[1])) 2954479Sbinkertn@umich.edu 2964479Sbinkertn@umich.edudef p_expr_variable(p): 2974479Sbinkertn@umich.edu '''expr : variable''' 2984479Sbinkertn@umich.edu p[0] = ('VAR',p[1]) 2994479Sbinkertn@umich.edu 3004479Sbinkertn@umich.edudef p_expr_group(p): 3014479Sbinkertn@umich.edu '''expr : LPAREN expr RPAREN''' 3024479Sbinkertn@umich.edu p[0] = ('GROUP',p[2]) 3034479Sbinkertn@umich.edu 3044479Sbinkertn@umich.edudef p_expr_unary(p): 3054479Sbinkertn@umich.edu '''expr : MINUS expr %prec UMINUS''' 3064479Sbinkertn@umich.edu p[0] = ('UNARY','-',p[2]) 3074479Sbinkertn@umich.edu 3084479Sbinkertn@umich.edu#### Relational expressions 3094479Sbinkertn@umich.edu 3104479Sbinkertn@umich.edudef p_relexpr(p): 3114479Sbinkertn@umich.edu '''relexpr : expr LT expr 3124479Sbinkertn@umich.edu | expr LE expr 3134479Sbinkertn@umich.edu | expr GT expr 3144479Sbinkertn@umich.edu | expr GE expr 3154479Sbinkertn@umich.edu | expr EQUALS expr 3164479Sbinkertn@umich.edu | expr NE expr''' 3174479Sbinkertn@umich.edu p[0] = ('RELOP',p[2],p[1],p[3]) 3184479Sbinkertn@umich.edu 3194479Sbinkertn@umich.edu#### Variables 3204479Sbinkertn@umich.edu 3214479Sbinkertn@umich.edudef p_variable(p): 3224479Sbinkertn@umich.edu '''variable : ID 3234479Sbinkertn@umich.edu | ID LPAREN expr RPAREN 3244479Sbinkertn@umich.edu | ID LPAREN expr COMMA expr RPAREN''' 3254479Sbinkertn@umich.edu if len(p) == 2: 3264479Sbinkertn@umich.edu p[0] = (p[1],None,None) 3274479Sbinkertn@umich.edu elif len(p) == 5: 3284479Sbinkertn@umich.edu p[0] = (p[1],p[3],None) 3294479Sbinkertn@umich.edu else: 3304479Sbinkertn@umich.edu p[0] = (p[1],p[3],p[5]) 3314479Sbinkertn@umich.edu 3324479Sbinkertn@umich.edu#### Builds a list of variable targets as a Python list 3334479Sbinkertn@umich.edu 3344479Sbinkertn@umich.edudef p_varlist(p): 3354479Sbinkertn@umich.edu '''varlist : varlist COMMA variable 3364479Sbinkertn@umich.edu | variable''' 3374479Sbinkertn@umich.edu if len(p) > 2: 3384479Sbinkertn@umich.edu p[0] = p[1] 3394479Sbinkertn@umich.edu p[0].append(p[3]) 3404479Sbinkertn@umich.edu else: 3414479Sbinkertn@umich.edu p[0] = [p[1]] 3424479Sbinkertn@umich.edu 3434479Sbinkertn@umich.edu 3444479Sbinkertn@umich.edu#### Builds a list of numbers as a Python list 3454479Sbinkertn@umich.edu 3464479Sbinkertn@umich.edudef p_numlist(p): 3474479Sbinkertn@umich.edu '''numlist : numlist COMMA number 3484479Sbinkertn@umich.edu | number''' 3494479Sbinkertn@umich.edu 3504479Sbinkertn@umich.edu if len(p) > 2: 3514479Sbinkertn@umich.edu p[0] = p[1] 3524479Sbinkertn@umich.edu p[0].append(p[3]) 3534479Sbinkertn@umich.edu else: 3544479Sbinkertn@umich.edu p[0] = [p[1]] 3554479Sbinkertn@umich.edu 3564479Sbinkertn@umich.edu#### A number. May be an integer or a float 3574479Sbinkertn@umich.edu 3584479Sbinkertn@umich.edudef p_number(p): 3594479Sbinkertn@umich.edu '''number : INTEGER 3604479Sbinkertn@umich.edu | FLOAT''' 3614479Sbinkertn@umich.edu p[0] = eval(p[1]) 3624479Sbinkertn@umich.edu 3634479Sbinkertn@umich.edu#### A signed number. 3644479Sbinkertn@umich.edu 3654479Sbinkertn@umich.edudef p_number_signed(p): 3664479Sbinkertn@umich.edu '''number : MINUS INTEGER 3674479Sbinkertn@umich.edu | MINUS FLOAT''' 3684479Sbinkertn@umich.edu p[0] = eval("-"+p[2]) 3694479Sbinkertn@umich.edu 3704479Sbinkertn@umich.edu#### List of targets for a print statement 3714479Sbinkertn@umich.edu#### Returns a list of tuples (label,expr) 3724479Sbinkertn@umich.edu 3734479Sbinkertn@umich.edudef p_plist(p): 3744479Sbinkertn@umich.edu '''plist : plist COMMA pitem 3754479Sbinkertn@umich.edu | pitem''' 3764479Sbinkertn@umich.edu if len(p) > 3: 3774479Sbinkertn@umich.edu p[0] = p[1] 3784479Sbinkertn@umich.edu p[0].append(p[3]) 3794479Sbinkertn@umich.edu else: 3804479Sbinkertn@umich.edu p[0] = [p[1]] 3814479Sbinkertn@umich.edu 3824479Sbinkertn@umich.edudef p_item_string(p): 3834479Sbinkertn@umich.edu '''pitem : STRING''' 3844479Sbinkertn@umich.edu p[0] = (p[1][1:-1],None) 3854479Sbinkertn@umich.edu 3864479Sbinkertn@umich.edudef p_item_string_expr(p): 3874479Sbinkertn@umich.edu '''pitem : STRING expr''' 3884479Sbinkertn@umich.edu p[0] = (p[1][1:-1],p[2]) 3894479Sbinkertn@umich.edu 3904479Sbinkertn@umich.edudef p_item_expr(p): 3914479Sbinkertn@umich.edu '''pitem : expr''' 3924479Sbinkertn@umich.edu p[0] = ("",p[1]) 3934479Sbinkertn@umich.edu 3944479Sbinkertn@umich.edu#### Empty 3954479Sbinkertn@umich.edu 3964479Sbinkertn@umich.edudef p_empty(p): 3974479Sbinkertn@umich.edu '''empty : ''' 3984479Sbinkertn@umich.edu 3994479Sbinkertn@umich.edu#### Catastrophic error handler 4004479Sbinkertn@umich.edudef p_error(p): 4014479Sbinkertn@umich.edu if not p: 4024479Sbinkertn@umich.edu print "SYNTAX ERROR AT EOF" 4034479Sbinkertn@umich.edu 4044479Sbinkertn@umich.edubparser = yacc.yacc() 4054479Sbinkertn@umich.edu 4064479Sbinkertn@umich.edudef parse(data): 4074479Sbinkertn@umich.edu bparser.error = 0 4084479Sbinkertn@umich.edu p = bparser.parse(data) 4094479Sbinkertn@umich.edu if bparser.error: return None 4104479Sbinkertn@umich.edu return p 4114479Sbinkertn@umich.edu 4124479Sbinkertn@umich.edu 4134479Sbinkertn@umich.edu 4144479Sbinkertn@umich.edu 4154479Sbinkertn@umich.edu 4164479Sbinkertn@umich.edu 4174479Sbinkertn@umich.edu 4184479Sbinkertn@umich.edu 4194479Sbinkertn@umich.edu 4204479Sbinkertn@umich.edu 4214479Sbinkertn@umich.edu 4224479Sbinkertn@umich.edu 4234479Sbinkertn@umich.edu 4244479Sbinkertn@umich.edu 425