英文:
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*argsand 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论