我想要的Yacc规则没有';不减少

我想要的Yacc规则没有';不减少,c,yacc,lex,C,Yacc,Lex,我有一个问题,我的规则不能减少。首先,我想编写一个Yacc规则来检测语句: STUDENT_T* pSearch=pHead; 所以我写了如下规则: struct_initialize: IDENTIFIER '*' IDENTIFIER '=' IDENTIFIER ';'; struct_declaration : struct_initialize | specifier_qualifier_list ';' /* for anonymous struct/union */ {pr

我有一个问题,我的规则不能减少。首先,我想编写一个Yacc规则来检测语句:

STUDENT_T* pSearch=pHead; 
所以我写了如下规则:

struct_initialize: IDENTIFIER '*' IDENTIFIER '=' IDENTIFIER ';';
struct_declaration
: struct_initialize
| specifier_qualifier_list ';'  /* for anonymous struct/union */ {printf("29\n");}
| specifier_qualifier_list struct_declarator_list ';' {printf("30\n");}
| static_assert_declaration {printf("31\n");}
;
然后我将
struct\u initialize
放在规则上,如下所示:

struct_initialize: IDENTIFIER '*' IDENTIFIER '=' IDENTIFIER ';';
struct_declaration
: struct_initialize
| specifier_qualifier_list ';'  /* for anonymous struct/union */ {printf("29\n");}
| specifier_qualifier_list struct_declarator_list ';' {printf("30\n");}
| static_assert_declaration {printf("31\n");}
;
我的完整Yacc文件如下:

%token  IDENTIFIER I_CONSTANT F_CONSTANT STRING_LITERAL FUNC_NAME 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
%token  TYPEDEF_NAME ENUMERATION_CONSTANT

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

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

%token  ALIGNAS ALIGNOF ATOMIC GENERIC NORETURN STATIC_ASSERT THREAD_LOCAL

%token INCLUDE


%start translation_unit
%{

    #include<stdio.h>
    #include<string.h>
    extern FILE* yyin;
int yylex();
void yyerror(const char *s);

%}
%union{
    char* a;
    char* b;
}

/*%type <a>IDENTIFIER
*%type <a>SIGNED UNSIGNED
*%type <a>INT CHAR DOUBLE FLOAT LONG SHORT
*%type <b>EXTERN STATIC AUTO REGISTER*/

%%

include
: '#' INCLUDE '<' IDENTIFIER '.' IDENTIFIER '>'
| '#' INCLUDE  STRING_LITERAL
;

struct_initialize
: IDENTIFIER '*' IDENTIFIER '=' IDENTIFIER ';'
;



primary_expression
: IDENTIFIER    {printf("1\n");}
| constant
| string
| '(' expression ')'
| generic_selection
;

constant
: I_CONSTANT        /* includes character_constant */ {printf("2\n");}
| F_CONSTANT
| ENUMERATION_CONSTANT  /* after it has been defined as such */
;

enumeration_constant        /* before it has been defined as such */
: IDENTIFIER {printf("3\n");}
;

string
: STRING_LITERAL
| FUNC_NAME
;

generic_selection
: GENERIC '(' assignment_expression ',' generic_assoc_list ')'
;

generic_assoc_list
: generic_association
| generic_assoc_list ',' generic_association
;

generic_association
: type_name ':' assignment_expression
| DEFAULT ':' assignment_expression
;

postfix_expression
: primary_expression  {printf("59\n");}
| postfix_expression '[' expression ']' {printf("60\n");}
| postfix_expression '(' ')' {printf("61\n");}
| postfix_expression '(' argument_expression_list ')' {printf("62\n");}
| postfix_expression '.' IDENTIFIER {printf("63\n");}
| postfix_expression PTR_OP IDENTIFIER {printf("64\n");}
| postfix_expression INC_OP
| postfix_expression DEC_OP
| '(' type_name ')' '{' initializer_list '}' {printf("65\n");}
| '(' type_name ')' '{' initializer_list ',' '}' {printf("66\n");}
;

