]> git.phdru.name Git - phdru.name/cgi-bin/blog-ru/search-tags.git/blobdiff - parser/parser.py
Version 0.7: Use lark instead of parsley
[phdru.name/cgi-bin/blog-ru/search-tags.git] / parser / parser.py
index 3f51d3f9c7b6ee84c597de07a81c354d1d1ee674..dbd054964820852fd530b4cfab0f1da2c8e79e30 100755 (executable)
@@ -1,7 +1,32 @@
 #! /usr/bin/env python
 
 import os
-from parsley import makeGrammar
+from lark import Lark, Transformer
+
+
+class TagsTransformer(Transformer):
+    def and_expression(self, items):
+        left = items[0]
+        right = items[2]
+        if len(items) > 3:
+            right = self.and_expression(items[2:])
+        return ('AND', left, right)
+
+    def or_expression(self, items):
+        left = items[0]
+        right = items[2]
+        if len(items) > 3:
+            right = self.or_expression(items[2:])
+        return ('OR', left, right)
+
+    def not_expression(self, items):
+        return ('NOT', items[1])
+
+    def expression_parens(self, items):
+        return ('PARENS', items[0])
+
+    def name(self, name):
+        return ('NAME', name[0].value)
 
 
 # cache
@@ -13,21 +38,29 @@ def load_grammar():
     parser_dir = os.path.dirname(__file__)
     with open(os.path.join(parser_dir, 'grammar.ebnf'), 'rt') as grammar_file:
         grammar_text = grammar_file.read()
-    _grammar = makeGrammar(grammar_text, {}, 'Tags')
+    grammar_lines = [line for line in grammar_text.splitlines()
+                     if not line.startswith('#')]
+    grammar_text = '\n'.join(grammar_lines)
+    _grammar = Lark(grammar_text)
 
 
 def parse(input):
     if _grammar is None:
         load_grammar()
-    return _grammar(input).expression()
+    tree = _grammar.parse(input)
+    return TagsTransformer().transform(tree)
 
 
 if __name__ == '__main__':
+    print '----------'
     print parse('test')
     print parse('!test')
     print parse('not test')
     print parse('foo or bar')
     print parse('foo && bar')
+    print parse('foo && bar && baz')
+    print parse('!foo && bar && baz')
     print parse('(test)')
     print parse('(foo || bar)')
     print parse('(foo and !bar)')
+    print '----------'