소스 검색

Added the ability to use templates as template arguments. Error reporting should still be horrible.

tags/gm/2021-09-23T00Z/github.com--lark-parser-lark/0.8.6
MegaIng1 4 년 전
부모
커밋
1b5ffc0660
2개의 변경된 파일19개의 추가작업 그리고 6개의 파일을 삭제
  1. +12
    -6
      lark/load_grammar.py
  2. +7
    -0
      tests/test_parser.py

+ 12
- 6
lark/load_grammar.py 파일 보기

@@ -358,9 +358,14 @@ class _ReplaceSymbols(Transformer_InPlace):
self.names = {}

def value(self, c):
if len(c) == 1 and isinstance(c[0], Token) and c[0].type == 'RULE' and c[0].value in self.names:
if len(c) == 1 and isinstance(c[0], Token) and c[0].value in self.names:
return self.names[c[0].value]
return self.__default__('value', c, None)
def template_usage(self, c):
if c[0] in self.names:
return self.__default__('template_usage', [self.names[c[0]].name] + c[1:], None)
return self.__default__('template_usage', c, None)

class ApplyTemplates(Transformer_InPlace):
" Apply the templates, creating new rules that represent the used templates "
@@ -912,11 +917,12 @@ class GrammarLoader:
for temp in expansions.find_data('template_usage'):
sym = temp.children[0]
args = temp.children[1:]
if sym not in rule_names:
raise GrammarError("Template '%s' used but not defined (in rule %s)" % (sym, name))
if len(args) != rule_names[sym]:
raise GrammarError("Wrong number of template arguments used for %s "
"(expected %s, got %s) (in rule %s)"%(sym, rule_names[sym], len(args), name))
if sym not in params:
if sym not in rule_names:
raise GrammarError("Template '%s' used but not defined (in rule %s)" % (sym, name))
if len(args) != rule_names[sym]:
raise GrammarError("Wrong number of template arguments used for %s "
"(expected %s, got %s) (in rule %s)"%(sym, rule_names[sym], len(args), name))
for sym in _find_used_symbols(expansions):
if sym.type == 'TERMINAL':
if sym not in terminal_names:


+ 7
- 0
tests/test_parser.py 파일 보기

@@ -895,6 +895,13 @@ def _make_parser_test(LEXER, PARSER):
x = g.parse("AB")
self.assertSequenceEqual(x.children, [Tree('b',[])])

def test_templates_templates(self):
g = _Lark('''start: a{b}
a{t}: t{"a"}
b{x}: x''')
x = g.parse('a')
self.assertSequenceEqual(x.children, [Tree('a', [Tree('b',[])])])

def test_g_regex_flags(self):
g = _Lark("""
start: "a" /b+/ C


불러오는 중...
취소
저장