From: Eric S. Raymond Date: Wed, 14 Jan 2004 04:01:16 +0000 (+0000) Subject: Added logical expressions. X-Git-Tag: 1.0~205 X-Git-Url: http://thyrsus.com/gitweb/?a=commitdiff_plain;h=26d1be8b4e9fddf7a4034aeaac64c86eb8b6f88c;p=mad.git Added logical expressions. --- diff --git a/mad b/mad index d892624..f32c76c 100755 --- a/mad +++ b/mad @@ -1,19 +1,19 @@ #!/usr/bin/env python -# ----------------------------------------------------------------------------- -# calc.py -# -# A simple calculator with variables. This is from O'Reilly's -# "Lex and Yacc", p. 63. -# ----------------------------------------------------------------------------- tokens = ( - 'NAME','NUMBER', - 'PLUS','MINUS','TIMES','DIVIDE','EQUALS', + 'NAME','INTEGER', 'FLOAT', 'LPAREN','RPAREN', + 'PLUS','MINUS','TIMES','DIVIDE','EQUALS', + 'NOT', 'OR', 'AND', 'THEN', 'EQV', ) # Tokens +t_NOT = r'\.NOT\.' +t_OR = r'\.OR\.' +t_AND = r'\.AND\.' +t_THEN = r'\.OR\.' +t_EQV = r'\.EQV\.' t_PLUS = r'\+' t_MINUS = r'-' t_TIMES = r'\*' @@ -22,17 +22,10 @@ t_EQUALS = r'=' t_LPAREN = r'\(' t_RPAREN = r'\)' t_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*' +t_FLOAT = r'\d+\.\d*' +t_INTEGER = r'\d+' -def t_NUMBER(t): - r'\d+' - try: - t.value = int(t.value) - except ValueError: - print "Integer value too large", t.value - t.value = 0 - return t - -t_ignore = " \t" +t_ignore = " " def t_newline(t): r'\n+' @@ -49,6 +42,11 @@ lex.lex() # Parsing rules precedence = ( + ('left','EQV'), + ('left','THEN'), + ('left','OR'), + ('left','AND'), + ('right','NOT'), ('left','PLUS','MINUS'), ('left','TIMES','DIVIDE'), ('right','UMINUS'), @@ -57,18 +55,30 @@ precedence = ( def p_statement_assign(t): 'statement : NAME EQUALS expression' t[0] = ('substitution', t[1], t[3]) + print t[0] def p_statement_expr(t): 'statement : expression' t[0] = t[1] print t[0] -def p_expression_binop(t): +def p_expression_binop1(t): '''expression : expression PLUS expression | expression MINUS expression | expression TIMES expression | expression DIVIDE expression''' - t[0] = (t[2], t[1], t[3]) + t[0] = (t[2].lower(), t[1], t[3]) + +def p_expression_binop2(t): + '''expression : expression OR expression + | expression AND expression + | expression THEN expression + | expression EQV expression''' + t[0] = (t[2][1:-1].lower(), t[1], t[3]) + +def p_expression_not(t): + 'expression : NOT expression %prec NOT' + t[0] = ('not', t[2]) def p_expression_uminus(t): 'expression : MINUS expression %prec UMINUS' @@ -78,13 +88,17 @@ 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_integer(t): + 'expression : INTEGER' + t[0] = ('integer', t[1]) + +def p_expression_float(t): + 'expression : FLOAT' + t[0] = ('float', t[1]) def p_expression_name(t): 'expression : NAME' - t[0] = t[1] + t[0] = ('variable', t[1]) def p_error(t): print "Syntax error at '%s'" % t.value