calc.py (4479:61d3ed46e373) | calc.py (6498:e21e9ab5fad0) |
---|---|
1#!/usr/bin/env python 2 3# ----------------------------------------------------------------------------- 4# calc.py 5# 6# A simple calculator with variables. This is from O'Reilly's 7# "Lex and Yacc", p. 63. 8# 9# Class-based example contributed to PLY by David McNab 10# ----------------------------------------------------------------------------- 11 12import sys 13sys.path.insert(0,"../..") 14 | 1#!/usr/bin/env python 2 3# ----------------------------------------------------------------------------- 4# calc.py 5# 6# A simple calculator with variables. This is from O'Reilly's 7# "Lex and Yacc", p. 63. 8# 9# Class-based example contributed to PLY by David McNab 10# ----------------------------------------------------------------------------- 11 12import sys 13sys.path.insert(0,"../..") 14 |
15import readline | 15if sys.version_info[0] >= 3: 16 raw_input = input 17 |
16import ply.lex as lex 17import ply.yacc as yacc 18import os 19 20class Parser: 21 """ 22 Base class for a lexer/parser that has the rules defined as methods 23 """ --- 22 unchanged lines hidden (view full) --- 46 while 1: 47 try: 48 s = raw_input('calc > ') 49 except EOFError: 50 break 51 if not s: continue 52 yacc.parse(s) 53 | 18import ply.lex as lex 19import ply.yacc as yacc 20import os 21 22class Parser: 23 """ 24 Base class for a lexer/parser that has the rules defined as methods 25 """ --- 22 unchanged lines hidden (view full) --- 48 while 1: 49 try: 50 s = raw_input('calc > ') 51 except EOFError: 52 break 53 if not s: continue 54 yacc.parse(s) 55 |
54 | 56 |
55class Calc(Parser): 56 57 tokens = ( 58 'NAME','NUMBER', 59 'PLUS','MINUS','EXP', 'TIMES','DIVIDE','EQUALS', 60 'LPAREN','RPAREN', 61 ) 62 --- 9 unchanged lines hidden (view full) --- 72 t_RPAREN = r'\)' 73 t_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*' 74 75 def t_NUMBER(self, t): 76 r'\d+' 77 try: 78 t.value = int(t.value) 79 except ValueError: | 57class Calc(Parser): 58 59 tokens = ( 60 'NAME','NUMBER', 61 'PLUS','MINUS','EXP', 'TIMES','DIVIDE','EQUALS', 62 'LPAREN','RPAREN', 63 ) 64 --- 9 unchanged lines hidden (view full) --- 74 t_RPAREN = r'\)' 75 t_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*' 76 77 def t_NUMBER(self, t): 78 r'\d+' 79 try: 80 t.value = int(t.value) 81 except ValueError: |
80 print "Integer value too large", t.value | 82 print("Integer value too large %s" % t.value) |
81 t.value = 0 82 #print "parsed number %s" % repr(t.value) 83 return t 84 85 t_ignore = " \t" 86 87 def t_newline(self, t): 88 r'\n+' 89 t.lexer.lineno += t.value.count("\n") | 83 t.value = 0 84 #print "parsed number %s" % repr(t.value) 85 return t 86 87 t_ignore = " \t" 88 89 def t_newline(self, t): 90 r'\n+' 91 t.lexer.lineno += t.value.count("\n") |
90 | 92 |
91 def t_error(self, t): | 93 def t_error(self, t): |
92 print "Illegal character '%s'" % t.value[0] | 94 print("Illegal character '%s'" % t.value[0]) |
93 t.lexer.skip(1) 94 95 # Parsing rules 96 97 precedence = ( 98 ('left','PLUS','MINUS'), 99 ('left','TIMES','DIVIDE'), 100 ('left', 'EXP'), 101 ('right','UMINUS'), 102 ) 103 104 def p_statement_assign(self, p): 105 'statement : NAME EQUALS expression' 106 self.names[p[1]] = p[3] 107 108 def p_statement_expr(self, p): 109 'statement : expression' | 95 t.lexer.skip(1) 96 97 # Parsing rules 98 99 precedence = ( 100 ('left','PLUS','MINUS'), 101 ('left','TIMES','DIVIDE'), 102 ('left', 'EXP'), 103 ('right','UMINUS'), 104 ) 105 106 def p_statement_assign(self, p): 107 'statement : NAME EQUALS expression' 108 self.names[p[1]] = p[3] 109 110 def p_statement_expr(self, p): 111 'statement : expression' |
110 print p[1] | 112 print(p[1]) |
111 112 def p_expression_binop(self, p): 113 """ 114 expression : expression PLUS expression 115 | expression MINUS expression 116 | expression TIMES expression 117 | expression DIVIDE expression 118 | expression EXP expression --- 17 unchanged lines hidden (view full) --- 136 'expression : NUMBER' 137 p[0] = p[1] 138 139 def p_expression_name(self, p): 140 'expression : NAME' 141 try: 142 p[0] = self.names[p[1]] 143 except LookupError: | 113 114 def p_expression_binop(self, p): 115 """ 116 expression : expression PLUS expression 117 | expression MINUS expression 118 | expression TIMES expression 119 | expression DIVIDE expression 120 | expression EXP expression --- 17 unchanged lines hidden (view full) --- 138 'expression : NUMBER' 139 p[0] = p[1] 140 141 def p_expression_name(self, p): 142 'expression : NAME' 143 try: 144 p[0] = self.names[p[1]] 145 except LookupError: |
144 print "Undefined name '%s'" % p[1] | 146 print("Undefined name '%s'" % p[1]) |
145 p[0] = 0 146 147 def p_error(self, p): | 147 p[0] = 0 148 149 def p_error(self, p): |
148 print "Syntax error at '%s'" % p.value | 150 if p: 151 print("Syntax error at '%s'" % p.value) 152 else: 153 print("Syntax error at EOF") |
149 150if __name__ == '__main__': 151 calc = Calc() 152 calc.run() | 154 155if __name__ == '__main__': 156 calc = Calc() 157 calc.run() |