目前我正在研究源到源编译器,我已经编写了一个野牛解析器,可以正确地为输入创建AST.我现在需要在语法树上进行几次转换,因此我需要在树中插入许多节点.
我可以手动创建我想要添加到语法树的所有结构/联合,但这似乎非常有效.
对我来说,创建一个字符串要容易得多,我希望这个字符串能够被我已经拥有的解析器解析.然后,解析器应返回此字符串的树,我可以在原始语法树中插入该字符串.
不幸的是,字符串无法使用我的解析器的启动规则进行解析,因为它必须由子规则解析(例如,我的解析器解析包含语句的函数列表,字符串是单个语句).
如何让bison解析字符串,从不同于起始规则的规则开始?
提前致谢!
有一个简单的hack,在bison FAQ中有描述..
基本上,对于您希望能够使用的每个非终端,您创建一个伪令牌,然后创建一个"元启动"非终端,它选择您要使用的终端:
%token START_PROGRAM
%token START_STATEMENT
%token START_EXPRESSION
%start meta_start
%%
meta_start: START_PROGRAM program
| START_STATEMENT statement
| START_EXPRESSION expression
;
Run Code Online (Sandbox Code Playgroud)
(在每个制作的动作中,您将保存$2调用者可以获得的某个值.)
现在你只需要安排你的词法分析器来提供正确的开始令牌.您可以通过使用纯解析器和纯词法分析器并通过共享数据结构传递消息来实现此目的.这将是最好的方法,但为了这个答案的目的,我将展示如何使用全局变量,因为原理是相同的:
extern int start_token;
// If all your start non-terminals produce a value of the same type, possibly a union
// type, you could arrange to return it instead of the error report.
int yyparse(int start) {
// I left out the code to cause the lexer to scan a given string.
start_token = start;
return real_yyparse();
}
int yylex() {
int rv = start_token;
if (start_token)
start_token = 0;
else
rv = real_yylex();
return rv;
}
Run Code Online (Sandbox Code Playgroud)