Приоритет в грамматике с использованием Lark

У меня есть проблема с приоритетом в моей грамматике, и у меня нет больше идей, чтобы ее исправить.

Я пользуюсь жаворонком

Вот в чем дело (я максимально упростил задачу):

from lark import Lark

parser = Lark(r"""
    start: set | set_mul

    set_mul: [nb] set
    set: [nb] "foo"
    nb: INT "x"

   %import common.INT
   %import common.WS
   %ignore WS

   """, start='start')

input = "3xfoo"
p = parser.parse(input)
print(p.pretty())

Выход:

  start
  set_mul
    set
      nb    3

Но то, что я хочу, это:

start
  set_mul
     nb 3
     set

Я пытался поставить приоритет в моих правилах, но это не работает.

Ты хоть представляешь, что мне нужно изменить, чтобы это работало?

Спасибо

2 ответа

Решение

Простым решением может быть переписать вашу грамматику, чтобы устранить неоднозначность.

parser = Lark(r"""
    start: set | set_mul

    set_mul: nb | nb set | nb nb_set
    set: "foo"
    nb_set: nb set
    nb: INT "x"

   %import common.INT
   %import common.WS
   %ignore WS

   """, start='start')

Таким образом, каждый из следующих входов имеет только одну возможную интерпретацию:

input = "3xfoo"
p = parser.parse(input)
print(p.pretty())

input = "3x4xfoo"
p = parser.parse(input)
print(p.pretty())         

Результат:

start
  set_mul
    nb  3
    set

start
  set_mul
    nb  3
    nb_set
      nb    4
      set

Это не полный ответ, но я надеюсь, что это поможет вам. Ваша проблема в том, что ваша грамматика неоднозначна, и пример, который вы используете, поражает этой неоднозначностью. Ларк выбирает для вас неоднозначность, и вы получите результат, который вы. увидеть.

Сделайте так, чтобы Lark не устранял неоднозначность ambiguity='explicit':

import lark

parser = lark.Lark(r"""
    start: set | set_mul

    set_mul: [nb] set
    set: [nb] "foo"
    nb: INT "x"

   %import common.INT
   %import common.WS
   %ignore WS

   """, start='start',ambiguity='explicit')

input = "3xfoo"
p = parser.parse(input)
print(p.pretty())

и вы получите этот вывод, который включает в себя тот, который вы хотите:

_ambig
  start
    set
      nb        3
  start
    set_mul
      set
        nb      3
  start
    set_mul
      nb        3
      set

Как вы можете побудить Ларк отойти от своего предпочтения? Хороший вопрос.

Другие вопросы по тегам