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# Modified to use new-style classes. Test case. 12# ----------------------------------------------------------------------------- 13 14import sys 15sys.path.insert(0,"../..") 16 | 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# Modified to use new-style classes. Test case. 12# ----------------------------------------------------------------------------- 13 14import sys 15sys.path.insert(0,"../..") 16 |
17import readline | 17if sys.version_info[0] >= 3: 18 raw_input = input 19 |
18import ply.lex as lex 19import ply.yacc as yacc 20import os 21 22class Parser(object): 23 """ 24 Base class for a lexer/parser that has the rules defined as methods 25 """ --- 20 unchanged lines hidden (view full) --- 46 tabmodule=self.tabmodule) 47 48 def run(self): 49 while 1: 50 try: 51 s = raw_input('calc > ') 52 except EOFError: 53 break | 20import ply.lex as lex 21import ply.yacc as yacc 22import os 23 24class Parser(object): 25 """ 26 Base class for a lexer/parser that has the rules defined as methods 27 """ --- 20 unchanged lines hidden (view full) --- 48 tabmodule=self.tabmodule) 49 50 def run(self): 51 while 1: 52 try: 53 s = raw_input('calc > ') 54 except EOFError: 55 break |
54 if not s: continue | 56 if not s: continue |
55 yacc.parse(s) 56 | 57 yacc.parse(s) 58 |
57 | 59 |
58class Calc(Parser): 59 60 tokens = ( 61 'NAME','NUMBER', 62 'PLUS','MINUS','EXP', 'TIMES','DIVIDE','EQUALS', 63 'LPAREN','RPAREN', 64 ) 65 --- 9 unchanged lines hidden (view full) --- 75 t_RPAREN = r'\)' 76 t_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*' 77 78 def t_NUMBER(self, t): 79 r'\d+' 80 try: 81 t.value = int(t.value) 82 except ValueError: | 60class Calc(Parser): 61 62 tokens = ( 63 'NAME','NUMBER', 64 'PLUS','MINUS','EXP', 'TIMES','DIVIDE','EQUALS', 65 'LPAREN','RPAREN', 66 ) 67 --- 9 unchanged lines hidden (view full) --- 77 t_RPAREN = r'\)' 78 t_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*' 79 80 def t_NUMBER(self, t): 81 r'\d+' 82 try: 83 t.value = int(t.value) 84 except ValueError: |
83 print "Integer value too large", t.value | 85 print("Integer value too large %s" % t.value) |
84 t.value = 0 85 #print "parsed number %s" % repr(t.value) 86 return t 87 88 t_ignore = " \t" 89 90 def t_newline(self, t): 91 r'\n+' 92 t.lexer.lineno += t.value.count("\n") | 86 t.value = 0 87 #print "parsed number %s" % repr(t.value) 88 return t 89 90 t_ignore = " \t" 91 92 def t_newline(self, t): 93 r'\n+' 94 t.lexer.lineno += t.value.count("\n") |
93 | 95 |
94 def t_error(self, t): | 96 def t_error(self, t): |
95 print "Illegal character '%s'" % t.value[0] | 97 print("Illegal character '%s'" % t.value[0]) |
96 t.lexer.skip(1) 97 98 # Parsing rules 99 100 precedence = ( 101 ('left','PLUS','MINUS'), 102 ('left','TIMES','DIVIDE'), 103 ('left', 'EXP'), 104 ('right','UMINUS'), 105 ) 106 107 def p_statement_assign(self, p): 108 'statement : NAME EQUALS expression' 109 self.names[p[1]] = p[3] 110 111 def p_statement_expr(self, p): 112 'statement : expression' | 98 t.lexer.skip(1) 99 100 # Parsing rules 101 102 precedence = ( 103 ('left','PLUS','MINUS'), 104 ('left','TIMES','DIVIDE'), 105 ('left', 'EXP'), 106 ('right','UMINUS'), 107 ) 108 109 def p_statement_assign(self, p): 110 'statement : NAME EQUALS expression' 111 self.names[p[1]] = p[3] 112 113 def p_statement_expr(self, p): 114 'statement : expression' |
113 print p[1] | 115 print(p[1]) |
114 115 def p_expression_binop(self, p): 116 """ 117 expression : expression PLUS expression 118 | expression MINUS expression 119 | expression TIMES expression 120 | expression DIVIDE expression 121 | expression EXP expression --- 17 unchanged lines hidden (view full) --- 139 'expression : NUMBER' 140 p[0] = p[1] 141 142 def p_expression_name(self, p): 143 'expression : NAME' 144 try: 145 p[0] = self.names[p[1]] 146 except LookupError: | 116 117 def p_expression_binop(self, p): 118 """ 119 expression : expression PLUS expression 120 | expression MINUS expression 121 | expression TIMES expression 122 | expression DIVIDE expression 123 | expression EXP expression --- 17 unchanged lines hidden (view full) --- 141 'expression : NUMBER' 142 p[0] = p[1] 143 144 def p_expression_name(self, p): 145 'expression : NAME' 146 try: 147 p[0] = self.names[p[1]] 148 except LookupError: |
147 print "Undefined name '%s'" % p[1] | 149 print("Undefined name '%s'" % p[1]) |
148 p[0] = 0 149 150 def p_error(self, p): | 150 p[0] = 0 151 152 def p_error(self, p): |
151 print "Syntax error at '%s'" % p.value | 153 if p: 154 print("Syntax error at '%s'" % p.value) 155 else: 156 print("Syntax error at EOF") |
152 153if __name__ == '__main__': 154 calc = Calc() 155 calc.run() | 157 158if __name__ == '__main__': 159 calc = Calc() 160 calc.run() |