# Yacc example import yacc # Get the token map from the lexer that we defined # earlier. This is required. from ourexlex import tokens __var_names = {} def p_assign_statement(t) : 'assign_statement : VAR EQUALS statement' __var_names[t[1]] = t[3] def p_statement_plus(t) : 'statement : statement ADDOP term' t[0] = t[1] + t[3] def p_statement_minus(t) : 'statement : statement SUBOP term' t[0] = t[1] - t[3] def p_statement_term(t) : 'statement : term' t[0] = t[1] def p_term_times(t) : 'term : term MULOP factor' t[0] = t[1] * t[3] def p_term_div(t) : 'term : term DIVOP factor' t[0] = t[1] / t[3] def p_term_factor(t) : 'term : factor' t[0] = t[1] def p_factor_num(t) : 'factor : NUM' t[0] = t[1] def p_factor_var(t) : 'factor : VAR' if __var_names.has_key(t[1]) : t[0] = __var_names[t[1]] else : print "Undefined Variable", t[1], "in line no.", t.lineno(1) def p_factor_expr(t): 'factor : LPAREN statement RPAREN' t[0] = t[2] # Error rule for syntax errors def p_error(t): print "Syntax error in input!" # Build the parser yacc.yacc() while 1: try: s = raw_input('enter > ') except EOFError: break if not s: continue yacc.parse(s)

Here each function accepts a single argument, t, which is a tuple. The values of t[i] are mapped to grammar symbols as shown here:


def p_statement_plus(t):
    'statement : statement ADDOP term'
    #   ^            ^        ^    ^
    #  t[0]         t[1]     t[2] t[3]

    t[0] = t[1] + t[3]