cscg24-lolpython

CSCG 2024 Challenge 'Can I Haz Lolpython?'
git clone https://git.sinitax.com/sinitax/cscg24-lolpython
Log | Files | Refs | sfeed.txt

calc.py (2384B)


      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
      8import sys
      9sys.path.insert(0,"../..")
     10
     11tokens = (
     12    'NAME','NUMBER',
     13    'PLUS','MINUS','TIMES','DIVIDE','EQUALS',
     14    'LPAREN','RPAREN',
     15    )
     16
     17# Tokens
     18
     19t_PLUS    = r'\+'
     20t_MINUS   = r'-'
     21t_TIMES   = r'\*'
     22t_DIVIDE  = r'/'
     23t_EQUALS  = r'='
     24t_LPAREN  = r'\('
     25t_RPAREN  = r'\)'
     26t_NAME    = r'[a-zA-Z_][a-zA-Z0-9_]*'
     27
     28def 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
     37t_ignore = " \t"
     38
     39def t_newline(t):
     40    r'\n+'
     41    t.lexer.lineno += t.value.count("\n")
     42    
     43def t_error(t):
     44    print "Illegal character '%s'" % t.value[0]
     45    t.lexer.skip(1)
     46    
     47# Build the lexer
     48import ply.lex as lex
     49lex.lex(optimize=1)
     50
     51# Parsing rules
     52
     53precedence = (
     54    ('left','PLUS','MINUS'),
     55    ('left','TIMES','DIVIDE'),
     56    ('right','UMINUS'),
     57    )
     58
     59# dictionary of names
     60names = { }
     61
     62def p_statement_assign(t):
     63    'statement : NAME EQUALS expression'
     64    names[t[1]] = t[3]
     65
     66def p_statement_expr(t):
     67    'statement : expression'
     68    print t[1]
     69
     70def 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
     81def p_expression_uminus(t):
     82    'expression : MINUS expression %prec UMINUS'
     83    t[0] = -t[2]
     84
     85def p_expression_group(t):
     86    'expression : LPAREN expression RPAREN'
     87    t[0] = t[2]
     88
     89def p_expression_number(t):
     90    'expression : NUMBER'
     91    t[0] = t[1]
     92
     93def 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
    101def p_error(t):
    102    print "Syntax error at '%s'" % t.value
    103
    104import ply.yacc as yacc
    105yacc.yacc(optimize=1)
    106
    107while 1:
    108    try:
    109        s = raw_input('calc > ')
    110    except EOFError:
    111        break
    112    yacc.parse(s)
    113