Home | History | Annotate | Download | only in test
      1 # -----------------------------------------------------------------------------
      2 # yacc_error5.py
      3 #
      4 # Lineno and position tracking with error tokens
      5 # -----------------------------------------------------------------------------
      6 import sys
      7 
      8 if ".." not in sys.path: sys.path.insert(0,"..")
      9 import ply.yacc as yacc
     10 
     11 from calclex import tokens
     12 
     13 # Parsing rules
     14 precedence = (
     15     ('left','PLUS','MINUS'),
     16     ('left','TIMES','DIVIDE'),
     17     ('right','UMINUS'),
     18     )
     19 
     20 # dictionary of names
     21 names = { }
     22 
     23 def p_statement_assign(t):
     24     'statement : NAME EQUALS expression'
     25     names[t[1]] = t[3]
     26 
     27 def p_statement_assign_error(t):
     28     'statement : NAME EQUALS error'
     29     line_start, line_end = t.linespan(3)
     30     pos_start, pos_end = t.lexspan(3)
     31     print("Assignment Error at %d:%d to %d:%d" % (line_start,pos_start,line_end,pos_end))
     32 
     33 def p_statement_expr(t):
     34     'statement : expression'
     35     print(t[1])
     36 
     37 def p_expression_binop(t):
     38     '''expression : expression PLUS expression
     39                   | expression MINUS expression
     40                   | expression TIMES expression
     41                   | expression DIVIDE expression'''
     42     if t[2] == '+'  : t[0] = t[1] + t[3]
     43     elif t[2] == '-': t[0] = t[1] - t[3]
     44     elif t[2] == '*': t[0] = t[1] * t[3]
     45     elif t[2] == '/': t[0] = t[1] / t[3]
     46 
     47 def p_expression_uminus(t):
     48     'expression : MINUS expression %prec UMINUS'
     49     t[0] = -t[2]
     50 
     51 def p_expression_group(t):
     52     'expression : LPAREN expression RPAREN'
     53     line_start, line_end = t.linespan(2)
     54     pos_start, pos_end = t.lexspan(2)
     55     print("Group at %d:%d to %d:%d" % (line_start,pos_start, line_end, pos_end))
     56     t[0] = t[2]
     57 
     58 def p_expression_group_error(t):
     59     'expression : LPAREN error RPAREN'
     60     line_start, line_end = t.linespan(2)
     61     pos_start, pos_end = t.lexspan(2)
     62     print("Syntax error at %d:%d to %d:%d" % (line_start,pos_start, line_end, pos_end))
     63     t[0] = 0
     64     
     65 def p_expression_number(t):
     66     'expression : NUMBER'
     67     t[0] = t[1]
     68 
     69 def p_expression_name(t):
     70     'expression : NAME'
     71     try:
     72         t[0] = names[t[1]]
     73     except LookupError:
     74         print("Undefined name '%s'" % t[1])
     75         t[0] = 0
     76 
     77 def p_error(t):
     78     print("Syntax error at '%s'" % t.value)
     79 
     80 parser = yacc.yacc()
     81 import calclex
     82 calclex.lexer.lineno=1
     83 parser.parse("""
     84 a = 3 +
     85 (4*5) +
     86 (a b c) +
     87 + 6 + 7
     88 """, tracking=True)
     89 
     90 
     91 
     92 
     93 
     94 
     95