如何在yacc中检测多个错误

时间:2011-03-06 04:59:47

标签: yacc

在检测到程序执行停止的第一个错误后,在此代码(使用yacc的c语言解析器)中

。我该怎么做才能显示所有错误,然后只停止程序执行。我读了一些你可以使用yyerrork的地方,但我无法应用它。请帮忙。


    %token IDENTIFIER CONSTANT STRING_LITERAL SIZEOF
%token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP
%token AND_OP OR_OP MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
%token SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN
%token XOR_ASSIGN OR_ASSIGN TYPE_NAME

%token TYPEDEF EXTERN STATIC AUTO REGISTER %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID %token STRUCT UNION ENUM ELLIPSIS

%token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN

%start translation_unit %%

primary_expression : IDENTIFIER | CONSTANT | STRING_LITERAL | '(' expression ')' ;

postfix_expression : primary_expression | postfix_expression '[' expression ']' | postfix_expression '(' ')' | postfix_expression '(' argument_expression_list ')' | postfix_expression '.' IDENTIFIER | postfix_expression PTR_OP IDENTIFIER | postfix_expression INC_OP | postfix_expression DEC_OP ;

argument_expression_list : assignment_expression | argument_expression_list ',' assignment_expression ;

unary_expression : postfix_expression | INC_OP unary_expression | DEC_OP unary_expression | unary_operator cast_expression | SIZEOF unary_expression | SIZEOF '(' type_name ')' ;

unary_operator : '&' | '*' | '+' | '-' | '~' | '!' ;

cast_expression : unary_expression | '(' type_name ')' cast_expression ;

multiplicative_expression : cast_expression | multiplicative_expression '*' cast_expression | multiplicative_expression '/' cast_expression | multiplicative_expression '%' cast_expression ;

additive_expression : multiplicative_expression | additive_expression '+' multiplicative_expression | additive_expression '-' multiplicative_expression ;

shift_expression : additive_expression | shift_expression LEFT_OP additive_expression | shift_expression RIGHT_OP additive_expression ;

relational_expression : shift_expression | relational_expression '<' shift_expression | relational_expression '>' shift_expression | relational_expression LE_OP shift_expression | relational_expression GE_OP shift_expression ;

equality_expression : relational_expression | equality_expression EQ_OP relational_expression | equality_expression NE_OP relational_expression ;

and_expression : equality_expression | and_expression '&' equality_expression ;

exclusive_or_expression : and_expression | exclusive_or_expression '^' and_expression ;

inclusive_or_expression : exclusive_or_expression | inclusive_or_expression '|' exclusive_or_expression ;

logical_and_expression : inclusive_or_expression | logical_and_expression AND_OP inclusive_or_expression ;

logical_or_expression : logical_and_expression | logical_or_expression OR_OP logical_and_expression ;

conditional_expression : logical_or_expression | logical_or_expression '?' expression ':' conditional_expression ;

assignment_expression : conditional_expression | unary_expression assignment_operator assignment_expression ;

assignment_operator : '=' | MUL_ASSIGN | DIV_ASSIGN | MOD_ASSIGN | ADD_ASSIGN | SUB_ASSIGN | LEFT_ASSIGN | RIGHT_ASSIGN | AND_ASSIGN | XOR_ASSIGN | OR_ASSIGN ;

expression : assignment_expression | expression ',' assignment_expression ;

constant_expression : conditional_expression ;

declaration : declaration_specifiers ';' | declaration_specifiers init_declarator_list ';' ;

declaration_specifiers : storage_class_specifier | storage_class_specifier declaration_specifiers | type_specifier | type_specifier declaration_specifiers | type_qualifier | type_qualifier declaration_specifiers ;

init_declarator_list : init_declarator | init_declarator_list ',' init_declarator ;

init_declarator : declarator | declarator '=' initializer ;

storage_class_specifier : TYPEDEF | EXTERN | STATIC | AUTO | REGISTER ;

type_specifier : VOID | CHAR | SHORT | INT | LONG | FLOAT | DOUBLE | SIGNED | UNSIGNED | struct_or_union_specifier | enum_specifier | TYPE_NAME ;

struct_or_union_specifier : struct_or_union IDENTIFIER '{' struct_declaration_list '}' | struct_or_union '{' struct_declaration_list '}' | struct_or_union IDENTIFIER ;

struct_or_union : STRUCT | UNION ;

struct_declaration_list : struct_declaration | struct_declaration_list struct_declaration ;

struct_declaration : specifier_qualifier_list struct_declarator_list ';' ;

specifier_qualifier_list : type_specifier specifier_qualifier_list | type_specifier | type_qualifier specifier_qualifier_list | type_qualifier ;

struct_declarator_list : struct_declarator | struct_declarator_list ',' struct_declarator ;

struct_declarator : declarator | ':' constant_expression | declarator ':' constant_expression ;

