diff options
Diffstat (limited to 'example/optcalc/calc.py')
-rw-r--r-- | example/optcalc/calc.py | 67 |
1 files changed, 41 insertions, 26 deletions
diff --git a/example/optcalc/calc.py b/example/optcalc/calc.py index dd83351..0c223e5 100644 --- a/example/optcalc/calc.py +++ b/example/optcalc/calc.py @@ -6,27 +6,28 @@ # ----------------------------------------------------------------------------- import sys -sys.path.insert(0,"../..") +sys.path.insert(0, "../..") if sys.version_info[0] >= 3: raw_input = input tokens = ( - 'NAME','NUMBER', - 'PLUS','MINUS','TIMES','DIVIDE','EQUALS', - 'LPAREN','RPAREN', - ) + 'NAME', 'NUMBER', + 'PLUS', 'MINUS', 'TIMES', 'DIVIDE', 'EQUALS', + 'LPAREN', 'RPAREN', +) # Tokens -t_PLUS = r'\+' -t_MINUS = r'-' -t_TIMES = r'\*' -t_DIVIDE = r'/' -t_EQUALS = r'=' -t_LPAREN = r'\(' -t_RPAREN = r'\)' -t_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*' +t_PLUS = r'\+' +t_MINUS = r'-' +t_TIMES = r'\*' +t_DIVIDE = r'/' +t_EQUALS = r'=' +t_LPAREN = r'\(' +t_RPAREN = r'\)' +t_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*' + def t_NUMBER(t): r'\d+' @@ -39,14 +40,16 @@ def t_NUMBER(t): t_ignore = " \t" + def t_newline(t): r'\n+' t.lexer.lineno += t.value.count("\n") - + + def t_error(t): print("Illegal character '%s'" % t.value[0]) t.lexer.skip(1) - + # Build the lexer import ply.lex as lex lex.lex(optimize=1) @@ -54,45 +57,57 @@ lex.lex(optimize=1) # Parsing rules precedence = ( - ('left','PLUS','MINUS'), - ('left','TIMES','DIVIDE'), - ('right','UMINUS'), - ) + ('left', 'PLUS', 'MINUS'), + ('left', 'TIMES', 'DIVIDE'), + ('right', 'UMINUS'), +) # dictionary of names -names = { } +names = {} + def p_statement_assign(t): 'statement : NAME EQUALS expression' names[t[1]] = t[3] + def p_statement_expr(t): 'statement : expression' print(t[1]) + def p_expression_binop(t): '''expression : expression PLUS expression | expression MINUS expression | expression TIMES expression | expression DIVIDE expression''' - if t[2] == '+' : t[0] = t[1] + t[3] - elif t[2] == '-': t[0] = t[1] - t[3] - elif t[2] == '*': t[0] = t[1] * t[3] - elif t[2] == '/': t[0] = t[1] / t[3] - elif t[2] == '<': t[0] = t[1] < t[3] + if t[2] == '+': + t[0] = t[1] + t[3] + elif t[2] == '-': + t[0] = t[1] - t[3] + elif t[2] == '*': + t[0] = t[1] * t[3] + elif t[2] == '/': + t[0] = t[1] / t[3] + elif t[2] == '<': + t[0] = t[1] < t[3] + def p_expression_uminus(t): 'expression : MINUS expression %prec UMINUS' t[0] = -t[2] + def p_expression_group(t): 'expression : LPAREN expression RPAREN' t[0] = t[2] + def p_expression_number(t): 'expression : NUMBER' t[0] = t[1] + def p_expression_name(t): 'expression : NAME' try: @@ -101,6 +116,7 @@ def p_expression_name(t): print("Undefined name '%s'" % t[1]) t[0] = 0 + def p_error(t): if t: print("Syntax error at '%s'" % t.value) @@ -116,4 +132,3 @@ while 1: except EOFError: break yacc.parse(s) - |