=+)71*+)723
? >3
@E
此示例显示了一个用户编写的函数,该函数解析文本文件并返回指向解析树的指针。
(为了简化起见,本示例中省略了所有错误处理代码。)我们假设存在某种符号生成器,
该 符 号 生 成 器 是 在 第 @ 行 使 用 +)7 ( ) 创 建 的 , 并 在 第 = 行 由
+)7()删除的。D+)()第 行上的函数从输入文件中检索下一
个标记,并将其类型放入整数变量 +)$ 中。假设 +) 变量是某种结构,其中包
含有关每个符号的详细信息,例如其完整文本,它出现在哪一行等。
此示例还假设存在 /> 类型的结构,该结构保存有关特定解析的状态信息。
这种结构的实例在第 = 行上创建,并在第 5 行上初始化。指向该结构的指针作为可选的
第 ; 个 参 数 传 递 到 / ( ) 函 数 中 。 语 法 为 解 析 器 指 定 的 操 作 函 数 可 以 使 用
/> 结构保存任何有用和适当的信息。在该示例中,我们注意到 /> 结
构的 字段指向分析树的根。
与 有关的此示例的核心如下:
/128
*/0/123
C1D+)1*+)74B+)$4B+)228
/1*/4+)$4+)23
E
/1*/454+)23
/1*/4&23
E
基本上,程序使用 生成的解析器所要做的是首先创建解析器,然后向其发送通
过对输入源进行标记化获得的许多标记。当到达输入结尾时,应该使用标记类型 5 上次调
用 /()函数。此步骤对于通知解析器已经到达输入结尾是必需的。最后,我们通过
调用 /()回收解析器使用的内存。
在继续之前,还应该提到另一个接口函数。/+()函数可用于从解析器生成
调试输出。该函数的原型如下:
/+1'.4.7/,23
调用此函数后,每次解析器更改状态或调用操作函数时,都会向指定的输出流中写入
一条短(单行)消息。每个此类消息均使用 7/, 给定的文本作为开头。可以通过使用
第一个参数 DF(5)再次调用 /+()来关闭此调试输出。
5 与 YACC 和 BISON 的差异
以前使用 或 解析器生成器的程序员会注意到 和G或 与
之间的一些重要区别。
在 和 中,解析器调用分词器。在 中,分词器调用解析器。
不使用全局变量。H 和 使用全局变量在符号生成器和解析器之间传
递信息。
允许多个解析器同时运行。H 和 则没有。