~ubuntu-branches/ubuntu/vivid/emscripten/vivid

« back to all changes in this revision

Viewing changes to third_party/ply/example/optcalc/calc.py

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-05-02 13:11:51 UTC
  • Revision ID: package-import@ubuntu.com-20130502131151-q8dvteqr1ef2x7xz
Tags: upstream-1.4.1~20130504~adb56cb
ImportĀ upstreamĀ versionĀ 1.4.1~20130504~adb56cb

Show diffs side-by-side

added added

removed removed

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