# HG changeset patch # User Jeff Hammel # Date 1307114576 25200 # Node ID a42bb6dc2fa7a70752ba5606671f8510c206b339 # Parent 5ac8eed856841ed5e7325c3d3b6a0b2952f4bad7 change parse mapping to **kwargs diff -r 5ac8eed85684 -r a42bb6dc2fa7 expr.py --- 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()