Update to ply 2.3
[gem5.git] / ext / ply / example / optcalc / calc.py
1 # -----------------------------------------------------------------------------
2 # calc.py
3 #
4 # A simple calculator with variables. This is from O'Reilly's
5 # "Lex and Yacc", p. 63.
6 # -----------------------------------------------------------------------------
7
8 import sys
9 sys.path.insert(0,"../..")
10
11 tokens = (
12 'NAME','NUMBER',
13 'PLUS','MINUS','TIMES','DIVIDE','EQUALS',
14 'LPAREN','RPAREN',
15 )
16
17 # Tokens
18
19 t_PLUS = r'\+'
20 t_MINUS = r'-'
21 t_TIMES = r'\*'
22 t_DIVIDE = r'/'
23 t_EQUALS = r'='
24 t_LPAREN = r'\('
25 t_RPAREN = r'\)'
26 t_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*'
27
28 def t_NUMBER(t):
29 r'\d+'
30 try:
31 t.value = int(t.value)
32 except ValueError:
33 print "Integer value too large", t.value
34 t.value = 0
35 return t
36
37 t_ignore = " \t"
38
39 def t_newline(t):
40 r'\n+'
41 t.lexer.lineno += t.value.count("\n")
42
43 def t_error(t):
44 print "Illegal character '%s'" % t.value[0]
45 t.lexer.skip(1)
46
47 # Build the lexer
48 import ply.lex as lex
49 lex.lex(optimize=1)
50
51 # Parsing rules
52
53 precedence = (
54 ('left','PLUS','MINUS'),
55 ('left','TIMES','DIVIDE'),
56 ('right','UMINUS'),
57 )
58
59 # dictionary of names
60 names = { }
61
62 def p_statement_assign(t):
63 'statement : NAME EQUALS expression'
64 names[t[1]] = t[3]
65
66 def p_statement_expr(t):
67 'statement : expression'
68 print t[1]
69
70 def p_expression_binop(t):
71 '''expression : expression PLUS expression
72 | expression MINUS expression
73 | expression TIMES expression
74 | expression DIVIDE expression'''
75 if t[2] == '+' : t[0] = t[1] + t[3]
76 elif t[2] == '-': t[0] = t[1] - t[3]
77 elif t[2] == '*': t[0] = t[1] * t[3]
78 elif t[2] == '/': t[0] = t[1] / t[3]
79 elif t[2] == '<': t[0] = t[1] < t[3]
80
81 def p_expression_uminus(t):
82 'expression : MINUS expression %prec UMINUS'
83 t[0] = -t[2]
84
85 def p_expression_group(t):
86 'expression : LPAREN expression RPAREN'
87 t[0] = t[2]
88
89 def p_expression_number(t):
90 'expression : NUMBER'
91 t[0] = t[1]
92
93 def p_expression_name(t):
94 'expression : NAME'
95 try:
96 t[0] = names[t[1]]
97 except LookupError:
98 print "Undefined name '%s'" % t[1]
99 t[0] = 0
100
101 def p_error(t):
102 print "Syntax error at '%s'" % t.value
103
104 import ply.yacc as yacc
105 yacc.yacc(optimize=1)
106
107 while 1:
108 try:
109 s = raw_input('calc > ')
110 except EOFError:
111 break
112 yacc.parse(s)
113