#!/usr/bin/env python
-# -----------------------------------------------------------------------------
-# calc.py
-#
-# A simple calculator with variables. This is from O'Reilly's
-# "Lex and Yacc", p. 63.
-# -----------------------------------------------------------------------------
tokens = (
- 'NAME','NUMBER',
- 'PLUS','MINUS','TIMES','DIVIDE','EQUALS',
+ 'NAME','INTEGER', 'FLOAT',
'LPAREN','RPAREN',
+ 'PLUS','MINUS','TIMES','DIVIDE','EQUALS',
+ 'NOT', 'OR', 'AND', 'THEN', 'EQV',
)
# Tokens
+t_NOT = r'\.NOT\.'
+t_OR = r'\.OR\.'
+t_AND = r'\.AND\.'
+t_THEN = r'\.OR\.'
+t_EQV = r'\.EQV\.'
t_PLUS = r'\+'
t_MINUS = r'-'
t_TIMES = r'\*'
t_LPAREN = r'\('
t_RPAREN = r'\)'
t_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*'
+t_FLOAT = r'\d+\.\d*'
+t_INTEGER = r'\d+'
-def t_NUMBER(t):
- r'\d+'
- try:
- t.value = int(t.value)
- except ValueError:
- print "Integer value too large", t.value
- t.value = 0
- return t
-
-t_ignore = " \t"
+t_ignore = " "
def t_newline(t):
r'\n+'
# Parsing rules
precedence = (
+ ('left','EQV'),
+ ('left','THEN'),
+ ('left','OR'),
+ ('left','AND'),
+ ('right','NOT'),
('left','PLUS','MINUS'),
('left','TIMES','DIVIDE'),
('right','UMINUS'),
def p_statement_assign(t):
'statement : NAME EQUALS expression'
t[0] = ('substitution', t[1], t[3])
+ print t[0]
def p_statement_expr(t):
'statement : expression'
t[0] = t[1]
print t[0]
-def p_expression_binop(t):
+def p_expression_binop1(t):
'''expression : expression PLUS expression
| expression MINUS expression
| expression TIMES expression
| expression DIVIDE expression'''
- t[0] = (t[2], t[1], t[3])
+ t[0] = (t[2].lower(), t[1], t[3])
+
+def p_expression_binop2(t):
+ '''expression : expression OR expression
+ | expression AND expression
+ | expression THEN expression
+ | expression EQV expression'''
+ t[0] = (t[2][1:-1].lower(), t[1], t[3])
+
+def p_expression_not(t):
+ 'expression : NOT expression %prec NOT'
+ t[0] = ('not', t[2])
def p_expression_uminus(t):
'expression : MINUS expression %prec UMINUS'
'expression : LPAREN expression RPAREN'
t[0] = t[2]
-def p_expression_number(t):
- 'expression : NUMBER'
- t[0] = t[1]
+def p_expression_integer(t):
+ 'expression : INTEGER'
+ t[0] = ('integer', t[1])
+
+def p_expression_float(t):
+ 'expression : FLOAT'
+ t[0] = ('float', t[1])
def p_expression_name(t):
'expression : NAME'
- t[0] = t[1]
+ t[0] = ('variable', t[1])
def p_error(t):
print "Syntax error at '%s'" % t.value