将文本转换为可执行语句

时间:2009-11-02 19:56:20

标签: java c++

这是一个出于java或c ++的好奇心的问题,我想问一下是否有可能将任何文本输入转换为某些可执行语句?

例如说我有一个文本文件,其中包含以下信息:

“班级:Abc, 帕拉姆:32“

现在用C ++或Java说我想读取该文件,并执行以下操作:

new Abc(32);

我该怎么做?它很容易读取Abc的值,但怎么说创建一个类Abc?有没有一种标准的方法可以做到这一点?在C ++和Java中?

主要的好奇心来自Java中的持久性机制,它们将对象属性存储在XML文件中,并通过读取该XML文件来创建对象,它们是如何做到的?这与我上面要求的分开吗? 编辑:这与标准的java序列化不同,我将其视为长期持久性的解决方案,其中对象实现可以更改,而不是序列化它们存储属性,包括用于在运行时创建对象的XML文件中的执行语句。

8 个答案:

答案 0 :(得分:4)

如果你的目标是接受任何文本输入并运行任意命令,那么开始查看JVM的地方是Java 6编译器API(http://java.sun.com/javase/6/docs/api/javax/tools/package-summary.html)或JSR 223(http://java.sun.com/developer/technicalArticles/J2SE/Desktop/scripting)。

如果您的目标是从文本文件存储和检索信息,请查看协议缓冲区(http://code.google.com/p/protobuf/)或Java序列化API(http://www.javaworld.com/javaworld/jw-07-2000/jw-0714-flatten.html)。

答案 1 :(得分:2)

首先需要解析您的迷你语言。所以(如上所述)Antlr或Javacc为您的语言创建解析器。

之后,您需要使用“解释器”/目标语言的元编程功能。对于Java,您需要start with reflection,如果您确实需要它,请稍后继续生成字节代码。

答案 2 :(得分:2)

[C ++回答]

你不能这样做。你需要在运行时解析/编译C ++行,这不是你想要处理的东西,相信我。

但是,如果您刚刚从“Java中存储对象属性的XML文件中的持久性机制”中获得了这一点,那么您要查找的关键字是Serialization。许多序列化技术和库可用于C ++,例如boost::serialization

答案 3 :(得分:1)

在java中你可以这样做:

// Read data from file:
String cls = "java.math.BigDecimal";
String arg = "123.45";

// Create the object
Class<?> objClass = Class.forName(cls);
Object obj = objClass.getConstructor(new Class[] {String.class }).newInstance(arg);
System.out.println("The object is: " + obj.toString() + "; type: " 
    + obj.getClass().getSimpleName());

答案 4 :(得分:1)

Java 6支持脚本语言,它可以像你描述的那样用传递的字符串做“填充”。

有一个JavaScript引擎和一个BeanShell引擎可用,但我不确定他们是否可以动态创建新类。所以你需要做的就是找到你喜欢的支持脚本语言

https://scripting.dev.java.net/

并安装它,然后使用它:)

答案 5 :(得分:0)

对于C ++,您可以使用预编译器的宏功能完成许多建议。对于Java,使用反射来实现上面的示例并不困难。你的例子非常稀疏。你能举一个用例说明为什么你有兴趣这样做吗?

如果您只是在寻找一种机制来设置程序的初始状态,那么您想要查找的是Inversion of Control的信息。在Java中,Spring是那里的大型IoC库。我不知道可能有什么C ++等价物。我怀疑C ++缺乏反射功能会使IoC更难。

编辑:我之前没有真正读过你的最后一段。与XML的序列化可以通过多种不同的方式完成,但在Java中,如果您只是希望能够序列化和反序列化对象的状态,则JAXB是一个允许这样做的库。

答案 6 :(得分:0)

创建解析器。对于Java和C ++,我建议您使用Antlr

对于解析器生成时未知的类,您可能还需要使用Reflection API。

答案 7 :(得分:0)

您根据语法解析输入(记住yacc?)并将语义操作附加到派生规则。这是编译器所做的非常遥远的描述。