]> git.phdru.name Git - phdru.name/cgi-bin/blog-ru/search-tags.git/blobdiff - parser/parser.py
Fix negative lookahead in grammar syntax
[phdru.name/cgi-bin/blog-ru/search-tags.git] / parser / parser.py
old mode 100644 (file)
new mode 100755 (executable)
index 38c4cd2..a1dd034
-# Parse query
-
-from ply import lex, yacc
-
-literals = '()'
-
-tokens = ('NAME', 'AND_OP', 'OR_OP', 'NOT_OP')
-
-t_NAME = '[a-z][a-z0-9_]*'
-
-t_AND_OP = '&'
-
-t_OR_OP = r'\|'
-
-t_NOT_OP = '!'
-
-t_ignore = '[ \t]+'
-
-def t_error(t):
-    """Avoid warnings on stderr"""
-
-lexer = lex.lex()
-
-def p_expression_name(p):
-    """expression : NAME"""
-    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])
-
-def p_expression_and(p):
-    """expression : expression AND_OP expression"""
-    p[0] = ('AND', p[1], p[3])
-
-def p_expression_not(p):
-    """expression : NOT_OP expression"""
-    p[0] = ('NOT', p[2])
-
-def p_expression_or(p):
-    """expression : expression OR_OP expression"""
-    p[0] = ('OR', p[1], p[3])
-
-def p_expression_parens(p):
-    """expression : '(' expression ')'"""
-    p[0] = ('PARENS', p[2])
-
-def p_error(p):
-    """Avoid warnings on stderr"""
-    yacc.restart()
-
-precedence = (
-    ('left', 'OR_OP'),
-    ('left', 'AND_OP'),
-    ('right', 'NOT_OP'),
-)
-
-parser = yacc.yacc()
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# CAVEAT UTILITOR
+#
+# This file was automatically generated by Grako.
+#
+#    https://pypi.python.org/pypi/grako/
+#
+# Any changes you make to it will be overwritten the next time
+# the file is generated.
+
+
+from __future__ import print_function, division, absolute_import, unicode_literals
+
+from grako.parsing import graken, Parser
+from grako.util import re, RE_FLAGS, generic_main  # noqa
+
+
+__version__ = (2016, 7, 11, 18, 15, 20, 0)
+
+__all__ = [
+    'TagsParser',
+    'TagsSemantics',
+    'main'
+]
+
+KEYWORDS = set([])
+
+
+class TagsParser(Parser):
+    def __init__(self,
+                 whitespace=None,
+                 nameguard=None,
+                 comments_re=None,
+                 eol_comments_re=None,
+                 ignorecase=None,
+                 left_recursion=True,
+                 keywords=KEYWORDS,
+                 namechars='',
+                 **kwargs):
+        super(TagsParser, self).__init__(
+            whitespace=whitespace,
+            nameguard=nameguard,
+            comments_re=comments_re,
+            eol_comments_re=eol_comments_re,
+            ignorecase=ignorecase,
+            left_recursion=left_recursion,
+            keywords=keywords,
+            namechars=namechars,
+            **kwargs
+        )
+
+    @graken()
+    def _start_(self):
+        self._expression_()
+        self._check_eof()
+
+    @graken()
+    def _expression_(self):
+        with self._choice():
+            with self._option():
+                self._expression1_()
+                with self._ifnot():
+                    self._or_op_()
+            with self._option():
+                self._or_expression_()
+            self._error('no available options')
+
+    @graken()
+    def _or_expression_(self):
+        self._expression1_()
+        self._or_op_()
+        self._expression_()
+
+    @graken()
+    def _and_expression_(self):
+        self._expression2_()
+        self._and_op_()
+        self._expression1_()
+
+    @graken()
+    def _not_expression_(self):
+        self._not_op_()
+        self._expression3_()
+
+    @graken()
+    def _parens_expression_(self):
+        self._token('(')
+        self._expression_()
+        self._token(')')
+
+    @graken()
+    def _expression1_(self):
+        with self._choice():
+            with self._option():
+                self._expression2_()
+                with self._ifnot():
+                    self._and_op_()
+            with self._option():
+                self._and_expression_()
+            self._error('no available options')
+
+    @graken()
+    def _expression2_(self):
+        with self._choice():
+            with self._option():
+                with self._ifnot():
+                    self._not_op_()
+                self._expression3_()
+            with self._option():
+                self._not_expression_()
+            self._error('no available options')
+
+    @graken()
+    def _expression3_(self):
+        with self._choice():
+            with self._option():
+                self._parens_expression_()
+            with self._option():
+                self._name_()
+            self._error('no available options')
+
+    @graken()
+    def _and_op_(self):
+        with self._choice():
+            with self._option():
+                self._token('&&')
+            with self._option():
+                self._token('&')
+            with self._option():
+                self._token('AND')
+            with self._option():
+                self._token('and')
+            self._error('expecting one of: & && AND and')
+
+    @graken()
+    def _or_op_(self):
+        with self._choice():
+            with self._option():
+                self._token('||')
+            with self._option():
+                self._token('|')
+            with self._option():
+                self._token('OR')
+            with self._option():
+                self._token('or')
+            self._error('expecting one of: OR or | ||')
+
+    @graken()
+    def _not_op_(self):
+        with self._choice():
+            with self._option():
+                self._token('!')
+            with self._option():
+                self._token('NOT')
+            with self._option():
+                self._token('not')
+            self._error('expecting one of: ! NOT not')
+
+    @graken()
+    def _name_(self):
+        self._pattern(r'[a-z][a-z0-9_]+')
+
+
+class TagsSemantics(object):
+    def start(self, ast):
+        return ast
+
+    def expression(self, ast):
+        return ast
+
+    def or_expression(self, ast):
+        return ast
+
+    def and_expression(self, ast):
+        return ast
+
+    def not_expression(self, ast):
+        return ast
+
+    def parens_expression(self, ast):
+        return ast
+
+    def expression1(self, ast):
+        return ast
+
+    def expression2(self, ast):
+        return ast
+
+    def expression3(self, ast):
+        return ast
+
+    def and_op(self, ast):
+        return ast
+
+    def or_op(self, ast):
+        return ast
+
+    def not_op(self, ast):
+        return ast
+
+    def name(self, ast):
+        return ast
+
+
+def main(
+        filename,
+        startrule,
+        trace=False,
+        whitespace=None,
+        nameguard=None,
+        comments_re=None,
+        eol_comments_re=None,
+        ignorecase=None,
+        left_recursion=True,
+        **kwargs):
+
+    with open(filename) as f:
+        text = f.read()
+    whitespace = whitespace or None
+    parser = TagsParser(parseinfo=False)
+    ast = parser.parse(
+        text,
+        startrule,
+        filename=filename,
+        trace=trace,
+        whitespace=whitespace,
+        nameguard=nameguard,
+        ignorecase=ignorecase,
+        **kwargs)
+    return ast
+
+if __name__ == '__main__':
+    import json
+    ast = generic_main(main, TagsParser, name='Tags')
+    print('AST:')
+    print(ast)
+    print()
+    print('JSON:')
+    print(json.dumps(ast, indent=2))
+    print()