英文:
Python3-Lark: Convenient way to handle a rule with optional terminals?
问题
在上面提供的代码片段中,您似乎在讨论如何在Python中处理语法规则和使用 Lark 解析器库。您在翻译时要求不翻译代码部分,因此我将提供关于代码和问题的概要的翻译。
以下是问题的概要:
在这个问题中,您正在讨论如何在使用 Lark 解析器库时处理语法规则,具体来说,是如何处理 top_rule
方法。您提出了两种可能的方式:使用 @v_args(inline=True)
或 @v_args(tree=True)
。您还展示了一个示例代码片段,其中您尝试使用 @v_args(inline=True)
处理 top_rule
方法。
您的问题是,哪种方法是合适的,以及是否可能基于参数数量来定义多个 top_rule
方法。
希望这个概要对您有所帮助。如果您需要更详细的信息或代码的翻译,请随时提出。
英文:
In a grammar rule like the following one:
top_rule: header? body footer?
?header: "DAY" DAY
| "SECT" SECT
?body: BODY
?footer: "ENDING"
| "TERMINATING"
DAY: /\[^s]+/
SECT: /\d+/
BODY: /\[^s]+/
What is the most convenient way for the transformer method ?
- Do I go for the
@v_args(inline=True)
? In this case I have to mess with lengths of the*args
and do if-else cases according to them. - Do I go for the
@v_args(tree=True)
? Checking whether the AST contains rules by traversing the AST children?
In python3:
#!/usr/bin/python3
from lark import Lark, Transformer, v_args
GRAMMAR = r"""
top_rule: header? body footer?
?header: "DAY" DAY
| "SECT" SECT
?body: BODY
?footer: "ENDING" DAY
| "TERMINATING" DAY
DAY: /\[^s]+/
SECT: /\d+/
BODY: /\[^s]+/
"""
def MyTransformer(Transformer)
@v_args(inline=True)
def top_rule(self, *args):
if len(args) == 3:
# all optionals are used of the rule...
elif len(args) == 1:
# no optionals (header/footer) used...
else:
# can be args(header, body) or args(body, footer)...
What is the appropriate way of handling it? Am I missing something? Or is this the way to go. As far as I understood I cannot have multiple top_rule
methods based on the number of arguments.
答案1
得分: 1
使用inline=True
和[TERMINAL]
代替TERMINAL?
。然后,Lark会为缺失的终端填充None
:
from lark import Lark, Transformer, v_args
GRAMMAR = r"""
top_rule: [header] body [footer]
?header: "DAY" DAY
| "SECT" SECT
?body: BODY
?footer: "ENDING" DAY
| "TERMINATING" DAY
DAY: /[^s]+/
SECT: /\d+/
BODY: /[^s]+/
"""
def MyTransformer(Transformer)
@v_args(inline=True)
def top_rule(self, header: Token | None, body: Token, footer: Token | None):
if header is not None:
# 正在使用 header
if footer is not None:
# 正在使用 footer
# body 一定会存在
英文:
Use inline=True
and [TERMINAL]
instead of TERMINAL?
. Then lark fills in None
for the terminals that are missing:
from lark import Lark, Transformer, v_args
GRAMMAR = r"""
top_rule: [header] body [footer]
?header: "DAY" DAY
| "SECT" SECT
?body: BODY
?footer: "ENDING" DAY
| "TERMINATING" DAY
DAY: /\[^s]+/
SECT: /\d+/
BODY: /\[^s]+/
"""
def MyTransformer(Transformer)
@v_args(inline=True)
def top_rule(self, header: Token | None, body: Token, footer: Token | None):
if header is not None:
# header is being used
if footer is not None:
# footer is being used
# body will always be there.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论