如何解释自定义语言

时间:2010-10-28 16:07:38

标签: c++ compiler-construction parser-generator

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

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

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

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

谢谢

2 个答案:

答案 0 :(得分:2)

构建解释器的简便方法:

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

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

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

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

Writing Interactive Interpreters and Compilers

答案 1 :(得分:1)

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

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

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

干杯&第h。,

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