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


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