Python3-Lark:处理具有可选终端的规则的便捷方式?

huangapple go评论65阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2023年3月12日 19:47:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/75712893.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定