1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
| %define parse.error verbose %locations %{ #include "stdio.h" #include "math.h" #include "string.h" #include "def.h" extern int yylineno; extern char *yytext; extern FILE *yyin; void yyerror(const char* fmt, ...); void display(struct node *,int); %}
%union { int type_int; float type_float; char type_char[3]; char type_string[31]; char type_id[32]; struct node *ptr; };
%type <ptr> program ExtDefList ExtDef Specifier StructSpecifier OptTag Tag ExtDecList FuncDec CompSt VarList VarDec ParamDec Stmt ForDec StmList DefList Def DecList Dec Exp Args
%token <type_int> INT %token <type_id> ID RELOP TYPE %token <type_float> FLOAT %token <type_char> CHAR %token <type_string> STRING
%token STRUCT LP RP LB RB LC RC SEMI COMMA DOT %token PPLUS MMINUS PLUS MINUS STAR DIV ASSIGNOP MINUSASSIGNOP PLUSASSIGNOP DIVASSIGNOP STARASSIGNOP AND OR NOT IF ELSE WHILE FOR RETURN
%right ASSIGNOP MINUSASSIGNOP PLUSASSIGNOP DIVASSIGNOP STARASSIGNOP %left OR %left AND %left RELOP %left PLUS MINUS %left STAR DIV %right UMINUS NOT PPLUS MMINUS %right LB %left RB %left DOT %nonassoc LOWER_THEN_ELSE %nonassoc ELSE
%%
program: ExtDefList {display($1,0);DisplaySymbolTable($1);} ; ExtDefList: {$$=NULL;} | ExtDef ExtDefList {$$=mknode(EXT_DEF_LIST,$1,$2,NULL,yylineno);} ; ExtDef: Specifier ExtDecList SEMI {$$=mknode(EXT_VAR_DEF,$1,$2,NULL,yylineno);} | Specifier SEMI | Specifier FuncDec CompSt {$$=mknode(FUNC_DEF,$1,$2,$3,yylineno);} | error SEMI {$$=NULL;} ;
ExtDecList: VarDec {$$=$1;} | VarDec COMMA ExtDecList {$$=mknode(EXT_DEC_LIST,$1,$3,NULL,yylineno);} ;
Specifier: TYPE {$$=mknode(TYPE,NULL,NULL,NULL,yylineno);strcpy($$->type_id,$1);if(!strcmp($1, "int"))$$->type=INT;if(!strcmp($1, "float"))$$->type=FLOAT;if(!strcmp($1, "char"))$$->type=CHAR;if(!strcmp($1, "string"))$$->type=STRING;} | StructSpecifier {$$=$1;} ;
StructSpecifier: STRUCT OptTag LC DefList RC {$$=mknode(STRUCT_DEF,$2,$4,NULL,yylineno);} | STRUCT Tag {$$=mknode(STRUCT_DEC,$2,NULL,NULL,yylineno);} ;
OptTag: {$$=NULL;} | ID {$$=mknode(STRUCT_TAG,NULL,NULL,NULL,yylineno);strcpy($$->struct_name,$1);} ; Tag: ID {$$=mknode(STRUCT_TAG,NULL,NULL,NULL,yylineno);strcpy($$->struct_name,$1);} ;
VarDec: ID {$$=mknode(ID,NULL,NULL,NULL,yylineno);strcpy($$->type_id,$1);} | VarDec LB INT RB {struct node *temp=mknode(INT,NULL,NULL,NULL,yylineno);temp->type_int=$3;$$=mknode(ARRAY_DEC, $1, temp, NULL,yylineno);} ; FuncDec: ID LP VarList RP {$$=mknode(FUNC_DEC,$3,NULL,NULL,yylineno);strcpy($$->type_id,$1);} |ID LP RP {$$=mknode(FUNC_DEC,NULL,NULL,NULL,yylineno);strcpy($$->type_id,$1);} ; VarList: ParamDec {$$=mknode(PARAM_LIST,$1,NULL,NULL,yylineno);} | ParamDec COMMA VarList {$$=mknode(PARAM_LIST,$1,$3,NULL,yylineno);} ; ParamDec: Specifier VarDec {$$=mknode(PARAM_DEC,$1,$2,NULL,yylineno);} ;
CompSt: LC DefList StmList RC {$$=mknode(COMP_STM,$2,$3,NULL,yylineno);} ; StmList: {$$=NULL; } | Stmt StmList {$$=mknode(STM_LIST,$1,$2,NULL,yylineno);} ; Stmt: Exp SEMI {$$=mknode(EXP_STMT,$1,NULL,NULL,yylineno);} | CompSt {$$=$1;} | RETURN Exp SEMI {$$=mknode(RETURN,$2,NULL,NULL,yylineno);} | IF LP Exp RP Stmt %prec LOWER_THEN_ELSE {$$=mknode(IF_THEN,$3,$5,NULL,yylineno);} | IF LP Exp RP Stmt ELSE Stmt {$$=mknode(IF_THEN_ELSE,$3,$5,$7,yylineno);} | WHILE LP Exp RP Stmt {$$=mknode(WHILE,$3,$5,NULL,yylineno);} | FOR LP ForDec RP Stmt {$$=mknode(FOR,$3,$5,NULL,yylineno);} ;
ForDec: Exp SEMI Exp SEMI Exp {$$=mknode(FOR_DEC,$1,$3,$5,yylineno);} | SEMI Exp SEMI {$$=mknode(FOR_DEC,NULL,$2,NULL,yylineno);} ;
DefList: {$$=NULL; } | Def DefList {$$=mknode(DEF_LIST,$1,$2,NULL,yylineno);} ; Def: Specifier DecList SEMI {$$=mknode(VAR_DEF,$1,$2,NULL,yylineno);} ; DecList: Dec {$$=mknode(DEC_LIST,$1,NULL,NULL,yylineno);} | Dec COMMA DecList {$$=mknode(DEC_LIST,$1,$3,NULL,yylineno);} ; Dec: VarDec {$$=$1;} | VarDec ASSIGNOP Exp {$$=mknode(ASSIGNOP,$1,$3,NULL,yylineno);strcpy($$->type_id,"ASSIGNOP");} ; Exp: Exp ASSIGNOP Exp {$$=mknode(ASSIGNOP,$1,$3,NULL,yylineno);strcpy($$->type_id,"ASSIGNOP");} | Exp AND Exp {$$=mknode(AND,$1,$3,NULL,yylineno);strcpy($$->type_id,"AND");} | Exp OR Exp {$$=mknode(OR,$1,$3,NULL,yylineno);strcpy($$->type_id,"OR");} | Exp RELOP Exp {$$=mknode(RELOP,$1,$3,NULL,yylineno);strcpy($$->type_id,$2);} | Exp PLUS Exp {$$=mknode(PLUS,$1,$3,NULL,yylineno);strcpy($$->type_id,"PLUS");} | Exp PLUS PLUS {$$=mknode(PPLUS,$1,NULL,NULL,yylineno);strcpy($$->type_id,"PPLUS");} | Exp PLUS ASSIGNOP Exp {$$=mknode(PLUSASSIGNOP,$1,$4,NULL,yylineno);strcpy($$->type_id,"PLUSASSIGNOP");} | Exp MINUS Exp {$$=mknode(MINUS,$1,$3,NULL,yylineno);strcpy($$->type_id,"MINUS");} | Exp MINUS MINUS {$$=mknode(MMINUS,$1,NULL,NULL,yylineno);strcpy($$->type_id,"MMINUS");} | Exp MINUS ASSIGNOP Exp {$$=mknode(MINUSASSIGNOP,$1,$4,NULL,yylineno);strcpy($$->type_id,"MINUSASSIGNOP");} | Exp STAR Exp {$$=mknode(STAR,$1,$3,NULL,yylineno);strcpy($$->type_id,"STAR");} | Exp STAR ASSIGNOP Exp {$$=mknode(STARASSIGNOP,$1,$4,NULL,yylineno);strcpy($$->type_id,"STARASSIGNOP");} | Exp DIV Exp {$$=mknode(DIV,$1,$3,NULL,yylineno);strcpy($$->type_id,"DIV");} | Exp DIV ASSIGNOP Exp {$$=mknode(DIVASSIGNOP,$1,$4,NULL,yylineno);strcpy($$->type_id,"DIVASSIGNOP");} | LP Exp RP {$$=$2;} | MINUS Exp %prec UMINUS {$$=mknode(UMINUS,$2,NULL,NULL,yylineno);strcpy($$->type_id,"UMINUS");} | NOT Exp {$$=mknode(NOT,$2,NULL,NULL,yylineno);strcpy($$->type_id,"NOT");} | ID LP Args RP {$$=mknode(FUNC_CALL,$3,NULL,NULL,yylineno);strcpy($$->type_id,$1);} | ID LP RP {$$=mknode(FUNC_CALL,NULL,NULL,NULL,yylineno);strcpy($$->type_id,$1);} | Exp LB Exp RB {$$=mknode(EXP_ARRAY,$1,$3,NULL,yylineno);} | Exp DOT ID {struct node *temp=mknode(ID,NULL,NULL,NULL,yylineno);strcpy($$->type_id,$3);$$=mknode(EXP_ELE,$1,temp,NULL,yylineno);} | ID {$$=mknode(ID,NULL,NULL,NULL,yylineno);strcpy($$->type_id,$1);} | INT {$$=mknode(INT,NULL,NULL,NULL,yylineno);$$->type_int=$1;$$->type=INT;} | FLOAT {$$=mknode(FLOAT,NULL,NULL,NULL,yylineno);$$->type_float=$1;$$->type=FLOAT;} | CHAR {$$=mknode(CHAR,NULL,NULL,NULL,yylineno);$$->type_char=$1[1];$$->type=CHAR;} | STRING {$$=mknode(STRING,NULL,NULL,NULL,yylineno);strcpy($$->type_string,$1);$$->type=STRING;} ;
Args: Exp COMMA Args {$$=mknode(ARGS,$1,$3,NULL,yylineno);} | Exp {$$=mknode(ARGS,$1,NULL,NULL,yylineno);} ;
%%
int main(int argc, char *argv[]){ yyin=fopen(argv[1],"r"); if (!yyin) return 0; yylineno=1; yyparse(); return 0; }
#include<stdarg.h> void yyerror(const char* fmt, ...){ va_list ap; va_start(ap, fmt); fprintf(stderr, "===>ERROR:Grammar Error at Line %d Column %d: ", yylloc.first_line,yylloc.first_column); vfprintf(stderr, fmt, ap); fprintf(stderr, ".\n"); }
|