From a701255bb701988f09266b1d3bbbbf7a063094a0 Mon Sep 17 00:00:00 2001 From: Oleg Broytman Date: Sun, 22 Jun 2014 04:00:40 +0400 Subject: [PATCH] Allow ' OR ' and ' or ' --- ChangeLog | 2 +- TODO | 2 -- parser/grammar | 6 +++++- parser/parser.py | 15 +++++++++------ parser/test_parser.py | 3 +++ 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index b1310a4..5b2e9eb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,6 @@ Version 0.3 (2014-06-??) - Allow '&&', '||', ' AND ' and ' and '. + Allow '&&', '||', ' AND ', ' and ', ' OR ' and ' or '. Version 0.2 (2014-06-06) diff --git a/TODO b/TODO index 2a96d7b..1985735 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,3 @@ -Allow ' OR ' and ' or '. - Allow 'NOT ' and 'not '. Forbid stupid expressions: double NOT, extra parens and so on. diff --git a/parser/grammar b/parser/grammar index 3332611..6944378 100644 --- a/parser/grammar +++ b/parser/grammar @@ -9,7 +9,7 @@ # TAG & (TAG | TAG) # !(TAG | TAG) # Allowed operators: conjunction - & && AND and -# disjunction - | || +# disjunction - | || OR or # negation - ! # This is a simple version of the grammar and it allows # rather stupid expressions, like !!TAG or ((TAG)); in the future @@ -32,6 +32,7 @@ expression : NAME | NOT_OP SP0 expression | expression SP0 OR_OP OR_OP SP0 expression | expression SP0 OR_OP SP0 expression + | l_expression or_word r_expression | expression_parens l_expression : expression_parens @@ -49,6 +50,9 @@ expression_sp : expression SP1 and_word : 'A' 'N' 'D' | 'a' 'n' 'd' +or_word : 'O' 'R' + | 'o' 'r' + SP0 : SP1 | empty empty : diff --git a/parser/parser.py b/parser/parser.py index d278e4b..c28474b 100644 --- a/parser/parser.py +++ b/parser/parser.py @@ -33,9 +33,12 @@ def p_expression_and(p): """expression : expression SP0 AND_OP SP0 expression""" p[0] = ('AND', p[1], p[5]) -def p_expression_and_word(p): - """expression : l_expression and_word r_expression""" - p[0] = ('AND', p[1], p[3]) +def p_expression_op_word(p): + """expression : l_expression op_word r_expression""" + if p[2] in ('AND', 'and'): + p[0] = ('AND', p[1], p[3]) + elif p[2] in ('OR', 'or'): + p[0] = ('OR', p[1], p[3]) def p_expression_not(p): """expression : NOT_OP SP0 expression""" @@ -79,9 +82,9 @@ def p_expression_parens(p): """expression_parens : '(' SP0 expression SP0 ')'""" p[0] = ('PARENS', p[3]) -def p_and_word(p): - """and_word : NAME""" - if p[1] in ('AND', 'and'): +def p_op_word(p): + """op_word : NAME""" + if p[1] in ('AND', 'and', 'OR', 'or'): p[0] = p[1] else: raise SyntaxError diff --git a/parser/test_parser.py b/parser/test_parser.py index 50870e9..d13e6e9 100755 --- a/parser/test_parser.py +++ b/parser/test_parser.py @@ -33,6 +33,9 @@ class TestParser(unittest.TestCase): self.assertEqual(parser.parse('xxx and yyy'), ('AND', ('NAME', 'xxx'), ('NAME', 'yyy')) ) + self.assertEqual(parser.parse('xxx or yyy'), + ('OR', ('NAME', 'xxx'), ('NAME', 'yyy')) + ) def test_05_bad_expression(self): self.assertIs(parser.parse('!(xxx&yyy'), None) -- 2.39.2