声明:本文梳理自 Bison 参考手册:https://www.gnu.org/software/bison/manual/bison.html;部分借鉴自通义千问 AI。
4.1 解析函数 yyparse
你调用函数 yyparse 来触发解析过程。这个函数读取标记(tokens),执行动作,并最终在遇到输入结束或无法恢复的语法错误时返回。你也可以编写一个动作来指示 yyparse 立即返回,不再进一步读取。
函数|int yyparse (void)
:如果解析成功(即返回是由于输入结束),则 yyparse()
函数的返回值是 0。如果解析因为无效输入而失败,即包含语法错误的输入或导致 YYABORT
被调用的情况,则返回值是 1。如果解析由于内存耗尽而失败,则返回值是 2。
在语义组行为(action)中,可以使用以下宏来使 yyparse 立即返回:
宏|YYACCEPT
:立即返回 0(解析成功)
宏|YYABORT
:立即返回 1(因无效输入而失败)
宏|YYNOMEM
:立即返回 2(因内存不足而失败)
如果你使用了一个可重入的解析器,可以选择以可重入的方式向其传递额外的参数信息。要做到这一点,可以使用声明 %parse-param
。
声明|%parse-param {argument-declaration} ...
:声明一个或多个参数声明为附加的 yyparse()
函数参数。参数声明在声明函数或原型时使用。参数声明中的最后一个标识符必须是参数名。
这是一个示例。在解析器中这样写:
%parse-param {int *nastiness} {int *randomness}
然后像这样调用解析器:
{
int nastiness, randomness;
… /* 将适当的数据存入 nastiness 和 randomness 中。*/
value = yyparse (&nastiness, &randomness);
…
}
在语义组行为(action)中,可以使用如下表达式来引用这些数据:
exp: … { …; *randomness += 1; … }
使用下面的声明:
%parse-param {int *randomness}
将会得到如下的函数签名:
void yyerror (int *randomness, const char *msg);
int yyparse (int *randomness);
或者,如果同时使用了 %define api.pure full
(或仅 %define api.pure
)和 %locations
:
void yyerror (YYLTYPE *llocp, int *randomness, const char *msg);
int yyparse (int *randomness);
这里的 YYLTYPE
是用于存储位置信息的数据类型。