2016-12-16 32 views
0

我有一個關於Yacc的問題。這是我用於解析C語言語法的Yacc代碼。需要注意的是,下面的代碼是唯一的完整代碼的一些相關部分:如何在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 

%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 

%% 
declaration 
: declaration_specifiers ';' 
| declaration_specifiers init_declarator_list ';' { printf("semicolon:%s\n", $<a>3);} 
| static_assert_declaration 
; 

declaration_specifiers 
: storage_class_specifier declaration_specifiers 
| storage_class_specifier      
| type_specifier declaration_specifiers  
| type_specifier        
| type_qualifier declaration_specifiers  
| type_qualifier        
| function_specifier declaration_specifiers 
| function_specifier 
| alignment_specifier declaration_specifiers 
| alignment_specifier 
; 

init_declarator_list 
: init_declarator       
| init_declarator_list ',' init_declarator {printf("The comma:%s\n",$<a>2);} 
; 

type_specifier 
: VOID           {printf("type_specifier:%s\n",$<a>1);} 
| CHAR           {printf("type_specifier:%s\n",$<a>1);} 
| SHORT           {printf("type_specifier:%s\n",$<a>1);} 
| INT           {printf("type_specifier:%s\n",$<a>1);} 
| LONG           {printf("type_specifier:%s\n",$<a>1);} 
| FLOAT           {printf("type_specifier:%s\n",$<a>1);} 
| DOUBLE          {printf("type_specifier:%s\n",$<a>1);} 
| SIGNED          {printf("type_specifier:%s\n",$<a>1);} 
| UNSIGNED          {printf("type_specifier:%s\n",$<a>1);} 
| BOOL           {printf("type_specifier:%s\n",$<a>1);} 
| COMPLEX          {printf("type_specifier:%s\n",$<a>1);} 
| IMAGINARY  /* non-mandated extension */ {printf("type_specifier:%s\n",$<a>1);} 
| atomic_type_specifier       {printf("type_specifier:%s\n",$<a>1);} 
| struct_or_union_specifier      {printf("type_specifier:%s\n",$<a>1);} 
| enum_specifier        {printf("type_specifier:%s\n",$<a>1);} 
| TYPEDEF_NAME {printf("type_specifier:%s\n",$<a>1);} 
; 

declarator 
: pointer direct_declarator 
| direct_declarator 
; 

direct_declarator 
: IDENTIFIER {printf("The identifier: %s\n", $<a>1);} 
| '(' declarator ')' 
| direct_declarator '[' ']'  
| direct_declarator '[' '*' ']' 
| direct_declarator '[' STATIC type_qualifier_list assignment_expression ']' 
| direct_declarator '[' STATIC assignment_expression ']' 
| 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 ']' 
| direct_declarator '[' assignment_expression ']' 
| direct_declarator '(' parameter_type_list ')' 
| direct_declarator '(' ')' 
| direct_declarator '(' identifier_list ')' 
; 

,這裏是對應的Yacc代碼(同樣,這些僅僅是相關部分)我萊克斯代碼:

"int"     { yylval.a=strdup(yytext); return(INT); } /* Data Type*/ 
"long"     { yylval.a=strdup(yytext); return(LONG); } 
"char"     { yylval.a=strdup(yytext); return(CHAR); } 
"short"     { yylval.a=strdup(yytext); return(SHORT); } 
"signed"    { yylval.a=strdup(yytext); return(SIGNED); } 
"double"    { yylval.a=strdup(yytext); return(DOUBLE); } 
"unsigned"    { yylval.a=strdup(yytext); return(UNSIGNED); } 
"float"     { yylval.a=strdup(yytext); return(FLOAT); } 
";"      { yylval.a=strdup(yytext); return ';'; } 
","      { yylval.a=strdup(yytext); return ','; } 

我的問題是,當我的命令,比如輸入輸入:

int a,b; 

它應該打印:

type_specifier:int 
The identifier: a 
The comma:, 
The identifier:b 
semicolon:; 

,但我的輸出是

type_specifier:int 
The identifier: a 
The identifier: b 
The comma:, 
semicolon:; 

我應該怎麼做,使例程:{printf("The comma:%s\n",$<a>2);}激活2個IDENTIFIER {printf("The identifier: %s\n", $<a>1);}

參考之間(原始版本)

https://www.lysator.liu.se/c/ANSI-C-grammar-y.html

https://www.lysator.liu.se/c/ANSI-C-grammar-l.html

回答

0

在您完成init_declarator的解析之後,您的printf纔會執行。試試這個:

| init_declarator_list ',' {printf("The comma:%s\n",$<a>2);} init_declarator