使用 Lark 语法优先
Priority in grammar using Lark
我的语法有一个优先级问题,我没有更多的想法来解决它。
我正在使用 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
我试图在我的规则中设置优先级,但它不起作用。
您知道我需要更改什么才能使其正常工作吗?
谢谢
这不是一个完整的答案,但我希望能让你有所了解。你的问题是你的语法有歧义,你使用的例子有歧义 head-on。 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 消除你喜欢的歧义?好问题。
一个简单的解决方案可能是re-write您的语法以消除歧义。
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
事情是这样的(我已经尽可能地简化了问题):
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
我试图在我的规则中设置优先级,但它不起作用。
您知道我需要更改什么才能使其正常工作吗?
谢谢
这不是一个完整的答案,但我希望能让你有所了解。你的问题是你的语法有歧义,你使用的例子有歧义 head-on。 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 消除你喜欢的歧义?好问题。
一个简单的解决方案可能是re-write您的语法以消除歧义。
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