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


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