我正在尝试为一个新项目做一些研究,我需要从随机数据动态创建对象。 为了实现这一点,我需要一种语言/编译器,它不会出现奇怪的不可编译代码问题。
基本上,我需要随机代码尽可能地编译(或被解释) - 意味着将忽略不可编译的部分,只有可编译的部分才能创建对象(可以运行)。
面向对象 - 不是必须的,但却是一个非常强大的优势。
我想到了ASM,但它非常混乱,我可能需要一个更易读的代码
谢谢!
答案 0 :(得分:3)
听起来你做的事情非常像genetic programming;即使你不是,GP也必须解决一些相同的问题 - 使用随机性来生成有效的程序。通常使用的方法是使用语法树:而不是存储x + y * 3 - 2
,您可以存储以下内容:
然后,可以随意更改树中的节点,而不是随机更改语法。如果x
应随机更改为+
,您可以静态地知道这意味着您需要插入两个孩子(或不是,取决于您定义+
的方式)。< / p>
使用这种语言的一个很好的选择是任何Lisp方言。在Lisp中,上面的程序将被编写(- (+ x (* y 3)) 2)
,这只是语法树的线性化,使用括号来显示深度。事实上,Lisps公开了这个功能:你可以轻松地使用对象'(- (+ x (* y 3)) 2)
(注意引用引号)。这是一个三元素列表,其第一个元素是-
,第二个元素是另一个列表,第三个元素是2
。并且,虽然您可能或可能不希望它适用于您的特定应用程序,但是有一个eval
函数,这样(eval '(- (+ x (* y 3)) 2))
将在给定列表中使用,将其视为Lisp语法树/程序,并评估它。这就是使Lisps对这类工作如此有吸引力的原因; Lisp语法基本上是语法树的一个具体化,如果你在语法树级别运行,你可以像处理一个值一样处理代码。 Lisp不会帮助你直接阅读/dev/random
作为一个程序,但是如果在顶部有一点解释,你应该能够得到你想要的东西。
我还应该提一下,虽然我对linear genetic programming的存在一无所知(不是我对普通遗传编程知之甚少)。这有点像你提到的装配模型 - 一个非常非常简单的指令的线性流。这里的优点似乎是,如果你正在使用/dev/random
或类似的东西,所需的解释量非常小;正如你所提到的,缺点是代码的低级性质。
答案 1 :(得分:2)
我不确定这是否是您正在寻找的,但任何编程语言都可以通过这种方式运行。对于任何编程语言P,定义语言P 始终,如下所示:
例如,我可以使语言C ++ 始终以便这个程序:
#include <iostream>
using namespace std;
int main() {
cout << "Hello, world!" << endl;
}
将编译为“Hello,world!”,而这个程序:
Hahaha! This isn't legal C++ code!
将是一个完全没有做任何事情的法律程序。
要解决原始问题,只需使用Java,Smalltalk等任何OOP语言,并构造相应的Java 始终,Smalltalk 始终等语言。 。再说一次,我不确定这是不是你想要的,但它可以很容易地完成。
或者,考虑为任何OOP语言找到语法,然后使用该语法生成随机语法上有效的程序。然后,您可以使用该语言的P always 编程语言来过滤这些程序,以消除语法上但不是语义上有效的程序。
答案 2 :(得分:0)
将ASCII字节值分为9个类(除以模9有助于)。然后再分配给Brainfuck代码字(参见http://en.wikipedia.org/wiki/Brainfuck)。然后解释为Brainfuck。
你去,任何ASCII字符序列都是一个程序。并不是说它会做任何明智的事情......与templatetypedef的答案相比,这种方法有更好的机会从随机字节序列中获得非平凡的程序。
答案 3 :(得分:0)
文字编辑
您可以尝试将随机字符串输入到Emacs或VI等编辑器中。许多(大多数?)字符将执行编辑操作,但有些字符将不执行任何操作(可能除了哔声)。您必须确保随机代码mutator永远不会生成退出编辑器的字符序列。但是,这种体验非常类似于图灵机的编程 - 代码不太可读。
<强>数学强>
在Mathematica中,未定义的符号和其他表达式会自行评估,而不会出错。因此,如果您可以安排随机代码变换器始终生成格式良好的表达式,那么该语言可能是一个可行的选择。这很容易实现,因为基本的Mathematica语法很简单,使得在句法单元而不是字符级别上操作变得容易。如果变换器是用Mathematica本身编写的话会更容易,因为表达式改变是Mathematica的强项。您可以在不导入系统定义符号的Mathematica包中定义有效操作的迷你语言。这样您就可以根据自己的内容生成结构良好的表达式,而不必担心会产生危险的表达,例如DeleteFile[FileNames["*.*", "/", Infinity]]
。
答案 4 :(得分:-1)
我相信 Common Lisp 应该符合您的需求。我总是在我的SLIME / Emacs会话中有一些无法编译的代码。您可以随时调整内容,在运行时重新定义函数。它实际上非常适合原型制作。
几年前我学习了很长一段时间。但是现在我们有了快速发展,一切都变得如此简单。
我在这里描述我的开发环境: Install lisp on my linux machine
PS:我想举个例子,Common Lisp对我有用: 直到2004年,我曾经用C编写小程序(保持简单的Unix方式)。
过去3年我必须运行许多不同的硬件。电动平台,科学相机,IO卡。
相机结果非常烦人。通常你必须将它们冷却到-50摄氏度左右,并且(在某些SDK中)当你关闭它们时它们不喜欢它。但是这个 正是我的C开发周期的工作方式:写(30s),编译(1s),运行(0.1s),重复。
最终我决定只使用Common Lisp。通常,直接定义外部函数接口以与SDK通信,我可以在不离开正在运行的Lisp映像的情况下完成此操作。我在早上启动编辑器定义开放设备功能,与设备通信,3小时后我有足够的功能来设置增益,温度,感兴趣的区域并获得视频。
然后,我经常可以放弃SDK手册,只需使用相机。
当我必须解析一些网页或一些奇怪的XML时,我使用了相同的交互式编程方法。