5

我的语法有一个优先问题,我没有更多的想法来解决它。

我正在使用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

我试图在我的规则中优先考虑,但它不起作用。

你知道我需要改变什么才能让它工作吗?

谢谢

4

2 回答 2

7

一个简单的解决方案可能是重新编写语法以消除歧义。

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
于 2018-04-05T14:54:05.490 回答
4

这不是一个完整的答案,但我希望能让你分道扬镳。你的问题是你的语法是模棱两可的,你使用的例子正面地击中了歧义。Lark 选择为你消歧,你得到你的结果。看。

使 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

你如何鼓励 Lark 消除对你的偏好的歧义?好问题。

于 2018-04-05T13:08:18.707 回答