argument_expression_list
: assignment_expression
| argument_expression_list ',' assignment_expression
;

unary_expression
: postfix_expression {printf("67\n");}
| INC_OP unary_expression
| DEC_OP unary_expression
| unary_operator cast_expression {printf("71\n");}
| SIZEOF unary_expression
| SIZEOF '(' type_name ')'
| ALIGNOF '(' type_name ')'
;

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

cast_expression
: unary_expression {printf("68\n");}
| '(' type_name ')' cast_expression {printf("69\n");}
;

multiplicative_expression
: cast_expression {printf("70\n");}
| multiplicative_expression '*' cast_expression
| multiplicative_expression '/' cast_expression
| multiplicative_expression '%' cast_expression
;

additive_expression
: multiplicative_expression {printf("71\n");}
| additive_expression '+' multiplicative_expression
| additive_expression '-' multiplicative_expression
;

shift_expression
: additive_expression {printf("72\n");}
| shift_expression LEFT_OP additive_expression
| shift_expression RIGHT_OP additive_expression
;

relational_expression
: shift_expression {printf("73\n");}
| relational_expression '<' shift_expression
| relational_expression '>' shift_expression
| relational_expression LE_OP shift_expression
| relational_expression GE_OP shift_expression
;

equality_expression
: relational_expression {printf("74\n");}
| equality_expression EQ_OP relational_expression
| equality_expression NE_OP relational_expression
;

and_expression
: equality_expression {printf("75\n");}
| and_expression '&' equality_expression
;

exclusive_or_expression
: and_expression {printf("76\n");}
| exclusive_or_expression '^' and_expression
;

inclusive_or_expression
: exclusive_or_expression {printf("77\n");}
| inclusive_or_expression '|' exclusive_or_expression
;

logical_and_expression
: inclusive_or_expression {printf("78\n");}
| logical_and_expression AND_OP inclusive_or_expression
;

logical_or_expression
: logical_and_expression {printf("79\n");}
| logical_or_expression OR_OP logical_and_expression
;

conditional_expression
: logical_or_expression {printf("80\n");}
| logical_or_expression '?' expression ':' conditional_expression
;

assignment_expression
: conditional_expression {printf("81\n");}
| unary_expression assignment_operator assignment_expression {printf("69\n");}
;

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 {printf("82\n");}
| expression ',' assignment_expression
;

constant_expression
: conditional_expression    /* with constraints */
;

declaration
: declaration_specifiers ';'    /* no rule need*/ {printf("4\n");}
| declaration_specifiers init_declarator_list ';' /* int a;*/ {printf("5\n");}
| static_assert_declaration {printf("6\n");}
;

declaration_specifiers
: storage_class_specifier declaration    {printf("7\n");}
| storage_class_specifier               {printf("8\n");}
| type_specifier declaration_specifiers {printf("9\n");}
| type_specifier {printf("10\n");}
| type_qualifier declaration_specifiers{printf("11\n");}
| type_qualifier {printf("12\n");}
| function_specifier declaration_specifiers {printf("13\n");}
| function_specifier {printf("14\n");}
| alignment_specifier declaration_specifiers {printf("15\n");}
| alignment_specifier {printf("16\n");}
;

init_declarator_list
: init_declarator {printf("17\n");}
| init_declarator_list ',' init_declarator {printf("18\n");}
;

init_declarator
: declarator '=' initializer {printf("19\n");}
| declarator {printf("20\n");}
;

storage_class_specifier
: TYPEDEF   /* identifiers must be flagged as TYPEDEF_NAME */ {printf("21\n");}
| EXTERN
| STATIC
| THREAD_LOCAL
| AUTO
| REGISTER
;

