X-Git-Url: https://git.phdru.name/?a=blobdiff_plain;f=parser%2Fparser.py;h=cf463da5b63433082a0fd360b23586871232506e;hb=710a8bc3e3cfc6a7497d5e71a1e53fe07d2bd927;hp=38c4cd236084d9bfb050214193503d64ced96c4c;hpb=2167fc0e09f4343c0fe67c8c754e29a41769e684;p=phdru.name%2Fcgi-bin%2Fblog-ru%2Fsearch-tags.git diff --git a/parser/parser.py b/parser/parser.py index 38c4cd2..cf463da 100644 --- a/parser/parser.py +++ b/parser/parser.py @@ -4,9 +4,9 @@ from ply import lex, yacc literals = '()' -tokens = ('NAME', 'AND_OP', 'OR_OP', 'NOT_OP') +tokens = ('NAME', 'AND_OP', 'OR_OP', 'NOT_OP', 'SP1') -t_NAME = '[a-z][a-z0-9_]*' +t_NAME = '([a-z][a-z0-9_]*)|AND|OR|NOT' t_AND_OP = '&' @@ -14,7 +14,7 @@ t_OR_OP = r'\|' t_NOT_OP = '!' -t_ignore = '[ \t]+' +t_SP1 = '[ \t]+' def t_error(t): """Avoid warnings on stderr""" @@ -26,24 +26,76 @@ def p_expression_name(p): p[0] = ('NAME', p[1]) def p_expression_and_and(p): - """expression : expression AND_OP AND_OP expression""" - p[0] = ('AND', p[1], p[4]) + """expression : expression SP0 AND_OP AND_OP SP0 expression""" + p[0] = ('AND', p[1], p[6]) def p_expression_and(p): - """expression : expression AND_OP expression""" - p[0] = ('AND', p[1], p[3]) + """expression : expression SP0 AND_OP SP0 expression""" + p[0] = ('AND', p[1], p[5]) -def p_expression_not(p): - """expression : NOT_OP expression""" - p[0] = ('NOT', p[2]) +def p_expression_op_word(p): + """expression : l_expression op_word r_expression""" + if p[2] in ('AND', 'and'): + p[0] = ('AND', p[1], p[3]) + elif p[2] in ('OR', 'or'): + p[0] = ('OR', p[1], p[3]) + +def p_expression_or_or(p): + """expression : expression SP0 OR_OP OR_OP SP0 expression""" + p[0] = ('OR', p[1], p[6]) def p_expression_or(p): - """expression : expression OR_OP expression""" - p[0] = ('OR', p[1], p[3]) + """expression : expression SP0 OR_OP SP0 expression""" + p[0] = ('OR', p[1], p[5]) + +def p_expression_not(p): + """expression : NOT_OP SP0 expression""" + p[0] = ('NOT', p[3]) + +def p_expression_in_parens(p): + """expression : expression_parens""" + p[0] = p[1] + +def p_l_expression(p): + """l_expression : expression_parens + | expression SP1 + """ + if len(p) == 2: + p[0] = p[1] + elif len(p) == 3: + p[0] = p[1] + else: + raise ValueError(p) + +def p_r_expression(p): + """r_expression : expression_parens + | SP1 expression + """ + if len(p) == 2: + p[0] = p[1] + elif len(p) == 3: + p[0] = p[2] + else: + raise ValueError(p) def p_expression_parens(p): - """expression : '(' expression ')'""" - p[0] = ('PARENS', p[2]) + """expression_parens : '(' SP0 expression SP0 ')'""" + p[0] = ('PARENS', p[3]) + +def p_op_word(p): + """op_word : NAME""" + if p[1] in ('AND', 'and', 'OR', 'or'): + p[0] = p[1] + else: + raise SyntaxError + +def p_SP0(p): + """SP0 : SP1 + | empty + """ + +def p_empty(p): + """empty :""" def p_error(p): """Avoid warnings on stderr"""