Ver código fonte

Merge pull request #821 from chanicpanic/issue-820

Fix an SPPF cycle edge case (Issue #820)
tags/gm/2021-09-23T00Z/github.com--lark-parser-lark/0.11.2
Erez Shinan 3 anos atrás
committed by GitHub
pai
commit
069ad4a6fe
Nenhuma chave conhecida encontrada para esta assinatura no banco de dados ID da chave GPG: 4AEE18F83AFDEB23
2 arquivos alterados com 16 adições e 3 exclusões
  1. +3
    -3
      lark/parsers/earley_forest.py
  2. +13
    -0
      tests/test_parser.py

+ 3
- 3
lark/parsers/earley_forest.py Ver arquivo

@@ -507,7 +507,7 @@ class ForestToParseTree(ForestTransformer):

def _check_cycle(self, node):
if self._on_cycle_retreat:
if id(node) == id(self._cycle_node):
if id(node) == id(self._cycle_node) or id(node) in self._successful_visits:
self._cycle_node = None
self._on_cycle_retreat = False
return
@@ -541,16 +541,16 @@ class ForestToParseTree(ForestTransformer):
def transform_symbol_node(self, node, data):
if id(node) not in self._successful_visits:
raise Discard()
self._successful_visits.remove(id(node))
self._check_cycle(node)
self._successful_visits.remove(id(node))
data = self._collapse_ambig(data)
return self._call_ambig_func(node, data)

def transform_intermediate_node(self, node, data):
if id(node) not in self._successful_visits:
raise Discard()
self._successful_visits.remove(id(node))
self._check_cycle(node)
self._successful_visits.remove(id(node))
if len(data) > 1:
children = [self.tree_class('_inter', c) for c in data]
return self.tree_class('_iambig', children)


+ 13
- 0
tests/test_parser.py Ver arquivo

@@ -775,6 +775,19 @@ def _make_full_earley_test(LEXER):
tree = l.parse('')
self.assertEqual(tree, Tree('start', []))

def test_cycle2(self):
grammar = """
start: _operation
_operation: value
value: "b"
| "a" value
| _operation
"""

l = Lark(grammar, ambiguity="explicit", lexer=LEXER)
tree = l.parse("ab")
self.assertEqual(tree, Tree('start', [Tree('value', [Tree('value', [])])]))

def test_cycles(self):
grammar = """
a: b


Carregando…
Cancelar
Salvar