+Version 0.3 (2014-06-??)
+
+ Allow '&&'.
+
Version 0.2 (2014-06-06)
Ignore spaces.
-Allow '&&', ' and ' and ' AND '.
+Allow ' and ' and ' AND '.
Allow '||', ' or ' and ' OR '.
# The grammar defines expressions in the following forms:
# TAG - search blog posts that contain the tag;
# !TAG - search blog posts that don't contain the tag;
-# TAG & TAG - search blog posts that contain both tags;
-# TAG | TAG - search blog posts that contain one of the tags or both;
+# TAG && TAG, TAG & TAG - search blog posts that contain both tags;
+# TAG | TAG - search blog posts that contain any of the tags;
# Parentheses are allowed to group expressions:
# TAG & (TAG | TAG)
# !(TAG | TAG)
-# and so on. This is the first version of the grammar and it allows
+# and so on. This is a simple version of the grammar and it allows
# rather stupid expressions, like !!TAG or ((TAG)); in the future
-# it will be fixed by making the grammar stricter and more complex.
+# it will be fixed by making the grammar more complex and stricter.
NAME : '[a-z][a-z0-9_]+'
NOT_OP : '!'
-SP0 : '[ \t]*'
-
SP1 : '[ \t]+'
expression : NAME
+ | expression AND_OP AND_OP expression
| expression AND_OP expression
| expression OR_OP expression
| NOT_OP expression
| '(' expression ')'
- | SP0 expression SP0
"""expression : NAME"""
p[0] = ('NAME', p[1])
+def p_expression_and_and(p):
+ """expression : expression AND_OP AND_OP expression"""
+ p[0] = ('AND', p[1], p[4])
+
def p_expression_and(p):
"""expression : expression AND_OP expression"""
p[0] = ('AND', p[1], p[3])
self.assertEqual(parser.parse('!(xxx & yyy)'),
('NOT', ('PARENS', ('AND', ('NAME', 'xxx'), ('NAME', 'yyy'))))
)
+ self.assertEqual(parser.parse('!(xxx && yyy)'),
+ ('NOT', ('PARENS', ('AND', ('NAME', 'xxx'), ('NAME', 'yyy'))))
+ )
self.assertEqual(parser.parse('!xxx&yyy&zzz|ooo'),
('OR', ('AND', ('AND', ('NOT', ('NAME', 'xxx')), ('NAME', 'yyy')), ('NAME', 'zzz')), ('NAME', 'ooo'))
)