-# Grammar rules for tag searching
+# Grammar rules for tag searching; EBNF.
# 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)) or !(!(TAG)).
+# rather stupid expressions, like !!TAG or ((TAG)); in the future
+# it will be fixed by making the grammar more complex and stricter.
-expression = or_expression / aterm_expression
+?start : expression
-or_expression = aterm_expression or_op expression
+?expression : or_expression
+ | and_expression
+ | and_sub_expression
-and_expression = term_expression and_op aterm_expression
+or_expression : or_sub_expression (or or_sub_expression)+
-not_expression = not_op space0 (parens_expression / name)
+?or_sub_expression : and_expression
+ | and_sub_expression
-aterm_expression = and_expression / term_expression
+and_expression : and_sub_expression (and and_sub_expression)+
-term_expression = not_expression / parens_expression / (name space_b4letter)
+?and_sub_expression : not_expression
+ | expression_parens
+ | name
-parens_expression = "(" space0 expression space0 ")"
+not_expression: not and_sub_expression
-and_op = (space0 ("&&" / "&") space0) / (space0 ("AND" / "and") space_b4letter)
+expression_parens : "(" expression ")"
-or_op = (space0 ("||" / "|") space0) / (space0 ("OR" / "or") space_b4letter)
+name : /[A-Za-zА-Яа-яЁё][A-Za-zА-Яа-яЁё0-9_]*[A-Za-zА-Яа-яЁё0-9]/
-not_op = (space0 "!" space0) / (space0 ("NOT" / "not") space_b4letter)
+?and : and_op
+ | and_op and_op
+ | and_word
-letter = ~"[a-z]"i
+?or : or_op
+ | or_op or_op
+ | or_word
-name = ~"[a-z][a-z0-9_]*"
+?not : not_op
+ | not_word
-space_b4letter = (space1 &letter) / space0
+?and_op : "&"
-space0 = ~" *"
+?or_op : "|"
-space1 = ~" +"
+?not_op : "!"
-# vim: set ft=text :
+?and_word : "AND"
+ | "and"
+ | "И"
+ | "и"
+
+?or_word : "OR"
+ | "or"
+ | "ИЛИ"
+ | "или"
+
+?not_word : "NOT"
+ | "not"
+ | "НЕ"
+ | "не"
+
+%import common.WS
+%ignore WS