ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

python – 将声明性DSL转换为嵌套函数调用

2019-06-30 14:44:26  阅读:179  来源: 互联网

标签:python parsing dsl


我有一个python库,可以在nested function calls之外构建特殊的迭代器(一个行为树).虽然API有一个相当好的轻量级语法(由于它是python),它实际上可以使用声明性DSL.

这是我想象的粗略草图:

DSL(使用YAML):

tree:
  - sequence:
    - do_action1
    - do_action2
    - select:
      - do_action3
      - sequence:
        - do_action4
        - do_action5
      - do_action6

会导致以下嵌套函数调用:

visit(
    sequence(
        do_action1(),
        do_action2(),
        select(
            do_action3(),
            sequence(
                do_action4(),
                do_action5(),
                ),
            do_action6(),
            )
        )
    )

我无法直观地看到如何做到这一点.因为DSL必须代表树,所以简单的深度优先遍历似乎是合适的.但是为了构建嵌套函数调用,我必须以某种方式将其内部转换出来.它可能涉及一些聪明的中间堆栈或某些东西,但我不能完全掌握它.执行此转换的正确方法是什么?

解决方法:

我想你可以让python跟踪函数调用和参数,而不是自己用堆栈来做.

假设您有一个YAML解析树,其中每个节点表示一个函数调用,并且该节点的每个子节点都是一个参数(它也是一个函数调用,因此它可能有自己的参数).

然后定义函数evaluate,它评估此树的节点,如下所示(伪代码):

def evaluate(node):
    # evaluate parameters of the call
    params = []
    for child in node:
        params.append(evaluate(child))

    # now make the call to whatever function this node represents,
    # passing the parameters
    return node.function.call(*params)

最后,调用evaluate传递YAML树的根作为参数,你应该得到所需的行为.

略微不同的eval-apply结构

def evaluate(node):
    # evaluate parameters of the call
    params = [ evaluate(child) for child in node ]

    # apply whatever function this node represents
    return node.function.call(*params)

标签:python,parsing,dsl
来源: https://codeday.me/bug/20190630/1337309.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有