如何更改yyerror函数的参数

时间:2016-12-09 12:00:18

标签: c yacc lex

yyerror打印"语法错误"在默认情况下。我想更改yyerror函数的参数。通过这种方式,我可以向用户打印更多信息性错误消息。例如在函数decleration中用户做了错误的事情。如果我可以更改yyerror函数的参数,我可以向用户打印更有意义的消息。

func_Dec:error_code = 1 .... var_dec:error_code = 2 ....

根据error_code值。我可以在yyerror函数中打印这样的错误信息:

void yyerror(int x){
if(x==1){printf("error while function decleration");};
if(x==2){printf("error while variable decleration ");};
}

2 个答案:

答案 0 :(得分:2)

这将非常困难/不可能。

当yacc遇到不在其预先设置中的令牌时,它会减少,直到堆栈上的状态变为可见,其中令牌有效。一旦它减少(弹出)所有状态并且堆栈变空,就会得出它与令牌不匹配并报告public static double cos(double x, int n) { // declaring cos and factorial double cos = 0.0; // this loop determines how long does the loop go so the answer is more // accurate for (long howlong = 1; howlong <= n; howlong++) { // now we need to create the pattern for the + and - // so we use % that switches the sign everytime i increments by 1 if (howlong % 2 == 1) { cos = cos + Math.pow(x, 2 * howlong - 2) / factorial(2 * howlong - 2); } else { cos = cos - Math.pow(x, 2 * howlong - 2) / factorial(2 * howlong - 2); } } return cos; } public static long factorial(long n) { long result = 1; for (int i = 2; i <= n; i++) { result *= i; } return result; }

你可以做的是保持自己的状态信息,并在Syntax error中使用它。

您可以自己编写yyerror功能。通常,如果未提供yyerror函数,yacc将使用库中的默认函数。但你可以自己写一个,例如:

yyerror

答案 1 :(得分:0)

如果您使用Gnu Bison作为yacc实现,您可以使用

请求更多信息性错误消息
%define parse.error verbose

通常情况下,您还需要请求"LAC"(前瞻校正),这会改善令牌预测,但会产生效率成本:

%define parse.lac full

您还可以使用error productions生成与上下文相关的错误消息,但请注意,在错误操作之前已经调用了yyerror。因此,您需要在yyerror中禁止打印输出,或者安排yyerror输出和错误操作的输出相互补充。

最后,考虑使用(f)lex的位置跟踪机制,以便至少可以为错误消息添加行号。