X-Git-Url: https://git.phdru.name/?a=blobdiff_plain;f=parser%2Fparser.py;h=0d9351bbfd6e66be8f31951972f5e8444b8c9750;hb=bee03d50e5a6c083962d5d855cea5445bc015472;hp=3f51d3f9c7b6ee84c597de07a81c354d1d1ee674;hpb=3db3a1c52868d865cac4e96d6521f62feb15cf77;p=phdru.name%2Fcgi-bin%2Fblog-ru%2Fsearch-tags.git diff --git a/parser/parser.py b/parser/parser.py index 3f51d3f..0d9351b 100755 --- a/parser/parser.py +++ b/parser/parser.py @@ -1,7 +1,32 @@ -#! /usr/bin/env python +#! /usr/bin/env python3 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 parse('test') - print parse('!test') - print parse('not test') - print parse('foo or bar') - print parse('foo && bar') - print parse('(test)') - print parse('(foo || bar)') - print parse('(foo and !bar)') + 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('----------')