type_specifier
: VOID
| CHAR
| SHORT
| INT
| LONG
| FLOAT
| DOUBLE
| SIGNED
| UNSIGNED
| BOOL
| COMPLEX
| IMAGINARY     /* non-mandated extension */
| atomic_type_specifier
| struct_or_union_specifier
| enum_specifier
| TYPEDEF_NAME      /* after it has been defined as such */ {printf("22\n");}
;



struct_or_union_specifier
: struct_or_union '{' struct_declaration_list '}' {printf("23\n");}
| struct_or_union IDENTIFIER '{' struct_declaration_list '}' {printf("24\n");}
| struct_or_union IDENTIFIER {printf("25\n");}
;

struct_or_union
: STRUCT
| UNION
;

struct_declaration_list
: struct_declaration {printf("26\n");}
| struct_declaration_list struct_declaration {printf("27\n");}
;

struct_declaration
: struct_initialize
| specifier_qualifier_list ';'  /* for anonymous struct/union */ {printf("29\n");}
| specifier_qualifier_list struct_declarator_list ';' {printf("30\n");}
| static_assert_declaration {printf("31\n");}
;

specifier_qualifier_list
: type_specifier specifier_qualifier_list {printf("32\n");}
| type_specifier {printf("33\n");}
| type_qualifier specifier_qualifier_list {printf("34\n");}
| type_qualifier {printf("35\n");}
;

struct_declarator_list
: struct_declarator {printf("36\n");}
| struct_declarator_list ',' struct_declarator {printf("37\n");}
;

struct_declarator
: ':' constant_expression {printf("38\n");}
| declarator ':' constant_expression {printf("39\n");}
| declarator {printf("40\n");}
;

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

enumerator_list
: enumerator
| enumerator_list ',' enumerator
;

enumerator  /* identifiers must be flagged as ENUMERATION_CONSTANT */
: enumeration_constant '=' constant_expression
| enumeration_constant
;

atomic_type_specifier
: ATOMIC '(' type_name ')'
;

type_qualifier
: CONST
| RESTRICT
| VOLATILE
| ATOMIC
;

function_specifier
: INLINE
| NORETURN
;

alignment_specifier
: ALIGNAS '(' type_name ')'
| ALIGNAS '(' constant_expression ')'
;

declarator
: pointer direct_declarator
| direct_declarator
;

direct_declarator
: IDENTIFIER  {printf("41\n");}
| '(' declarator ')' {printf("42\n");}
| direct_declarator '[' ']' {printf("43\n");}
| direct_declarator '[' '*' ']' {printf("44\n");}
| direct_declarator '[' STATIC type_qualifier_list assignment_expression ']' {printf("45\n");}
| direct_declarator '[' STATIC assignment_expression ']' {printf("46\n");}
| direct_declarator '[' type_qualifier_list '*' ']'
| direct_declarator '[' type_qualifier_list STATIC assignment_expression ']'
| direct_declarator '[' type_qualifier_list assignment_expression ']'
| direct_declarator '[' type_qualifier_list ']' {printf("47\n");}
| direct_declarator '[' assignment_expression ']' {printf("48\n");}
| direct_declarator '(' parameter_type_list ')' {printf("49\n");}
| direct_declarator '(' ')' {printf("50\n");}
| direct_declarator '(' identifier_list ')' {printf("51\n");}
;

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

type_qualifier_list
: type_qualifier {printf("52\n");}
| type_qualifier_list type_qualifier {printf("53\n");}
;


parameter_type_list
: parameter_list ',' ELLIPSIS
| parameter_list
;

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 abstract_declarator
| specifier_qualifier_list
;

abstract_declarator
: pointer direct_abstract_declarator
| pointer
| direct_abstract_declarator
;

