Bug 980788 - [manifestparser] Add greater-than/less-than (equal) support. r=ahal

This commit is contained in:
Julien Pagès 2015-07-15 04:42:00 -04:00
parent 9295a3b690
commit 4d6ac1199d
2 changed files with 88 additions and 2 deletions

View File

@ -21,6 +21,10 @@ __all__ = ['parse', 'ParseError', 'ExpressionParser']
# | expr '||' expr
# | expr '==' expr
# | expr '!=' expr
# | expr '<' expr
# | expr '>' expr
# | expr '<=' expr
# | expr '>=' expr
# literal := BOOL
# | INT
# | STRING
@ -63,6 +67,26 @@ class neq_op_token(object):
def led(self, parser, left):
return left != parser.expression(self.lbp)
class lt_op_token(object):
"<"
def led(self, parser, left):
return left < parser.expression(self.lbp)
class gt_op_token(object):
">"
def led(self, parser, left):
return left > parser.expression(self.lbp)
class le_op_token(object):
"<="
def led(self, parser, left):
return left <= parser.expression(self.lbp)
class ge_op_token(object):
">="
def led(self, parser, left):
return left >= parser.expression(self.lbp)
class not_op_token(object):
"!"
def nud(self, parser):
@ -111,7 +135,8 @@ class string_token(literal_token):
precedence = [(end_token, rparen_token),
(or_op_token,),
(and_op_token,),
(eq_op_token, neq_op_token),
(lt_op_token, gt_op_token, le_op_token, ge_op_token,
eq_op_token, neq_op_token),
(lparen_token,),
]
for index, rank in enumerate(precedence):
@ -128,7 +153,7 @@ class ExpressionParser(object):
The expression language can be described as follows::
EXPRESSION ::= LITERAL | '(' EXPRESSION ')' | '!' EXPRESSION | EXPRESSION OP EXPRESSION
OP ::= '==' | '!=' | '&&' | '||'
OP ::= '==' | '!=' | '<' | '>' | '<=' | '>=' | '&&' | '||'
LITERAL ::= BOOL | INT | IDENT | STRING
BOOL ::= 'true' | 'false'
INT ::= [0-9]+
@ -179,6 +204,10 @@ class ExpressionParser(object):
(r'("[^"]*")|(\'[^\']*\')', string_token),
(r"==", eq_op_token()),
(r"!=", neq_op_token()),
(r"<=", le_op_token()),
(r">=", ge_op_token()),
(r"<", lt_op_token()),
(r">", gt_op_token()),
(r"\|\|", or_op_token()),
(r"!", not_op_token()),
(r"&&", and_op_token()),

View File

@ -91,5 +91,62 @@ class ExpressionParserTest(unittest.TestCase):
self.assertFalse(parse("!true && true"))
self.assertFalse(parse("true && !true"))
def test_lesser_than(self):
"""
Test the < operator.
"""
self.assertTrue(parse("1 < 2"))
self.assertFalse(parse("3 < 2"))
self.assertTrue(parse("false || (1 < 2)"))
self.assertTrue(parse("1 < 2 && true"))
self.assertTrue(parse("true && 1 < 2"))
self.assertTrue(parse("!(5 < 1)"))
self.assertTrue(parse("'abc' < 'def'"))
self.assertFalse(parse("1 < 1"))
self.assertFalse(parse("'abc' < 'abc'"))
def test_greater_than(self):
"""
Test the > operator.
"""
self.assertTrue(parse("2 > 1"))
self.assertFalse(parse("2 > 3"))
self.assertTrue(parse("false || (2 > 1)"))
self.assertTrue(parse("2 > 1 && true"))
self.assertTrue(parse("true && 2 > 1"))
self.assertTrue(parse("!(1 > 5)"))
self.assertTrue(parse("'def' > 'abc'"))
self.assertFalse(parse("1 > 1"))
self.assertFalse(parse("'abc' > 'abc'"))
def test_lesser_or_equals_than(self):
"""
Test the <= operator.
"""
self.assertTrue(parse("1 <= 2"))
self.assertFalse(parse("3 <= 2"))
self.assertTrue(parse("false || (1 <= 2)"))
self.assertTrue(parse("1 < 2 && true"))
self.assertTrue(parse("true && 1 <= 2"))
self.assertTrue(parse("!(5 <= 1)"))
self.assertTrue(parse("'abc' <= 'def'"))
self.assertTrue(parse("1 <= 1"))
self.assertTrue(parse("'abc' <= 'abc'"))
def test_greater_or_equals_than(self):
"""
Test the > operator.
"""
self.assertTrue(parse("2 >= 1"))
self.assertFalse(parse("2 >= 3"))
self.assertTrue(parse("false || (2 >= 1)"))
self.assertTrue(parse("2 >= 1 && true"))
self.assertTrue(parse("true && 2 >= 1"))
self.assertTrue(parse("!(1 >= 5)"))
self.assertTrue(parse("'def' >= 'abc'"))
self.assertTrue(parse("1 >= 1"))
self.assertTrue(parse("'abc' >= 'abc'"))
if __name__ == '__main__':
unittest.main()