1

我将构建一个命令行工具。我希望用户输入一个文本/字符串(函数/命令)。然后,我的工具会将这些字符串转换为 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语句来知道我必须运行哪种数据类型/函数。

但我觉得这种方式一点都不好。

4

3 回答 3

4

摘要:这可能比看起来更难做到。如果你有一小部分案例,并且你想在今晚有一些工作(这主要是一个学习练习),那么你可以简单地使用你的第一种方法。

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

如果您熟悉以下主题,您将了解有多少选项可供您使用:

  • 编译和链接
    • 动态链接
  • 反射
  • 脚本和解释语言
    • 语言绑定
  • 代码生成

为了让您的程序了解其自身的结构和标识符,该语言需要一个称为反射的功能。标准 C++ 没有这个特性(而许多其他的有)。到编译代码时,您的函数、类型或参数不再有字符串标识符。

有关 C/C++ 中类似反射的行为的讨论,请参阅以下问题:如何将反射添加到 C++ 应用程序?

(C 和 C++ 存在动态链接约定,它们提供了从字符串到已编译二进制文件中位置的映射,但这可能不是完成您想要的最直接的方法。)

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

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

于 2013-03-08T02:35:37.597 回答
2

如果您确实打算做一些相对完整的事情,那么编写自己的语言是一项艰巨的任务。上千行代码绝对是可能的。在我 30 年的职业生涯和业余爱好中,我参与了各种形式的工作——从在调试器中编写简单的命令解析器或类似的运行良好的“迷你基本”解释器和小型 Lisp 解释器。我还制作了很多“伪语言”,其中将文本文件用作程序的输入,但它不是一种成熟的编程语言 - 只有一组有限的变量。

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

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

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

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

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

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

如果您还没有编写像带变量的计算器一样的东西,那可能是一个很好的起点。

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

于 2013-03-08T02:35:05.200 回答
0

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

根据值分配函数:

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

使用你的函数指针来调用函数:

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

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

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

于 2013-03-08T02:43:18.513 回答