-# Grammar rules for tag searching; EBNF.
+# Grammar rules for tag searching
# The grammar defines expressions in the following forms:
# TAG - search blog posts that contain the tag;
# Allowed operators: conjunction - & && AND and
# disjunction - | || OR or
# negation - ! NOT not
+# Usual priority: NOT recognized before AND, AND before OR.
# This is a simple version of the grammar and it allows
-# rather stupid expressions, like !!TAG or ((TAG))
+# rather stupid expressions, like (TAG) or ((TAG)) or !(!(TAG)).
-@@grammar :: Tags
+expression = inner_expression:e end -> e
-start = expression $ ;
+inner_expression = (or_expression | aterm_expression):e -> e
-expression = (
- | expression and_op expression
- | expression or_op expression
- | not_op expression
- | expression_parens
- | name ) ;
+or_expression = aterm_expression:a or_op inner_expression:e -> ('OR', a, e)
-expression_parens = '(' expression ')' ;
+and_expression = term_expression:t and_op aterm_expression:a -> ('AND',
+t, a)
-name = /[a-z][a-z0-9_]+/ ;
+not_expression = not_op ws (parens_expression | name):n -> ('NOT', n)
-and_op = '&' | '&&' | 'AND' | 'and' ;
+aterm_expression = (and_expression | term_expression):e -> e
-or_op = '|' | '||' | 'OR' | 'or' ;
+term_expression = (not_expression:e -> e) | (parens_expression:p -> p) | (name:n space_b4letter -> n)
-not_op = '!' | 'NOT' | 'not' ;
+parens_expression = '(' ws inner_expression:e ws ')' -> ('PARENS', e)
+
+and_op = (ws ('&&' | '&') ws) | (ws ('AND' | 'and') space_b4letter)
+
+or_op = (ws ('||' | '|') ws) | (ws ('OR' | 'or') space_b4letter)
+
+not_op = (ws '!' ws) | (ws ('NOT' | 'not') space_b4letter)
+
+name = <lletter lletterOrDigit*>:n -> ('NAME', n)
+
+lletter = :l ?(l in 'abcdefghijklmnopqrstuvwxyz') -> l
+
+digit = :d ?(d in '0123456789') -> d
+
+lletterOrDigit = (lletter | digit):c -> c
+
+space_b4letter = (' '+ ~~letter) | ws
+
+# vim: set ft=text :