python - 如何在 Python 中将上下文无关设计语法表达为内部 DSL?

标签 python dsl blender context-free-grammar

[注意:在提交之前重读了这篇文章,我意识到这个问题已经变得有点像史诗了。感谢您容忍我对这种追求背后的原因的长篇解释。我觉得,如果我能够帮助另一个人开展类似的项目,如果我知道这个问题背后的动机,我就更有可能加入。]

我一直在进入Structure Synth最近由 Mikael Hvidtfeldt Christensen 撰写。它是一种用于从称为 Eisenscript 的(大部分)上下文无关语法生成 3D 几何的工具。 Structure Synth 本身的灵感来自 Context Free Art。上下文无关语法可以从非常简单的规则集创建一些惊人的结果。

我目前的 Structure Synth 工作流程涉及从 Structure Synth 导出 OBJ 文件,将其导入 Blender,设置灯光、 Material 等,然后使用 Luxrender 进行渲染。不幸的是,导入这些 OBJ 文件通常会使 Blender 停顿下来,因为可能有数千个具有相当复杂几何形状的对象。我说“相当”是因为 Structure Synth 只生成基本形状,但由三角形表示的球体仍然有很多面。

因此,直接在 Blender 中生成结构比当前过程更可取(Blender 对 Python 脚本的深度支持应该使这成为可能)。一个智能的 Python 库可以使用 Blender 的实例化能力来使用一个网格生成无数的对象,从而节省内存。 Plus Blender 是一个功能齐全的 3D 套件,它解释 CFDG 的能力将提供远远超出 Structure Synth 所能提供的创造性可能性。

所以我的问题是如何最好地将 Eisenscript 语法转换为 Python DSL。这是一个简单的 Eisenscript 的样子:

set maxdepth 2000
{ a 0.9 hue 30 } R1 

rule R1 { 
  { x 1  rz 3 ry 5  } R1
  { s 1 1 0.1 sat 0.9 } box
}

rule R1 { 
  { x 1  rz -3 ry 5  } R1
  { s 1 1 0.1 } box
}

解释一下,第一次调用 R1(第 2 行)将随机调用 R1 的两个定义之一。 R1 的每个定义递归调用 R1(随机调用两个定义之一)并创建一个盒子。递归深入 2000 层后,第一行终止生成。

Jeremy Ashkenas(CoffeeScript 的成名者)成功实现了 context free DSL in Ruby使用 block 。在内部,它通过为每个规则“名称”创建一个哈希键来工作,并将该规则的每个定义的 block 存储在一个数组中,以便在调用规则时随机选择。

以前的 Eisenscript 规则定义将像这样转换为 Ruby DSL:

rule :r1 do
  r1 :x => 1, :rz => 3, :ry => 5
  box :s => [1, 1, 0.1], :sat => 0.9
end

rule :r1 do
  r1 :x => 1, :rz => -3, :ry => 5
  box :s => [1, 1, 0.1]
end

我是一名 Python 新手,因此一直在研究 Python 的函数式编程功能。似乎 lambda 太有限,无法创建类似于 Jeremy 的 Ruby DSL 的东西,而且据我所知,lambda 是匿名函数的唯一选择?

经验丰富的 Pythonista 会如何处理设计?

最佳答案

为上下文无关文法编写解析器很困难。您可能最好使用某种库来简化自己的工作。

我会查看 PyParsing模块。该下载包含许多示例,其中一个是简单的 SQL 解析器,至少作为第一步,看看它可能很有启发性。

关于python - 如何在 Python 中将上下文无关设计语法表达为内部 DSL?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6552380/

相关文章:

ruby - 如何在 Ruby 中从文本生成代码

elasticsearch - 弹性搜寻(DSL):字词不符任何内容

python - blender - 导入 pandas ImportError : No module named pandas

c++ - blender :不可能的立方体

python - 使用 csvcut (python) 获取列时如何将文本限定符包含为 none?

python - 是否可以继承 win32serviceutil.ServiceFramework 的子类?

.net - DSL : TCL or Lisp? 有什么更好的

shader - 你如何在 blender 循环节点着色器中添加时间关系?

python - 通用编程语言 (Python) 与定制语言 (PureData/MaxMSP/ChucK) 的综合

python - 在 python 中按字符串模式对项目进行分组