YACC 中的语法片段(包含或导入)

问题描述 投票:0回答:1

是否可以将不同文件中的 yacc 片段文件包含/导入到主 YACC 中?

为了举例说明我正在寻找的内容,我想为 3 个不同的文件创建 3 个语法解析器,但它们共享一个公共语法块。

所以,我想将这一语法保留在一个 yacc 片段文件中,这样我就可以更好地维护它。

parsing yacc jflex cup
1个回答
0
投票

GNU Bison 的最新版本支持多个语法起始符号。因此,您可以定义一个包含多种语言的语法文件,这些语言共享一些通用的语法规则。

使用一些外部预处理工具,您可以在多个 Yacc 文件中包含常见的语法材料。我所知道的任何类似 Yacc 的程序都不直接支持这种包含。当然,支持 C

#include
,但它会传递到 C 代码,而不是由 Yacc 处理。

在任何Yacc中,您都可以模拟具有多个开始符号的功能。这可以通过在顶级规则中处理秘密短语结构规则来完成,这些规则由秘密令牌分隔。

您需要一个

YYINPUT
运算符,让您可以在解析器和扫描器之间填充这些秘密令牌,以“启动”扫描,以便解析器能够看到秘密令牌并识别以它们为首的规则。当解析器调用
yylex()
时,它必须首先获取已注入的秘密令牌;当这些都用尽时,然后调用真正的扫描仪。

秘密令牌是不是由扫描仪生成的抽象令牌值;它们纯粹是内部的。

您可以在这个语法文件中看到该技术;查找包含

SECRET_ESCAPE_R
和其他类似终端符号的规则。

示例

SECRET_ESCAPE_R
代表正则表达式;它创建的入口点用于解析正则表达式。在这个
parser.c
文件中,有一个
regex_parse
函数,它使用参数枚举值
parse
来调用
prime_regex
。这个
prime_regex
枚举值告诉
parse
准备
SECRET_ESCAPE_R
令牌。
parse
再次出现在语法文件中,朝向底部。它使用再次在
prime_parser
中找到的助手
primer_parser_post
prime.c

该项目中的启动机制不仅处理子语法的解析,还处理来自同一流的多个表达式(或其他单元)的解析。这也是 Lex 和 Yacc “开箱即用”不能很好支持的东西。
在某些语言中,当您尝试读取一种语言的单个表达式(或定义、声明或其他单元)时,会发生的情况是 Yacc 解析器将提前读取一个标记。 (讨厌的 LALR(1) 喜欢这样做。)换句话说,在提取一个表达式时,它最终会消耗下一个表达式的令牌。

prime_parser
函数注意到之前有一个解析以某个前瞻标记结束。该令牌首先被推回流中,然后是任何将引导解析到所需子语法的秘密令牌。

© www.soinside.com 2019 - 2024. All rights reserved.