X-Git-Url: https://git.phdru.name/?a=blobdiff_plain;f=parser%2Fgrammar.ebnf;h=3be4d166e0ed7eac1643b7e0176d35e2e75f7d8a;hb=HEAD;hp=4a702edf2bbcfa7f0bfcecb1c47171580cefacb9;hpb=4661dada0cb0d3fa6e38bc87d370c56eb062eac8;p=phdru.name%2Fcgi-bin%2Fblog-ru%2Fsearch-tags.git diff --git a/parser/grammar.ebnf b/parser/grammar.ebnf index 4a702ed..3be4d16 100644 --- a/parser/grammar.ebnf +++ b/parser/grammar.ebnf @@ -11,34 +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. -@@grammar :: Tags +?start : expression -start = expression $ ; +?expression : or_expression + | and_expression + | and_sub_expression -expression = expression1 !&or_op | or_expression ; +or_expression : or_sub_expression (or or_sub_expression)+ -or_expression = expression1 or_op expression ; +?or_sub_expression : and_expression + | and_sub_expression -and_expression = expression2 and_op expression1 ; +and_expression : and_sub_expression (and and_sub_expression)+ -not_expression = not_op expression3 ; +?and_sub_expression : not_expression + | expression_parens + | name -parens_expression = '(' expression ')' ; +not_expression: not and_sub_expression -expression1 = expression2 !&and_op | and_expression ; +expression_parens : "(" expression ")" -expression2 = !¬_op expression3 | not_expression ; +name : /[a-z][a-z0-9_]+/ -expression3 = parens_expression | name ; +?and : and_op + | and_op and_op + | and_word -and_op = '&&' | '&' | 'AND' | 'and' ; +?or : or_op + | or_op or_op + | or_word -or_op = '||' | '|' | 'OR' | 'or' ; +?not : not_op + | not_word -not_op = '!' | 'NOT' | 'not' ; +?and_op : "&" -name = /[a-z][a-z0-9_]+/ ; +?or_op : "|" + +?not_op : "!" + +?and_word : "AND" + | "and" + +?or_word : "OR" + | "or" + +?not_word : "NOT" + | "not" + +%import common.WS +%ignore WS