]> git.phdru.name Git - phdru.name/cgi-bin/blog-ru/search-tags.git/blob - parser/parser.py
Docs(TODO): Try Pyleri
[phdru.name/cgi-bin/blog-ru/search-tags.git] / parser / parser.py
1 #! /usr/bin/env python
2
3 import os
4 from lark import Lark, Transformer
5
6
7 class TagsTransformer(Transformer):
8     def and_expression(self, items):
9         left = items[0]
10         right = items[2]
11         if len(items) > 3:
12             right = self.and_expression(items[2:])
13         return ('AND', left, right)
14
15     def or_expression(self, items):
16         left = items[0]
17         right = items[2]
18         if len(items) > 3:
19             right = self.or_expression(items[2:])
20         return ('OR', left, right)
21
22     def not_expression(self, items):
23         return ('NOT', items[1])
24
25     def expression_parens(self, items):
26         return ('PARENS', items[0])
27
28     def name(self, name):
29         return ('NAME', name[0].value)
30
31
32 # cache
33 _grammar = None
34
35
36 def load_grammar():
37     global _grammar
38     parser_dir = os.path.dirname(__file__)
39     with open(os.path.join(parser_dir, 'grammar.ebnf'), 'rt') as grammar_file:
40         grammar_text = grammar_file.read()
41     grammar_lines = [line for line in grammar_text.splitlines()
42                      if not line.startswith('#')]
43     grammar_text = '\n'.join(grammar_lines)
44     _grammar = Lark(grammar_text)
45
46
47 def parse(input):
48     if _grammar is None:
49         load_grammar()
50     tree = _grammar.parse(input)
51     return TagsTransformer().transform(tree)
52
53
54 if __name__ == '__main__':
55     print '----------'
56     print parse('test')
57     print parse('!test')
58     print parse('not test')
59     print parse('foo or bar')
60     print parse('foo && bar')
61     print parse('foo && bar && baz')
62     print parse('!foo && bar && baz')
63     print parse('(test)')
64     print parse('(foo || bar)')
65     print parse('(foo and !bar)')
66     print '----------'