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