Home | History | Annotate | Download | only in calcdebug
      1 # -----------------------------------------------------------------------------
      2 # calc.py
      3 #
      4 # This example shows how to run the parser in a debugging mode
      5 # with output routed to a logging object.
      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 )
     17 
     18 literals = ['=', '+', '-', '*', '/', '(', ')']
     19 
     20 # Tokens
     21 
     22 t_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*'
     23 
     24 
     25 def t_NUMBER(t):
     26     r'\d+'
     27     t.value = int(t.value)
     28     return t
     29 
     30 t_ignore = " \t"
     31 
     32 
     33 def t_newline(t):
     34     r'\n+'
     35     t.lexer.lineno += t.value.count("\n")
     36 
     37 
     38 def t_error(t):
     39     print("Illegal character '%s'" % t.value[0])
     40     t.lexer.skip(1)
     41 
     42 # Build the lexer
     43 import ply.lex as lex
     44 lex.lex()
     45 
     46 # Parsing rules
     47 
     48 precedence = (
     49     ('left', '+', '-'),
     50     ('left', '*', '/'),
     51     ('right', 'UMINUS'),
     52 )
     53 
     54 # dictionary of names
     55 names = {}
     56 
     57 
     58 def p_statement_assign(p):
     59     'statement : NAME "=" expression'
     60     names[p[1]] = p[3]
     61 
     62 
     63 def p_statement_expr(p):
     64     'statement : expression'
     65     print(p[1])
     66 
     67 
     68 def p_expression_binop(p):
     69     '''expression : expression '+' expression
     70                   | expression '-' expression
     71                   | expression '*' expression
     72                   | expression '/' expression'''
     73     if p[2] == '+':
     74         p[0] = p[1] + p[3]
     75     elif p[2] == '-':
     76         p[0] = p[1] - p[3]
     77     elif p[2] == '*':
     78         p[0] = p[1] * p[3]
     79     elif p[2] == '/':
     80         p[0] = p[1] / p[3]
     81 
     82 
     83 def p_expression_uminus(p):
     84     "expression : '-' expression %prec UMINUS"
     85     p[0] = -p[2]
     86 
     87 
     88 def p_expression_group(p):
     89     "expression : '(' expression ')'"
     90     p[0] = p[2]
     91 
     92 
     93 def p_expression_number(p):
     94     "expression : NUMBER"
     95     p[0] = p[1]
     96 
     97 
     98 def p_expression_name(p):
     99     "expression : NAME"
    100     try:
    101         p[0] = names[p[1]]
    102     except LookupError:
    103         print("Undefined name '%s'" % p[1])
    104         p[0] = 0
    105 
    106 
    107 def p_error(p):
    108     if p:
    109         print("Syntax error at '%s'" % p.value)
    110     else:
    111         print("Syntax error at EOF")
    112 
    113 import ply.yacc as yacc
    114 yacc.yacc()
    115 
    116 import logging
    117 logging.basicConfig(
    118     level=logging.INFO,
    119     filename="parselog.txt"
    120 )
    121 
    122 while 1:
    123     try:
    124         s = raw_input('calc > ')
    125     except EOFError:
    126         break
    127     if not s:
    128         continue
    129     yacc.parse(s, debug=logging.getLogger())
    130