Version 0.3 (2014-06-??)
- Allow '&&', '||', ' AND ' and ' and '.
+ Allow '&&', '||', ' AND ', ' and ', ' OR ' and ' or '.
Version 0.2 (2014-06-06)
-Allow ' OR ' and ' or '.
-
Allow 'NOT ' and 'not '.
Forbid stupid expressions: double NOT, extra parens and so on.
# 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
| 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
and_word : 'A' 'N' 'D'
| 'a' 'n' 'd'
+or_word : 'O' 'R'
+ | 'o' 'r'
+
SP0 : SP1 | empty
empty :
"""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"""
"""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
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)