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()