X-Git-Url: https://git.phdru.name/?a=blobdiff_plain;f=parser%2Fgrammar.ebnf;h=3be4d166e0ed7eac1643b7e0176d35e2e75f7d8a;hb=HEAD;hp=935e6a4d3477f7bfa557fde4a28c5dca83786eaa;hpb=fcd51c190450165c3315ed7e4f77bc1415db3d48;p=phdru.name%2Fcgi-bin%2Fblog-ru%2Fsearch-tags.git diff --git a/parser/grammar.ebnf b/parser/grammar.ebnf index 935e6a4..3be4d16 100644 --- a/parser/grammar.ebnf +++ b/parser/grammar.ebnf @@ -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; @@ -11,38 +11,58 @@ # 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