direct_abstract_declarator
: '(' abstract_declarator ')'
| '[' ']'
| '[' '*' ']'
| '[' STATIC type_qualifier_list assignment_expression ']'
| '[' STATIC assignment_expression ']'
| '[' type_qualifier_list STATIC assignment_expression ']'
| '[' type_qualifier_list assignment_expression ']'
| '[' type_qualifier_list ']'
| '[' assignment_expression ']'
| direct_abstract_declarator '[' ']'
| direct_abstract_declarator '[' '*' ']'
| direct_abstract_declarator '[' STATIC type_qualifier_list assignment_expression ']'
| direct_abstract_declarator '[' STATIC assignment_expression ']'
| direct_abstract_declarator '[' type_qualifier_list assignment_expression ']'
| direct_abstract_declarator '[' type_qualifier_list STATIC assignment_expression ']'
| direct_abstract_declarator '[' type_qualifier_list ']'
| direct_abstract_declarator '[' assignment_expression ']'
| '(' ')'
| '(' parameter_type_list ')'
| direct_abstract_declarator '(' ')'
| direct_abstract_declarator '(' parameter_type_list ')'
;

initializer
: '{' initializer_list '}'
| '{' initializer_list ',' '}'
| assignment_expression {printf("83\n");}
;

initializer_list
: designation initializer
| initializer
| initializer_list ',' designation initializer
| initializer_list ',' initializer
;

designation
: designator_list '=' {printf("54\n");}
;

designator_list
: designator {printf("55\n");}
| designator_list designator {printf("56\n");}
;

designator
: '[' constant_expression ']'
| '.' IDENTIFIER
;

static_assert_declaration
: STATIC_ASSERT '(' constant_expression ',' STRING_LITERAL ')' ';'
;

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
: '{' '}'
| '{'  block_item_list '}'
;

block_item_list
: block_item
| block_item_list block_item
;

block_item
: declaration
| statement
;

expression_statement
: ';'
| expression ';'
;

selection_statement
: IF '(' expression ')' statement ELSE statement
| IF '(' expression ')' 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
| FOR '(' declaration expression_statement ')' statement
| FOR '(' declaration 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
| include    /********/
;

function_definition
: declaration_specifiers declarator declaration_list compound_statement
| declaration_specifiers declarator compound_statement
;

declaration_list
: declaration  {printf("57\n");}
| declaration_list declaration {printf("58\n");}
;

%%
#include <stdio.h>

void yyerror(const char *s)
{
    fflush(stdout);
    fprintf(stderr, "*** %s\n", s);
}
void parse(FILE* fileInput)
{
    yyin= fileInput;
    while(feof(yyin)==0)
    {
        yyparse();// To read file, while() and yyparse() is necessary because we need to read until the content is run out
    }
}
注意,我在Yacc文件中使用了
printf
,其中字符串文字为数字1-80进行调试。

您能告诉我哪里出了问题以及如何修复吗?

文本只包含

在您介绍的语法中无效,因为它正在被标记化

您的lexer将
STUDENT\T
作为第一个标记进行匹配,这很好。它将其分类为
标识符
,这在上下文中似乎是合理的。但在这一点上,你就死定了:没有符合语法的文本是以
标识符开头的。事实上,您的
struct\u initialize
产品可以匹配您的令牌序列,这并没有帮助,因为即使解析器将整个输入减少到该符号,也无法将其减少到
translation\u单元的剩余部分
start符号

值得一提的是,我的
yacc
(byacc 1.9)会发出一个解析器,当它看到
标识符
作为第一个标记时就会出错,我的
bison
(v2.7)也是如此。我觉得有点奇怪,您的
yacc
为您提供了一个解析器,它在认识到没有希望之前做了更多的工作,如果它确实在您指定的输入上运行的话。无论如何,我看不出有理由认为解析器产生了错误的结果


更深入地查看语法,唯一可以出现
struct\u initialize
的地方就是它可以用作
struct\u声明的地方。仅用作结构声明或联合声明内容的
结构声明列表
的一部分或全部。事实上,根据您的语法构建的解析器可以接受此文本:

struct { STUDENT_T* pSearch=pHead; };
还有一点额外的插装说明解析器使用了您的产品

struct { STUDENT_T* pSearch=pHead; };