你好,我正在尝试制作一个简单的解析器并使用 lex 和 yacc。问题是我想打印我自己的错误消息而不是error
yacc 使用的打印符号syntax error
。例如这是我的 yacc 代码;
%{
#include <stdio.h>
#include <string.h>
#include "y.tab.h"
extern FILE *yyin;
extern int linenum;
%}
%token INTRSW IDENTIFIER INTEGER ASSIGNOP SEMICOLON DOUBLEVAL DOUBLERSW COMMA
%token IF ELSE WHILE FOR
%token CLOSE_BRA OPEN_BRA CLOSE_PARA OPEN_PARA EQ LE GE
%token SUM MINUS MULTIP DIV
%left OPEN_BRA OPEN_PARA
%left MULTIP DIV
%left SUM MINUS
%union
{
int number;
char* string;
}
%token <number> INTEGER
%token <string> IDENTIFIER
%%
program:
statement_list
;
statement_list:
statement_list statement
|
statement
;
statement:
if_statement OPEN_BRA statement_list CLOSE_BRA
|
if_statement
|
assignment_block
|
single_assignment
;
if_statement:
IF OPEN_PARA condition_statement CLOSE_PARA
;
condition_statement:
logical_expression
;
logical_expression:
expression EQ expression
|
expression LE expression
|
expression GE expression
;
expression:
double
|
IDENTIFIER
|
OPEN_PARA expression CLOSE_PARA
|
expression MULTIP expression
|
expression DIV expression
|
expression SUM expression
|
expression MINUS expression
;
assignment_block:
integer_assignment_block
|
double_assignment_block
;
integer_assignment_block:
INTRSW integer_assignment_list SEMICOLON
;
double_assignment_block:
DOUBLERSW double_assignment_list SEMICOLON
;
integer_assignment_list:
integer_assignment
|
integer_assignment_list COMMA integer_assignment
;
double_assignment_list:
double_assignment
|
double_assignment_list COMMA double_assignment
;
single_assignment:
IDENTIFIER ASSIGNOP double SEMICOLON
|
IDENTIFIER ASSIGNOP IDENTIFIER SEMICOLON
|
error ';' { printf("You made en error"); }
;
integer_assignment:
IDENTIFIER ASSIGNOP INTEGER
|
IDENTIFIER
;
double_assignment:
IDENTIFIER ASSIGNOP double
|
IDENTIFIER
;
double:
DOUBLEVAL
|
INTEGER
;
%%
void yyerror(char *s){
fprintf(stderr,"%s Error at line: %d\n",s, linenum);
}
int yywrap(){
return 1;
}
int main(int argc, char *argv[])
{
/* Call the lexer, then quit. */
yyin=fopen(argv[1],"r");
yyparse();
fclose(yyin);
return 0;
}
所以这是我添加错误语句的块。
single_assignment:
IDENTIFIER ASSIGNOP double SEMICOLON
|
IDENTIFIER ASSIGNOP IDENTIFIER SEMICOLON
|
error ';' { printf("You made en error"); }
;
所以我在一行中写了 a=7 (没有“;”),它只是说syntax error Error at line:7
。那么我的错误消息在哪里_?如果您能帮助我解决这个问题,我将非常非常高兴。无论如何,谢谢
所以我在一行中写了 a=7 (没有“;”),它只是说语法错误错误
位于第 7 行。那么我的错误消息在哪里_?
Your error
action 告诉 Yacc 丢弃标记,直到找到 ';'令牌。在此之前,它不能按照该规则减少。
另外,你应该执行yyerrok;
规则体中的某个位置向解析器发出信号表明恢复已实现。或者,您可以使用yyclearin;
同时丢弃触发错误的令牌。这样做很棘手,因为您猜测该令牌不合适。它实际上可能是正确的令牌,但在它之前缺少了其他东西!例如,您看到一个分号,因为省略了右大括号等。
错误动作不会replace打电话的行为yyerror
。当发生语法错误时,解析器将调用yyerror
带有消息(通常是“语法错误”),然后考虑错误产生式。错误产生式与“语法错误的自定义覆盖”完全不同。 (看起来您希望将“语法错误”替换为您自己的通用错误消息“您犯了一个错误”。)
在错误产生中,如果您可以猜测错误的性质,则可以打印更有帮助的附加诊断信息。
有用的一件事是yychar
告诉您先行标记的变量。您可以在错误恢复规则中检查这一点,并尝试根据其值猜测出了什么问题。您不仅可以检查您自己的令牌类型,还可以检查其值YYEOF
这表明语法错误不是由于到达了一些错误的标记,而是由于到达了输入的结尾。
我编写了一个解析器,在某些错误产生中,我只是简单地从yychar
并将其转换为其描述性名称并打印消息“unexpected in”。这总比没有好;它告诉用户语法在哪个标记处偏离了预期。
此外,yacc 解析器即使在正确的解析中也可以生成诊断信息! (显然;例如,否则您将如何为一种语言实现警告。)基本上,您需要一些可以自己调用的中央错误报告函数,并且yyerror
也会打电话。该函数应该设置一个标志,指示是否发生致命错误(或记录错误、警告等的数量)。例如,如果存在致命错误,即使解析器从任何语法错误中恢复,您也可能希望丢弃解析树并以失败的终止状态保释程序。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)