]> git.phdru.name Git - phdru.name/cgi-bin/blog-ru/search-tags.git/blobdiff - parser/grammar.ebnf
Docs(TODO): Try Pyleri
[phdru.name/cgi-bin/blog-ru/search-tags.git] / parser / grammar.ebnf
index 935e6a4d3477f7bfa557fde4a28c5dca83786eaa..3be4d166e0ed7eac1643b7e0176d35e2e75f7d8a 100644 (file)
@@ -1,4 +1,4 @@
-# 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-z][a-z0-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