1

我基本上是一个 ruby​​ 人,并且遇到了我需要在 py 中制作一个小的 dsl 的情况,如下所示,我知道在 ruby​​ 中以下是可行的,我在 py 中寻找完全相同

from_a_dsl_file = "
   take_this 'abc'
   and_process_it
   and_give_me_the_output
"

class A
   def take_this abc
   end

   def and_process_it
   end

   def and_give_me_the_output
     'desired'
   end
end

A.new.instance_eval from_a_dsl_file
# => 'desired'

任何提示,或者很高兴有一个工作示例

提前致谢

4

2 回答 2

3

据我了解,在 Ruby 中,您可以使用不需要括号的函数调用来做一些棘手的事情:

x y

在 Ruby 中,这可能是一个函数调用,其中函数x被调用y为参数。

好吧,在 Python 中,我们没有这些技巧。如果你正在调用一个函数,你需要在函数名后面加上括号。所以,我认为你不会有太多的运气尝试为此玩游戏eval()

更好的方法是编写一个解析器来为您解析语言并弄清楚该语言正在尝试做什么。为此,Python 有一个特别好的库:pyparsing

http://pyparsing.wikispaces.com/

PS 只是在 Google 上搜索“Python 领域特定语言”会发现一些很好的链接,其中很多都在 StackOverflow 中。这是我找到的最好的:

Python中的迷你语言

编辑:好的,你问了一个例子,你去。这是我在 PyParsing 中的第一个程序,非常简单。我什至没有阅读文档;我刚刚从网上找到的演示文稿中的示例开始工作。

这是演示文稿的 URL:http ://www.ptmcg.com/geo/python/confs/TxUnconf2008Pyparsing.html

from pyparsing import *

def give_desired_output(s):
    return "desired"

TAKE_THIS = Suppress("take_this") + Suppress(Word(printables))
AND_PROC = Suppress("and_process_it")
AND_GIVE = Keyword("and_give_me_the_output")
AND_GIVE.setParseAction(give_desired_output)

LANGUAGE_LINE = TAKE_THIS | AND_PROC | AND_GIVE

LANGUAGE = ZeroOrMore(LANGUAGE_LINE)


def parse_language(text):
    lst = LANGUAGE.parseString(text)
    assert len(lst) == 1  # trivial language returns a single value
    return lst[0]

if __name__ == "__main__":
    from_a_dsl_file = \
"""
   take_this 'abc'
   and_process_it
   and_give_me_the_output
"""

    print(parse_language(from_a_dsl_file))  # prints the word: desired
于 2013-01-21T08:08:27.760 回答
1

听起来您可能想查看exec()和/或execfile()(特别是诸如指定可用全局变量和局部变量的能力之类的东西)。

(还有eval(),但它只允许一个表达式,而不是一系列命令。)

于 2013-01-21T07:06:20.333 回答