2

我有一个 C++ 应用程序,它实际上处理一个二进制文件。二进制文件是事件的集合,例如 A/B/C,在文件中检测到事件 A 时,应用程序会在“处理程序 A”中处理事件。

现在我需要用自定义语言编写另一个脚本,该脚本与二进制文件处理正交执行。脚本可以有类似的东西,

define proc onA
{
 c= QueryVariable(cat)
print ( c )
}

因此,当应用程序处理来自二进制文件的事件“A”时,应用程序必须解析此脚本文件,检查 OnA 并将 OnA proc 中的语句转换为应用程序支持的例程。例如,QueryVariable 应该将应用程序中定义的变量“cat”的值复制到变量“C”。该应用程序还应检查脚本中语言的语法/语义。我在哪里可以获得决定设计的最佳信息?我对解析树/语法的了解真的变弱了。

谢谢

4

2 回答 2

2

构建解释器的简单方法:

  • 根据语法定义语言的解析器
  • 构建抽象语法树 AST
  • 应用访问者功能是按预先顺序遍历 AST 并“执行”由 AST 节点建议的操作。

一些 AST 节点将是“定义的”,例如,将声明某些命名实体的存在,例如上面的“define proc onA”短语。通常,动作是将命名实体与内容相关联,例如,形成一个三元组 <onA,proc,<body>> 并将其存储在由第一个条目索引的符号表中。这使得查找此类定义更加容易。

稍后,当您的事件进程遇到 A 事件时,您的应用程序知道在此符号表中查找“onA”。找到后,访问者函数将遍历 AST 以执行其内容。您通常需要一个值堆栈来记录中间表达式值,其中 AST 叶表示操作数(变量、常量)将值推送到该堆栈上,运算符(+、-、<=)弹出值并计算要推送的新结果。赋值操作取栈顶值并放入与标识符名称相关的符号表中。控制操作符(if、do)从栈顶取出值并使用它们来指导程序的哪个部分(例如,哪个子树)接下来要执行。

所有这些都是众所周知的,可以在大多数关于编译器和解释器的书籍中找到。彼得布朗关于这方面的书特别好,尽管它看起来相对较旧:

编写交互式解释器和编译器

于 2010-11-02T01:19:40.707 回答
1

脚本语言必须有一些解释器或编译器。检查它是否支持嵌入 C 或 C++。大多数脚本语言都可以。

下一个选择,或者可能是第一个选择,就是使用现有的编译器/解释器在外部运行脚本。

我想不出为什么前两个选项中的一个不可行,但如果不是,请考虑使用 ANTLR 或小型语言 Boost Spirit 构建解释器。免责声明:我没有使用过第一个,我只是尝试了 Boost Spirit 作为一个小玩具示例。

干杯&hth.,

PS:如果您可以选择脚本语言,请考虑使用 JavaScript 并使用 Google 据称出色的嵌入 API。

于 2010-10-28T16:13:37.070 回答