enum_specifier : ENUM '{' enumerator_list '}' | ENUM IDENTIFIER '{' enumerator_list '}' | ENUM IDENTIFIER ;

enumerator_list : enumerator | enumerator_list ',' enumerator ;

enumerator : IDENTIFIER | IDENTIFIER '=' constant_expression ;

type_qualifier : CONST | VOLATILE ;

declarator : pointer direct_declarator | direct_declarator ;

direct_declarator : IDENTIFIER | '(' declarator ')' | direct_declarator '[' constant_expression ']' | direct_declarator '[' ']' | direct_declarator '(' parameter_type_list ')' | direct_declarator '(' identifier_list ')' | direct_declarator '(' ')' ;

pointer : '' | '' type_qualifier_list | '' pointer | '' type_qualifier_list pointer ;

type_qualifier_list : type_qualifier | type_qualifier_list type_qualifier ;

parameter_type_list : parameter_list | parameter_list ',' ELLIPSIS ;

parameter_list : parameter_declaration | parameter_list ',' parameter_declaration ;

parameter_declaration : declaration_specifiers declarator | declaration_specifiers abstract_declarator | declaration_specifiers ;

identifier_list : IDENTIFIER | identifier_list ',' IDENTIFIER ;

type_name : specifier_qualifier_list | specifier_qualifier_list abstract_declarator ;

abstract_declarator : pointer | direct_abstract_declarator | pointer direct_abstract_declarator ;

direct_abstract_declarator : '(' abstract_declarator ')' | '[' ']' | '[' constant_expression ']' | direct_abstract_declarator '[' ']' | direct_abstract_declarator '[' constant_expression ']' | '(' ')' | '(' parameter_type_list ')' | direct_abstract_declarator '(' ')' | direct_abstract_declarator '(' parameter_type_list ')' ;

initializer : assignment_expression | '{' initializer_list '}' | '{' initializer_list ',' '}' ;

initializer_list : initializer | initializer_list ',' initializer ;

statement : labeled_statement | compound_statement | expression_statement | selection_statement | iteration_statement | jump_statement ;

labeled_statement : IDENTIFIER ':' statement | CASE constant_expression ':' statement | DEFAULT ':' statement ;

compound_statement : '{' '}' | '{' statement_list '}' | '{' declaration_list '}' | '{' declaration_list statement_list '}' ;

declaration_list : declaration | declaration_list declaration ;

statement_list : statement | statement_list statement ;

expression_statement : ';' | expression ';' ;

selection_statement : IF '(' expression ')' statement | IF '(' expression ')' statement ELSE statement | SWITCH '(' expression ')' statement ;

iteration_statement : WHILE '(' expression ')' statement | DO statement WHILE '(' expression ')' ';' | FOR '(' expression_statement expression_statement ')' statement | FOR '(' expression_statement expression_statement expression ')' statement ;

jump_statement : GOTO IDENTIFIER ';' | CONTINUE ';' | BREAK ';' | RETURN ';' | RETURN expression ';' ;

translation_unit : external_declaration | translation_unit external_declaration ;

external_declaration : function_definition | declaration ;

function_definition : declaration_specifiers declarator declaration_list compound_statement | declaration_specifiers declarator compound_statement | declarator declaration_list compound_statement | declarator compound_statement ;

%%

include

extern char yytext[]; extern int column;

yyerror(s) char *s; { fflush(stdout); printf("\n%*s\n%*s\n", column, "^", column, s); }

2 个答案:

答案 0 :(得分:1)

您需要为yacc提供一些规则以从语法错误中恢复并尝试继续。在语法中,您可以添加如下规则:

declaration: error ';'

此规则可以从解析声明时看到的错误中恢复 - 解析器将扫描输入,直到看到';'并说这是声明的结束并试图从那里继续。您还可以添加以下规则:

struct_or_union_specifier
    : struct_or_union IDENTIFIER '{' error '}'
    | struct_or_union '{' error '}'

在结构说明符中遇到错误时跳到下一个}。您可以尝试添加更多规则,但要弄清楚在任何给定情况下将使用哪个错误恢复规则变得棘手(yacc弹出状态,直到找到有错误操作的状态,因此您确实需要了解状态它为你的解析器构建的机器)

答案 1 :(得分:0)

男孩这让我回来了几年。我以为民间现在使用Bison。从错误中恢复是很棘手的,YACC试图重新纠正错误。我记得有时候不得不玩堆栈,并使用yyerrok以便解析器可以继续。请记住,当事情向南移动时,通常有充分的理由,而这种充分的理由会产生许多误报。也就是说,如果你知道你的语法很多,如果你愿意调整你的语法,那么一些非常好的错误恢复是可能的。

我找到了以前使用的引用的网址:http://dinosaur.compilertools.net/yacc/index.html

相关问题