changeset 4:a42bb6dc2fa7

change parse mapping to **kwargs
author Jeff Hammel <jhammel@mozilla.com>
date Fri, 03 Jun 2011 08:22:56 -0700
parents 5ac8eed85684
children e55489813783
files expr.py
diffstat 1 files changed, 22 insertions(+), 71 deletions(-) [+]
line wrap: on
line diff
--- a/expr.py	Thu Jun 02 07:47:33 2011 -0400
+++ b/expr.py	Fri Jun 03 08:22:56 2011 -0700
@@ -23,10 +23,10 @@
 # argument.
 
 __all__ = ['parse', 'ParseError']
-import re, unittest
+import re
 
 # token classes
-class ident_token:
+class ident_token(object):
     def __init__(self, value):
         self.value = value
     def nud(self, parser):
@@ -34,39 +34,39 @@
         # to the parser
         return parser.value(self.value)
 
-class literal_token:
+class literal_token(object):
     def __init__(self, value):
         self.value = value
     def nud(self, parser):
         return self.value
 
-class eq_op_token:
+class eq_op_token(object):
     "=="
     lbp = 20
     def led(self, parser, left):
         return left == parser.expression(self.lbp)
     
-class neq_op_token:
+class neq_op_token(object):
     "!="
     lbp = 20
     def led(self, parser, left):
         return left != parser.expression(self.lbp)
 
-class and_op_token:
+class and_op_token(object):
     "&&"
     lbp = 11
     def led(self, parser, left):
         right = parser.expression(self.lbp)
         return left and right
     
-class or_op_token:
+class or_op_token(object):
     "||"
     lbp = 10
     def led(self, parser, left):
         right = parser.expression(self.lbp)
         return left or right
 
-class lparen_token:
+class lparen_token(object):
     "("
     lbp = 50
     def nud(self, parser):
@@ -74,16 +74,23 @@
         parser.advance(rparen_token)
         return expr
 
-class rparen_token:
+class rparen_token(object):
     ")"
     lbp = 0
 
-class end_token:
+class end_token(object):
     # lowest left binding power, always ends parsing
     lbp = 0
 
+precedence = [(end_token, rparen_token),
+              (or_op_token,),
+              (and_op_token,),
+              (eq_op_token, neq_op_token),
+              (lparen_token,),
+              ]
+
 class ParseError(Exception):
-    pass
+    """errror parsing conditional expression"""
 
 class ExpressionParser(object):
     def __init__(self, text, valuemapping):
@@ -169,70 +176,14 @@
             self.token = self.iter.next()
             return self.expression()
         except:
-            raise ParseError
+            raise ParseError("could not parse: %s" % self.text)
 
-def parse(text, values):
+    __call__ = parse
+
+def parse(text, **values):
     """
     Parse and evaluate a boolean expression in |text|. Use |values| to look
     up the value of identifiers referenced in the expression. Returns the final
     value of the expression. A ParseError will be raised if parsing fails.
     """
     return ExpressionParser(text, values).parse()
-
-class ExpressionParserUnittest(unittest.TestCase):
-    def test_BasicValues(self):
-        self.assertEqual(1, parse("1", {}))
-        self.assertEqual(100, parse("100", {}))
-        self.assertEqual(True, parse("true", {}))
-        self.assertEqual(False, parse("false", {}))
-        self.assertEqual("", parse('""', {}))
-        self.assertEqual("foo bar", parse('"foo bar"', {}))
-        self.assertEqual(1, parse("foo", {'foo':1}))
-        self.assertEqual(True, parse("bar", {'bar':True}))
-        self.assertEqual("xyz", parse("abc123", {'abc123':"xyz"}))
-
-    def test_Equality(self):
-        self.assertTrue(parse("true == true", {}))
-        self.assertTrue(parse("false == false", {}))
-        self.assertTrue(parse("false == false", {}))
-        self.assertTrue(parse("1 == 1", {}))
-        self.assertTrue(parse("100 == 100", {}))
-        self.assertTrue(parse('"some text" == "some text"', {}))
-        self.assertTrue(parse("true != false", {}))
-        self.assertTrue(parse("1 != 2", {}))
-        self.assertTrue(parse('"text" != "other text"', {}))
-        self.assertTrue(parse("foo == true", {'foo': True}))
-        self.assertTrue(parse("foo == 1", {'foo': 1}))
-        self.assertTrue(parse('foo == "bar"', {'foo': 'bar'}))
-        self.assertTrue(parse("foo == bar", {'foo': True, 'bar': True}))
-        self.assertTrue(parse("true == foo", {'foo': True}))
-        self.assertTrue(parse("foo != true", {'foo': False}))
-        self.assertTrue(parse("foo != 2", {'foo': 1}))
-        self.assertTrue(parse('foo != "bar"', {'foo': 'abc'}))
-        self.assertTrue(parse("foo != bar", {'foo': True, 'bar': False}))
-        self.assertTrue(parse("true != foo", {'foo': False}))
-
-    def test_Conjunctions(self):
-        self.assertTrue(parse("true && true", {}))
-        self.assertTrue(parse("true || false", {}))
-        self.assertFalse(parse("false || false", {}))
-        self.assertFalse(parse("true && false", {}))
-        self.assertTrue(parse("true || false && false", {}))
-
-    def test_Parens(self):
-        self.assertTrue(parse("(true)", {}))
-        self.assertEquals(10, parse("(10)", {}))
-        self.assertEquals('foo', parse('("foo")', {}))
-        self.assertEquals(1, parse("(foo)", {'foo':1}))
-        self.assertTrue(parse("(true == true)", {}))
-        self.assertTrue(parse("(true != false)", {}))
-        self.assertTrue(parse("(true && true)", {}))
-        self.assertTrue(parse("(true || false)", {}))
-        self.assertTrue(parse("(true && true || false)", {}))
-        self.assertFalse(parse("(true || false) && false", {}))
-        self.assertTrue(parse("(true || false) && true", {}))
-        self.assertTrue(parse("true && (true || false)", {}))
-        self.assertTrue(parse("true && (true || false)", {}))
-        
-if __name__ == '__main__':
-    unittest.main()