使用Lark的语法优先级

时间:2018-04-05 11:51:22

标签: python grammar lark-parser

我的语法中存在优先级问题,我没有任何想法来解决它。

我正在使用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 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:2)

这不是一个完整的答案,但是让你分道扬锯。你的问题是你的语法含糊不清,你使用的例子正面临着这种模糊性。 Lark选择为你消除歧义,你就得到了结果。见。

通过添加SO_EXCLUSIVEADDRUSE

,让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())

你怎么能鼓励Lark消除你的偏爱?好问题。