разница между Эрли и Лалром в жаворонке? - PullRequest
1 голос
/ 06 мая 2019

У меня есть простая грамматика, которая разбирает пары ключ-значение по разделам.

k1:1
k2:x

k3:3
k4:4

Грамматика, которую я имею для этого:

start:  section (_sep section)*
_sep: _NEWLINE _NEWLINE+
section: item (_NEWLINE item)*
item: NAME ":" VALUE

_NEWLINE: /\r?\n[\t ]*/
VALUE: /\w+/
NAME: /\w+/

Однако грамматика работает при использовании парсера earley, но не при использовании парсера lalr.

со следующим кодом:

from lark import Lark
import logging
from pathlib import Path
logging.basicConfig(level=logging.DEBUG)

my_grammar = Path("my_grammar.lark").read_text()
print(my_grammar)
early = Lark(my_grammar, debug=True)

print(my_grammar)
lalr = Lark(my_grammar, parser='lalr', debug=True)

text = """
k1:1
k2:x

k3:3
k4:4
"""
print(text.strip())
print(early.parse(text.strip()).pretty())
print(lalr.parse(text.strip()).pretty())

Парсли Эрли дают мне верный результат.

start
  section
    item
      k1
      1
    item
      k2
      x
  section
    item
      k3
      3
    item
      k4
      4

но парсер lalr не

lark.exceptions.UnexpectedCharacters: No terminal defined for '
' at line 3 col 1


^

Expecting: {'NAME'}

PS: проблема с _NEWLINE.

Lark-parser грамматика настраивает лексер и анализатор в файле грамматики. В моей грамматике выше строка будет обозначена как _NEWLINE. Несколько новых строк будут помечены как _NEWLINE .. _NEWLINE. Это смущает парсер.

изменить _sep на /\r?\n[\t ]*(\r?\n[\t ]*)/. несколько строк будут маркированы как один токен. и lalr (1) парсер может работать на нем плавно.

пока я работаю. все еще интересно, как рано парсер понял это правильно.

...