如何将输入字符串转换为function()

时间:2013-03-08 02:04:42

标签: c++ reflection scripting

我打算建立一个命令行工具。 我希望用户键入文本/字符串(函数/命令)。 然后,我的工具会将这些字符串转换为C ++函数/变量。

[他们将运行我的自定义数据类型,我自己的功能,而不是运行系统功能]

例: 用户类型

>> myVar = c(123,456,789)

我的工具会知道myVar是变量名称。 c(123,456,789)integer的数组。它将这些字符串转换成这样的字符:

int myVar[] = {123,456,789};

用户也可以调用函数:

输入:

   >> myPrintf(myVar[0]);

输出

   << 123

我的解决方案:我将建立一个类,可能是这样的:

public class cVariable
{
    public string varName; // the variable name
    private varType; // the variable data-type
    public string varData;  // the value of this variable
}

我将使用if/else语句来了解我必须运行的数据类型/函数。

但我认为这种方式并不好。

3 个答案:

答案 0 :(得分:4)

总结:这可能比看起来更难。如果您有一小部分案例,并且您希望今晚有一些工作(这主要是一个学习练习),那么您可能只是采用第一种方法。

从您的问题来看,您似乎想要创建自定义语言,解释该语言并将其绑定到已编译的二进制文件。总的来说,这是一项艰巨的任务。如果缩小范围,可能会得到更好的答案或结果。

如果您熟悉以下主题,您将了解可以使用的选项数量:

  • 编译&amp;链接
    • 动态链接
  • 反射
  • 脚本和口译语言
    • 语言绑定
  • 代码生成

为了让您的程序了解自己的结构和标识符,语言需要一个名为Reflection的功能。标准C ++没有此功能(而其他许多功能)。在编译代码时,不再有函数,类型或参数的字符串标识符。

有关C / C ++中反射式行为的讨论,请参阅以下问题:How can I add reflection to a C++ application?

(C和C ++存在动态链接约定,它提供了从编译二进制文件中的字符串到位置的映射,但这可能不是实现所需内容的最直接方法。)

听起来你想要的是构建一个绑定到原始源代码的解释语言。如果你有一组非常孤立的案例,你可以考虑使用预处理器技巧。 (上面链接的问题是指Qt的实现,以及Boost工具。)

如果您愿意使用现有的脚本语言,则可以研究从该语言生成对C ++代码的绑定。以下是Python的一些资源,例如:http://wiki.python.org/moin/IntegratingPythonWithOtherLanguages

答案 1 :(得分:2)

如果您真的打算做一些相对完整的事情,那么编写自己的语言是一项非常重要的任务。数千行代码绝对是可能的。在我30年的专业和爱好生活中,我参与了各种形式的这种 - 从在调试器或类似的程序中编写一个简单的命令解析器到一个相当好的“迷你基本”解释器和一个小的Lisp解释器。我还制作了很多“伪语言”,其中文本文件用作程序的输入,但它不是一种成熟的编程语言 - 只有一组有限的变量。

我做过的另一件事是“表驱动编程”,其中实际的“代码”以表格的形式构建到程序中。

在所有这些中,有各种形式的“我有一些输入/数据要转换成与其他对象相关的动作”。

如您所述,基本机制是将名称和其他一些数据(例如类型)存储在某种数据结构中。 std::map<std::string, cVariable>是一种相对容易地从名称(字符串)检索数据到该名称的变量的方法。

你可以清楚地为功能做同样的事情。您当然也可以通过某种方式将参数传递给函数。你究竟如何解决这个问题是每种语言必须要解决的问题,而且通常最终会成为某种“堆栈”。

您当然可以将map<std::string, function>从名称转换为函数 - 函数定义可能包含有关函数所使用的参数的数量和类型的一些信息。

对于“内置”函数,您还可以使用argc, argv[]类型方法,其中参数作为cVariable传递[其中一个选项为constantexpression ],允许myPrint(myVar[0] + 100),当然这不是一个真正的变量,而是一个变量内容的结果添加到一个常量。

如果你没有写过像变量计算器这样的东西,那可能是一个很好的起点。

许多“脚本”类型语言都有一个“多态”变量 - 也就是说,该值可以用作数字或字符串,而不实际要求转换变量。

答案 2 :(得分:0)

对于标题“将字符串转换为函数()”,您可以使用函数指针实现此目的:

根据值分配函数:

int (*p)(char*,...) = printf;

使用函数指针调用函数:

char* str = "hello function pointer";
p("say %s", str);

但这只是你问题的一半,首先你需要做一个词法分析来解析你的输入,并根据定义的规则确定什么是一个令牌(组成你的命令行工具的语言的符号),如数字,括号,分配等。然后你需要一个语法分析器,为你的命令中的语法含义设置规则。这基本上是通过状态机来完成的,但这是一项复杂的任务,我认为你不想自己实现它?查看FlexBisson工具以自动生成解析器。

这为您提供了一个通用命令行工具的通用解决方案,该工具可以解释您想要的任何语言。如果语法变化很简单,你可以自己做一个解析器,也许有一些正则表达式。