├── README.md ├── lab1_词法分析 ├── auto_lex.l └── auto_lex_icoding.l ├── lab2_递归下降分析 ├── icoding_test.c ├── rd_icoding.c ├── sysy_lex.l └── 使用说明.txt ├── lab3_LR语法分析 ├── Readme.md ├── ast.c ├── ast.h ├── lrlex.l ├── lrparser.tab.c ├── lrparser.tab.h ├── lrparser.y └── main.c └── lab4_中间代码生成 ├── ast.c ├── ast.h ├── genthreeaddrees.c ├── genthreeaddress.h ├── lex.yy.c ├── main.c ├── test.exe ├── threeaddress.l ├── threeaddress.tab.c ├── threeaddress.tab.h └── threeaddress.y /README.md: -------------------------------------------------------------------------------- 1 | # Compiler_UESTC 2 | 电子科技大学编译原理实验 3 | -------------------------------------------------------------------------------- /lab1_词法分析/auto_lex.l: -------------------------------------------------------------------------------- 1 | %{ 2 | 3 | // token definition 4 | #ifndef COMPILER_LAB_TOKEN_H 5 | #define COMPILER_LAB_TOKEN_H 6 | enum yytokentype { 7 | num_INT = 258, 8 | num_FLOAT = 259, 9 | 10 | Y_ID = 260, 11 | 12 | Y_INT = 261, 13 | Y_VOID = 262, 14 | Y_CONST = 263, 15 | Y_IF = 264, 16 | Y_ELSE = 265, 17 | Y_WHILE = 266, 18 | Y_BREAK = 267, 19 | Y_CONTINUE = 268, 20 | Y_RETURN = 269, 21 | 22 | Y_ADD = 270, 23 | Y_SUB = 271, 24 | Y_MUL = 272, 25 | Y_DIV = 273, 26 | Y_MODULO = 274, 27 | Y_LESS = 275, 28 | Y_LESSEQ = 276, 29 | Y_GREAT = 277, 30 | Y_GREATEQ = 278, 31 | Y_NOTEQ = 279, 32 | Y_EQ = 280, 33 | Y_NOT = 281, 34 | Y_AND = 282, 35 | Y_OR = 283, 36 | Y_ASSIGN = 284, 37 | 38 | Y_LPAR = 285, 39 | Y_RPAR = 286, 40 | Y_LBRACKET = 287, 41 | Y_RBRACKET = 288, 42 | Y_LSQUARE = 289, 43 | Y_RSQUARE = 290, 44 | Y_COMMA = 291, 45 | Y_SEMICOLON = 292, 46 | 47 | Y_FLOAT = 293 48 | }; 49 | 50 | typedef union _YYLVAL{ 51 | int token; 52 | int int_value; 53 | float float_value; 54 | char* id_name; 55 | }_YYLVAL; 56 | 57 | _YYLVAL yylval; 58 | #endif //COMPILER_LAB_TOKEN_H 59 | 60 | %} 61 | 62 | /* Regular definition */ 63 | DELIM [\t \n] 64 | WS {DELIM}+ 65 | DIGIT [0-9] 66 | LETTER [A-Za-z] 67 | 68 | %% 69 | 70 | (\/\/.*\n)|(\/\*.*\*\/) {/* noaction */} 71 | {WS} {/* noaction */} 72 | {DIGIT}+ {yylval.int_value = atoi(yytext); return num_INT;} 73 | {DIGIT}+"."{DIGIT}+ {yylval.float_value = (float)atof(yytext); return num_FLOAT;} 74 | int {return Y_INT;} 75 | float {return Y_FLOAT;} 76 | void {return Y_VOID;} 77 | const {return Y_CONST;} 78 | if {return Y_IF;} 79 | else {return Y_ELSE;} 80 | while {return Y_WHILE;} 81 | break {return Y_BREAK;} 82 | continue {return Y_CONTINUE;} 83 | return {return Y_RETURN;} 84 | ("_"|{LETTER})({DIGIT}|"_"|{LETTER})* {return Y_ID;} 85 | "+" {return Y_ADD;} 86 | "-" {return Y_SUB;} 87 | "*" {return Y_MUL;} 88 | "/" {return Y_DIV;} 89 | "%" {return Y_MODULO;} 90 | "<" {return Y_LESS;} 91 | "<=" {return Y_LESSEQ;} 92 | ">" {return Y_GREAT;} 93 | ">=" {return Y_GREATEQ;} 94 | "!=" {return Y_NOTEQ;} 95 | "==" {return Y_EQ;} 96 | "!" {return Y_NOT;} 97 | "&&" {return Y_AND;} 98 | "||" {return Y_OR;} 99 | "=" {return Y_ASSIGN;} 100 | "(" {return Y_LPAR;} 101 | ")" {return Y_RPAR;} 102 | "[" {return Y_LSQUARE;} 103 | "]" {return Y_RSQUARE;} 104 | "{" {return Y_LBRACKET;} 105 | "}" {return Y_RBRACKET;} 106 | "," {return Y_COMMA;} 107 | ";" {return Y_SEMICOLON;} 108 | 109 | 110 | %% 111 | 112 | //auxiliary function 113 | 114 | int main() { 115 | int tok; 116 | while(tok = yylex()){ 117 | if (tok == num_INT){ 118 | printf("<%d, %d> \n", tok, yylval.int_value); 119 | } else if (tok == num_FLOAT){ 120 | printf("<%d, %f> \n", tok, yylval.float_value); 121 | } else if (tok == Y_ID){ 122 | printf("<%d, %s> \n", tok, yytext); 123 | } else if ((tok >= 261 && tok <= 269) || tok == 293){ 124 | printf("<%d, KEYWORD> \n", tok); 125 | } else if(tok >= 270 && tok <= 284){ 126 | printf("<%d, OPERATOR> \n", tok); 127 | } else{ 128 | printf("<%d, SYMBOL> \n", tok); 129 | } 130 | } 131 | 132 | return 1; 133 | } 134 | 135 | 136 | int yywrap() { 137 | return 1; 138 | } 139 | -------------------------------------------------------------------------------- /lab1_词法分析/auto_lex_icoding.l: -------------------------------------------------------------------------------- 1 | %{ 2 | #include 3 | #include 4 | enum yytokentype { 5 | num_INT = 258, 6 | num_FLOAT = 259, 7 | 8 | Y_ID = 260, 9 | 10 | Y_INT = 261, 11 | Y_VOID = 262, 12 | Y_CONST = 263, 13 | Y_IF = 264, 14 | Y_ELSE = 265, 15 | Y_WHILE = 266, 16 | Y_BREAK = 267, 17 | Y_CONTINUE = 268, 18 | Y_RETURN = 269, 19 | 20 | Y_ADD = 270, 21 | Y_SUB = 271, 22 | Y_MUL = 272, 23 | Y_DIV = 273, 24 | Y_MODULO = 274, 25 | Y_LESS = 275, 26 | Y_LESSEQ = 276, 27 | Y_GREAT = 277, 28 | Y_GREATEQ = 278, 29 | Y_NOTEQ = 279, 30 | Y_EQ = 280, 31 | Y_NOT = 281, 32 | Y_AND = 282, 33 | Y_OR = 283, 34 | Y_ASSIGN = 284, 35 | 36 | Y_LPAR = 285, 37 | Y_RPAR = 286, 38 | Y_LBRACKET = 287, 39 | Y_RBRACKET = 288, 40 | Y_LSQUARE = 289, 41 | Y_RSQUARE = 290, 42 | Y_COMMA = 291, 43 | Y_SEMICOLON = 292, 44 | 45 | Y_FLOAT = 293 46 | }; 47 | 48 | typedef union _YYLVAL{ 49 | //终结符的种别码 50 | int token; 51 | //以下三个都是终结符可能的属性值,int值,float值,string值 52 | int int_value; 53 | float float_value; 54 | char* id_name; 55 | }_YYLVAL; 56 | 57 | _YYLVAL yylval; 58 | // 显示行列信息 59 | // int line=1; 60 | // int column=1; 61 | %} 62 | SPACE [ \f\r\v\n\t] 63 | line_comment (\/\/.*\n)|(\/\*.*\*\/) 64 | ID [a-zA-Z_]+[a-zA-Z0-9_]* 65 | %% 66 | "int" {yylval.id_name="int"; return Y_INT;} 67 | 68 | "void" {yylval.id_name="void";return Y_VOID;} 69 | 70 | "const" {yylval.id_name="const";return Y_CONST;} 71 | 72 | "if" {yylval.id_name="if";return Y_IF;} 73 | 74 | "else" {yylval.id_name="else";return Y_ELSE;} 75 | 76 | "while" {yylval.id_name="while";return Y_WHILE;} 77 | 78 | "break" {yylval.id_name="break";return Y_BREAK;} 79 | 80 | "continue" {yylval.id_name="continue";return Y_CONTINUE;} 81 | 82 | "return" {yylval.id_name="return";return Y_RETURN;} 83 | 84 | "float" {yylval.id_name="float";return Y_FLOAT;} 85 | 86 | [-]?[0-9]+ {yylval.int_value=atoi(yytext);return num_INT;} 87 | 88 | 0[xX][0-9]+ {yylval.int_value=atoi(yytext);return num_INT;} 89 | 90 | "0xa" {yylval.int_value=10;return num_INT;} 91 | 92 | "0xb" {yylval.int_value=11;return num_INT;} 93 | 94 | "0xc" {yylval.int_value=12;return num_INT;} 95 | 96 | "0xd" {yylval.int_value=13;return num_INT;} 97 | 98 | "0xe" {yylval.int_value=14;return num_INT;} 99 | 100 | "0xf" {yylval.int_value=15;return num_INT;} 101 | 102 | [0-9]+"."+[0-9]+ {yylval.float_value=atof(yytext);return num_FLOAT;} 103 | 104 | "+" {yylval.id_name="+";return Y_ADD;} 105 | 106 | "-" {yylval.id_name="-";return Y_SUB;} 107 | 108 | "*" {yylval.id_name="*";return Y_MUL;} 109 | 110 | "/" {yylval.id_name="/";return Y_DIV;} 111 | 112 | "%" {yylval.id_name="%";return Y_MODULO;} 113 | 114 | "<=" {yylval.id_name="<=";return Y_LESSEQ;} 115 | 116 | ">" {yylval.id_name=">";return Y_GREAT;} 117 | 118 | "<" {yylval.id_name="<";return Y_LESS;} 119 | 120 | ">=" {yylval.id_name=">=";return Y_GREATEQ;} 121 | 122 | "!=" {yylval.id_name="!=";return Y_NOTEQ;} 123 | 124 | "==" {yylval.id_name="==";return Y_EQ;} 125 | 126 | "!" {yylval.id_name="!";return Y_NOT;} 127 | 128 | "&&" {yylval.id_name="&&";return Y_AND;} 129 | 130 | "||" {yylval.id_name="||";return Y_OR;} 131 | 132 | "=" {yylval.id_name="=";return Y_ASSIGN;} 133 | 134 | "(" {yylval.id_name="(";return Y_LPAR;} 135 | 136 | ")" {yylval.id_name=")";return Y_RPAR;} 137 | 138 | "{" {yylval.id_name="{";return Y_LBRACKET;} 139 | 140 | "}" {yylval.id_name="}";return Y_RBRACKET;} 141 | 142 | "[" {yylval.id_name="[";return Y_LSQUARE;} 143 | 144 | "]" {yylval.id_name="]";return Y_RSQUARE;} 145 | 146 | "," {yylval.id_name=",";return Y_COMMA;} 147 | 148 | ";" {yylval.id_name=";";return Y_SEMICOLON;} 149 | 150 | {ID} {yylval.id_name=yytext;return Y_ID;} 151 | 152 | {line_comment} {/*ignore line_comment*/} 153 | 154 | {SPACE} {/*ignore whitespace*/} 155 | 156 | %% 157 | main(int argc, char **argv){ 158 | int token_type; 159 | 160 | while(token_type = yylex()) 161 | { 162 | printf("<%d", token_type); 163 | if(token_type > 284 && token_type <293) 164 | { 165 | printf(", SYMBOL>\n"); 166 | } 167 | else if(token_type >269&& token_type<285) 168 | { 169 | printf(", OPERATOR>\n"); 170 | } 171 | else if(token_type >260 &&token_type<270 ) 172 | { 173 | printf(", KEYWORD>\n"); 174 | } 175 | else if(token_type==Y_ID) 176 | { 177 | printf(", %s>\n", yylval.id_name); 178 | } 179 | else if(token_type==num_INT) 180 | { 181 | printf(", %d>\n",yylval.int_value); 182 | } 183 | else if(token_type==num_FLOAT) 184 | { 185 | printf(", %f>\n",yylval.float_value); 186 | } 187 | } 188 | 189 | } 190 | 191 | int yywrap(){ 192 | return 1; 193 | } -------------------------------------------------------------------------------- /lab2_递归下降分析/icoding_test.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "rdlab2.h" 4 | 5 | int cord = 0; 6 | 7 | past newParaDecl(past left, past right, past next); 8 | past newBinaryOper(int oper, past left, past right); 9 | past newCompoundStmt(past left, past right); 10 | past newWhileStmt(past left, past right); 11 | past newIfStmt(past if_cond, past left, past right); 12 | past newReturnStmt(past left, past right); 13 | past newDeclRefExp(char * name, past left, past right); 14 | past newBreakStmt(); 15 | past newContinueStmt(); 16 | past astAddExp(); 17 | past astMulExp(); 18 | past astMulExp(); 19 | past astUnaryExp(); 20 | past astPrimaryExp(); 21 | past astLOrExp(); 22 | past astLAndExp(); 23 | past astEqExp(); 24 | 25 | past rd_call_paras(){ 26 | past l = astAddExp(); 27 | past t = l; 28 | while(cur_token.token == Y_COMMA){ 29 | advance(); 30 | past r = astAddExp(); 31 | l->next = r; 32 | l = l->next; 33 | } 34 | return t; 35 | } 36 | 37 | 38 | past rd_relexp(){ // 39 | past l = astAddExp(); 40 | while(cur_token.token == Y_LESS || cur_token.token == Y_LESSEQ || cur_token.token == Y_GREAT || cur_token.token == Y_GREATEQ){ 41 | int oper = cur_token.token; 42 | advance(); 43 | past r = astAddExp(); 44 | l = newBinaryOper(oper, l, r); 45 | } 46 | return l; 47 | } 48 | 49 | 50 | past rd_stmt(){ 51 | past t; 52 | if(cur_token.token == Y_ID){ 53 | char* s = cur_token.attr.svalue; 54 | advance(); 55 | rd_array_subscripts(); 56 | if(cur_token.token != Y_ASSIGN){ 57 | return NULL; 58 | } 59 | advance(); 60 | past l = astAddExp(); 61 | if(cur_token.token != Y_SEMICOLON){ 62 | return NULL; 63 | } 64 | advance(); 65 | past r = newDeclRefExp(s, NULL, NULL); 66 | return newBinaryOper(Y_ASSIGN, r, l); 67 | } else if(cur_token.token == Y_SEMICOLON){ 68 | advance(); 69 | return NULL; 70 | } else if((t = astAddExp())){ 71 | if(cur_token.token != Y_SEMICOLON){ 72 | return NULL; 73 | } 74 | advance(); 75 | return t; 76 | } else if(cur_token.token == Y_LBRACKET){ 77 | advance(); 78 | past l = rd_block(); 79 | if(cur_token.token != Y_RBRACKET){ 80 | return NULL; 81 | } 82 | advance(); 83 | return l; 84 | } else if(cur_token.token == Y_WHILE){ 85 | cord = 1; 86 | advance(); 87 | if(cur_token.token != Y_LPAR){ 88 | return NULL; 89 | } 90 | advance(); 91 | past l = astLOrExp(); 92 | if(cur_token.token != Y_RPAR){ 93 | return NULL; 94 | } 95 | advance(); 96 | past r = rd_stmt(); 97 | return newWhileStmt(l, r); 98 | } else if(cur_token.token == Y_IF){ 99 | advance(); 100 | if(cur_token.token != Y_LPAR){ 101 | return NULL; 102 | } 103 | advance(); 104 | past l1 = astLOrExp(); 105 | if(cur_token.token != Y_RPAR){ 106 | return NULL; 107 | } 108 | advance(); 109 | past l2 = rd_stmt(); 110 | if(cur_token.token != Y_ELSE){ 111 | return newIfStmt(l1, l2, NULL); 112 | } 113 | advance(); 114 | past l3 = rd_stmt(); 115 | return newIfStmt(l1, l2, l3); 116 | } else if(cur_token.token == Y_BREAK){ 117 | advance(); 118 | if(cur_token.token != Y_SEMICOLON){ 119 | return NULL; 120 | } 121 | advance(); 122 | return newBreakStmt(); 123 | } else if(cur_token.token == Y_CONTINUE){ 124 | advance(); 125 | if(cur_token.token != Y_SEMICOLON){ 126 | return NULL; 127 | } 128 | advance(); 129 | return newContinueStmt(); 130 | } else if(cur_token.token == Y_RETURN){ 131 | advance(); 132 | past l = astAddExp(); 133 | if(cur_token.token != Y_SEMICOLON){ 134 | return NULL; 135 | } 136 | advance(); 137 | return newReturnStmt(l, NULL); 138 | } else { 139 | return NULL; 140 | } 141 | } 142 | 143 | past astLOrExp(){ 144 | past l = astLAndExp(); 145 | while(cur_token.token == Y_OR){ 146 | advance(); 147 | past r = astLAndExp(); 148 | l = newBinaryOper(Y_OR, l, r); 149 | } 150 | return l; 151 | } 152 | 153 | past astLAndExp(){ 154 | past l = astEqExp(); 155 | while(cur_token.token == Y_AND){ 156 | advance(); 157 | past r = astEqExp(); 158 | l = newBinaryOper( Y_AND, l, r); 159 | } 160 | 161 | return l; 162 | } 163 | 164 | past astEqExp(){ 165 | past l = rd_relexp(); 166 | while(cur_token.token == Y_EQ || cur_token.token == Y_NOTEQ){ 167 | int oper = cur_token.token; 168 | advance(); 169 | past r = rd_relexp(); 170 | l = newBinaryOper(oper, l, r); 171 | } 172 | 173 | return l; 174 | } 175 | 176 | past astPrimaryExp(){ 177 | if(cur_token.token == Y_LPAR){ 178 | advance(); 179 | past n1 = astAddExp(); 180 | if(cur_token.token != Y_RPAR){ 181 | return NULL; 182 | } 183 | return n1; 184 | } else if(cur_token.token == Y_ID){ 185 | char* s = cur_token.attr.svalue; 186 | past l = newDeclRefExp(s, NULL, NULL); 187 | advance(); 188 | if(cur_token.token == Y_LPAR){ 189 | rd_array_subscripts(); 190 | } 191 | return l; 192 | } else if(cur_token.token == num_INT){ 193 | past n2 = newInt(cur_token.attr.ivalue); 194 | advance(); 195 | return n2; 196 | } else if(cur_token.token == num_FLOAT){ 197 | past n3 = newAstNode(); 198 | advance(); 199 | n3->fvalue = cur_token.attr.fvalue; 200 | return n3; 201 | } else { 202 | return NULL; 203 | } 204 | } 205 | 206 | past astUnaryExp(){ 207 | past l = astPrimaryExp(); 208 | if(l != NULL){ 209 | return l; 210 | } else if(cur_token.token == Y_ID){ 211 | char* s = cur_token.attr.svalue; 212 | advance(); 213 | if(cur_token.token != Y_LPAR){ 214 | return NULL; 215 | } 216 | advance(); 217 | if(cur_token.token == Y_RPAR){ 218 | advance(); 219 | return newDeclRefExp(s, NULL, NULL); 220 | } else { 221 | rd_call_paras(); 222 | if(cur_token.token != Y_RPAR){ 223 | return NULL; 224 | } 225 | advance(); 226 | return newDeclRefExp(s, NULL, NULL); 227 | } 228 | } else if(cur_token.token == Y_ADD){ 229 | advance(); 230 | past l = astUnaryExp(); 231 | return newBinaryOper(Y_ADD, NULL, l); 232 | } else if(cur_token.token == Y_SUB){ 233 | advance(); 234 | past l = astUnaryExp(); 235 | return newBinaryOper(Y_SUB, NULL, l); 236 | } else if(cur_token.token == Y_NOT){ 237 | advance(); 238 | past l = astUnaryExp(); 239 | return newBinaryOper(Y_NOT, NULL, l); 240 | } else { 241 | return NULL; 242 | } 243 | } 244 | 245 | past astMulExp(){ 246 | past l = astUnaryExp(); 247 | while(cur_token.token == Y_MUL || cur_token.token == Y_DIV ||cur_token.token == Y_MODULO){ 248 | int oper = cur_token.token; 249 | advance(); 250 | past r = astUnaryExp(); 251 | l = newBinaryOper(oper, l, r); 252 | } 253 | return l; 254 | } 255 | 256 | past astAddExp(){ 257 | past l = astMulExp(); 258 | while(cur_token.token == Y_ADD || cur_token.token == Y_SUB){ 259 | int oper = cur_token.token; 260 | advance(); 261 | past r = astMulExp(); 262 | l = newBinaryOper(oper, l, r); 263 | } 264 | return l; 265 | } 266 | 267 | past newWhileStmt(past left, past right){ 268 | past node = newAstNode(); 269 | node->nodeType = WHILE_STMT; 270 | node->left = left; 271 | node->right = right; 272 | return node; 273 | } 274 | 275 | past newIfStmt(past if_cond, past left, past right){ 276 | past node = newAstNode(); 277 | node->nodeType = IF_STMT; 278 | node->if_cond = if_cond; 279 | node->left = left; 280 | node->right = right; 281 | return node; 282 | } 283 | 284 | past newCompoundStmt(past left, past right){ 285 | past node = newAstNode(); 286 | node->nodeType = COMPOUND_STMT; 287 | node->left = left; 288 | node->right = right; 289 | return node; 290 | } 291 | 292 | past newBinaryOper(int oper, past left, past right){ 293 | past node = newAstNode(); 294 | node->nodeType = BINARY_OPERATOR; 295 | node->ivalue = oper; 296 | node->left = left; 297 | node->right = right; 298 | return node; 299 | } 300 | 301 | past newParaDecl(past left, past right, past next){ 302 | past node = newAstNode(); 303 | node->nodeType = PARM_DECL; 304 | node->left = left; 305 | node->right = right; 306 | return node; 307 | } 308 | past newBreakStmt(){ 309 | past node = newAstNode(); 310 | node->nodeType = BREAK_STMT; 311 | return node; 312 | } 313 | 314 | past newContinueStmt(){ 315 | past node = newAstNode(); 316 | node->nodeType = CONTINUE_STMT; 317 | return node; 318 | } 319 | 320 | past newReturnStmt(past left, past right){ 321 | past node = newAstNode(); 322 | node->nodeType = RETURN_STMT; 323 | node->left = left; 324 | node->right = right; 325 | return node; 326 | } 327 | 328 | past newDeclRefExp(char * name, past left, past right){ 329 | past node = newAstNode(); 330 | node->nodeType = DECL_REF_EXPR; 331 | node->svalue = name; 332 | node->left = left; 333 | node->right = right; 334 | return node; 335 | } 336 | -------------------------------------------------------------------------------- /lab2_递归下降分析/rd_icoding.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | // Declaration Kinds 6 | #ifndef COMPILER_LAB_NODE_TYPE_H 7 | #define COMPILER_LAB_NODE_TYPE_H 8 | 9 | enum _node_type{ 10 | 11 | // A declaration whose specific kind is not exposed via this interface 12 | // 13 | 14 | // A C or C++ struct 15 | STRUCT_DECL = 2, 16 | 17 | // A C or C++ union 18 | UNION_DECL = 3, 19 | 20 | // An enumeration 21 | ENUM_DECL = 5, 22 | 23 | // A field in C, or non-static data member in C++, in a struct, union, or C++ 24 | // class 25 | FIELD_DECL = 6, 26 | 27 | // An enumerator constant 28 | ENUM_CONSTANT_DECL = 7, 29 | 30 | // A function 31 | FUNCTION_DECL = 8, 32 | 33 | // A variable 34 | VAR_DECL = 9, 35 | 36 | // A function or method parameter 37 | PARM_DECL = 10, 38 | 39 | 40 | // A typedef 41 | TYPEDEF_DECL = 20, 42 | 43 | // A Type alias decl 44 | TYPE_ALIAS_DECL = 36, 45 | 46 | 47 | // A reference to a member of a struct, union, or class that occurs in 48 | // some non-expression context, eg, a designated initializer 49 | MEMBER_REF = 47, 50 | 51 | // A reference to a labeled statement 52 | LABEL_REF = 48, 53 | 54 | // A reference to a set of overloaded functions or function templates 55 | // that has not yet been resolved to a specific function or function template 56 | OVERLOADED_DECL_REF = 49, 57 | 58 | // A reference to a variable that occurs in some non-expression 59 | // context, eg, a C++ lambda capture list 60 | VARIABLE_REF = 50, 61 | 62 | 63 | ////// 64 | // Invalid/Error Kinds 65 | 66 | INVALID_FILE = 70, 67 | NO_DECL_FOUND = 71, 68 | NOT_IMPLEMENTED = 72, 69 | INVALID_CODE = 73, 70 | 71 | 72 | ////// 73 | // Expression Kinds 74 | 75 | // An expression whose specific kind is not exposed via this interface 76 | // 77 | // Unexposed expressions have the same operations as any other kind of 78 | // expression; one can extract their location information, spelling, children, 79 | // etc However, the specific kind of the expression is not reported 80 | UNEXPOSED_EXPR = 100, 81 | 82 | // An expression that refers to some value declaration, such as a function, 83 | // variable, or enumerator 84 | DECL_REF_EXPR = 101, 85 | 86 | // An expression that refers to a member of a struct, union, class, Objective-C 87 | // class, etc 88 | MEMBER_REF_EXPR = 102, 89 | 90 | // An expression that calls a function 91 | CALL_EXPR = 103, 92 | 93 | 94 | // An expression that represents a block literal 95 | BLOCK_EXPR = 105, 96 | 97 | // An integer literal 98 | INTEGER_LITERAL = 106, 99 | 100 | // A floating point number literal 101 | FLOATING_LITERAL = 107, 102 | 103 | // An imaginary number literal 104 | IMAGINARY_LITERAL = 108, 105 | 106 | // A string literal 107 | STRING_LITERAL = 109, 108 | 109 | // A character literal 110 | CHARACTER_LITERAL = 110, 111 | 112 | // A parenthesized expression, eg "1," 113 | // 114 | // This AST node is only formed if full location information is requested 115 | PAREN_EXPR = 111, 116 | 117 | // This represents the unary-expression's except sizeof and 118 | // alignof, 119 | UNARY_OPERATOR = 112, 120 | 121 | // [C99 6521] Array Subscripting 122 | ARRAY_SUBSCRIPT_EXPR = 113, 123 | 124 | // A builtin binary operation expression such as "x + y" or 125 | // "x <= y" 126 | BINARY_OPERATOR = 114, 127 | 128 | // Compound assignment such as "+=" 129 | COMPOUND_ASSIGNMENT_OPERATOR = 115, 130 | 131 | // The ?: ternary operator 132 | CONDITIONAL_OPERATOR = 116, 133 | 134 | // An explicit cast in C C99 654, or a C-style cast in C++ 135 | // C++ [exprcast],, which uses the syntax Type,expr 136 | // 137 | // For example: int,f 138 | CSTYLE_CAST_EXPR = 117, 139 | 140 | // [C99 6525] 141 | COMPOUND_LITERAL_EXPR = 118, 142 | 143 | // Describes an C or C++ initializer list 144 | INIT_LIST_EXPR = 119, 145 | 146 | // The GNU address of label extension, representing &&label 147 | ADDR_LABEL_EXPR = 120, 148 | 149 | 150 | 151 | // A statement whose specific kind is not exposed via this interface 152 | // 153 | // Unexposed statements have the same operations as any other kind of statement; 154 | // one can extract their location information, spelling, children, etc However, 155 | // the specific kind of the statement is not reported 156 | UNEXPOSED_STMT = 200, 157 | 158 | // A labelled statement in a function 159 | LABEL_STMT = 201, 160 | 161 | // A compound statement 162 | COMPOUND_STMT = 202, 163 | 164 | // A case statement 165 | CASE_STMT = 203, 166 | 167 | // A default statement 168 | DEFAULT_STMT = 204, 169 | 170 | // An if statement 171 | IF_STMT = 205, 172 | 173 | // A switch statement 174 | SWITCH_STMT = 206, 175 | 176 | // A while statement 177 | WHILE_STMT = 207, 178 | 179 | // A do statement 180 | DO_STMT = 208, 181 | 182 | // A for statement 183 | FOR_STMT = 209, 184 | 185 | // A goto statement 186 | GOTO_STMT = 210, 187 | 188 | // An indirect goto statement 189 | INDIRECT_GOTO_STMT = 211, 190 | 191 | // A continue statement 192 | CONTINUE_STMT = 212, 193 | 194 | // A break statement 195 | BREAK_STMT = 213, 196 | 197 | // A return statement 198 | RETURN_STMT = 214, 199 | 200 | 201 | // The null statement 202 | NULL_STMT = 230, 203 | 204 | // Adaptor class for mixing declarations with statements and expressions 205 | DECL_STMT = 231, 206 | 207 | 208 | ////// 209 | // Other Kinds 210 | 211 | // Cursor that represents the translation unit itself 212 | // 213 | // The translation unit cursor exists primarily to act as the root cursor for 214 | // traversing the contents of a translation unit 215 | TRANSLATION_UNIT = 300, 216 | }; 217 | 218 | typedef enum _node_type node_type; 219 | 220 | #endif 221 | //词法分析单词类型 222 | enum yytokentype { 223 | num_INT = 258, 224 | num_FLOAT = 259, 225 | 226 | Y_ID = 260, 227 | 228 | Y_INT = 261, 229 | Y_VOID = 262, 230 | Y_CONST = 263, 231 | Y_IF = 264, 232 | Y_ELSE = 265, 233 | Y_WHILE = 266, 234 | Y_BREAK = 267, 235 | Y_CONTINUE = 268, 236 | Y_RETURN = 269, 237 | 238 | Y_ADD = 270, 239 | Y_SUB = 271, 240 | Y_MUL = 272, 241 | Y_DIV = 273, 242 | Y_MODULO = 274, 243 | Y_LESS = 275, 244 | Y_LESSEQ = 276, 245 | Y_GREAT = 277, 246 | Y_GREATEQ = 278, 247 | Y_NOTEQ = 279, 248 | Y_EQ = 280, 249 | Y_NOT = 281, 250 | Y_AND = 282, 251 | Y_OR = 283, 252 | Y_ASSIGN = 284, 253 | 254 | Y_LPAR = 285, 255 | Y_RPAR = 286, 256 | Y_LBRACKET = 287, 257 | Y_RBRACKET = 288, 258 | Y_LSQUARE = 289, 259 | Y_RSQUARE = 290, 260 | Y_COMMA = 291, 261 | Y_SEMICOLON = 292, 262 | 263 | Y_FLOAT = 293 264 | }; 265 | 266 | //全局变量~ 267 | extern int yylex(); 268 | extern int yylval; 269 | extern char* yytext; 270 | extern int yyleng; 271 | int paranum; 272 | int callParaNum; 273 | int compoundStmtNum; 274 | int if_DeclStmt; 275 | int tok; 276 | 277 | //结点声明 278 | typedef struct _ast ast; 279 | typedef struct _ast *past; 280 | struct _ast{ 281 | char* stype; 282 | int ivalue; 283 | float fvalue; 284 | char* svalue; 285 | node_type nodeType; 286 | char* snodeType; 287 | int if_const; 288 | past left; 289 | past right; 290 | past if_cond; 291 | past next; 292 | }; 293 | 294 | //函数声明 295 | 296 | //返回ast结点函数 297 | past newAstNode(); 298 | //显示ast 299 | void showAst(char* sym, past node, int nest); 300 | void showParaDecl(past node); 301 | void showCompoundStmt(past node, int nest); 302 | void showCallExp(past node, int nest); 303 | void showTranstion(past node, int nest); 304 | //匹配函数 305 | int match(int x); 306 | //移进函数 307 | void advance(); 308 | 309 | past astDecl(); 310 | past astConstDecl(); 311 | past astConstDefs(char* stype, int type); 312 | past astConstDef(char* stype, int type); 313 | past astConstInitVal(); 314 | past astVarDecl(); 315 | past astVarDecls(); 316 | past astVarDef(char* stype, int type); 317 | past astInitVal(); 318 | past astFuncDef(); 319 | past astFuncParams(); 320 | past astFuncParam(); 321 | past astBlock(); 322 | int astType(); 323 | past astCompUnit(); 324 | past astStmt(); 325 | past astBlockItems(); 326 | past astBlockItem(); 327 | past astLOrExp(); 328 | past astLAndExp(); 329 | past astEqExp(); 330 | past astRelExp(); 331 | past astExp(); 332 | past astAddExp(); 333 | past astMulExp(); 334 | past astUnaryExp(); 335 | past astCallParams(); 336 | past astPrimaryExp(); 337 | past astArraySubscriptsExp(); 338 | past newDeclStmt(past left, past right); 339 | past newCompUnit(past left, past right); 340 | past newDeclRefExp(char* name, past left, past right); 341 | past newFuncDecl(char* stype, int type,char* svalue, past left, past right); 342 | past newBinaryOper(char* soper, int oper, past left, past right); 343 | past newArraySubscriptsExp(past left, past right); 344 | past newCallExp(char* stype, int type, char* name, past left, past right); 345 | past newParaDecl(char* stype, char* name, past left, past right); 346 | past newCompoundStmt(past left, past right); 347 | past newIntVal(int ival); 348 | past newFloatVal(float fval); 349 | past newVarDecl(char* stype, int type, int if_cond, char* s, past left, past right); 350 | past newIfStmt(past if_cond, past left, past right); 351 | past newWhileStmt(past left, past right); 352 | past newContinueStmt(); 353 | past newBreakStmt(); 354 | past newReturnStmt(past left, past right); 355 | 356 | 357 | int main(int argc, char **argv){ 358 | advance(); 359 | past node = astCompUnit(); 360 | showAst("|", node, 0); 361 | return 0; 362 | } 363 | 364 | int match(int x){ 365 | if(tok == x){ 366 | return 1; 367 | } 368 | return 0; 369 | } 370 | 371 | void advance(){ 372 | tok = yylex(); 373 | printf("tok: %s\n", yytext); 374 | } 375 | 376 | past newAstNode(){ 377 | past node = malloc(sizeof(ast)); 378 | if(node == NULL) 379 | { 380 | printf("run out of memory.\n"); 381 | exit(0); 382 | } 383 | memset(node, 0, sizeof(ast)); 384 | return node; 385 | } 386 | 387 | void showAst(char* sym, past node, int nest){ 388 | if(node == NULL) 389 | return; 390 | int i = 0; 391 | for(i = 0; i < nest; i ++) 392 | printf(" "); 393 | if(node->nodeType == TRANSLATION_UNIT){ 394 | printf("%s-%s\n", sym, node->snodeType); 395 | showTranstion(node, nest + 1); 396 | return; 397 | } else if(node->nodeType == INTEGER_LITERAL){ 398 | printf("%s-%s %d\n", sym, node->snodeType, node->ivalue); 399 | } else if(node->nodeType == FLOATING_LITERAL){ 400 | printf("%s-%s %f\n", sym, node->snodeType, node->fvalue); 401 | } else if(node->nodeType == IF_STMT){ 402 | printf("%s-%s %s\n", sym, node->snodeType, node->svalue); 403 | showAst("|", node->if_cond, nest+1); 404 | } else if(node->nodeType == FUNCTION_DECL){ 405 | printf("%s-%s %s '%s'\n", sym, node->snodeType, node->svalue, node->stype); 406 | } else if(node->nodeType == PARM_DECL){ 407 | showParaDecl(node); 408 | return; 409 | } else if(node->nodeType == COMPOUND_STMT){ 410 | printf("%s-%s\n", sym, node->snodeType); 411 | node = node->right; 412 | showCompoundStmt(node, nest + 1); 413 | return; 414 | } else if(node->nodeType == VAR_DECL){ 415 | printf("%s-%s %s '%s'\n", sym, node->snodeType, node->svalue, node->stype); 416 | } else if(node->nodeType == CALL_EXPR){ 417 | printf("%s-%s %s\n", sym, node->snodeType, node->svalue); 418 | node = node->left; 419 | showCallExp(node, nest + 1); 420 | return; 421 | } else if(node->svalue != NULL){ 422 | printf("%s-%s '%s'\n", sym, node->snodeType, node->svalue); 423 | } else{ 424 | printf("%s-%s\n", sym, node->snodeType); 425 | } 426 | showAst("|", node->left, nest+1); 427 | showAst("`", node->right, nest+1); 428 | } 429 | 430 | void showTranstion(past node, int nest){ ////编译单元 431 | if(node == NULL){ 432 | return; 433 | } 434 | while(node->right != NULL){ 435 | showAst("|", node->left, nest); 436 | node = node->right; 437 | } 438 | showAst("`", node->left, nest); 439 | } 440 | 441 | void showCallExp(past node, int nest){ //函数调用遍历 442 | if(node == NULL){ 443 | return; 444 | } 445 | while(node->right != NULL){ 446 | showAst("|", node->left, nest); 447 | node = node->right; 448 | } 449 | showAst("`", node->left, nest); 450 | } 451 | 452 | void showCompoundStmt(past node, int nest){ //复合语句遍历 453 | if(node == NULL){ 454 | return; 455 | } 456 | while(node->right != NULL){ 457 | showAst("|", node->left, nest); 458 | node = node->right; 459 | } 460 | showAst("`", node->left, nest); 461 | } 462 | 463 | void showParaDecl(past node){ //函数参数,非递归中序遍历 464 | if(node == NULL){ 465 | return; 466 | } 467 | int i = paranum; 468 | past stack[paranum]; 469 | int top = 0; 470 | while(top || node){ 471 | if(node != NULL){ 472 | stack[top++] = node; 473 | node = node->left; 474 | }else if(top != 0){ 475 | node = stack[--top]; 476 | if(i == paranum){ 477 | printf("|-%s used %s '%s'\n", node->snodeType, node->svalue, node->stype); 478 | i--; 479 | } else { 480 | printf(" |-%s used %s '%s'\n", node->snodeType, node->svalue, node->stype); 481 | } 482 | node = node->right; 483 | } 484 | } 485 | } 486 | 487 | past astCompUnit(){ 488 | past l = astDecl(); 489 | if(l == NULL){ 490 | l = astFuncDef(); 491 | } 492 | l = newCompUnit(l, NULL); 493 | past res = l; 494 | past r = astDecl(); 495 | if(r == NULL){ 496 | r = astFuncDef(); 497 | } 498 | while(r != NULL){ 499 | r = newCompUnit(r, NULL); 500 | l->right = r; 501 | l = r; 502 | r = astDecl(); 503 | if(r == NULL){ 504 | r = astFuncDef(); 505 | } 506 | } 507 | return res; 508 | } 509 | 510 | past astDecl(){ 511 | past l; 512 | if((l = astConstDecl())){ 513 | return l; 514 | } else if((l = astVarDecl())){ 515 | return l; 516 | } else { 517 | return NULL; 518 | } 519 | } 520 | 521 | past astConstDecl(){ 522 | if(!match(Y_CONST)){ 523 | return NULL; 524 | } 525 | advance(); 526 | int type = astType(); 527 | char* stype; 528 | if(type == 0){ 529 | return NULL; 530 | } else if(type == Y_INT){ 531 | stype = "const int"; 532 | } else if(type == Y_FLOAT){ 533 | stype = "const float"; 534 | } else { 535 | stype = "const void"; 536 | } 537 | 538 | past r = astConstDefs(stype, type); 539 | if(!match(Y_SEMICOLON)){ 540 | return NULL; 541 | } 542 | advance(); 543 | return newDeclStmt(NULL, r); 544 | } 545 | 546 | 547 | past astConstDefs(char* stype, int type){ 548 | past l = astConstDef(stype, type); 549 | while(match(Y_COMMA)){ 550 | advance(); 551 | past r = astConstDef(stype, type); 552 | l = newDeclStmt(l, r); 553 | } 554 | return l; 555 | } 556 | 557 | past astConstDef(char* stype, int type){ 558 | if(!match(Y_ID)){ 559 | return NULL; 560 | } 561 | char* s = malloc(sizeof(char) * (yyleng + 1)); 562 | strcpy(s, yytext); 563 | advance(); 564 | if(match(Y_ASSIGN)){ 565 | advance(); 566 | past l = astConstInitVal(); 567 | return newVarDecl(stype, type, 1, s, NULL, l); 568 | } else if(match(Y_LSQUARE)){ 569 | advance(); 570 | past l = astAddExp(); 571 | if(!match(Y_RSQUARE)){ 572 | return NULL; 573 | } 574 | advance(); 575 | while(match(Y_LSQUARE)){ 576 | advance(); 577 | past r = astAddExp(); 578 | if(!match(Y_RSQUARE)){ 579 | return NULL; 580 | } 581 | advance(); 582 | // l = newArraySubscriptsExp(l,r); //待修改 583 | } 584 | if(!match(Y_ASSIGN)){ 585 | return NULL; 586 | } 587 | advance(); 588 | past r = astConstInitVal(); 589 | return newVarDecl(stype, type, 1, s, NULL, r); 590 | } else { 591 | return NULL; 592 | } 593 | } 594 | 595 | past astConstInitVal(){ 596 | past l = astAddExp(); 597 | if(l != NULL){ 598 | return l; 599 | } else if(match(Y_LBRACKET)){ 600 | advance(); 601 | if(match(Y_RBRACKET)){ 602 | advance(); 603 | // return newBinaryOper(0,NULL,NULL);//待修改 604 | } else { 605 | past l = astConstInitVal(); 606 | while(match(Y_COMMA)){ 607 | advance(); 608 | past r = astConstInitVal(); 609 | // l = newBinaryOper(Y_COMMA,l,r); 610 | } 611 | if(!match(Y_RBRACKET)){ 612 | return NULL; 613 | } 614 | advance(); 615 | return l; 616 | } 617 | } else { 618 | return NULL; 619 | } 620 | } 621 | 622 | past astVarDecl(){ 623 | int type = astType(); 624 | char* stype; 625 | if(type == 0){ 626 | return NULL; 627 | } else if(type == Y_INT){ 628 | stype = "int"; 629 | } else if(type == Y_FLOAT){ 630 | stype = "float"; 631 | } else { 632 | stype = "void"; 633 | } 634 | past r = astVarDecls(stype, type); 635 | if(r->nodeType == FUNCTION_DECL){ 636 | return r; 637 | } 638 | if(!match(Y_SEMICOLON)){ 639 | return NULL; 640 | } 641 | advance(); 642 | return newDeclStmt(NULL, r); 643 | } 644 | 645 | past astVarDecls(char* stype, int type){ 646 | past l = astVarDef(stype, type); 647 | if(l->nodeType == FUNCTION_DECL){ 648 | return l; 649 | } 650 | while(match(Y_COMMA)){ 651 | advance(); 652 | past r = astVarDef(stype, type); 653 | l = newDeclStmt(l, r); //要有专门的遍历函数 654 | } 655 | return l; 656 | } 657 | 658 | past astVarDef(char* stype, int type){ 659 | if(!match(Y_ID)){ 660 | return NULL; 661 | } 662 | char* s = malloc(sizeof(char) * (yyleng + 1)); 663 | strcpy(s, yytext); 664 | advance(); 665 | if(match(Y_LPAR)){ 666 | advance(); 667 | if(match(Y_RPAR)){ 668 | advance(); 669 | past l = astBlock(); 670 | l = newCompoundStmt(NULL, l); 671 | return newFuncDecl(stype, type, s, NULL, l); 672 | } else { 673 | past r = astFuncParams(); 674 | if(!match(Y_RPAR)){ 675 | return NULL; 676 | } 677 | advance(); 678 | past b = astBlock(); 679 | b = newCompoundStmt(NULL, b); 680 | return newFuncDecl(stype, type, s, r, b); 681 | } 682 | } else if(match(Y_ASSIGN)){ 683 | advance(); 684 | past l = astInitVal(); 685 | return newVarDecl(stype, type, 0, s, NULL, l); 686 | } else if(match(Y_LSQUARE)){ 687 | advance(); 688 | past l = astAddExp(); 689 | if(!match(Y_RSQUARE)){ 690 | return NULL; 691 | } 692 | advance(); 693 | while(match(Y_LSQUARE)){ 694 | advance(); 695 | past r = astAddExp(); 696 | if(!match(Y_RSQUARE)){ 697 | return NULL; 698 | } 699 | advance(); 700 | // l = newArraySubscriptsExp(l,r); //需要修改 701 | } 702 | 703 | if(match(Y_ASSIGN)){ 704 | advance(); 705 | past r = astInitVal(); 706 | return newVarDecl(stype, type, 0, s, NULL, r); 707 | } else { 708 | return newVarDecl(stype, type, 0, s, NULL, NULL); 709 | } 710 | } else { 711 | return newVarDecl(stype, type, 0, s, NULL, NULL); 712 | } 713 | } 714 | 715 | past astInitVal(){ 716 | past l = astExp(); 717 | if(l != NULL){ 718 | return l; 719 | } else if(match(Y_LBRACKET)){ //待修改 720 | advance(); 721 | if(match(Y_RBRACKET)){ 722 | advance(); 723 | // return newBinaryOper(0,NULL,NULL); 724 | } else { 725 | past l = astInitVal(); 726 | while(match(Y_COMMA)){ 727 | advance(); 728 | past r = astInitVal(); 729 | // l = newBinaryOper(Y_COMMA,l,r); 730 | } 731 | if(!match(Y_RBRACKET)){ 732 | return NULL; 733 | } 734 | advance(); 735 | return l; 736 | } 737 | } else { 738 | return NULL; 739 | } 740 | } 741 | 742 | past astFuncDef(){ 743 | int type = astType(); 744 | char* stype; 745 | if(type == 0){ 746 | return NULL; 747 | } else if(type == Y_INT){ 748 | stype = "int"; 749 | } else if(type == Y_FLOAT){ 750 | stype = "float"; 751 | } else { 752 | stype = "void"; 753 | } 754 | if(!match(Y_ID)){ 755 | return NULL; 756 | } 757 | char* s = malloc(sizeof(char) * (yyleng + 1)); 758 | strcpy(s, yytext); 759 | advance(); 760 | if(!match(Y_LPAR)){ 761 | return NULL; 762 | } 763 | advance(); 764 | if(match(Y_RPAR)){ 765 | advance(); 766 | past l = astBlock(); 767 | l = newCompoundStmt(NULL, l); 768 | return newFuncDecl(stype, type, s, NULL, l); 769 | } else { 770 | past r = astFuncParams(); 771 | if(!match(Y_RPAR)){ 772 | return NULL; 773 | } 774 | advance(); 775 | past b = astBlock(); 776 | b = newCompoundStmt(NULL, b); 777 | return newFuncDecl(stype, type, s, r, b); 778 | } 779 | } 780 | 781 | past astFuncParams(){ 782 | paranum = 1; 783 | past l = astFuncParam(); 784 | while(match(Y_COMMA)){ 785 | advance(); 786 | past r = astFuncParam(); 787 | r->left = l; 788 | l = r; 789 | paranum++; 790 | } 791 | return l; 792 | } 793 | 794 | past astFuncParam(){ 795 | int type = astType(); 796 | char* stype; 797 | if(type == 0){ 798 | return NULL; 799 | } else if(type == Y_INT){ 800 | stype = "int"; 801 | } else if(type == Y_FLOAT){ 802 | stype = "float"; 803 | } else { 804 | stype = "void"; 805 | } 806 | 807 | if(!match(Y_ID)){ 808 | return NULL; 809 | } 810 | char* s = malloc(sizeof(char) * (yyleng + 1)); 811 | strcpy(s, yytext); 812 | advance(); 813 | past l = NULL; 814 | if(match(Y_LSQUARE)){ 815 | advance(); 816 | if(!match(Y_RSQUARE)){ 817 | return NULL; 818 | } 819 | advance(); 820 | l = astArraySubscriptsExp(); //需要修改 821 | return newParaDecl(stype, s, NULL, NULL); 822 | } else { 823 | l = astArraySubscriptsExp(); 824 | return newParaDecl(stype, s, NULL, NULL); 825 | } 826 | } 827 | 828 | //检查部分 829 | 830 | past astStmt(){ 831 | past t; 832 | if(match(Y_ID)){ 833 | char* s = malloc(sizeof(char) * (yyleng + 1)); 834 | strcpy(s, yytext); 835 | advance(); 836 | past n = astArraySubscriptsExp(); 837 | if(n == NULL){ 838 | if(!match(Y_ASSIGN)){ 839 | return NULL; 840 | } 841 | advance(); 842 | past l = astExp(); 843 | if(!match(Y_SEMICOLON)){ 844 | return NULL; 845 | } 846 | advance(); 847 | past r = newDeclRefExp(s, NULL, NULL); 848 | return newBinaryOper("=", Y_ASSIGN, r, l); 849 | } else { 850 | if(!match(Y_ASSIGN)){ 851 | return NULL; 852 | } 853 | advance(); 854 | past l = astExp(); 855 | if(!match(Y_SEMICOLON)){ 856 | return NULL; 857 | } 858 | advance(); 859 | past r = newDeclRefExp(s, NULL, NULL); 860 | n = newArraySubscriptsExp(r, n); 861 | 862 | return newBinaryOper("=", Y_ASSIGN, n, l); 863 | } 864 | } else if(match(Y_SEMICOLON)){ 865 | advance(); 866 | return NULL; 867 | } else if((t = astExp())){ 868 | if(!match(Y_SEMICOLON)){ 869 | return NULL; 870 | } 871 | advance(); 872 | return t; 873 | } else if(match(Y_LBRACKET)){ //Block 874 | advance(); 875 | past l = astBlockItems(); 876 | if(!match(Y_RBRACKET)){ 877 | return NULL; 878 | } 879 | advance(); 880 | return l; 881 | } else if(match(Y_WHILE)){ 882 | advance(); 883 | if(!match(Y_LPAR)){ 884 | return NULL; 885 | } 886 | advance(); 887 | past l = astLOrExp(); 888 | if(!match(Y_RPAR)){ 889 | return NULL; 890 | } 891 | advance(); 892 | past r = astStmt(); 893 | r = newCompoundStmt(NULL, r); 894 | return newWhileStmt(l, r); 895 | } else if(match(Y_IF)){ 896 | advance(); 897 | if(!match(Y_LPAR)){ 898 | return NULL; 899 | } 900 | advance(); 901 | past l1 = astLOrExp(); 902 | if(!match(Y_RPAR)){ 903 | return NULL; 904 | } 905 | advance(); 906 | past l2 = astStmt(); 907 | l2 = newCompoundStmt(NULL, l2); 908 | if(!match(Y_ELSE)){ 909 | return newIfStmt(l1, l2, NULL); 910 | } 911 | advance(); 912 | past l3 = astStmt(); 913 | l3 = newCompoundStmt(NULL, l3); 914 | return newIfStmt(l1, l2, l3); 915 | } else if(match(Y_BREAK)){ 916 | advance(); 917 | if(!match(Y_SEMICOLON)){ 918 | return NULL; 919 | } 920 | advance(); 921 | return newBreakStmt(); 922 | } else if(match(Y_CONTINUE)){ 923 | advance(); 924 | if(!match(Y_SEMICOLON)){ 925 | return NULL; 926 | } 927 | advance(); 928 | return newContinueStmt(); 929 | } else if(match(Y_RETURN)){ 930 | advance(); 931 | past l = astExp(); 932 | if(!match(Y_SEMICOLON)){ 933 | return NULL; 934 | } 935 | advance(); 936 | return newReturnStmt(l, NULL); 937 | } else { 938 | return NULL; 939 | } 940 | } 941 | 942 | past astBlock(){ //需要修改 943 | if(!match(Y_LBRACKET)){ 944 | return NULL; 945 | } 946 | advance(); 947 | past l = astBlockItems(); 948 | if(!match(Y_RBRACKET)){ 949 | return NULL; 950 | } 951 | advance(); 952 | return l; 953 | } 954 | 955 | past astBlockItems(){ 956 | compoundStmtNum = 1; 957 | past temp; 958 | past l = astBlockItem(); 959 | l = newCompoundStmt(l, NULL); 960 | temp = l; 961 | past r = astBlockItem(); 962 | while(r!= NULL){ 963 | compoundStmtNum++; 964 | r = newCompoundStmt(r, NULL); 965 | l->right = r; 966 | l = r; 967 | r = astBlockItem(); 968 | } 969 | return temp; 970 | } 971 | 972 | past astBlockItem(){ 973 | past l = astDecl(); 974 | if(l){ 975 | return l; 976 | } 977 | return astStmt(); 978 | } 979 | 980 | past astLOrExp(){ 981 | past l = astLAndExp(); 982 | while(match(Y_OR)){ 983 | int oper = tok; 984 | advance(); 985 | past r = astLAndExp(); 986 | l = newBinaryOper("||", oper, l, r); 987 | } 988 | return l; 989 | } 990 | 991 | past astLAndExp(){ 992 | past l = astEqExp(); 993 | while(match(Y_AND)){ 994 | int oper = tok; 995 | advance(); 996 | past r = astEqExp(); 997 | l = newBinaryOper("&&", oper, l, r); 998 | } 999 | return l; 1000 | } 1001 | 1002 | past astEqExp(){ 1003 | past l = astRelExp(); 1004 | while(match(Y_EQ) || match(Y_NOTEQ)){ 1005 | int oper = tok; 1006 | advance(); 1007 | past r = astRelExp(); 1008 | if(oper == Y_EQ){ 1009 | l = newBinaryOper("==", oper, l, r); 1010 | } else { 1011 | l = newBinaryOper("!=", oper, l, r); 1012 | } 1013 | } 1014 | return l; 1015 | } 1016 | 1017 | past astRelExp(){ 1018 | past l = astAddExp(); 1019 | while(match(Y_LESS) || match(Y_LESSEQ) || match(Y_GREAT) || match(Y_GREATEQ)){ 1020 | int oper = tok; 1021 | advance(); 1022 | past r = astAddExp(); 1023 | if(oper == Y_LESS){ 1024 | l = newBinaryOper("<", oper, l, r); 1025 | } else if(oper == Y_GREAT){ 1026 | l = newBinaryOper(">", oper, l, r); 1027 | } else if(oper == Y_LESSEQ){ 1028 | l = newBinaryOper("<=", oper, l, r); 1029 | } else { 1030 | l = newBinaryOper(">=", oper, l, r); 1031 | } 1032 | } 1033 | return l; 1034 | } 1035 | 1036 | past astExp(){ 1037 | return astAddExp(); 1038 | } 1039 | 1040 | past astAddExp(){ 1041 | past l = astMulExp(); 1042 | while(match(Y_ADD) || match(Y_SUB)){ 1043 | int oper = tok; 1044 | advance(); 1045 | past r = astMulExp(); 1046 | if(oper == Y_ADD){ 1047 | l = newBinaryOper("+", oper, l, r); 1048 | } else { 1049 | l = newBinaryOper("-", oper, l, r); 1050 | } 1051 | } 1052 | return l; 1053 | } 1054 | 1055 | past astMulExp(){ 1056 | past l = astUnaryExp(); 1057 | while(match(Y_MUL) || match(Y_DIV) || match(Y_MODULO)){ 1058 | int oper = tok; 1059 | advance(); 1060 | past r = astUnaryExp(); 1061 | if(oper == Y_MUL){ 1062 | l = newBinaryOper("*", oper, l, r); 1063 | } else if(oper == Y_DIV){ 1064 | l = newBinaryOper("/", oper, l, r); 1065 | } else { 1066 | l = newBinaryOper("%",oper, l, r); 1067 | } 1068 | } 1069 | return l; 1070 | } 1071 | 1072 | past astUnaryExp(){ 1073 | past l = astPrimaryExp(); 1074 | if(l != NULL){ 1075 | return l; 1076 | } else if(match(Y_ID)){ //执行不到这里,该部分在astPrinmaryExp函数执行 1077 | char* s = malloc(sizeof(char) * (yyleng + 1)); 1078 | strcpy(s, yytext); 1079 | advance(); 1080 | if(!match(Y_LPAR)){ 1081 | return NULL; 1082 | } 1083 | advance(); 1084 | if(match(Y_RPAR)){ 1085 | advance(); 1086 | return newCallExp(NULL,0, s, NULL, NULL); 1087 | } else { 1088 | past l = astCallParams(); 1089 | if(!match(Y_RPAR)){ 1090 | return NULL; 1091 | } 1092 | advance(); 1093 | return newCallExp(NULL, 0, s, l, NULL); 1094 | } 1095 | } else if(match(Y_ADD)){ 1096 | advance(); 1097 | past l = astUnaryExp(); 1098 | return newBinaryOper("+", Y_ADD, NULL, l); 1099 | } else if(match(Y_SUB)){ 1100 | advance(); 1101 | past l = astUnaryExp(); 1102 | return newBinaryOper("-", Y_SUB, NULL, l); 1103 | } else if(match(Y_NOT)){ 1104 | advance(); 1105 | past l = astUnaryExp(); 1106 | return newBinaryOper("!", Y_NOT, NULL, l); 1107 | } else { 1108 | return NULL; 1109 | } 1110 | } 1111 | 1112 | past astCallParams(){ 1113 | callParaNum = 1; 1114 | past l = astExp(); 1115 | past t = newParaDecl(NULL, NULL, l, NULL); 1116 | l = t; 1117 | while(match(Y_COMMA)){ 1118 | advance(); 1119 | callParaNum++; 1120 | past r = astExp(); 1121 | l->right = newParaDecl(NULL, NULL, r, NULL); 1122 | l = l->right; 1123 | } 1124 | return t; 1125 | } 1126 | 1127 | past astPrimaryExp(){ 1128 | if(match(Y_LPAR)){ 1129 | advance(); 1130 | past n1 = astExp(); 1131 | if(!match(Y_RPAR)){ 1132 | return NULL; 1133 | } 1134 | return n1; 1135 | } else if(match(Y_ID)){ 1136 | char* s = malloc(sizeof(char) * (yyleng + 1)); 1137 | strcpy(s, yytext); 1138 | past l = newDeclRefExp(s, NULL, NULL); 1139 | advance(); 1140 | if(match(Y_LPAR)){ //函数调用 1141 | advance(); 1142 | if(match(Y_RPAR)){ 1143 | advance(); 1144 | return newCallExp(NULL,0, s, NULL, NULL); 1145 | } else { 1146 | past l = astCallParams(); 1147 | if(!match(Y_RPAR)){ 1148 | return NULL; 1149 | } 1150 | advance(); 1151 | return newCallExp(NULL, 0, s, l, NULL); 1152 | } 1153 | } 1154 | past n = astArraySubscriptsExp(); 1155 | if(n != NULL){ 1156 | return newArraySubscriptsExp(l, n); 1157 | } else { 1158 | return l; 1159 | } 1160 | } else if(match(num_INT)){ 1161 | past n2 = newIntVal(atoi(yytext)); 1162 | advance(); 1163 | return n2; 1164 | } else if(match(num_FLOAT)){ 1165 | past n3 = newFloatVal(atof(yytext)); 1166 | advance(); 1167 | return n3; 1168 | } else { 1169 | return NULL; 1170 | } 1171 | } 1172 | 1173 | past astArraySubscriptsExp(){ 1174 | if(!match(Y_LSQUARE)){ 1175 | return NULL; 1176 | } 1177 | advance(); 1178 | past l = astExp(); 1179 | if(!match(Y_RSQUARE)){ 1180 | return NULL; 1181 | } 1182 | advance(); 1183 | while(match(Y_LSQUARE)){ //多维数组不太行这里,待修改 1184 | advance(); 1185 | past r = astExp(); 1186 | if(!match(Y_RSQUARE)){ 1187 | return NULL; 1188 | } 1189 | 1190 | l = newArraySubscriptsExp(l,r); 1191 | } 1192 | return l; 1193 | } 1194 | 1195 | int astType(){ 1196 | if(match(Y_INT)){ 1197 | advance(); 1198 | return Y_INT; 1199 | } else if(match(Y_FLOAT)){ 1200 | advance(); 1201 | return Y_FLOAT; 1202 | } else if(match(Y_VOID)){ 1203 | advance(); 1204 | return Y_VOID; 1205 | } else { 1206 | return 0; 1207 | } 1208 | } 1209 | 1210 | past newCompUnit(past left, past right){ 1211 | past node = newAstNode(); 1212 | node->nodeType = TRANSLATION_UNIT; 1213 | node->snodeType = "TRANSLATION_UNIT"; 1214 | node->left = left; 1215 | node->right = right; 1216 | return node; 1217 | } 1218 | 1219 | past newDeclStmt(past left, past right){ //声明语句,left 为变量/常声明结点,right为下一个声明语句 1220 | past node = newAstNode(); 1221 | node->nodeType = DECL_STMT; 1222 | node->snodeType = "DECL_STMT"; 1223 | node->left = left; 1224 | node->right = right; 1225 | return node; 1226 | } 1227 | 1228 | past newDeclRefExp(char* name, past left, past right){ //声明调用,主要用于变量引用,name为变量名,left,right,默认为NULL 1229 | past node = newAstNode(); 1230 | node->nodeType = DECL_REF_EXPR; 1231 | node->snodeType = "DECL_REF_EXPR"; 1232 | node->svalue = name; 1233 | node->left = left; 1234 | node->right = right; 1235 | return node; 1236 | } 1237 | 1238 | past newFuncDecl(char* stype, int type, char* name, past left, past right){ //left为形参列表,right为函数体 1239 | past node = newAstNode(); 1240 | node->nodeType = FUNCTION_DECL; 1241 | node->snodeType = "FUNCTION_DECL"; 1242 | node->svalue = name; 1243 | node->left = left; 1244 | node->right = right; 1245 | node->ivalue = type; 1246 | node->stype = stype; 1247 | return node; 1248 | } 1249 | 1250 | past newVarDecl(char* stype, int type, int if_const, char *name, past left, past right){ //left固定为空,right为下一个变量声明结点 1251 | past node = newAstNode(); 1252 | node->nodeType = VAR_DECL; 1253 | node->snodeType = "VAR_DECL"; 1254 | node->stype = stype; 1255 | node->left = left; 1256 | node->right = right; 1257 | node->ivalue = type; 1258 | node->svalue = name; 1259 | node->if_const = if_const; 1260 | return node; 1261 | } 1262 | 1263 | 1264 | past newCompoundStmt(past left, past right){ //复合语句表达式,left代表当前语句,right代表下一条语句 1265 | past node = newAstNode(); 1266 | node->nodeType = COMPOUND_STMT; 1267 | node->snodeType = "COMPOUND_STMT"; 1268 | node->left = left; 1269 | node->right = right; 1270 | return node; 1271 | } 1272 | 1273 | 1274 | past newArraySubscriptsExp(past left, past right){ //数组下标表达式,left为数组名,right为数组下标,若为多维数组则right的left,right均为数组下标 1275 | past node = newAstNode(); 1276 | node->nodeType = ARRAY_SUBSCRIPT_EXPR; 1277 | node->snodeType = "ARRAY_SUBSCRIPT_EXPR"; 1278 | node->left = left; 1279 | node->right = right; 1280 | return node; 1281 | } 1282 | 1283 | past newBinaryOper(char* soper, int oper, past left, past right){ //oper为运算符,left,right为操作数表达式 1284 | past node = newAstNode(); 1285 | node->nodeType = BINARY_OPERATOR; 1286 | node->snodeType = "BINARY_OPERATOR"; 1287 | node->ivalue = oper; 1288 | node->svalue = soper; 1289 | node->left = left; 1290 | node->right = right; 1291 | return node; 1292 | } 1293 | 1294 | 1295 | past newCallExp(char* stype, int type, char* name, past left, past right){ //函数调用表达式,left为实参,right为NULL,stype,type默认为NULL跟0,name为函数名 1296 | past node = newAstNode(); 1297 | node->nodeType = CALL_EXPR; 1298 | node->snodeType = "CALL_EXPR"; 1299 | node->stype = stype; 1300 | node->ivalue = type; 1301 | node->svalue = name; 1302 | node->left = left; 1303 | node->right = right; 1304 | return node; 1305 | } 1306 | 1307 | past newParaDecl(char* stype,char* name, past left, past right){ //函数参数表达式,,left为下一个变量结点,right 默认为NULL,只需记录类型即可 1308 | past node = newAstNode(); 1309 | node->nodeType = PARM_DECL; 1310 | node->snodeType = "PARM_DECL"; 1311 | node->stype = stype; 1312 | node->svalue = name; 1313 | node->left = left; 1314 | node->right = right; 1315 | return node; 1316 | } 1317 | 1318 | past newIntVal(int ival){ 1319 | past node = newAstNode(); 1320 | node->nodeType = INTEGER_LITERAL; 1321 | node->snodeType = "INTEGER_LITERAL"; 1322 | node->ivalue = ival; 1323 | return node; 1324 | } 1325 | 1326 | past newFloatVal(float fval){ 1327 | past node = newAstNode(); 1328 | node->nodeType = FLOATING_LITERAL; 1329 | node->snodeType = "FLOATING_LITERAL"; 1330 | node->fvalue = fval; 1331 | return node; 1332 | } 1333 | 1334 | past newIfStmt(past if_cond, past left, past right){ //if_cond为条件表达式,left为if复合语句,right为else复合语句 1335 | past node = newAstNode(); 1336 | node->nodeType = IF_STMT; 1337 | node->snodeType = "IF_STMT"; 1338 | node->if_cond = if_cond; 1339 | node->left = left; 1340 | node->right = right; 1341 | if(right != NULL){ 1342 | node->svalue = "has else"; 1343 | } else { 1344 | node->svalue = "no else"; 1345 | } 1346 | return node; 1347 | } 1348 | 1349 | past newWhileStmt(past left, past right){ //left为循环条件表达式,right为循环体复合语句 1350 | past node = newAstNode(); 1351 | node->nodeType = WHILE_STMT; 1352 | node->snodeType = "WHILE_STMT"; 1353 | node->left = left; 1354 | node->right = right; 1355 | return node; 1356 | } 1357 | 1358 | past newContinueStmt(){ 1359 | past node = newAstNode(); 1360 | node->nodeType = CONTINUE_STMT; 1361 | node->snodeType = "CONTINUE_STMT"; 1362 | return node; 1363 | } 1364 | 1365 | past newBreakStmt(){ 1366 | past node = newAstNode(); 1367 | node->nodeType = BREAK_STMT; 1368 | node->snodeType = "BREAK_STMT"; 1369 | return node; 1370 | } 1371 | 1372 | past newReturnStmt(past left, past right){ //left为返回值结点,right默认为NULL 1373 | past node = newAstNode(); 1374 | node->nodeType = RETURN_STMT; 1375 | node->snodeType = "RETURN_STMT"; 1376 | node->left = left; 1377 | node->right = right; 1378 | return node; 1379 | } -------------------------------------------------------------------------------- /lab2_递归下降分析/sysy_lex.l: -------------------------------------------------------------------------------- 1 | %{ 2 | 3 | // token definition 4 | #ifndef COMPILER_LAB_TOKEN_H 5 | #define COMPILER_LAB_TOKEN_H 6 | enum yytokentype { 7 | num_INT = 258, 8 | num_FLOAT = 259, 9 | 10 | Y_ID = 260, 11 | 12 | Y_INT = 261, 13 | Y_VOID = 262, 14 | Y_CONST = 263, 15 | Y_IF = 264, 16 | Y_ELSE = 265, 17 | Y_WHILE = 266, 18 | Y_BREAK = 267, 19 | Y_CONTINUE = 268, 20 | Y_RETURN = 269, 21 | 22 | Y_ADD = 270, 23 | Y_SUB = 271, 24 | Y_MUL = 272, 25 | Y_DIV = 273, 26 | Y_MODULO = 274, 27 | Y_LESS = 275, 28 | Y_LESSEQ = 276, 29 | Y_GREAT = 277, 30 | Y_GREATEQ = 278, 31 | Y_NOTEQ = 279, 32 | Y_EQ = 280, 33 | Y_NOT = 281, 34 | Y_AND = 282, 35 | Y_OR = 283, 36 | Y_ASSIGN = 284, 37 | 38 | Y_LPAR = 285, 39 | Y_RPAR = 286, 40 | Y_LBRACKET = 287, 41 | Y_RBRACKET = 288, 42 | Y_LSQUARE = 289, 43 | Y_RSQUARE = 290, 44 | Y_COMMA = 291, 45 | Y_SEMICOLON = 292, 46 | 47 | Y_FLOAT = 293 48 | }; 49 | 50 | typedef union _YYLVAL{ 51 | int token; 52 | int int_value; 53 | float float_value; 54 | char* id_name; 55 | }_YYLVAL; 56 | 57 | _YYLVAL yylval; 58 | #endif //COMPILER_LAB_TOKEN_H 59 | 60 | %} 61 | 62 | /* Regular definition */ 63 | DELIM [\t] 64 | WS {DELIM}+ 65 | DIGIT [0-9] 66 | LETTER [A-Za-z] 67 | 68 | %% 69 | 70 | (\/\/.*\n)|(\/\*.*\*\/) {/* noaction */} 71 | {WS} {/* noaction */} 72 | \n {return -1;} 73 | {DIGIT}+ {yylval.int_value = atoi(yytext); return num_INT;} 74 | {DIGIT}+"."{DIGIT}+ {yylval.float_value = (float)atof(yytext); return num_FLOAT;} 75 | int {return Y_INT;} 76 | float {return Y_FLOAT;} 77 | void {return Y_VOID;} 78 | const {return Y_CONST;} 79 | if {return Y_IF;} 80 | else {return Y_ELSE;} 81 | while {return Y_WHILE;} 82 | break {return Y_BREAK;} 83 | continue {return Y_CONTINUE;} 84 | return {return Y_RETURN;} 85 | ("_"|{LETTER})({DIGIT}|"_"|{LETTER})* {yylval.id_name = yytext; return Y_ID;} 86 | "+" {return Y_ADD;} 87 | "-" {return Y_SUB;} 88 | "*" {return Y_MUL;} 89 | "/" {return Y_DIV;} 90 | "%" {return Y_MODULO;} 91 | "<" {return Y_LESS;} 92 | "<=" {return Y_LESSEQ;} 93 | ">" {return Y_GREAT;} 94 | ">=" {return Y_GREATEQ;} 95 | "!=" {return Y_NOTEQ;} 96 | "==" {return Y_EQ;} 97 | "!" {return Y_NOT;} 98 | "&&" {return Y_AND;} 99 | "||" {return Y_OR;} 100 | "=" {return Y_ASSIGN;} 101 | "(" {return Y_LPAR;} 102 | ")" {return Y_RPAR;} 103 | "[" {return Y_LSQUARE;} 104 | "]" {return Y_RSQUARE;} 105 | "{" {return Y_LBRACKET;} 106 | "}" {return Y_RBRACKET;} 107 | "," {return Y_COMMA;} 108 | ";" {return Y_SEMICOLON;} 109 | 110 | 111 | %% 112 | 113 | int yywrap() { 114 | return 1; 115 | } 116 | -------------------------------------------------------------------------------- /lab2_递归下降分析/使用说明.txt: -------------------------------------------------------------------------------- 1 |    源文件rd_icoding.c包含全部的语法分析,使用时请您按照如下两种开头方式输入您想要测试的语句: 2 |    1. 以一个函数定义开头,函数体里面可以添加您想要测试的语句,例如表达式,if语句等,比如int main(){ if(a+5) {1+3;}; } 3 |    2.以定义一个全局变量的形式开头,例如int x = 2; 4 | -------------------------------------------------------------------------------- /lab3_LR语法分析/Readme.md: -------------------------------------------------------------------------------- 1 | 本次实验代码提交时,请按照实验老师要求的文件格式上传到icoding,否则提交结果不会通过 2 | -------------------------------------------------------------------------------- /lab3_LR语法分析/ast.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "ast.h" 5 | #include "lrparser.tab.h" 6 | 7 | 8 | past newAstNode(){ 9 | past node = malloc(sizeof(ast)); 10 | if(node == NULL) 11 | { 12 | printf("run out of memory.\n"); 13 | exit(0); 14 | } 15 | memset(node, 0, sizeof(ast)); 16 | return node; 17 | } 18 | 19 | void showAst(char* sym, past node, int nest){ 20 | if(node == NULL) 21 | return; 22 | int i = 0; 23 | for(i = 0; i < nest; i ++) 24 | printf(" "); 25 | if(node->nodeType == TRANSLATION_UNIT){ 26 | printf("%s-%s\n", sym, node->snodeType); 27 | showTranstion(node, nest + 1); 28 | return; 29 | } else if(node->nodeType == INTEGER_LITERAL){ 30 | printf("%s-%s %d\n", sym, node->snodeType, node->ivalue); 31 | } else if(node->nodeType == FLOATING_LITERAL){ 32 | printf("%s-%s %f\n", sym, node->snodeType, node->fvalue); 33 | } else if(node->nodeType == IF_STMT){ 34 | printf("%s-%s %s\n", sym, node->snodeType, node->svalue); 35 | showAst("|", node->if_cond, nest+1); 36 | } else if(node->nodeType == FUNCTION_DECL){ 37 | printf("%s-%s %s '%s'\n", sym, node->snodeType, node->svalue, node->stype); 38 | } else if(node->nodeType == PARM_DECL){ 39 | showParaDecl(node); 40 | return; 41 | } else if(node->nodeType == COMPOUND_STMT){ 42 | printf("%s-%s\n", sym, node->snodeType); 43 | node = node->right; 44 | showCompoundStmt(node, nest + 1); 45 | return; 46 | } else if(node->nodeType == VAR_DECL){ 47 | printf("%s-%s %s '%s'\n", sym, node->snodeType, node->svalue, node->stype); 48 | } else if(node->nodeType == CALL_EXPR){ 49 | printf("%s-%s %s\n", sym, node->snodeType, node->svalue); 50 | node = node->left; 51 | showCallExp(node, nest + 1); 52 | return; 53 | } else if(node->svalue != NULL){ 54 | printf("%s-%s '%s'\n", sym, node->snodeType, node->svalue); 55 | } else{ 56 | printf("%s-%s\n", sym, node->snodeType); 57 | } 58 | showAst("|", node->left, nest+1); 59 | showAst("`", node->right, nest+1); 60 | } 61 | 62 | void showTranstion(past node, int nest){ //函数块 63 | if(node == NULL){ 64 | return; 65 | } 66 | while(node->right != NULL){ 67 | showAst("|", node->left, nest); 68 | node = node->right; 69 | } 70 | showAst("`", node->left, nest); 71 | } 72 | 73 | void showCallExp(past node, int nest){ //函数调用遍历 74 | if(node == NULL){ 75 | return; 76 | } 77 | while(node->right != NULL){ 78 | showAst("|", node->left, nest); 79 | node = node->right; 80 | } 81 | showAst("'", node->left, nest); 82 | } 83 | 84 | void showCompoundStmt(past node, int nest){ //复合语句遍历 85 | if(node == NULL){ 86 | return; 87 | } 88 | while(node->right != NULL){ 89 | showAst("|", node->left, nest); 90 | node = node->right; 91 | } 92 | showAst("'", node->left, nest); 93 | } 94 | 95 | void showParaDecl(past node){ //函数参数,非递归中序遍历 96 | if(node == NULL){ 97 | return; 98 | } 99 | int sym = 1; 100 | past stack[100]; 101 | int top = 0; 102 | while(top || node){ 103 | if(node != NULL){ 104 | stack[top++] = node; 105 | node = node->left; 106 | }else if(top != 0){ 107 | node = stack[--top]; 108 | if(sym == 1){ 109 | printf("|-%s used %s '%s'\n", node->snodeType, node->svalue, node->stype); 110 | sym--; 111 | } else { 112 | printf(" |-%s used %s '%s'\n", node->snodeType, node->svalue, node->stype); 113 | } 114 | node = node->right; 115 | } 116 | } 117 | } 118 | 119 | char* get_id(char* id){ 120 | int i = 0; 121 | while(id[i] != '\0'){ 122 | i++; 123 | } 124 | char* s = malloc(sizeof(char) * (i + 1)); 125 | memcpy(s, id, i + 1); 126 | return s; 127 | } 128 | 129 | char* get_stype(int type){ 130 | char* stype; 131 | if(type == 0){ 132 | return NULL; 133 | } else if(type == Y_INT){ 134 | stype = "int"; 135 | } else if(type == Y_FLOAT){ 136 | stype = "float"; 137 | } else { 138 | stype = "void"; 139 | } 140 | return stype; 141 | } 142 | 143 | char* get_conststype(int type){ 144 | char* stype; 145 | if(type == 0){ 146 | return NULL; 147 | } else if(type == Y_INT){ 148 | stype = "const int"; 149 | } else if(type == Y_FLOAT){ 150 | stype = "const float"; 151 | } else { 152 | stype = "const void"; 153 | } 154 | return stype; 155 | } 156 | 157 | past newCompUnit(past left, past right){ 158 | past node = newAstNode(); 159 | node->nodeType = TRANSLATION_UNIT; 160 | node->snodeType = "TRANSLATION_UNIT"; 161 | node->left = left; 162 | node->right = right; 163 | return node; 164 | } 165 | 166 | past newDeclStmt(past left, past right){ //声明语句,left 为变量/常声明结点,right为下一个声明语句 167 | past node = newAstNode(); 168 | node->nodeType = DECL_STMT; 169 | node->snodeType = "DECL_STMT"; 170 | node->left = left; 171 | node->right = right; 172 | return node; 173 | } 174 | 175 | past newDeclRefExp(char* name, past left, past right){ //声明调用,主要用于变量引用,name为变量名,left,right,默认为NULL 176 | past node = newAstNode(); 177 | node->nodeType = DECL_REF_EXPR; 178 | node->snodeType = "DECL_REF_EXPR"; 179 | node->svalue = name; 180 | node->left = left; 181 | node->right = right; 182 | return node; 183 | } 184 | 185 | past newFuncDecl(char* stype, int type, char* name, past left, past right){ //left为形参列表,right为函数体 186 | past node = newAstNode(); 187 | node->nodeType = FUNCTION_DECL; 188 | node->snodeType = "FUNCTION_DECL"; 189 | node->svalue = name; 190 | node->left = left; 191 | node->right = right; 192 | node->ivalue = type; 193 | node->stype = stype; 194 | return node; 195 | } 196 | 197 | past newVarDecl(char* stype, int type, int if_const, char *name, past left, past right){ //left固定为空,right为变量初始赋值 198 | past node = newAstNode(); 199 | node->nodeType = VAR_DECL; 200 | node->snodeType = "VAR_DECL"; 201 | node->stype = stype; 202 | node->left = left; 203 | node->right = right; 204 | node->ivalue = type; 205 | node->svalue = name; 206 | node->if_const = if_const; 207 | return node; 208 | } 209 | 210 | 211 | past newCompoundStmt(past left, past right){ //复合语句表达式,left代表当前语句,right代表下一条语句 212 | past node = newAstNode(); 213 | node->nodeType = COMPOUND_STMT; 214 | node->snodeType = "COMPOUND_STMT"; 215 | node->left = left; 216 | node->right = right; 217 | return node; 218 | } 219 | 220 | 221 | past newArraySubscriptsExp(past left, past right){ //数组下标表达式,left为数组名,right为数组下标,若为多维数组则right的left,right均为数组下标 222 | past node = newAstNode(); 223 | node->nodeType = ARRAY_SUBSCRIPT_EXPR; 224 | node->snodeType = "ARRAY_SUBSCRIPT_EXPR"; 225 | node->left = left; 226 | node->right = right; 227 | return node; 228 | } 229 | 230 | past newBinaryOper(char* soper, int oper, past left, past right){ //oper为运算符,left,right为操作数表达式 231 | past node = newAstNode(); 232 | node->nodeType = BINARY_OPERATOR; 233 | node->snodeType = "BINARY_OPERATOR"; 234 | node->ivalue = oper; 235 | node->svalue = soper; 236 | node->left = left; 237 | node->right = right; 238 | return node; 239 | } 240 | 241 | 242 | past newCallExp(char* stype, int type, char* name, past left, past right){ //函数调用表达式,left为实参,right为NULL,stype,type默认为NULL跟0,name为函数名 243 | past node = newAstNode(); 244 | node->nodeType = CALL_EXPR; 245 | node->snodeType = "CALL_EXPR"; 246 | node->stype = stype; 247 | node->ivalue = type; 248 | node->svalue = name; 249 | node->left = left; 250 | node->right = right; 251 | return node; 252 | } 253 | 254 | past newParaDecl(char* stype,char* name, past left, past right){ //函数参数表达式,,left为下一个变量结点,right 默认为NULL,只需记录类型即可 255 | past node = newAstNode(); 256 | node->nodeType = PARM_DECL; 257 | node->snodeType = "PARM_DECL"; 258 | node->stype = stype; 259 | node->svalue = name; 260 | node->left = left; 261 | node->right = right; 262 | return node; 263 | } 264 | 265 | past newIntVal(int ival){ 266 | past node = newAstNode(); 267 | node->nodeType = INTEGER_LITERAL; 268 | node->snodeType = "INTEGER_LITERAL"; 269 | node->ivalue = ival; 270 | return node; 271 | } 272 | 273 | past newFloatVal(float fval){ 274 | past node = newAstNode(); 275 | node->nodeType = FLOATING_LITERAL; 276 | node->snodeType = "FLOATING_LITERAL"; 277 | node->fvalue = fval; 278 | return node; 279 | } 280 | 281 | past newIfStmt(past if_cond, past left, past right){ //if_cond为条件表达式,left为if复合语句,right为else复合语句 282 | past node = newAstNode(); 283 | node->nodeType = IF_STMT; 284 | node->snodeType = "IF_STMT"; 285 | node->if_cond = if_cond; 286 | node->left = left; 287 | node->right = right; 288 | if(right != NULL){ 289 | node->svalue = "has else"; 290 | } else { 291 | node->svalue = "no else"; 292 | } 293 | return node; 294 | } 295 | 296 | past newWhileStmt(past left, past right){ //left为循环条件表达式,right为循环体复合语句 297 | past node = newAstNode(); 298 | node->nodeType = WHILE_STMT; 299 | node->snodeType = "WHILE_STMT"; 300 | node->left = left; 301 | node->right = right; 302 | return node; 303 | } 304 | 305 | past newContinueStmt(){ 306 | past node = newAstNode(); 307 | node->nodeType = CONTINUE_STMT; 308 | node->snodeType = "CONTINUE_STMT"; 309 | return node; 310 | } 311 | 312 | past newBreakStmt(){ 313 | past node = newAstNode(); 314 | node->nodeType = BREAK_STMT; 315 | node->snodeType = "BREAK_STMT"; 316 | return node; 317 | } 318 | 319 | past newReturnStmt(past left, past right){ //left为返回值结点,right默认为NULL 320 | past node = newAstNode(); 321 | node->nodeType = RETURN_STMT; 322 | node->snodeType = "RETURN_STMT"; 323 | node->left = left; 324 | node->right = right; 325 | return node; 326 | } 327 | 328 | past newType(int oper){ 329 | past node = newAstNode(); 330 | node->ivalue = oper; 331 | return node; 332 | } 333 | -------------------------------------------------------------------------------- /lab3_LR语法分析/ast.h: -------------------------------------------------------------------------------- 1 | // Declaration Kinds 2 | #ifndef COMPILER_LAB_NODE_TYPE_H 3 | #define COMPILER_LAB_NODE_TYPE_H 4 | 5 | enum _node_type{ 6 | 7 | // A declaration whose specific kind is not exposed via this interface 8 | // 9 | 10 | // A C or C++ struct 11 | STRUCT_DECL = 2, 12 | 13 | // A C or C++ union 14 | UNION_DECL = 3, 15 | 16 | // An enumeration 17 | ENUM_DECL = 5, 18 | 19 | // A field in C, or non-static data member in C++, in a struct, union, or C++ 20 | // class 21 | FIELD_DECL = 6, 22 | 23 | // An enumerator constant 24 | ENUM_CONSTANT_DECL = 7, 25 | 26 | // A function 27 | FUNCTION_DECL = 8, 28 | 29 | // A variable 30 | VAR_DECL = 9, 31 | 32 | // A function or method parameter 33 | PARM_DECL = 10, 34 | 35 | 36 | // A typedef 37 | TYPEDEF_DECL = 20, 38 | 39 | // A Type alias decl 40 | TYPE_ALIAS_DECL = 36, 41 | 42 | 43 | // A reference to a member of a struct, union, or class that occurs in 44 | // some non-expression context, eg, a designated initializer 45 | MEMBER_REF = 47, 46 | 47 | // A reference to a labeled statement 48 | LABEL_REF = 48, 49 | 50 | // A reference to a set of overloaded functions or function templates 51 | // that has not yet been resolved to a specific function or function template 52 | OVERLOADED_DECL_REF = 49, 53 | 54 | // A reference to a variable that occurs in some non-expression 55 | // context, eg, a C++ lambda capture list 56 | VARIABLE_REF = 50, 57 | 58 | 59 | ////// 60 | // Invalid/Error Kinds 61 | 62 | INVALID_FILE = 70, 63 | NO_DECL_FOUND = 71, 64 | NOT_IMPLEMENTED = 72, 65 | INVALID_CODE = 73, 66 | 67 | 68 | ////// 69 | // Expression Kinds 70 | 71 | // An expression whose specific kind is not exposed via this interface 72 | // 73 | // Unexposed expressions have the same operations as any other kind of 74 | // expression; one can extract their location information, spelling, children, 75 | // etc However, the specific kind of the expression is not reported 76 | UNEXPOSED_EXPR = 100, 77 | 78 | // An expression that refers to some value declaration, such as a function, 79 | // variable, or enumerator 80 | DECL_REF_EXPR = 101, 81 | 82 | // An expression that refers to a member of a struct, union, class, Objective-C 83 | // class, etc 84 | MEMBER_REF_EXPR = 102, 85 | 86 | // An expression that calls a function 87 | CALL_EXPR = 103, 88 | 89 | 90 | // An expression that represents a block literal 91 | BLOCK_EXPR = 105, 92 | 93 | // An integer literal 94 | INTEGER_LITERAL = 106, 95 | 96 | // A floating point number literal 97 | FLOATING_LITERAL = 107, 98 | 99 | // An imaginary number literal 100 | IMAGINARY_LITERAL = 108, 101 | 102 | // A string literal 103 | STRING_LITERAL = 109, 104 | 105 | // A character literal 106 | CHARACTER_LITERAL = 110, 107 | 108 | // A parenthesized expression, eg "1," 109 | // 110 | // This AST node is only formed if full location information is requested 111 | PAREN_EXPR = 111, 112 | 113 | // This represents the unary-expression's except sizeof and 114 | // alignof, 115 | UNARY_OPERATOR = 112, 116 | 117 | // [C99 6521] Array Subscripting 118 | ARRAY_SUBSCRIPT_EXPR = 113, 119 | 120 | // A builtin binary operation expression such as "x + y" or 121 | // "x <= y" 122 | BINARY_OPERATOR = 114, 123 | 124 | // Compound assignment such as "+=" 125 | COMPOUND_ASSIGNMENT_OPERATOR = 115, 126 | 127 | // The ?: ternary operator 128 | CONDITIONAL_OPERATOR = 116, 129 | 130 | // An explicit cast in C C99 654, or a C-style cast in C++ 131 | // C++ [exprcast],, which uses the syntax Type,expr 132 | // 133 | // For example: int,f 134 | CSTYLE_CAST_EXPR = 117, 135 | 136 | // [C99 6525] 137 | COMPOUND_LITERAL_EXPR = 118, 138 | 139 | // Describes an C or C++ initializer list 140 | INIT_LIST_EXPR = 119, 141 | 142 | // The GNU address of label extension, representing &&label 143 | ADDR_LABEL_EXPR = 120, 144 | 145 | 146 | 147 | // A statement whose specific kind is not exposed via this interface 148 | // 149 | // Unexposed statements have the same operations as any other kind of statement; 150 | // one can extract their location information, spelling, children, etc However, 151 | // the specific kind of the statement is not reported 152 | UNEXPOSED_STMT = 200, 153 | 154 | // A labelled statement in a function 155 | LABEL_STMT = 201, 156 | 157 | // A compound statement 158 | COMPOUND_STMT = 202, 159 | 160 | // A case statement 161 | CASE_STMT = 203, 162 | 163 | // A default statement 164 | DEFAULT_STMT = 204, 165 | 166 | // An if statement 167 | IF_STMT = 205, 168 | 169 | // A switch statement 170 | SWITCH_STMT = 206, 171 | 172 | // A while statement 173 | WHILE_STMT = 207, 174 | 175 | // A do statement 176 | DO_STMT = 208, 177 | 178 | // A for statement 179 | FOR_STMT = 209, 180 | 181 | // A goto statement 182 | GOTO_STMT = 210, 183 | 184 | // An indirect goto statement 185 | INDIRECT_GOTO_STMT = 211, 186 | 187 | // A continue statement 188 | CONTINUE_STMT = 212, 189 | 190 | // A break statement 191 | BREAK_STMT = 213, 192 | 193 | // A return statement 194 | RETURN_STMT = 214, 195 | 196 | 197 | // The null statement 198 | NULL_STMT = 230, 199 | 200 | // Adaptor class for mixing declarations with statements and expressions 201 | DECL_STMT = 231, 202 | 203 | 204 | ////// 205 | // Other Kinds 206 | 207 | // Cursor that represents the translation unit itself 208 | // 209 | // The translation unit cursor exists primarily to act as the root cursor for 210 | // traversing the contents of a translation unit 211 | TRANSLATION_UNIT = 300, 212 | }; 213 | 214 | typedef enum _node_type node_type; 215 | extern int type; 216 | #endif 217 | 218 | //全局变量~ 219 | extern int yylex(); 220 | extern char* yytext; 221 | extern int yyleng; 222 | extern int tok; 223 | 224 | //结点声明 225 | typedef struct _ast ast; 226 | typedef struct _ast *past; 227 | struct _ast{ 228 | char* stype; 229 | int ivalue; 230 | float fvalue; 231 | char* svalue; 232 | node_type nodeType; 233 | char* snodeType; 234 | int if_const; 235 | past left; 236 | past right; 237 | past if_cond; 238 | past next; 239 | }; 240 | 241 | //函数声明 242 | 243 | //返回ast结点函数 244 | past newAstNode(); 245 | //显示ast 246 | void showAst(char* sym, past node, int nest); 247 | void showParaDecl(past node); 248 | void showCompoundStmt(past node, int nest); 249 | void showCallExp(past node, int nest); 250 | void showTranstion(past node, int nest); 251 | 252 | char* get_id(char* yytext); 253 | char* get_stype(int type); 254 | char* get_conststype(int type); 255 | 256 | past newDeclStmt(past left, past right); 257 | past newCompUnit(past left, past right); 258 | past newDeclRefExp(char* name, past left, past right); 259 | past newFuncDecl(char* stype, int type,char* svalue, past left, past right); 260 | past newBinaryOper(char* soper, int oper, past left, past right); 261 | past newArraySubscriptsExp(past left, past right); 262 | past newCallExp(char* stype, int type, char* name, past left, past right); 263 | past newParaDecl(char* stype, char* name, past left, past right); 264 | past newCompoundStmt(past left, past right); 265 | past newIntVal(int ival); 266 | past newFloatVal(float fval); 267 | past newVarDecl(char* stype, int type, int if_cond, char* s, past left, past right); 268 | past newIfStmt(past if_cond, past left, past right); 269 | past newWhileStmt(past left, past right); 270 | past newContinueStmt(); 271 | past newBreakStmt(); 272 | past newReturnStmt(past left, past right); 273 | past newType(int oper); -------------------------------------------------------------------------------- /lab3_LR语法分析/lrlex.l: -------------------------------------------------------------------------------- 1 | %{ 2 | #include 3 | #include "ast.h" 4 | #include "lrparser.tab.h" 5 | int type; 6 | 7 | %} 8 | 9 | /* Regular definition */ 10 | DELIM [\t ] 11 | WS {DELIM}+ 12 | DIGIT [0-9] 13 | LETTER [A-Za-z] 14 | 15 | %% 16 | 17 | (\/\/.*\n)|(\/\*.*\*\/) {/* noaction */} 18 | {WS} {/* noaction */} 19 | \n {return *yytext;} 20 | {DIGIT}+ {yylval.int_value = atoi(yytext); return num_INT;} 21 | {DIGIT}+"."{DIGIT}+ {yylval.float_value = (float)atof(yytext); return num_FLOAT;} 22 | int {type = Y_INT;return Y_INT;} 23 | float {type = Y_FLOAT;return Y_FLOAT;} 24 | void {type = Y_VOID;return Y_VOID;} 25 | const {return Y_CONST;} 26 | if {return Y_IF;} 27 | else {return Y_ELSE;} 28 | while {return Y_WHILE;} 29 | break {return Y_BREAK;} 30 | continue {return Y_CONTINUE;} 31 | return {return Y_RETURN;} 32 | ("_"|{LETTER})({DIGIT}|"_"|{LETTER})* {yylval.id_name = malloc(sizeof(char) * (yyleng + 1)); memcpy(yylval.id_name, yytext, yyleng); yylval.id_name[yyleng] = '\0'; return Y_ID;} 33 | "+" {return Y_ADD;} 34 | "-" {return Y_SUB;} 35 | "*" {return Y_MUL;} 36 | "/" {return Y_DIV;} 37 | "%" {return Y_MODULO;} 38 | "<" {return Y_LESS;} 39 | "<=" {return Y_LESSEQ;} 40 | ">" {return Y_GREAT;} 41 | ">=" {return Y_GREATEQ;} 42 | "!=" {return Y_NOTEQ;} 43 | "==" {return Y_EQ;} 44 | "!" {return Y_NOT;} 45 | "&&" {return Y_AND;} 46 | "||" {return Y_OR;} 47 | "=" {return Y_ASSIGN;} 48 | "(" {return Y_LPAR;} 49 | ")" {return Y_RPAR;} 50 | "[" {return Y_LSQUARE;} 51 | "]" {return Y_RSQUARE;} 52 | "{" {return Y_LBRACKET;} 53 | "}" {return Y_RBRACKET;} 54 | "," {return Y_COMMA;} 55 | ";" {return Y_SEMICOLON;} 56 | 57 | 58 | %% 59 | 60 | int yywrap() { 61 | return 1; 62 | } 63 | -------------------------------------------------------------------------------- /lab3_LR语法分析/lrparser.tab.h: -------------------------------------------------------------------------------- 1 | 2 | /* A Bison parser, made by GNU Bison 2.4.1. */ 3 | 4 | /* Skeleton interface for Bison's Yacc-like parsers in C 5 | 6 | Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 7 | Free Software Foundation, Inc. 8 | 9 | This program is free software: you can redistribute it and/or modify 10 | it under the terms of the GNU General Public License as published by 11 | the Free Software Foundation, either version 3 of the License, or 12 | (at your option) any later version. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program. If not, see . */ 21 | 22 | /* As a special exception, you may create a larger work that contains 23 | part or all of the Bison parser skeleton and distribute that work 24 | under terms of your choice, so long as that work isn't itself a 25 | parser generator using the skeleton or a modified version thereof 26 | as a parser skeleton. Alternatively, if you modify or redistribute 27 | the parser skeleton itself, you may (at your option) remove this 28 | special exception, which will cause the skeleton and the resulting 29 | Bison output files to be licensed under the GNU General Public 30 | License without this special exception. 31 | 32 | This special exception was added by the Free Software Foundation in 33 | version 2.2 of Bison. */ 34 | 35 | 36 | /* Tokens. */ 37 | #ifndef YYTOKENTYPE 38 | # define YYTOKENTYPE 39 | /* Put the tokens into the symbol table, so that GDB and other debuggers 40 | know about them. */ 41 | enum yytokentype { 42 | num_INT = 258, 43 | Y_INT = 259, 44 | Y_VOID = 260, 45 | Y_CONST = 261, 46 | Y_IF = 262, 47 | Y_ELSE = 263, 48 | Y_WHILE = 264, 49 | Y_BREAK = 265, 50 | Y_CONTINUE = 266, 51 | Y_FLOAT = 267, 52 | Y_RETURN = 268, 53 | Y_ADD = 269, 54 | Y_COMMA = 270, 55 | Y_DIV = 271, 56 | Y_LPAR = 272, 57 | Y_SUB = 273, 58 | Y_LSQUARE = 274, 59 | Y_MODULO = 275, 60 | Y_MUL = 276, 61 | Y_NOT = 277, 62 | Y_RPAR = 278, 63 | Y_RSQUARE = 279, 64 | Y_RBRACKET = 280, 65 | Y_LESS = 281, 66 | Y_LESSEQ = 282, 67 | Y_GREAT = 283, 68 | Y_GREATEQ = 284, 69 | Y_NOTEQ = 285, 70 | Y_EQ = 286, 71 | Y_AND = 287, 72 | Y_OR = 288, 73 | Y_ASSIGN = 289, 74 | Y_LBRACKET = 290, 75 | Y_SEMICOLON = 291, 76 | num_FLOAT = 292, 77 | Y_ID = 293 78 | }; 79 | #endif 80 | 81 | 82 | 83 | #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED 84 | typedef union YYSTYPE 85 | { 86 | 87 | /* Line 1676 of yacc.c */ 88 | #line 13 "lrparser.y" 89 | 90 | int token; 91 | int int_value; 92 | float float_value; 93 | char* id_name; 94 | past pAst; 95 | 96 | 97 | 98 | /* Line 1676 of yacc.c */ 99 | #line 100 "lrparser.tab.h" 100 | } YYSTYPE; 101 | # define YYSTYPE_IS_TRIVIAL 1 102 | # define yystype YYSTYPE /* obsolescent; will be withdrawn */ 103 | # define YYSTYPE_IS_DECLARED 1 104 | #endif 105 | 106 | extern YYSTYPE yylval; 107 | 108 | 109 | -------------------------------------------------------------------------------- /lab3_LR语法分析/lrparser.y: -------------------------------------------------------------------------------- 1 | %{ 2 | 3 | #include 4 | #include "ast.h" 5 | int yylex(void); 6 | void yyerror(char *); 7 | extern int type; 8 | //FuncParam还需要修改 9 | //需要修改VarDef、ConstExps、ConstDef、ConstInitVal、InitVal、ConstInitVals、InitVals 10 | 11 | %} 12 | 13 | %union { 14 | int token; 15 | int int_value; 16 | float float_value; 17 | char* id_name; 18 | past pAst; 19 | }; 20 | 21 | 22 | %token num_INT Y_INT Y_VOID Y_CONST Y_IF Y_ELSE Y_WHILE Y_BREAK Y_CONTINUE Y_FLOAT Y_RETURN 23 | %token Y_ADD Y_COMMA Y_DIV Y_LPAR Y_SUB Y_LSQUARE Y_MODULO Y_MUL Y_NOT Y_RPAR Y_RSQUARE Y_RBRACKET 24 | %token Y_LESS Y_LESSEQ Y_GREAT Y_GREATEQ Y_NOTEQ Y_EQ Y_AND Y_OR Y_ASSIGN Y_LBRACKET Y_SEMICOLON 25 | %token num_FLOAT 26 | %token Y_ID 27 | %type program Exp AddExp MulExp UnaryExp CallParams PrimaryExp LVal ArraySubscripts 28 | %type Block BlockItem BlockItems Stmt RelExp EqExp LAndExp LOrExp 29 | %type FuncDef FuncParam FuncParams Type 30 | %type CompUnit Decl ConstDecl ConstDefs ConstDef ConstExps ConstInitVal ConstInitVals 31 | %type VarDecl VarDecls VarDef InitVal InitVals ConstExp 32 | 33 | 34 | 35 | %% 36 | program: CompUnit '\n'{showAst("|", $1, 0); } 37 | ; 38 | 39 | CompUnit: Decl CompUnit {past l = newCompUnit($1, NULL); l->right = $2; $$ = l} 40 | | FuncDef CompUnit {past l = newCompUnit($1, NULL); l->right = $2; $$ = l} 41 | | Decl {$$ = newCompUnit($1, NULL);} 42 | | FuncDef {$$ = newCompUnit($1, NULL);} 43 | ; 44 | 45 | Decl: ConstDecl 46 | | VarDecl 47 | ; 48 | 49 | ConstDecl: Y_CONST Type ConstDef Y_SEMICOLON {$$ = newDeclStmt(NULL, $3);} 50 | | Y_CONST Type ConstDefs Y_SEMICOLON {$$ = newDeclStmt(NULL, $3);} 51 | ; 52 | 53 | ConstDefs: ConstDef Y_COMMA ConstDef {$$ = newDeclStmt($1, $3);} 54 | | ConstDefs Y_COMMA ConstDef {$$ = newDeclStmt($1, $3);} 55 | ; 56 | 57 | ConstDef: Y_ID Y_ASSIGN ConstInitVal {$$ = newVarDecl(get_conststype(type), type, 1, $1, NULL, $3);} 58 | | Y_ID ConstExps Y_ASSIGN ConstInitVal {$$ = newVarDecl(get_conststype(type), type, 1, $1, NULL, $4); } 59 | ; 60 | 61 | ConstExps: Y_LSQUARE ConstExp Y_RSQUARE {$$ = $2;} 62 | | Y_LSQUARE ConstExp Y_RSQUARE ConstExps {$$ = $2; } 63 | ; 64 | 65 | ConstInitVal: ConstExp 66 | | Y_LBRACKET Y_RBRACKET {$$ = NULL; } 67 | | Y_LBRACKET ConstInitVal Y_RBRACKET {$$ = $2;} 68 | | Y_LBRACKET ConstInitVal ConstInitVals Y_RBRACKET {$$ = $2; } 69 | ; 70 | 71 | ConstExp: AddExp 72 | ; 73 | 74 | ConstInitVals: Y_COMMA ConstInitVal {$$ = $2;} 75 | | Y_COMMA ConstInitVal ConstInitVals {$$ = $2; } 76 | ; 77 | 78 | VarDecl: Type VarDef Y_SEMICOLON {$$ = newDeclStmt(NULL, $2);} 79 | | Type VarDef VarDecls Y_SEMICOLON {$$ = newDeclStmt($2, $3);} 80 | ; 81 | 82 | VarDecls: Y_COMMA VarDef {$$ = $2;} 83 | | Y_COMMA VarDef VarDecls {$$ = newDeclStmt($2, $3);} 84 | ; 85 | 86 | VarDef: Y_ID {$$ = newVarDecl(get_stype(type), type, 0, $1, NULL, NULL);} 87 | | Y_ID Y_ASSIGN InitVal {$$ = newVarDecl(get_stype(type), type, 0, $1, NULL, $3);} 88 | | Y_ID ConstExps {$$ = newVarDecl(get_stype(type), type, 0, $1, NULL, NULL); } 89 | | Y_ID ConstExps Y_ASSIGN InitVal {$$ = newVarDecl(get_stype(type), type, 0, $1, NULL, $4); } 90 | ; 91 | 92 | InitVal: Exp 93 | | Y_LBRACKET Y_RBRACKET {$$ = NULL;} 94 | | Y_LBRACKET InitVal Y_RBRACKET {$$ = $2;} 95 | | Y_LBRACKET InitVal InitVals Y_RBRACKET {$$ = $2; } 96 | ; 97 | 98 | InitVals: Y_COMMA InitVal {$$ = $2; } 99 | | Y_COMMA InitVal InitVals {$$ = $2; } 100 | ; 101 | 102 | 103 | FuncDef: Type Y_ID Y_LPAR Y_RPAR Block {$$ = newFuncDecl(get_stype($1->ivalue), $1->ivalue,$2, NULL, newCompoundStmt(NULL, $5));} 104 | | Type Y_ID Y_LPAR FuncParams Y_RPAR Block {$$ = newFuncDecl(get_stype($1->ivalue), $1->ivalue, $2, $4, newCompoundStmt(NULL, $6));} 105 | ; 106 | 107 | FuncParams: FuncParam 108 | | FuncParams Y_COMMA FuncParam {$3->left = $1; $$ = $3;} 109 | ; 110 | 111 | FuncParam: Type Y_ID {$$ = newParaDecl(get_stype($1->ivalue), $2, NULL, NULL);} 112 | | Type Y_ID Y_LSQUARE Y_RSQUARE {$$ = newParaDecl(get_stype($1->ivalue), $2, NULL, NULL);} 113 | | Type Y_ID ArraySubscripts {$$ = newParaDecl(get_stype($1->ivalue), $2, NULL, NULL);} 114 | | Type Y_ID Y_LSQUARE Y_RSQUARE ArraySubscripts {$$ = newParaDecl(get_stype($1->ivalue), $2, NULL, NULL);} 115 | ; 116 | 117 | Type: Y_INT {yylval.int_value = Y_INT;$$ = newType(Y_INT);} 118 | | Y_FLOAT {yylval.int_value = Y_FLOAT;$$ = newType(Y_FLOAT);} 119 | | Y_VOID {yylval.int_value = Y_VOID;$$ = newType(Y_VOID);} 120 | ; 121 | 122 | Stmt: LVal Y_ASSIGN Exp Y_SEMICOLON {$$ = newBinaryOper("=", Y_ASSIGN, $1, $3);} 123 | | Y_SEMICOLON {$$ = NULL;} 124 | | Exp Y_SEMICOLON {$$ = $1;} 125 | | Block 126 | | Y_WHILE Y_LPAR LOrExp Y_RPAR Stmt {$$ = newWhileStmt($3, newCompoundStmt(NULL,$5));} 127 | | Y_IF Y_LPAR LOrExp Y_RPAR Stmt {$$ = newIfStmt($3, newCompoundStmt(NULL,$5), NULL);} 128 | | Y_IF Y_LPAR LOrExp Y_RPAR Stmt Y_ELSE Stmt {$$ = newIfStmt($3, newCompoundStmt(NULL,$5), newCompoundStmt(NULL,$7));} 129 | | Y_BREAK Y_SEMICOLON {$$ = newBreakStmt();} 130 | | Y_CONTINUE Y_SEMICOLON {$$ = newContinueStmt();} 131 | | Y_RETURN Exp Y_SEMICOLON {$$ = newReturnStmt($2, NULL);} 132 | | Y_RETURN Y_SEMICOLON {$$ = newReturnStmt(NULL, NULL);} 133 | ; 134 | 135 | Block: Y_LBRACKET BlockItems Y_RBRACKET {$$ = $2;} 136 | | Y_LBRACKET Y_RBRACKET {$$ = NULL;} 137 | ; 138 | 139 | BlockItems: BlockItem {$$ = newCompoundStmt($1, NULL);} 140 | | BlockItem BlockItems {past l = newCompoundStmt($1, NULL); l->right = $2; $$ = l;} 141 | ; 142 | 143 | BlockItem: Decl 144 | | Stmt 145 | ; 146 | 147 | RelExp: AddExp 148 | | AddExp Y_LESS RelExp {$$ = newBinaryOper("<", Y_LESS, $1, $3);} 149 | | AddExp Y_GREAT RelExp {$$ = newBinaryOper(">", Y_GREAT, $1, $3);} 150 | | AddExp Y_LESSEQ RelExp {$$ = newBinaryOper("<=", Y_LESSEQ, $1, $3);} 151 | | AddExp Y_GREATEQ RelExp {$$ = newBinaryOper(">=", Y_GREATEQ, $1, $3);} 152 | ; 153 | 154 | EqExp: RelExp 155 | | RelExp Y_EQ EqExp {$$ = newBinaryOper("==", Y_EQ, $1, $3);} 156 | | RelExp Y_NOTEQ EqExp {$$ = newBinaryOper("!=", Y_NOTEQ, $1, $3);} 157 | ; 158 | 159 | LAndExp: EqExp 160 | | EqExp Y_AND LAndExp {$$ = newBinaryOper("&&", Y_AND, $1, $3);} 161 | ; 162 | 163 | LOrExp: LAndExp 164 | | LAndExp Y_OR LOrExp {$$ = newBinaryOper("||", Y_OR, $1, $3);} 165 | ; 166 | 167 | Exp: AddExp 168 | ; 169 | 170 | 171 | AddExp: MulExp 172 | | AddExp Y_ADD MulExp {$$ = newBinaryOper("+", Y_ADD, $1, $3);} 173 | | AddExp Y_SUB MulExp {$$ = newBinaryOper("-", Y_SUB, $1, $3);} 174 | ; 175 | 176 | MulExp: UnaryExp 177 | | MulExp Y_MUL UnaryExp {$$ = newBinaryOper("*", Y_MUL, $1, $3);} 178 | | MulExp Y_DIV UnaryExp {$$ = newBinaryOper("/", Y_DIV, $1, $3);} 179 | | MulExp Y_MODULO UnaryExp {$$ = newBinaryOper("%", Y_MODULO, $1, $3);} 180 | ; 181 | 182 | UnaryExp: PrimaryExp 183 | | Y_ID Y_LPAR Y_RPAR {$$ = newCallExp(NULL, 0, $1, NULL, NULL);} 184 | | Y_ID Y_LPAR CallParams Y_RPAR {$$ = newCallExp(NULL, 0, $1, $3, NULL);} 185 | | Y_ADD UnaryExp {$$ = newBinaryOper("+", Y_ADD, NULL, $2);} 186 | | Y_SUB UnaryExp {$$ = newBinaryOper("-", Y_SUB, NULL, $2);} 187 | | Y_NOT UnaryExp {$$ = newBinaryOper("!", Y_NOT, NULL, $2);} 188 | ; 189 | 190 | CallParams: Exp 191 | | Exp Y_COMMA CallParams {$$ = newBinaryOper("-", Y_SUB, $1, $3);} 192 | ; 193 | 194 | PrimaryExp: Y_LPAR Exp Y_RPAR {$$ = $2;} 195 | | LVal 196 | | num_INT {$$ = newIntVal($1);} 197 | | num_FLOAT {$$ = newFloatVal($1);} 198 | ; 199 | 200 | LVal: Y_ID {$$ = newDeclRefExp($1, NULL, NULL);} 201 | | Y_ID ArraySubscripts {$$ = newDeclRefExp($1, NULL, NULL);} 202 | ; 203 | 204 | ArraySubscripts: Y_LSQUARE Exp Y_RSQUARE {$$ = $2} 205 | | Y_LSQUARE Exp Y_RSQUARE ArraySubscripts {$$ = newArraySubscriptsExp($2, $4);} 206 | ; 207 | 208 | %% 209 | -------------------------------------------------------------------------------- /lab3_LR语法分析/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void yyerror(char *s) 4 | { 5 | printf("%s\n", s); 6 | } 7 | 8 | int main(void) 9 | { 10 | yyparse(); 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /lab4_中间代码生成/ast.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "ast.h" 5 | #include "threeaddress.tab.h" 6 | 7 | 8 | past newAstNode(){ 9 | past node = malloc(sizeof(ast)); 10 | if(node == NULL) 11 | { 12 | printf("run out of memory.\n"); 13 | exit(0); 14 | } 15 | memset(node, 0, sizeof(ast)); 16 | return node; 17 | } 18 | 19 | void showAst(char* sym, past node, int nest){ 20 | if(node == NULL) 21 | return; 22 | int i = 0; 23 | for(i = 0; i < nest; i ++) 24 | printf(" "); 25 | if(node->nodeType == TRANSLATION_UNIT){ 26 | printf("%s-%s\n", sym, node->snodeType); 27 | showTranstion(node, nest + 1); 28 | return; 29 | } else if(node->nodeType == INTEGER_LITERAL){ 30 | printf("%s-%s %d\n", sym, node->snodeType, node->ivalue); 31 | } else if(node->nodeType == FLOATING_LITERAL){ 32 | printf("%s-%s %f\n", sym, node->snodeType, node->fvalue); 33 | } else if(node->nodeType == IF_STMT){ 34 | printf("%s-%s %s\n", sym, node->snodeType, node->svalue); 35 | showAst("|", node->if_cond, nest+1); 36 | } else if(node->nodeType == FUNCTION_DECL){ 37 | printf("%s-%s %s '%s'\n", sym, node->snodeType, node->svalue, node->stype); 38 | } else if(node->nodeType == PARM_DECL){ 39 | showParaDecl(node); 40 | return; 41 | } else if(node->nodeType == COMPOUND_STMT){ 42 | printf("%s-%s\n", sym, node->snodeType); 43 | node = node->right; 44 | showCompoundStmt(node, nest + 1); 45 | return; 46 | } else if(node->nodeType == VAR_DECL){ 47 | printf("%s-%s %s '%s'\n", sym, node->snodeType, node->svalue, node->stype); 48 | } else if(node->nodeType == CALL_EXPR){ 49 | printf("%s-%s %s\n", sym, node->snodeType, node->svalue); 50 | node = node->left; 51 | showCallExp(node, nest + 1); 52 | return; 53 | } else if(node->svalue != NULL){ 54 | printf("%s-%s '%s'\n", sym, node->snodeType, node->svalue); 55 | } else{ 56 | printf("%s-%s\n", sym, node->snodeType); 57 | } 58 | showAst("|", node->left, nest+1); 59 | showAst("`", node->right, nest+1); 60 | } 61 | 62 | void showTranstion(past node, int nest){ //函数块 63 | if(node == NULL){ 64 | return; 65 | } 66 | while(node->right != NULL){ 67 | showAst("|", node->left, nest); 68 | node = node->right; 69 | } 70 | showAst("`", node->left, nest); 71 | } 72 | 73 | void showCallExp(past node, int nest){ //函数调用遍历 74 | if(node == NULL){ 75 | return; 76 | } 77 | while(node->right != NULL){ 78 | showAst("|", node->left, nest); 79 | node = node->right; 80 | } 81 | showAst("'", node->left, nest); 82 | } 83 | 84 | void showCompoundStmt(past node, int nest){ //复合语句遍历 85 | if(node == NULL){ 86 | return; 87 | } 88 | while(node->right != NULL){ 89 | showAst("|", node->left, nest); 90 | node = node->right; 91 | } 92 | showAst("'", node->left, nest); 93 | } 94 | 95 | void showParaDecl(past node){ //函数参数,非递归中序遍历 96 | if(node == NULL){ 97 | return; 98 | } 99 | int sym = 1; 100 | past stack[100]; 101 | int top = 0; 102 | while(top || node){ 103 | if(node != NULL){ 104 | stack[top++] = node; 105 | node = node->left; 106 | }else if(top != 0){ 107 | node = stack[--top]; 108 | if(sym == 1){ 109 | printf("|-%s used %s '%s'\n", node->snodeType, node->svalue, node->stype); 110 | sym--; 111 | } else { 112 | printf(" |-%s used %s '%s'\n", node->snodeType, node->svalue, node->stype); 113 | } 114 | node = node->right; 115 | } 116 | } 117 | } 118 | 119 | past newList(past list, past node) { //链表节点,ivalue为链表节点数,left为链表的第一个具有实际意义的结点,right为尾结点 120 | if(list != NULL) { 121 | //add node to the tail of list 122 | listTail(list)->next = node; 123 | 124 | //make tail to point to the last element of list 125 | listTail(list) = node; 126 | list->ivalue += 1; 127 | return list; 128 | } 129 | 130 | list = newAstNode(); 131 | list->nodeType = INIT_LIST_EXPR; 132 | list->next = node; 133 | list->ivalue = 1; 134 | 135 | listHead(list) = node; 136 | listTail(list) = node; 137 | 138 | return list; 139 | } 140 | 141 | char* get_id(char* id){ 142 | int i = 0; 143 | while(id[i] != '\0'){ 144 | i++; 145 | } 146 | char* s = malloc(sizeof(char) * (i + 1)); 147 | memcpy(s, id, i + 1); 148 | return s; 149 | } 150 | 151 | char* get_stype(int type){ 152 | char* stype; 153 | if(type == 0){ 154 | return NULL; 155 | } else if(type == Y_INT){ 156 | stype = "int"; 157 | } else if(type == Y_FLOAT){ 158 | stype = "float"; 159 | } else { 160 | stype = "void"; 161 | } 162 | return stype; 163 | } 164 | 165 | char* get_conststype(int type){ 166 | char* stype; 167 | if(type == 0){ 168 | return NULL; 169 | } else if(type == Y_INT){ 170 | stype = "const int"; 171 | } else if(type == Y_FLOAT){ 172 | stype = "const float"; 173 | } else { 174 | stype = "const void"; 175 | } 176 | return stype; 177 | } 178 | 179 | past newCompUnit(past left, past right){ 180 | past node = newAstNode(); 181 | node->nodeType = TRANSLATION_UNIT; 182 | node->snodeType = "TRANSLATION_UNIT"; 183 | node->left = left; 184 | node->right = right; 185 | return node; 186 | } 187 | 188 | past newDeclStmt(past left, past right){ //声明语句,left 为变量/常声明结点,right为下一个声明语句 189 | past node = newAstNode(); 190 | node->nodeType = DECL_STMT; 191 | node->snodeType = "DECL_STMT"; 192 | node->left = left; 193 | node->right = right; 194 | return node; 195 | } 196 | 197 | past newDeclRefExp(char* name, past left, past right){ //声明调用,主要用于变量引用,name为变量名,left,right,默认为NULL 198 | past node = newAstNode(); 199 | node->nodeType = DECL_REF_EXPR; 200 | node->snodeType = "DECL_REF_EXPR"; 201 | node->svalue = name; 202 | node->left = left; 203 | node->right = right; 204 | return node; 205 | } 206 | 207 | past newFuncDecl(char* stype, int type, char* name, past left, past right){ //left为形参列表,right为函数体 208 | past node = newAstNode(); 209 | node->nodeType = FUNCTION_DECL; 210 | node->snodeType = "FUNCTION_DECL"; 211 | node->svalue = name; 212 | node->left = left; 213 | node->right = right; 214 | node->ivalue = type; 215 | node->stype = stype; 216 | return node; 217 | } 218 | 219 | past newVarDecl(char* stype, int type, int if_const, char *name, past left, past right){ //left固定为空,right为变量初始赋值 220 | past node = newAstNode(); 221 | node->nodeType = VAR_DECL; 222 | node->snodeType = "VAR_DECL"; 223 | node->stype = stype; 224 | node->left = left; 225 | node->right = right; 226 | node->ivalue = type; 227 | node->svalue = name; 228 | node->if_const = if_const; 229 | return node; 230 | } 231 | 232 | 233 | past newCompoundStmt(past left, past right){ //复合语句表达式,left代表当前语句,right代表下一条语句 234 | past node = newAstNode(); 235 | node->nodeType = COMPOUND_STMT; 236 | node->snodeType = "COMPOUND_STMT"; 237 | node->left = left; 238 | node->right = right; 239 | return node; 240 | } 241 | 242 | 243 | past newArraySubscriptsExp(past left, past right){ //数组下标表达式,left为数组名,right为数组下标,若为多维数组则right的left,right均为数组下标 244 | past node = newAstNode(); 245 | node->nodeType = ARRAY_SUBSCRIPT_EXPR; 246 | node->snodeType = "ARRAY_SUBSCRIPT_EXPR"; 247 | node->left = left; 248 | node->right = right; 249 | return node; 250 | } 251 | 252 | past newBinaryOper(char* soper, int oper, past left, past right){ //oper为运算符,left,right为操作数表达式 253 | past node = newAstNode(); 254 | node->nodeType = BINARY_OPERATOR; 255 | node->snodeType = "BINARY_OPERATOR"; 256 | node->ivalue = oper; 257 | node->svalue = soper; 258 | node->left = left; 259 | node->right = right; 260 | return node; 261 | } 262 | 263 | 264 | past newCallExp(char* stype, int type, char* name, past left, past right){ //函数调用表达式,left为实参,right为NULL,stype,type默认为NULL跟0,name为函数名 265 | past node = newAstNode(); 266 | node->nodeType = CALL_EXPR; 267 | node->snodeType = "CALL_EXPR"; 268 | node->stype = stype; 269 | node->ivalue = type; 270 | node->svalue = name; 271 | node->left = left; 272 | node->right = right; 273 | return node; 274 | } 275 | 276 | past newParaDecl(char* stype,char* name, past left, past right){ //函数参数表达式,,left为下一个变量结点,right 默认为NULL,只需记录类型即可 277 | past node = newAstNode(); 278 | node->nodeType = PARM_DECL; 279 | node->snodeType = "PARM_DECL"; 280 | node->stype = stype; 281 | node->svalue = name; 282 | node->left = left; 283 | node->right = right; 284 | return node; 285 | } 286 | 287 | past newIntVal(int ival){ 288 | past node = newAstNode(); 289 | node->nodeType = INTEGER_LITERAL; 290 | node->snodeType = "INTEGER_LITERAL"; 291 | node->ivalue = ival; 292 | return node; 293 | } 294 | 295 | past newFloatVal(float fval){ 296 | past node = newAstNode(); 297 | node->nodeType = FLOATING_LITERAL; 298 | node->snodeType = "FLOATING_LITERAL"; 299 | node->fvalue = fval; 300 | return node; 301 | } 302 | 303 | past newIfStmt(past if_cond, past left, past right){ //if_cond为条件表达式,left为if复合语句,right为else复合语句 304 | past node = newAstNode(); 305 | node->nodeType = IF_STMT; 306 | node->snodeType = "IF_STMT"; 307 | node->if_cond = if_cond; 308 | node->left = left; 309 | node->right = right; 310 | if(right != NULL){ 311 | node->svalue = "has else"; 312 | } else { 313 | node->svalue = "no else"; 314 | } 315 | return node; 316 | } 317 | 318 | past newWhileStmt(past left, past right){ //left为循环条件表达式,right为循环体复合语句 319 | past node = newAstNode(); 320 | node->nodeType = WHILE_STMT; 321 | node->snodeType = "WHILE_STMT"; 322 | node->left = left; 323 | node->right = right; 324 | return node; 325 | } 326 | 327 | past newContinueStmt(){ 328 | past node = newAstNode(); 329 | node->nodeType = CONTINUE_STMT; 330 | node->snodeType = "CONTINUE_STMT"; 331 | return node; 332 | } 333 | 334 | past newBreakStmt(){ 335 | past node = newAstNode(); 336 | node->nodeType = BREAK_STMT; 337 | node->snodeType = "BREAK_STMT"; 338 | return node; 339 | } 340 | 341 | past newReturnStmt(past left, past right){ //left为返回值结点,right默认为NULL 342 | past node = newAstNode(); 343 | node->nodeType = RETURN_STMT; 344 | node->snodeType = "RETURN_STMT"; 345 | node->left = left; 346 | node->right = right; 347 | return node; 348 | } 349 | 350 | past newType(int oper){ 351 | past node = newAstNode(); 352 | node->ivalue = oper; 353 | return node; 354 | } -------------------------------------------------------------------------------- /lab4_中间代码生成/ast.h: -------------------------------------------------------------------------------- 1 | // Declaration Kinds 2 | #ifndef AST_H 3 | #define AST_H 4 | 5 | enum _node_type{ 6 | 7 | // A declaration whose specific kind is not exposed via this interface 8 | // 9 | 10 | // A C or C++ struct 11 | STRUCT_DECL = 2, 12 | 13 | // A C or C++ union 14 | UNION_DECL = 3, 15 | 16 | // An enumeration 17 | ENUM_DECL = 5, 18 | 19 | // A field in C, or non-static data member in C++, in a struct, union, or C++ 20 | // class 21 | FIELD_DECL = 6, 22 | 23 | // An enumerator constant 24 | ENUM_CONSTANT_DECL = 7, 25 | 26 | // A function 27 | FUNCTION_DECL = 8, 28 | 29 | // A variable 30 | VAR_DECL = 9, 31 | 32 | // A function or method parameter 33 | PARM_DECL = 10, 34 | 35 | 36 | // A typedef 37 | TYPEDEF_DECL = 20, 38 | 39 | // A Type alias decl 40 | TYPE_ALIAS_DECL = 36, 41 | 42 | 43 | // A reference to a member of a struct, union, or class that occurs in 44 | // some non-expression context, eg, a designated initializer 45 | MEMBER_REF = 47, 46 | 47 | // A reference to a labeled statement 48 | LABEL_REF = 48, 49 | 50 | // A reference to a set of overloaded functions or function templates 51 | // that has not yet been resolved to a specific function or function template 52 | OVERLOADED_DECL_REF = 49, 53 | 54 | // A reference to a variable that occurs in some non-expression 55 | // context, eg, a C++ lambda capture list 56 | VARIABLE_REF = 50, 57 | 58 | 59 | ////// 60 | // Invalid/Error Kinds 61 | 62 | INVALID_FILE = 70, 63 | NO_DECL_FOUND = 71, 64 | NOT_IMPLEMENTED = 72, 65 | INVALID_CODE = 73, 66 | 67 | 68 | ////// 69 | // Expression Kinds 70 | 71 | // An expression whose specific kind is not exposed via this interface 72 | // 73 | // Unexposed expressions have the same operations as any other kind of 74 | // expression; one can extract their location information, spelling, children, 75 | // etc However, the specific kind of the expression is not reported 76 | UNEXPOSED_EXPR = 100, 77 | 78 | // An expression that refers to some value declaration, such as a function, 79 | // variable, or enumerator 80 | DECL_REF_EXPR = 101, 81 | 82 | // An expression that refers to a member of a struct, union, class, Objective-C 83 | // class, etc 84 | MEMBER_REF_EXPR = 102, 85 | 86 | // An expression that calls a function 87 | CALL_EXPR = 103, 88 | 89 | 90 | // An expression that represents a block literal 91 | BLOCK_EXPR = 105, 92 | 93 | // An integer literal 94 | INTEGER_LITERAL = 106, 95 | 96 | // A floating point number literal 97 | FLOATING_LITERAL = 107, 98 | 99 | // An imaginary number literal 100 | IMAGINARY_LITERAL = 108, 101 | 102 | // A string literal 103 | STRING_LITERAL = 109, 104 | 105 | // A character literal 106 | CHARACTER_LITERAL = 110, 107 | 108 | // A parenthesized expression, eg "1," 109 | // 110 | // This AST node is only formed if full location information is requested 111 | PAREN_EXPR = 111, 112 | 113 | // This represents the unary-expression's except sizeof and 114 | // alignof, 115 | UNARY_OPERATOR = 112, 116 | 117 | // [C99 6521] Array Subscripting 118 | ARRAY_SUBSCRIPT_EXPR = 113, 119 | 120 | // A builtin binary operation expression such as "x + y" or 121 | // "x <= y" 122 | BINARY_OPERATOR = 114, 123 | 124 | // Compound assignment such as "+=" 125 | COMPOUND_ASSIGNMENT_OPERATOR = 115, 126 | 127 | // The ?: ternary operator 128 | CONDITIONAL_OPERATOR = 116, 129 | 130 | // An explicit cast in C C99 654, or a C-style cast in C++ 131 | // C++ [exprcast],, which uses the syntax Type,expr 132 | // 133 | // For example: int,f 134 | CSTYLE_CAST_EXPR = 117, 135 | 136 | // [C99 6525] 137 | COMPOUND_LITERAL_EXPR = 118, 138 | 139 | // Describes an C or C++ initializer list 140 | INIT_LIST_EXPR = 119, 141 | 142 | // The GNU address of label extension, representing &&label 143 | ADDR_LABEL_EXPR = 120, 144 | 145 | 146 | 147 | // A statement whose specific kind is not exposed via this interface 148 | // 149 | // Unexposed statements have the same operations as any other kind of statement; 150 | // one can extract their location information, spelling, children, etc However, 151 | // the specific kind of the statement is not reported 152 | UNEXPOSED_STMT = 200, 153 | 154 | // A labelled statement in a function 155 | LABEL_STMT = 201, 156 | 157 | // A compound statement 158 | COMPOUND_STMT = 202, 159 | 160 | // A case statement 161 | CASE_STMT = 203, 162 | 163 | // A default statement 164 | DEFAULT_STMT = 204, 165 | 166 | // An if statement 167 | IF_STMT = 205, 168 | 169 | // A switch statement 170 | SWITCH_STMT = 206, 171 | 172 | // A while statement 173 | WHILE_STMT = 207, 174 | 175 | // A do statement 176 | DO_STMT = 208, 177 | 178 | // A for statement 179 | FOR_STMT = 209, 180 | 181 | // A goto statement 182 | GOTO_STMT = 210, 183 | 184 | // An indirect goto statement 185 | INDIRECT_GOTO_STMT = 211, 186 | 187 | // A continue statement 188 | CONTINUE_STMT = 212, 189 | 190 | // A break statement 191 | BREAK_STMT = 213, 192 | 193 | // A return statement 194 | RETURN_STMT = 214, 195 | 196 | 197 | // The null statement 198 | NULL_STMT = 230, 199 | 200 | // Adaptor class for mixing declarations with statements and expressions 201 | DECL_STMT = 231, 202 | 203 | 204 | ////// 205 | // Other Kinds 206 | 207 | // Cursor that represents the translation unit itself 208 | // 209 | // The translation unit cursor exists primarily to act as the root cursor for 210 | // traversing the contents of a translation unit 211 | TRANSLATION_UNIT = 300, 212 | }; 213 | 214 | typedef enum _node_type node_type; 215 | extern int type; 216 | 217 | //全局变量~ 218 | extern int yylex(); 219 | extern char* yytext; 220 | extern int yyleng; 221 | extern int tok; 222 | 223 | //结点声明 224 | typedef struct _ast ast; 225 | typedef struct _ast *past; 226 | struct _ast{ 227 | char* stype; 228 | int ivalue; 229 | float fvalue; 230 | char* svalue; 231 | node_type nodeType; 232 | char* snodeType; 233 | int if_const; 234 | past left; 235 | past right; 236 | past if_cond; 237 | past next; 238 | }; 239 | 240 | past newList(past list, past node); 241 | #define listHead(node) node->left 242 | #define listTail(node) node->right 243 | 244 | //返回ast结点函数 245 | past newAstNode(); 246 | //显示ast 247 | void showAst(char* sym, past node, int nest); 248 | void showParaDecl(past node); 249 | void showCompoundStmt(past node, int nest); 250 | void showCallExp(past node, int nest); 251 | void showTranstion(past node, int nest); 252 | 253 | char* get_id(char* yytext); 254 | char* get_stype(int type); 255 | char* get_conststype(int type); 256 | 257 | past newDeclStmt(past left, past right); 258 | past newCompUnit(past left, past right); 259 | past newDeclRefExp(char* name, past left, past right); 260 | past newFuncDecl(char* stype, int type,char* svalue, past left, past right); 261 | past newBinaryOper(char* soper, int oper, past left, past right); 262 | past newArraySubscriptsExp(past left, past right); 263 | past newCallExp(char* stype, int type, char* name, past left, past right); 264 | past newParaDecl(char* stype, char* name, past left, past right); 265 | past newCompoundStmt(past left, past right); 266 | past newIntVal(int ival); 267 | past newFloatVal(float fval); 268 | past newVarDecl(char* stype, int type, int if_cond, char* s, past left, past right); 269 | past newIfStmt(past if_cond, past left, past right); 270 | past newWhileStmt(past left, past right); 271 | past newContinueStmt(); 272 | past newBreakStmt(); 273 | past newReturnStmt(past left, past right); 274 | past newType(int oper); 275 | 276 | #endif -------------------------------------------------------------------------------- /lab4_中间代码生成/genthreeaddrees.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "ast.h" 5 | #include "genthreeaddress.h" 6 | #include "threeaddress.tab.h" 7 | #define arry_len 1000 8 | char* codearry[1000]; 9 | char sprintfBuffer[500]; 10 | int temVarNum = 0; 11 | int ad_num = 100; 12 | int count = 0; 13 | int if_record = 0; 14 | 15 | void addCodes(char* codes) { 16 | if(count < arry_len){ 17 | codearry[count] = (char *)malloc(sizeof(char) * 100); 18 | strcpy(codearry[count], codes); 19 | codearry[count][99] = '\0'; 20 | count++; 21 | } 22 | } 23 | 24 | int getTemVarNum() { 25 | temVarNum ++; 26 | return temVarNum; 27 | } 28 | 29 | void print_func(){ 30 | int i = 0; 31 | while(i < arry_len && codearry[i] != NULL){ 32 | printf("%s", codearry[i]); 33 | i++; 34 | } 35 | printf("%d: 中间代码结束", ad_num); 36 | } 37 | 38 | int get_sym(past node){ 39 | if(node == NULL){ 40 | return 0; 41 | } else if(node->nodeType == BINARY_OPERATOR && (node->ivalue == Y_ADD || node->ivalue == Y_SUB || node->ivalue == Y_MUL || node->ivalue == Y_DIV || node->ivalue == Y_MODULO)){ 42 | return 1; 43 | } else if(node->nodeType == BINARY_OPERATOR && (node->ivalue == Y_NOT || node->ivalue == Y_AND || node->ivalue == Y_OR || node->ivalue == Y_EQ || node->ivalue == Y_NOTEQ || node->ivalue == Y_LESS || node->ivalue == Y_LESSEQ || node->ivalue == Y_GREAT || node->ivalue == Y_GREATEQ)){ 44 | return 2; 45 | } else if(node->nodeType == BINARY_OPERATOR && node->ivalue == Y_ASSIGN){ 46 | return 3; 47 | } else if(node->nodeType == IF_STMT){ 48 | return 4; 49 | } else { 50 | return 5; 51 | } 52 | } 53 | 54 | int genPrimaryExpr(past node, char* result){ //基本表达式 55 | if(node->nodeType == INTEGER_LITERAL){ 56 | if(result != NULL){ 57 | sprintf(result, "%d", node->ivalue); 58 | } 59 | } else if(node->nodeType == FLOATING_LITERAL){ 60 | if(result != NULL){ 61 | sprintf(result, "%f", node->fvalue); 62 | } 63 | } else if(node->nodeType == BINARY_OPERATOR){ 64 | //表达式的中间结果用临时变量保存 65 | //其结果为当前的 temVarNum 66 | if_record = 0; 67 | int tep = get_sym(node); 68 | if(tep == 2){ 69 | genLogicExpr(node, NULL); 70 | } else { 71 | genArithmeticExpr(node, NULL); 72 | } 73 | if(result != NULL){ 74 | sprintf(result, "t%d", temVarNum); 75 | } 76 | if_record = 1; 77 | } else if(node->nodeType == COMPOUND_STMT){ 78 | //复合语句处理 79 | if(node->left == NULL && node->right != NULL){ 80 | node = node->right; 81 | } 82 | int tep = get_sym(node->left); 83 | if(tep == 1){ 84 | genArithmeticExpr(node->left, NULL); 85 | } else if(tep == 0){ 86 | return 1; 87 | } else if(tep == 2){ 88 | genLogicExpr(node->left, NULL); 89 | } else if(tep == 3){ 90 | genAssignStmt(node->left, NULL); 91 | } else if(tep == 4){ 92 | genIfStmt(node->left, NULL); 93 | } else{ 94 | genWhileStmt(node->left, NULL); 95 | } 96 | if(node->right != NULL){ 97 | genPrimaryExpr(node->right, NULL); 98 | } 99 | return 1; 100 | } else if(node->nodeType == DECL_REF_EXPR){ 101 | if(result != NULL){ 102 | sprintf(result, "%s", node->svalue); 103 | } 104 | } else { 105 | printf("ERROR!"); 106 | return -1; 107 | } 108 | return 1; 109 | } 110 | 111 | int genArithmeticExpr(past node, char* result){ //算术表达式 112 | if(node == NULL){ 113 | return -1; 114 | } 115 | 116 | int ltype = -1; 117 | int rtype = -1; 118 | 119 | if(node->nodeType == BINARY_OPERATOR){ 120 | char loperand[100]; 121 | char roperand[100]; 122 | char oper[5]; 123 | 124 | //一元表达式左操作符为空 125 | if( node->left != NULL){ 126 | ltype = genPrimaryExpr(node->left, loperand); 127 | } 128 | rtype = genPrimaryExpr(node->right, roperand); 129 | if(node->left == NULL) { 130 | //处理一元表达式 131 | ltype = rtype; 132 | sprintf(loperand, "0"); 133 | } 134 | 135 | if( ltype == rtype && ltype != -1) { 136 | switch(node->ivalue) { 137 | case Y_ADD: sprintf(oper, "+"); 138 | break; 139 | case Y_SUB: sprintf(oper, "-"); 140 | break; 141 | case Y_MUL: sprintf(oper, "*"); 142 | break; 143 | case Y_DIV: sprintf(oper, "/"); 144 | break; 145 | case Y_MODULO: sprintf(oper, "%"); 146 | break; 147 | } 148 | 149 | sprintf(sprintfBuffer, "%d: t%d = %s %s %s\n", ad_num, getTemVarNum(), loperand, oper, roperand); 150 | ad_num++; 151 | addCodes(sprintfBuffer); 152 | result = sprintfBuffer; 153 | return 1; 154 | } 155 | 156 | } 157 | return -1; 158 | } 159 | 160 | int genLogicExpr(past node, char* result){ //逻辑表达式 161 | if(node == NULL){ 162 | return -1; 163 | } 164 | 165 | int ltype = -1; 166 | int rtype = -1; 167 | 168 | if(node->nodeType == BINARY_OPERATOR){ 169 | char loperand[100]; 170 | char roperand[100]; 171 | char oper[5]; 172 | //一元表达式左操作符为空 173 | if( node->left != NULL){ 174 | ltype = genPrimaryExpr(node->left, loperand); 175 | } 176 | rtype = genPrimaryExpr(node->right, roperand); 177 | if(node->left == NULL) { 178 | //处理一元表达式 179 | ltype = rtype; 180 | sprintf(loperand, "0"); 181 | } 182 | if( ltype == rtype && ltype != -1) { 183 | switch(node->ivalue) { 184 | case Y_NOT: sprintf(oper, "!"); 185 | break; 186 | case Y_AND: sprintf(oper, "&&"); 187 | break; 188 | case Y_OR: sprintf(oper, "||"); 189 | break; 190 | case Y_EQ: sprintf(oper, "=="); 191 | break; 192 | case Y_NOTEQ: sprintf(oper, "!="); 193 | break; 194 | case Y_LESS: sprintf(oper, "<"); 195 | break; 196 | case Y_LESSEQ: sprintf(oper, "<="); 197 | break; 198 | case Y_GREAT: sprintf(oper, ">"); 199 | break; 200 | case Y_GREATEQ: sprintf(oper, ">="); 201 | break; 202 | } 203 | if(if_record == 1){ 204 | sprintf(sprintfBuffer, "%s %s %s", loperand, oper, roperand); 205 | strncpy(result, sprintfBuffer, 100); 206 | result[99] = '\0'; 207 | } else { 208 | sprintf(sprintfBuffer, "%d: t%d = %s %s %s\n", ad_num, getTemVarNum(), loperand, oper, roperand); 209 | ad_num++; 210 | addCodes(sprintfBuffer); 211 | } 212 | return 1; 213 | } 214 | } 215 | return -1; 216 | } 217 | 218 | int genLVal(past node, char* result){ //赋值表达式的左值 219 | if(node->nodeType == DECL_REF_EXPR){ 220 | if(result != NULL){ 221 | sprintf(result, "%s", node->svalue); 222 | } 223 | } else { 224 | printf("ERROR: 发现不支持的运算类型"); 225 | return -1; 226 | } 227 | return 1; 228 | } 229 | 230 | int genAssignStmt(past node, char* result){ //赋值表达式 231 | if(node == NULL){ 232 | return -1; 233 | } 234 | 235 | int ltype = -1; 236 | int rtype = -1; 237 | 238 | if(node->nodeType == BINARY_OPERATOR){ 239 | char loperand[100]; 240 | char roperand[100]; 241 | ltype = genLVal(node->left, loperand); 242 | rtype = genPrimaryExpr(node->right, roperand); 243 | if(rtype == 1 && ltype == 1) { 244 | sprintf(sprintfBuffer, "%d: %s = %s\n", ad_num, loperand, roperand); 245 | ad_num++; 246 | addCodes(sprintfBuffer); 247 | result = sprintfBuffer; 248 | return 1; 249 | } 250 | } 251 | return -1; 252 | } 253 | 254 | int genIfStmt(past node, char* result){ 255 | if(node == NULL){ 256 | return -1; 257 | } 258 | 259 | int Texpr = -1; 260 | int Fexpr = -1; 261 | int ifexpr = -1; 262 | int Trecord = 0; 263 | int Frecord = 0; 264 | if(node->nodeType == IF_STMT){ 265 | char sTexpr[100]; 266 | char sFexpr[100]; 267 | char sifexpr[100]; 268 | if_record = 1; 269 | ifexpr = genLogicExpr(node->if_cond, sifexpr); 270 | if_record = 0; 271 | if(ifexpr == 1){ 272 | sprintf(sprintfBuffer, "%d: if %s goto %d\n", ad_num, sifexpr, ad_num + 2); 273 | ad_num++; 274 | addCodes(sprintfBuffer); 275 | sprintf(sprintfBuffer, "%d: goto", ad_num); 276 | ad_num++; 277 | Trecord = count; 278 | addCodes(sprintfBuffer); 279 | } 280 | Texpr = genPrimaryExpr(node->left, sTexpr); 281 | if(Texpr == 1){ 282 | if(node->right != NULL){ 283 | sprintf(sprintfBuffer, " %d\n", ad_num + 1); 284 | } else { 285 | sprintf(sprintfBuffer, " %d\n", ad_num); 286 | } 287 | strcat(codearry[Trecord], sprintfBuffer); 288 | } 289 | if(node->right != NULL){ 290 | sprintf(sprintfBuffer, "%d: goto", ad_num, ad_num + 1); 291 | ad_num++; 292 | Frecord = count; 293 | addCodes(sprintfBuffer); 294 | Fexpr = genPrimaryExpr(node->right, sFexpr); 295 | sprintf(sprintfBuffer, " %d\n", ad_num); 296 | strcat(codearry[Frecord], sprintfBuffer); 297 | } 298 | 299 | return 1; 300 | } 301 | return -1; 302 | } 303 | 304 | int genWhileStmt(past node, char* result){ 305 | if(node == NULL){ 306 | return -1; 307 | } 308 | 309 | int lexpr = -1; 310 | int rexpr = -1; 311 | int record; 312 | int loop = ad_num; 313 | if(node->nodeType == WHILE_STMT){ 314 | char slexpr[100]; 315 | char srexpr[100]; 316 | if_record = 1; 317 | lexpr = genLogicExpr(node->left, slexpr); 318 | if_record = 0; 319 | if(lexpr == 1){ 320 | sprintf(sprintfBuffer, "%d: if %s goto %d\n", ad_num, slexpr, ad_num + 2); 321 | ad_num++; 322 | addCodes(sprintfBuffer); 323 | sprintf(sprintfBuffer, "%d: goto", ad_num); 324 | ad_num++; 325 | record = count; 326 | addCodes(sprintfBuffer); 327 | } 328 | rexpr = genPrimaryExpr(node->right, srexpr); 329 | if(rexpr == 1){ 330 | sprintf(sprintfBuffer, " %d\n", ad_num); 331 | strcat(codearry[record], sprintfBuffer); 332 | } 333 | sprintf(sprintfBuffer, "%d: goto %d\n", ad_num, loop); 334 | ad_num++; 335 | addCodes(sprintfBuffer); 336 | return 1; 337 | } 338 | return -1; 339 | } 340 | -------------------------------------------------------------------------------- /lab4_中间代码生成/genthreeaddress.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GENTHREEADDRESS_H 3 | #define GENTHREEADDRESS_H 4 | 5 | #include "ast.h" 6 | 7 | 8 | #define true 1 9 | #define false 0 10 | int get_sym(past node); 11 | void print_func(); 12 | int getTemVarNum(); 13 | void addCodes(char* codes); 14 | int genPrimaryExpr(past node, char* result); 15 | int genArithmeticExpr(past node, char* result); 16 | int genLogicExpr(past node, char* result); 17 | int genIfStmt(past node, char* result); 18 | int genWhileStmt(past node, char* result); 19 | int genAssignStmt(past node, char* result); 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /lab4_中间代码生成/lex.yy.c: -------------------------------------------------------------------------------- 1 | /* A lexical scanner generated by flex */ 2 | 3 | /* Scanner skeleton version: 4 | * $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.91 96/09/10 16:58:48 vern Exp $ 5 | */ 6 | 7 | #define FLEX_SCANNER 8 | #define YY_FLEX_MAJOR_VERSION 2 9 | #define YY_FLEX_MINOR_VERSION 5 10 | 11 | #include 12 | 13 | 14 | /* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ 15 | #ifdef c_plusplus 16 | #ifndef __cplusplus 17 | #define __cplusplus 18 | #endif 19 | #endif 20 | 21 | 22 | #ifdef __cplusplus 23 | 24 | #include 25 | #include 26 | 27 | /* Use prototypes in function declarations. */ 28 | #define YY_USE_PROTOS 29 | 30 | /* The "const" storage-class-modifier is valid. */ 31 | #define YY_USE_CONST 32 | 33 | #else /* ! __cplusplus */ 34 | 35 | #if __STDC__ 36 | 37 | #define YY_USE_PROTOS 38 | #define YY_USE_CONST 39 | 40 | #endif /* __STDC__ */ 41 | #endif /* ! __cplusplus */ 42 | 43 | #ifdef __TURBOC__ 44 | #pragma warn -rch 45 | #pragma warn -use 46 | #include 47 | #include 48 | #define YY_USE_CONST 49 | #define YY_USE_PROTOS 50 | #endif 51 | 52 | #ifdef YY_USE_CONST 53 | #define yyconst const 54 | #else 55 | #define yyconst 56 | #endif 57 | 58 | 59 | #ifdef YY_USE_PROTOS 60 | #define YY_PROTO(proto) proto 61 | #else 62 | #define YY_PROTO(proto) () 63 | #endif 64 | 65 | /* Returned upon end-of-file. */ 66 | #define YY_NULL 0 67 | 68 | /* Promotes a possibly negative, possibly signed char to an unsigned 69 | * integer for use as an array index. If the signed char is negative, 70 | * we want to instead treat it as an 8-bit unsigned char, hence the 71 | * double cast. 72 | */ 73 | #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) 74 | 75 | /* Enter a start condition. This macro really ought to take a parameter, 76 | * but we do it the disgusting crufty way forced on us by the ()-less 77 | * definition of BEGIN. 78 | */ 79 | #define BEGIN yy_start = 1 + 2 * 80 | 81 | /* Translate the current start state into a value that can be later handed 82 | * to BEGIN to return to the state. The YYSTATE alias is for lex 83 | * compatibility. 84 | */ 85 | #define YY_START ((yy_start - 1) / 2) 86 | #define YYSTATE YY_START 87 | 88 | /* Action number for EOF rule of a given start state. */ 89 | #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) 90 | 91 | /* Special action meaning "start processing a new file". */ 92 | #define YY_NEW_FILE yyrestart( yyin ) 93 | 94 | #define YY_END_OF_BUFFER_CHAR 0 95 | 96 | /* Size of default input buffer. */ 97 | #define YY_BUF_SIZE 16384 98 | 99 | typedef struct yy_buffer_state *YY_BUFFER_STATE; 100 | 101 | extern int yyleng; 102 | extern FILE *yyin, *yyout; 103 | 104 | #define EOB_ACT_CONTINUE_SCAN 0 105 | #define EOB_ACT_END_OF_FILE 1 106 | #define EOB_ACT_LAST_MATCH 2 107 | 108 | /* The funky do-while in the following #define is used to turn the definition 109 | * int a single C statement (which needs a semi-colon terminator). This 110 | * avoids problems with code like: 111 | * 112 | * if ( condition_holds ) 113 | * yyless( 5 ); 114 | * else 115 | * do_something_else(); 116 | * 117 | * Prior to using the do-while the compiler would get upset at the 118 | * "else" because it interpreted the "if" statement as being all 119 | * done when it reached the ';' after the yyless() call. 120 | */ 121 | 122 | /* Return all but the first 'n' matched characters back to the input stream. */ 123 | 124 | #define yyless(n) \ 125 | do \ 126 | { \ 127 | /* Undo effects of setting up yytext. */ \ 128 | *yy_cp = yy_hold_char; \ 129 | YY_RESTORE_YY_MORE_OFFSET \ 130 | yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ 131 | YY_DO_BEFORE_ACTION; /* set up yytext again */ \ 132 | } \ 133 | while ( 0 ) 134 | 135 | #define unput(c) yyunput( c, yytext_ptr ) 136 | 137 | /* The following is because we cannot portably get our hands on size_t 138 | * (without autoconf's help, which isn't available because we want 139 | * flex-generated scanners to compile on their own). 140 | */ 141 | typedef unsigned int yy_size_t; 142 | 143 | 144 | struct yy_buffer_state 145 | { 146 | FILE *yy_input_file; 147 | 148 | char *yy_ch_buf; /* input buffer */ 149 | char *yy_buf_pos; /* current position in input buffer */ 150 | 151 | /* Size of input buffer in bytes, not including room for EOB 152 | * characters. 153 | */ 154 | yy_size_t yy_buf_size; 155 | 156 | /* Number of characters read into yy_ch_buf, not including EOB 157 | * characters. 158 | */ 159 | int yy_n_chars; 160 | 161 | /* Whether we "own" the buffer - i.e., we know we created it, 162 | * and can realloc() it to grow it, and should free() it to 163 | * delete it. 164 | */ 165 | int yy_is_our_buffer; 166 | 167 | /* Whether this is an "interactive" input source; if so, and 168 | * if we're using stdio for input, then we want to use getc() 169 | * instead of fread(), to make sure we stop fetching input after 170 | * each newline. 171 | */ 172 | int yy_is_interactive; 173 | 174 | /* Whether we're considered to be at the beginning of a line. 175 | * If so, '^' rules will be active on the next match, otherwise 176 | * not. 177 | */ 178 | int yy_at_bol; 179 | 180 | /* Whether to try to fill the input buffer when we reach the 181 | * end of it. 182 | */ 183 | int yy_fill_buffer; 184 | 185 | int yy_buffer_status; 186 | #define YY_BUFFER_NEW 0 187 | #define YY_BUFFER_NORMAL 1 188 | /* When an EOF's been seen but there's still some text to process 189 | * then we mark the buffer as YY_EOF_PENDING, to indicate that we 190 | * shouldn't try reading from the input source any more. We might 191 | * still have a bunch of tokens to match, though, because of 192 | * possible backing-up. 193 | * 194 | * When we actually see the EOF, we change the status to "new" 195 | * (via yyrestart()), so that the user can continue scanning by 196 | * just pointing yyin at a new input file. 197 | */ 198 | #define YY_BUFFER_EOF_PENDING 2 199 | }; 200 | 201 | static YY_BUFFER_STATE yy_current_buffer = 0; 202 | 203 | /* We provide macros for accessing buffer states in case in the 204 | * future we want to put the buffer states in a more general 205 | * "scanner state". 206 | */ 207 | #define YY_CURRENT_BUFFER yy_current_buffer 208 | 209 | 210 | /* yy_hold_char holds the character lost when yytext is formed. */ 211 | static char yy_hold_char; 212 | 213 | static int yy_n_chars; /* number of characters read into yy_ch_buf */ 214 | 215 | 216 | int yyleng; 217 | 218 | /* Points to current character in buffer. */ 219 | static char *yy_c_buf_p = (char *) 0; 220 | static int yy_init = 1; /* whether we need to initialize */ 221 | static int yy_start = 0; /* start state number */ 222 | 223 | /* Flag which is used to allow yywrap()'s to do buffer switches 224 | * instead of setting up a fresh yyin. A bit of a hack ... 225 | */ 226 | static int yy_did_buffer_switch_on_eof; 227 | 228 | void yyrestart YY_PROTO(( FILE *input_file )); 229 | 230 | void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer )); 231 | void yy_load_buffer_state YY_PROTO(( void )); 232 | YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size )); 233 | void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b )); 234 | void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file )); 235 | void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b )); 236 | #define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer ) 237 | 238 | YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size )); 239 | YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str )); 240 | YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len )); 241 | 242 | static void *yy_flex_alloc YY_PROTO(( yy_size_t )); 243 | static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t )); 244 | static void yy_flex_free YY_PROTO(( void * )); 245 | 246 | #define yy_new_buffer yy_create_buffer 247 | 248 | #define yy_set_interactive(is_interactive) \ 249 | { \ 250 | if ( ! yy_current_buffer ) \ 251 | yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ 252 | yy_current_buffer->yy_is_interactive = is_interactive; \ 253 | } 254 | 255 | #define yy_set_bol(at_bol) \ 256 | { \ 257 | if ( ! yy_current_buffer ) \ 258 | yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ 259 | yy_current_buffer->yy_at_bol = at_bol; \ 260 | } 261 | 262 | #define YY_AT_BOL() (yy_current_buffer->yy_at_bol) 263 | 264 | typedef unsigned char YY_CHAR; 265 | FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; 266 | typedef int yy_state_type; 267 | extern char *yytext; 268 | #define yytext_ptr yytext 269 | 270 | static yy_state_type yy_get_previous_state YY_PROTO(( void )); 271 | static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state )); 272 | static int yy_get_next_buffer YY_PROTO(( void )); 273 | static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); 274 | 275 | /* Done after the current pattern has been matched and before the 276 | * corresponding action - sets up yytext. 277 | */ 278 | #define YY_DO_BEFORE_ACTION \ 279 | yytext_ptr = yy_bp; \ 280 | yyleng = (int) (yy_cp - yy_bp); \ 281 | yy_hold_char = *yy_cp; \ 282 | *yy_cp = '\0'; \ 283 | yy_c_buf_p = yy_cp; 284 | 285 | #define YY_NUM_RULES 40 286 | #define YY_END_OF_BUFFER 41 287 | static yyconst short int yy_accept[90] = 288 | { 0, 289 | 0, 0, 41, 40, 2, 3, 28, 21, 40, 32, 290 | 33, 19, 17, 38, 18, 20, 4, 39, 22, 31, 291 | 24, 16, 34, 35, 16, 16, 16, 16, 16, 16, 292 | 16, 16, 36, 40, 37, 2, 26, 29, 0, 0, 293 | 0, 4, 23, 27, 25, 16, 16, 16, 16, 16, 294 | 10, 16, 16, 16, 16, 30, 0, 0, 0, 1, 295 | 5, 16, 16, 16, 16, 6, 16, 16, 16, 1, 296 | 16, 16, 16, 11, 16, 16, 8, 16, 13, 9, 297 | 16, 7, 16, 12, 16, 15, 16, 14, 0 298 | } ; 299 | 300 | static yyconst int yy_ec[256] = 301 | { 0, 302 | 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 303 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 304 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 305 | 1, 2, 4, 1, 1, 1, 5, 6, 1, 7, 306 | 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 307 | 15, 15, 15, 15, 15, 15, 15, 1, 16, 17, 308 | 18, 19, 1, 1, 20, 20, 20, 20, 20, 20, 309 | 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 310 | 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 311 | 21, 1, 22, 1, 23, 1, 24, 25, 26, 27, 312 | 313 | 28, 29, 20, 30, 31, 20, 32, 33, 20, 34, 314 | 35, 20, 20, 36, 37, 38, 39, 40, 41, 20, 315 | 20, 20, 42, 43, 44, 1, 1, 1, 1, 1, 316 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 317 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 318 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 319 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 320 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 321 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 322 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 323 | 324 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 325 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 326 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 327 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 328 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 329 | 1, 1, 1, 1, 1 330 | } ; 331 | 332 | static yyconst int yy_meta[45] = 333 | { 0, 334 | 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 335 | 1, 1, 1, 1, 3, 1, 1, 1, 1, 3, 336 | 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 337 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 338 | 3, 1, 1, 1 339 | } ; 340 | 341 | static yyconst short int yy_base[93] = 342 | { 0, 343 | 0, 0, 109, 110, 106, 110, 89, 110, 100, 110, 344 | 110, 110, 110, 110, 110, 36, 33, 110, 87, 86, 345 | 85, 0, 110, 110, 66, 66, 67, 66, 18, 70, 346 | 62, 66, 110, 52, 110, 92, 110, 110, 84, 89, 347 | 76, 36, 110, 110, 110, 0, 62, 55, 51, 52, 348 | 0, 48, 47, 53, 52, 110, 73, 44, 78, 110, 349 | 65, 55, 17, 50, 53, 0, 37, 48, 41, 64, 350 | 40, 33, 39, 0, 31, 32, 0, 39, 0, 0, 351 | 32, 0, 31, 0, 21, 0, 29, 0, 110, 53, 352 | 58, 61 353 | 354 | } ; 355 | 356 | static yyconst short int yy_def[93] = 357 | { 0, 358 | 89, 1, 89, 89, 89, 89, 89, 89, 89, 89, 359 | 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 360 | 89, 90, 89, 89, 90, 90, 90, 90, 90, 90, 361 | 90, 90, 89, 89, 89, 89, 89, 89, 91, 92, 362 | 89, 89, 89, 89, 89, 90, 90, 90, 90, 90, 363 | 90, 90, 90, 90, 90, 89, 91, 91, 92, 89, 364 | 89, 90, 90, 90, 90, 90, 90, 90, 90, 91, 365 | 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 366 | 90, 90, 90, 90, 90, 90, 90, 90, 0, 89, 367 | 89, 89 368 | 369 | } ; 370 | 371 | static yyconst short int yy_nxt[155] = 372 | { 0, 373 | 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 374 | 14, 15, 4, 16, 17, 18, 19, 20, 21, 22, 375 | 23, 24, 22, 22, 25, 26, 22, 27, 28, 22, 376 | 29, 22, 22, 22, 22, 30, 22, 22, 22, 31, 377 | 32, 33, 34, 35, 39, 41, 51, 42, 41, 40, 378 | 42, 52, 58, 72, 73, 46, 88, 70, 57, 87, 379 | 57, 59, 59, 59, 86, 85, 84, 83, 82, 81, 380 | 80, 79, 58, 78, 77, 76, 75, 74, 71, 61, 381 | 60, 58, 69, 68, 67, 66, 65, 64, 63, 62, 382 | 61, 60, 58, 36, 56, 55, 54, 53, 50, 49, 383 | 384 | 48, 47, 45, 44, 43, 38, 37, 36, 89, 3, 385 | 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 386 | 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 387 | 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 388 | 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 389 | 89, 89, 89, 89 390 | } ; 391 | 392 | static yyconst short int yy_chk[155] = 393 | { 0, 394 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 395 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 396 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 397 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 398 | 1, 1, 1, 1, 16, 17, 29, 17, 42, 16, 399 | 42, 29, 58, 63, 63, 90, 87, 58, 91, 85, 400 | 91, 92, 92, 92, 83, 81, 78, 76, 75, 73, 401 | 72, 71, 70, 69, 68, 67, 65, 64, 62, 61, 402 | 59, 57, 55, 54, 53, 52, 50, 49, 48, 47, 403 | 41, 40, 39, 36, 34, 32, 31, 30, 28, 27, 404 | 405 | 26, 25, 21, 20, 19, 9, 7, 5, 3, 89, 406 | 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 407 | 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 408 | 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 409 | 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 410 | 89, 89, 89, 89 411 | } ; 412 | 413 | static yy_state_type yy_last_accepting_state; 414 | static char *yy_last_accepting_cpos; 415 | 416 | /* The intent behind this definition is that it'll catch 417 | * any uses of REJECT which flex missed. 418 | */ 419 | #define REJECT reject_used_but_not_detected 420 | #define yymore() yymore_used_but_not_detected 421 | #define YY_MORE_ADJ 0 422 | #define YY_RESTORE_YY_MORE_OFFSET 423 | char *yytext; 424 | #line 1 "threeaddress.l" 425 | #define INITIAL 0 426 | #line 2 "threeaddress.l" 427 | #include 428 | #include "ast.h" 429 | #include "threeaddress.tab.h" 430 | int type; 431 | 432 | /* Regular definition */ 433 | #line 434 "lex.yy.c" 434 | 435 | /* Macros after this point can all be overridden by user definitions in 436 | * section 1. 437 | */ 438 | 439 | #ifndef YY_SKIP_YYWRAP 440 | #ifdef __cplusplus 441 | extern "C" int yywrap YY_PROTO(( void )); 442 | #else 443 | extern int yywrap YY_PROTO(( void )); 444 | #endif 445 | #endif 446 | 447 | #ifndef YY_NO_UNPUT 448 | static void yyunput YY_PROTO(( int c, char *buf_ptr )); 449 | #endif 450 | 451 | #ifndef yytext_ptr 452 | static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int )); 453 | #endif 454 | 455 | #ifdef YY_NEED_STRLEN 456 | static int yy_flex_strlen YY_PROTO(( yyconst char * )); 457 | #endif 458 | 459 | #ifndef YY_NO_INPUT 460 | #ifdef __cplusplus 461 | static int yyinput YY_PROTO(( void )); 462 | #else 463 | static int input YY_PROTO(( void )); 464 | #endif 465 | #endif 466 | 467 | #if YY_STACK_USED 468 | static int yy_start_stack_ptr = 0; 469 | static int yy_start_stack_depth = 0; 470 | static int *yy_start_stack = 0; 471 | #ifndef YY_NO_PUSH_STATE 472 | static void yy_push_state YY_PROTO(( int new_state )); 473 | #endif 474 | #ifndef YY_NO_POP_STATE 475 | static void yy_pop_state YY_PROTO(( void )); 476 | #endif 477 | #ifndef YY_NO_TOP_STATE 478 | static int yy_top_state YY_PROTO(( void )); 479 | #endif 480 | 481 | #else 482 | #define YY_NO_PUSH_STATE 1 483 | #define YY_NO_POP_STATE 1 484 | #define YY_NO_TOP_STATE 1 485 | #endif 486 | 487 | #ifdef YY_MALLOC_DECL 488 | YY_MALLOC_DECL 489 | #else 490 | #if __STDC__ 491 | #ifndef __cplusplus 492 | #include 493 | #endif 494 | #else 495 | /* Just try to get by without declaring the routines. This will fail 496 | * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int) 497 | * or sizeof(void*) != sizeof(int). 498 | */ 499 | #endif 500 | #endif 501 | 502 | /* Amount of stuff to slurp up with each read. */ 503 | #ifndef YY_READ_BUF_SIZE 504 | #define YY_READ_BUF_SIZE 8192 505 | #endif 506 | 507 | /* Copy whatever the last rule matched to the standard output. */ 508 | 509 | #ifndef ECHO 510 | /* This used to be an fputs(), but since the string might contain NUL's, 511 | * we now use fwrite(). 512 | */ 513 | #define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) 514 | #endif 515 | 516 | /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, 517 | * is returned in "result". 518 | */ 519 | #ifndef YY_INPUT 520 | #define YY_INPUT(buf,result,max_size) \ 521 | if ( yy_current_buffer->yy_is_interactive ) \ 522 | { \ 523 | int c = '*', n; \ 524 | for ( n = 0; n < max_size && \ 525 | (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ 526 | buf[n] = (char) c; \ 527 | if ( c == '\n' ) \ 528 | buf[n++] = (char) c; \ 529 | if ( c == EOF && ferror( yyin ) ) \ 530 | YY_FATAL_ERROR( "input in flex scanner failed" ); \ 531 | result = n; \ 532 | } \ 533 | else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \ 534 | && ferror( yyin ) ) \ 535 | YY_FATAL_ERROR( "input in flex scanner failed" ); 536 | #endif 537 | 538 | /* No semi-colon after return; correct usage is to write "yyterminate();" - 539 | * we don't want an extra ';' after the "return" because that will cause 540 | * some compilers to complain about unreachable statements. 541 | */ 542 | #ifndef yyterminate 543 | #define yyterminate() return YY_NULL 544 | #endif 545 | 546 | /* Number of entries by which start-condition stack grows. */ 547 | #ifndef YY_START_STACK_INCR 548 | #define YY_START_STACK_INCR 25 549 | #endif 550 | 551 | /* Report a fatal error. */ 552 | #ifndef YY_FATAL_ERROR 553 | #define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) 554 | #endif 555 | 556 | /* Default declaration of generated scanner - a define so the user can 557 | * easily add parameters. 558 | */ 559 | #ifndef YY_DECL 560 | #define YY_DECL int yylex YY_PROTO(( void )) 561 | #endif 562 | 563 | /* Code executed at the beginning of each rule, after yytext and yyleng 564 | * have been set up. 565 | */ 566 | #ifndef YY_USER_ACTION 567 | #define YY_USER_ACTION 568 | #endif 569 | 570 | /* Code executed at the end of each rule. */ 571 | #ifndef YY_BREAK 572 | #define YY_BREAK break; 573 | #endif 574 | 575 | #define YY_RULE_SETUP \ 576 | YY_USER_ACTION 577 | 578 | YY_DECL 579 | { 580 | register yy_state_type yy_current_state; 581 | register char *yy_cp, *yy_bp; 582 | register int yy_act; 583 | 584 | #line 15 "threeaddress.l" 585 | 586 | 587 | #line 588 "lex.yy.c" 588 | 589 | if ( yy_init ) 590 | { 591 | yy_init = 0; 592 | 593 | #ifdef YY_USER_INIT 594 | YY_USER_INIT; 595 | #endif 596 | 597 | if ( ! yy_start ) 598 | yy_start = 1; /* first start state */ 599 | 600 | if ( ! yyin ) 601 | yyin = stdin; 602 | 603 | if ( ! yyout ) 604 | yyout = stdout; 605 | 606 | if ( ! yy_current_buffer ) 607 | yy_current_buffer = 608 | yy_create_buffer( yyin, YY_BUF_SIZE ); 609 | 610 | yy_load_buffer_state(); 611 | } 612 | 613 | while ( 1 ) /* loops until end-of-file is reached */ 614 | { 615 | yy_cp = yy_c_buf_p; 616 | 617 | /* Support of yytext. */ 618 | *yy_cp = yy_hold_char; 619 | 620 | /* yy_bp points to the position in yy_ch_buf of the start of 621 | * the current run. 622 | */ 623 | yy_bp = yy_cp; 624 | 625 | yy_current_state = yy_start; 626 | yy_match: 627 | do 628 | { 629 | register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; 630 | if ( yy_accept[yy_current_state] ) 631 | { 632 | yy_last_accepting_state = yy_current_state; 633 | yy_last_accepting_cpos = yy_cp; 634 | } 635 | while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) 636 | { 637 | yy_current_state = (int) yy_def[yy_current_state]; 638 | if ( yy_current_state >= 90 ) 639 | yy_c = yy_meta[(unsigned int) yy_c]; 640 | } 641 | yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; 642 | ++yy_cp; 643 | } 644 | while ( yy_base[yy_current_state] != 110 ); 645 | 646 | yy_find_action: 647 | yy_act = yy_accept[yy_current_state]; 648 | if ( yy_act == 0 ) 649 | { /* have to back up */ 650 | yy_cp = yy_last_accepting_cpos; 651 | yy_current_state = yy_last_accepting_state; 652 | yy_act = yy_accept[yy_current_state]; 653 | } 654 | 655 | YY_DO_BEFORE_ACTION; 656 | 657 | 658 | do_action: /* This label is used only to access EOF actions. */ 659 | 660 | 661 | switch ( yy_act ) 662 | { /* beginning of action switch */ 663 | case 0: /* must back up */ 664 | /* undo the effects of YY_DO_BEFORE_ACTION */ 665 | *yy_cp = yy_hold_char; 666 | yy_cp = yy_last_accepting_cpos; 667 | yy_current_state = yy_last_accepting_state; 668 | goto yy_find_action; 669 | 670 | case 1: 671 | YY_RULE_SETUP 672 | #line 17 "threeaddress.l" 673 | {/* noaction */} 674 | YY_BREAK 675 | case 2: 676 | YY_RULE_SETUP 677 | #line 18 "threeaddress.l" 678 | {/* noaction */} 679 | YY_BREAK 680 | case 3: 681 | YY_RULE_SETUP 682 | #line 19 "threeaddress.l" 683 | {return *yytext;} 684 | YY_BREAK 685 | case 4: 686 | YY_RULE_SETUP 687 | #line 20 "threeaddress.l" 688 | {yylval.int_value = atoi(yytext); return num_INT;} 689 | YY_BREAK 690 | case 5: 691 | YY_RULE_SETUP 692 | #line 21 "threeaddress.l" 693 | {yylval.float_value = (float)atof(yytext); return num_FLOAT;} 694 | YY_BREAK 695 | case 6: 696 | YY_RULE_SETUP 697 | #line 22 "threeaddress.l" 698 | {type = Y_INT;return Y_INT;} 699 | YY_BREAK 700 | case 7: 701 | YY_RULE_SETUP 702 | #line 23 "threeaddress.l" 703 | {type = Y_FLOAT;return Y_FLOAT;} 704 | YY_BREAK 705 | case 8: 706 | YY_RULE_SETUP 707 | #line 24 "threeaddress.l" 708 | {type = Y_VOID;return Y_VOID;} 709 | YY_BREAK 710 | case 9: 711 | YY_RULE_SETUP 712 | #line 25 "threeaddress.l" 713 | {return Y_CONST;} 714 | YY_BREAK 715 | case 10: 716 | YY_RULE_SETUP 717 | #line 26 "threeaddress.l" 718 | {return Y_IF;} 719 | YY_BREAK 720 | case 11: 721 | YY_RULE_SETUP 722 | #line 27 "threeaddress.l" 723 | {return Y_ELSE;} 724 | YY_BREAK 725 | case 12: 726 | YY_RULE_SETUP 727 | #line 28 "threeaddress.l" 728 | {return Y_WHILE;} 729 | YY_BREAK 730 | case 13: 731 | YY_RULE_SETUP 732 | #line 29 "threeaddress.l" 733 | {return Y_BREAK;} 734 | YY_BREAK 735 | case 14: 736 | YY_RULE_SETUP 737 | #line 30 "threeaddress.l" 738 | {return Y_CONTINUE;} 739 | YY_BREAK 740 | case 15: 741 | YY_RULE_SETUP 742 | #line 31 "threeaddress.l" 743 | {return Y_RETURN;} 744 | YY_BREAK 745 | case 16: 746 | YY_RULE_SETUP 747 | #line 32 "threeaddress.l" 748 | {yylval.id_name = malloc(sizeof(char) * (yyleng + 1)); memcpy(yylval.id_name, yytext, yyleng); yylval.id_name[yyleng] = '\0'; return Y_ID;} 749 | YY_BREAK 750 | case 17: 751 | YY_RULE_SETUP 752 | #line 33 "threeaddress.l" 753 | {return Y_ADD;} 754 | YY_BREAK 755 | case 18: 756 | YY_RULE_SETUP 757 | #line 34 "threeaddress.l" 758 | {return Y_SUB;} 759 | YY_BREAK 760 | case 19: 761 | YY_RULE_SETUP 762 | #line 35 "threeaddress.l" 763 | {return Y_MUL;} 764 | YY_BREAK 765 | case 20: 766 | YY_RULE_SETUP 767 | #line 36 "threeaddress.l" 768 | {return Y_DIV;} 769 | YY_BREAK 770 | case 21: 771 | YY_RULE_SETUP 772 | #line 37 "threeaddress.l" 773 | {return Y_MODULO;} 774 | YY_BREAK 775 | case 22: 776 | YY_RULE_SETUP 777 | #line 38 "threeaddress.l" 778 | {return Y_LESS;} 779 | YY_BREAK 780 | case 23: 781 | YY_RULE_SETUP 782 | #line 39 "threeaddress.l" 783 | {return Y_LESSEQ;} 784 | YY_BREAK 785 | case 24: 786 | YY_RULE_SETUP 787 | #line 40 "threeaddress.l" 788 | {return Y_GREAT;} 789 | YY_BREAK 790 | case 25: 791 | YY_RULE_SETUP 792 | #line 41 "threeaddress.l" 793 | {return Y_GREATEQ;} 794 | YY_BREAK 795 | case 26: 796 | YY_RULE_SETUP 797 | #line 42 "threeaddress.l" 798 | {return Y_NOTEQ;} 799 | YY_BREAK 800 | case 27: 801 | YY_RULE_SETUP 802 | #line 43 "threeaddress.l" 803 | {return Y_EQ;} 804 | YY_BREAK 805 | case 28: 806 | YY_RULE_SETUP 807 | #line 44 "threeaddress.l" 808 | {return Y_NOT;} 809 | YY_BREAK 810 | case 29: 811 | YY_RULE_SETUP 812 | #line 45 "threeaddress.l" 813 | {return Y_AND;} 814 | YY_BREAK 815 | case 30: 816 | YY_RULE_SETUP 817 | #line 46 "threeaddress.l" 818 | {return Y_OR;} 819 | YY_BREAK 820 | case 31: 821 | YY_RULE_SETUP 822 | #line 47 "threeaddress.l" 823 | {return Y_ASSIGN;} 824 | YY_BREAK 825 | case 32: 826 | YY_RULE_SETUP 827 | #line 48 "threeaddress.l" 828 | {return Y_LPAR;} 829 | YY_BREAK 830 | case 33: 831 | YY_RULE_SETUP 832 | #line 49 "threeaddress.l" 833 | {return Y_RPAR;} 834 | YY_BREAK 835 | case 34: 836 | YY_RULE_SETUP 837 | #line 50 "threeaddress.l" 838 | {return Y_LSQUARE;} 839 | YY_BREAK 840 | case 35: 841 | YY_RULE_SETUP 842 | #line 51 "threeaddress.l" 843 | {return Y_RSQUARE;} 844 | YY_BREAK 845 | case 36: 846 | YY_RULE_SETUP 847 | #line 52 "threeaddress.l" 848 | {return Y_LBRACKET;} 849 | YY_BREAK 850 | case 37: 851 | YY_RULE_SETUP 852 | #line 53 "threeaddress.l" 853 | {return Y_RBRACKET;} 854 | YY_BREAK 855 | case 38: 856 | YY_RULE_SETUP 857 | #line 54 "threeaddress.l" 858 | {return Y_COMMA;} 859 | YY_BREAK 860 | case 39: 861 | YY_RULE_SETUP 862 | #line 55 "threeaddress.l" 863 | {return Y_SEMICOLON;} 864 | YY_BREAK 865 | case 40: 866 | YY_RULE_SETUP 867 | #line 58 "threeaddress.l" 868 | ECHO; 869 | YY_BREAK 870 | #line 871 "lex.yy.c" 871 | case YY_STATE_EOF(INITIAL): 872 | yyterminate(); 873 | 874 | case YY_END_OF_BUFFER: 875 | { 876 | /* Amount of text matched not including the EOB char. */ 877 | int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1; 878 | 879 | /* Undo the effects of YY_DO_BEFORE_ACTION. */ 880 | *yy_cp = yy_hold_char; 881 | YY_RESTORE_YY_MORE_OFFSET 882 | 883 | if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) 884 | { 885 | /* We're scanning a new file or input source. It's 886 | * possible that this happened because the user 887 | * just pointed yyin at a new source and called 888 | * yylex(). If so, then we have to assure 889 | * consistency between yy_current_buffer and our 890 | * globals. Here is the right place to do so, because 891 | * this is the first action (other than possibly a 892 | * back-up) that will match for the new input source. 893 | */ 894 | yy_n_chars = yy_current_buffer->yy_n_chars; 895 | yy_current_buffer->yy_input_file = yyin; 896 | yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; 897 | } 898 | 899 | /* Note that here we test for yy_c_buf_p "<=" to the position 900 | * of the first EOB in the buffer, since yy_c_buf_p will 901 | * already have been incremented past the NUL character 902 | * (since all states make transitions on EOB to the 903 | * end-of-buffer state). Contrast this with the test 904 | * in input(). 905 | */ 906 | if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) 907 | { /* This was really a NUL. */ 908 | yy_state_type yy_next_state; 909 | 910 | yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; 911 | 912 | yy_current_state = yy_get_previous_state(); 913 | 914 | /* Okay, we're now positioned to make the NUL 915 | * transition. We couldn't have 916 | * yy_get_previous_state() go ahead and do it 917 | * for us because it doesn't know how to deal 918 | * with the possibility of jamming (and we don't 919 | * want to build jamming into it because then it 920 | * will run more slowly). 921 | */ 922 | 923 | yy_next_state = yy_try_NUL_trans( yy_current_state ); 924 | 925 | yy_bp = yytext_ptr + YY_MORE_ADJ; 926 | 927 | if ( yy_next_state ) 928 | { 929 | /* Consume the NUL. */ 930 | yy_cp = ++yy_c_buf_p; 931 | yy_current_state = yy_next_state; 932 | goto yy_match; 933 | } 934 | 935 | else 936 | { 937 | yy_cp = yy_c_buf_p; 938 | goto yy_find_action; 939 | } 940 | } 941 | 942 | else switch ( yy_get_next_buffer() ) 943 | { 944 | case EOB_ACT_END_OF_FILE: 945 | { 946 | yy_did_buffer_switch_on_eof = 0; 947 | 948 | if ( yywrap() ) 949 | { 950 | /* Note: because we've taken care in 951 | * yy_get_next_buffer() to have set up 952 | * yytext, we can now set up 953 | * yy_c_buf_p so that if some total 954 | * hoser (like flex itself) wants to 955 | * call the scanner after we return the 956 | * YY_NULL, it'll still work - another 957 | * YY_NULL will get returned. 958 | */ 959 | yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; 960 | 961 | yy_act = YY_STATE_EOF(YY_START); 962 | goto do_action; 963 | } 964 | 965 | else 966 | { 967 | if ( ! yy_did_buffer_switch_on_eof ) 968 | YY_NEW_FILE; 969 | } 970 | break; 971 | } 972 | 973 | case EOB_ACT_CONTINUE_SCAN: 974 | yy_c_buf_p = 975 | yytext_ptr + yy_amount_of_matched_text; 976 | 977 | yy_current_state = yy_get_previous_state(); 978 | 979 | yy_cp = yy_c_buf_p; 980 | yy_bp = yytext_ptr + YY_MORE_ADJ; 981 | goto yy_match; 982 | 983 | case EOB_ACT_LAST_MATCH: 984 | yy_c_buf_p = 985 | &yy_current_buffer->yy_ch_buf[yy_n_chars]; 986 | 987 | yy_current_state = yy_get_previous_state(); 988 | 989 | yy_cp = yy_c_buf_p; 990 | yy_bp = yytext_ptr + YY_MORE_ADJ; 991 | goto yy_find_action; 992 | } 993 | break; 994 | } 995 | 996 | default: 997 | YY_FATAL_ERROR( 998 | "fatal flex scanner internal error--no action found" ); 999 | } /* end of action switch */ 1000 | } /* end of scanning one token */ 1001 | } /* end of yylex */ 1002 | 1003 | 1004 | /* yy_get_next_buffer - try to read in a new buffer 1005 | * 1006 | * Returns a code representing an action: 1007 | * EOB_ACT_LAST_MATCH - 1008 | * EOB_ACT_CONTINUE_SCAN - continue scanning from current position 1009 | * EOB_ACT_END_OF_FILE - end of file 1010 | */ 1011 | 1012 | static int yy_get_next_buffer() 1013 | { 1014 | register char *dest = yy_current_buffer->yy_ch_buf; 1015 | register char *source = yytext_ptr; 1016 | register int number_to_move, i; 1017 | int ret_val; 1018 | 1019 | if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) 1020 | YY_FATAL_ERROR( 1021 | "fatal flex scanner internal error--end of buffer missed" ); 1022 | 1023 | if ( yy_current_buffer->yy_fill_buffer == 0 ) 1024 | { /* Don't try to fill the buffer, so this is an EOF. */ 1025 | if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) 1026 | { 1027 | /* We matched a single character, the EOB, so 1028 | * treat this as a final EOF. 1029 | */ 1030 | return EOB_ACT_END_OF_FILE; 1031 | } 1032 | 1033 | else 1034 | { 1035 | /* We matched some text prior to the EOB, first 1036 | * process it. 1037 | */ 1038 | return EOB_ACT_LAST_MATCH; 1039 | } 1040 | } 1041 | 1042 | /* Try to read more data. */ 1043 | 1044 | /* First move last chars to start of buffer. */ 1045 | number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1; 1046 | 1047 | for ( i = 0; i < number_to_move; ++i ) 1048 | *(dest++) = *(source++); 1049 | 1050 | if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) 1051 | /* don't do the read, it's not guaranteed to return an EOF, 1052 | * just force an EOF 1053 | */ 1054 | yy_current_buffer->yy_n_chars = yy_n_chars = 0; 1055 | 1056 | else 1057 | { 1058 | int num_to_read = 1059 | yy_current_buffer->yy_buf_size - number_to_move - 1; 1060 | 1061 | while ( num_to_read <= 0 ) 1062 | { /* Not enough room in the buffer - grow it. */ 1063 | #ifdef YY_USES_REJECT 1064 | YY_FATAL_ERROR( 1065 | "input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); 1066 | #else 1067 | 1068 | /* just a shorter name for the current buffer */ 1069 | YY_BUFFER_STATE b = yy_current_buffer; 1070 | 1071 | int yy_c_buf_p_offset = 1072 | (int) (yy_c_buf_p - b->yy_ch_buf); 1073 | 1074 | if ( b->yy_is_our_buffer ) 1075 | { 1076 | int new_size = b->yy_buf_size * 2; 1077 | 1078 | if ( new_size <= 0 ) 1079 | b->yy_buf_size += b->yy_buf_size / 8; 1080 | else 1081 | b->yy_buf_size *= 2; 1082 | 1083 | b->yy_ch_buf = (char *) 1084 | /* Include room in for 2 EOB chars. */ 1085 | yy_flex_realloc( (void *) b->yy_ch_buf, 1086 | b->yy_buf_size + 2 ); 1087 | } 1088 | else 1089 | /* Can't grow it, we don't own it. */ 1090 | b->yy_ch_buf = 0; 1091 | 1092 | if ( ! b->yy_ch_buf ) 1093 | YY_FATAL_ERROR( 1094 | "fatal error - scanner input buffer overflow" ); 1095 | 1096 | yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; 1097 | 1098 | num_to_read = yy_current_buffer->yy_buf_size - 1099 | number_to_move - 1; 1100 | #endif 1101 | } 1102 | 1103 | if ( num_to_read > YY_READ_BUF_SIZE ) 1104 | num_to_read = YY_READ_BUF_SIZE; 1105 | 1106 | /* Read in more data. */ 1107 | YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), 1108 | yy_n_chars, num_to_read ); 1109 | 1110 | yy_current_buffer->yy_n_chars = yy_n_chars; 1111 | } 1112 | 1113 | if ( yy_n_chars == 0 ) 1114 | { 1115 | if ( number_to_move == YY_MORE_ADJ ) 1116 | { 1117 | ret_val = EOB_ACT_END_OF_FILE; 1118 | yyrestart( yyin ); 1119 | } 1120 | 1121 | else 1122 | { 1123 | ret_val = EOB_ACT_LAST_MATCH; 1124 | yy_current_buffer->yy_buffer_status = 1125 | YY_BUFFER_EOF_PENDING; 1126 | } 1127 | } 1128 | 1129 | else 1130 | ret_val = EOB_ACT_CONTINUE_SCAN; 1131 | 1132 | yy_n_chars += number_to_move; 1133 | yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; 1134 | yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; 1135 | 1136 | yytext_ptr = &yy_current_buffer->yy_ch_buf[0]; 1137 | 1138 | return ret_val; 1139 | } 1140 | 1141 | 1142 | /* yy_get_previous_state - get the state just before the EOB char was reached */ 1143 | 1144 | static yy_state_type yy_get_previous_state() 1145 | { 1146 | register yy_state_type yy_current_state; 1147 | register char *yy_cp; 1148 | 1149 | yy_current_state = yy_start; 1150 | 1151 | for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) 1152 | { 1153 | register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); 1154 | if ( yy_accept[yy_current_state] ) 1155 | { 1156 | yy_last_accepting_state = yy_current_state; 1157 | yy_last_accepting_cpos = yy_cp; 1158 | } 1159 | while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) 1160 | { 1161 | yy_current_state = (int) yy_def[yy_current_state]; 1162 | if ( yy_current_state >= 90 ) 1163 | yy_c = yy_meta[(unsigned int) yy_c]; 1164 | } 1165 | yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; 1166 | } 1167 | 1168 | return yy_current_state; 1169 | } 1170 | 1171 | 1172 | /* yy_try_NUL_trans - try to make a transition on the NUL character 1173 | * 1174 | * synopsis 1175 | * next_state = yy_try_NUL_trans( current_state ); 1176 | */ 1177 | 1178 | #ifdef YY_USE_PROTOS 1179 | static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state ) 1180 | #else 1181 | static yy_state_type yy_try_NUL_trans( yy_current_state ) 1182 | yy_state_type yy_current_state; 1183 | #endif 1184 | { 1185 | register int yy_is_jam; 1186 | register char *yy_cp = yy_c_buf_p; 1187 | 1188 | register YY_CHAR yy_c = 1; 1189 | if ( yy_accept[yy_current_state] ) 1190 | { 1191 | yy_last_accepting_state = yy_current_state; 1192 | yy_last_accepting_cpos = yy_cp; 1193 | } 1194 | while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) 1195 | { 1196 | yy_current_state = (int) yy_def[yy_current_state]; 1197 | if ( yy_current_state >= 90 ) 1198 | yy_c = yy_meta[(unsigned int) yy_c]; 1199 | } 1200 | yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; 1201 | yy_is_jam = (yy_current_state == 89); 1202 | 1203 | return yy_is_jam ? 0 : yy_current_state; 1204 | } 1205 | 1206 | 1207 | #ifndef YY_NO_UNPUT 1208 | #ifdef YY_USE_PROTOS 1209 | static void yyunput( int c, register char *yy_bp ) 1210 | #else 1211 | static void yyunput( c, yy_bp ) 1212 | int c; 1213 | register char *yy_bp; 1214 | #endif 1215 | { 1216 | register char *yy_cp = yy_c_buf_p; 1217 | 1218 | /* undo effects of setting up yytext */ 1219 | *yy_cp = yy_hold_char; 1220 | 1221 | if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) 1222 | { /* need to shift things up to make room */ 1223 | /* +2 for EOB chars. */ 1224 | register int number_to_move = yy_n_chars + 2; 1225 | register char *dest = &yy_current_buffer->yy_ch_buf[ 1226 | yy_current_buffer->yy_buf_size + 2]; 1227 | register char *source = 1228 | &yy_current_buffer->yy_ch_buf[number_to_move]; 1229 | 1230 | while ( source > yy_current_buffer->yy_ch_buf ) 1231 | *--dest = *--source; 1232 | 1233 | yy_cp += (int) (dest - source); 1234 | yy_bp += (int) (dest - source); 1235 | yy_current_buffer->yy_n_chars = 1236 | yy_n_chars = yy_current_buffer->yy_buf_size; 1237 | 1238 | if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) 1239 | YY_FATAL_ERROR( "flex scanner push-back overflow" ); 1240 | } 1241 | 1242 | *--yy_cp = (char) c; 1243 | 1244 | 1245 | yytext_ptr = yy_bp; 1246 | yy_hold_char = *yy_cp; 1247 | yy_c_buf_p = yy_cp; 1248 | } 1249 | #endif /* ifndef YY_NO_UNPUT */ 1250 | 1251 | 1252 | #ifdef __cplusplus 1253 | static int yyinput() 1254 | #else 1255 | static int input() 1256 | #endif 1257 | { 1258 | int c; 1259 | 1260 | *yy_c_buf_p = yy_hold_char; 1261 | 1262 | if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) 1263 | { 1264 | /* yy_c_buf_p now points to the character we want to return. 1265 | * If this occurs *before* the EOB characters, then it's a 1266 | * valid NUL; if not, then we've hit the end of the buffer. 1267 | */ 1268 | if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) 1269 | /* This was really a NUL. */ 1270 | *yy_c_buf_p = '\0'; 1271 | 1272 | else 1273 | { /* need more input */ 1274 | int offset = yy_c_buf_p - yytext_ptr; 1275 | ++yy_c_buf_p; 1276 | 1277 | switch ( yy_get_next_buffer() ) 1278 | { 1279 | case EOB_ACT_LAST_MATCH: 1280 | /* This happens because yy_g_n_b() 1281 | * sees that we've accumulated a 1282 | * token and flags that we need to 1283 | * try matching the token before 1284 | * proceeding. But for input(), 1285 | * there's no matching to consider. 1286 | * So convert the EOB_ACT_LAST_MATCH 1287 | * to EOB_ACT_END_OF_FILE. 1288 | */ 1289 | 1290 | /* Reset buffer status. */ 1291 | yyrestart( yyin ); 1292 | 1293 | /* fall through */ 1294 | 1295 | case EOB_ACT_END_OF_FILE: 1296 | { 1297 | if ( yywrap() ) 1298 | return EOF; 1299 | 1300 | if ( ! yy_did_buffer_switch_on_eof ) 1301 | YY_NEW_FILE; 1302 | #ifdef __cplusplus 1303 | return yyinput(); 1304 | #else 1305 | return input(); 1306 | #endif 1307 | } 1308 | 1309 | case EOB_ACT_CONTINUE_SCAN: 1310 | yy_c_buf_p = yytext_ptr + offset; 1311 | break; 1312 | } 1313 | } 1314 | } 1315 | 1316 | c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ 1317 | *yy_c_buf_p = '\0'; /* preserve yytext */ 1318 | yy_hold_char = *++yy_c_buf_p; 1319 | 1320 | 1321 | return c; 1322 | } 1323 | 1324 | 1325 | #ifdef YY_USE_PROTOS 1326 | void yyrestart( FILE *input_file ) 1327 | #else 1328 | void yyrestart( input_file ) 1329 | FILE *input_file; 1330 | #endif 1331 | { 1332 | if ( ! yy_current_buffer ) 1333 | yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); 1334 | 1335 | yy_init_buffer( yy_current_buffer, input_file ); 1336 | yy_load_buffer_state(); 1337 | } 1338 | 1339 | 1340 | #ifdef YY_USE_PROTOS 1341 | void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) 1342 | #else 1343 | void yy_switch_to_buffer( new_buffer ) 1344 | YY_BUFFER_STATE new_buffer; 1345 | #endif 1346 | { 1347 | if ( yy_current_buffer == new_buffer ) 1348 | return; 1349 | 1350 | if ( yy_current_buffer ) 1351 | { 1352 | /* Flush out information for old buffer. */ 1353 | *yy_c_buf_p = yy_hold_char; 1354 | yy_current_buffer->yy_buf_pos = yy_c_buf_p; 1355 | yy_current_buffer->yy_n_chars = yy_n_chars; 1356 | } 1357 | 1358 | yy_current_buffer = new_buffer; 1359 | yy_load_buffer_state(); 1360 | 1361 | /* We don't actually know whether we did this switch during 1362 | * EOF (yywrap()) processing, but the only time this flag 1363 | * is looked at is after yywrap() is called, so it's safe 1364 | * to go ahead and always set it. 1365 | */ 1366 | yy_did_buffer_switch_on_eof = 1; 1367 | } 1368 | 1369 | 1370 | #ifdef YY_USE_PROTOS 1371 | void yy_load_buffer_state( void ) 1372 | #else 1373 | void yy_load_buffer_state() 1374 | #endif 1375 | { 1376 | yy_n_chars = yy_current_buffer->yy_n_chars; 1377 | yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; 1378 | yyin = yy_current_buffer->yy_input_file; 1379 | yy_hold_char = *yy_c_buf_p; 1380 | } 1381 | 1382 | 1383 | #ifdef YY_USE_PROTOS 1384 | YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) 1385 | #else 1386 | YY_BUFFER_STATE yy_create_buffer( file, size ) 1387 | FILE *file; 1388 | int size; 1389 | #endif 1390 | { 1391 | YY_BUFFER_STATE b; 1392 | 1393 | b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); 1394 | if ( ! b ) 1395 | YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); 1396 | 1397 | b->yy_buf_size = size; 1398 | 1399 | /* yy_ch_buf has to be 2 characters longer than the size given because 1400 | * we need to put in 2 end-of-buffer characters. 1401 | */ 1402 | b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); 1403 | if ( ! b->yy_ch_buf ) 1404 | YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); 1405 | 1406 | b->yy_is_our_buffer = 1; 1407 | 1408 | yy_init_buffer( b, file ); 1409 | 1410 | return b; 1411 | } 1412 | 1413 | 1414 | #ifdef YY_USE_PROTOS 1415 | void yy_delete_buffer( YY_BUFFER_STATE b ) 1416 | #else 1417 | void yy_delete_buffer( b ) 1418 | YY_BUFFER_STATE b; 1419 | #endif 1420 | { 1421 | if ( ! b ) 1422 | return; 1423 | 1424 | if ( b == yy_current_buffer ) 1425 | yy_current_buffer = (YY_BUFFER_STATE) 0; 1426 | 1427 | if ( b->yy_is_our_buffer ) 1428 | yy_flex_free( (void *) b->yy_ch_buf ); 1429 | 1430 | yy_flex_free( (void *) b ); 1431 | } 1432 | 1433 | 1434 | #ifndef YY_ALWAYS_INTERACTIVE 1435 | #ifndef YY_NEVER_INTERACTIVE 1436 | extern int isatty YY_PROTO(( int )); 1437 | #endif 1438 | #endif 1439 | 1440 | #ifdef YY_USE_PROTOS 1441 | void yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) 1442 | #else 1443 | void yy_init_buffer( b, file ) 1444 | YY_BUFFER_STATE b; 1445 | FILE *file; 1446 | #endif 1447 | 1448 | 1449 | { 1450 | yy_flush_buffer( b ); 1451 | 1452 | b->yy_input_file = file; 1453 | b->yy_fill_buffer = 1; 1454 | 1455 | #if YY_ALWAYS_INTERACTIVE 1456 | b->yy_is_interactive = 1; 1457 | #else 1458 | #if YY_NEVER_INTERACTIVE 1459 | b->yy_is_interactive = 0; 1460 | #else 1461 | b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; 1462 | #endif 1463 | #endif 1464 | } 1465 | 1466 | 1467 | #ifdef YY_USE_PROTOS 1468 | void yy_flush_buffer( YY_BUFFER_STATE b ) 1469 | #else 1470 | void yy_flush_buffer( b ) 1471 | YY_BUFFER_STATE b; 1472 | #endif 1473 | 1474 | { 1475 | if ( ! b ) 1476 | return; 1477 | 1478 | b->yy_n_chars = 0; 1479 | 1480 | /* We always need two end-of-buffer characters. The first causes 1481 | * a transition to the end-of-buffer state. The second causes 1482 | * a jam in that state. 1483 | */ 1484 | b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; 1485 | b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; 1486 | 1487 | b->yy_buf_pos = &b->yy_ch_buf[0]; 1488 | 1489 | b->yy_at_bol = 1; 1490 | b->yy_buffer_status = YY_BUFFER_NEW; 1491 | 1492 | if ( b == yy_current_buffer ) 1493 | yy_load_buffer_state(); 1494 | } 1495 | 1496 | 1497 | #ifndef YY_NO_SCAN_BUFFER 1498 | #ifdef YY_USE_PROTOS 1499 | YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size ) 1500 | #else 1501 | YY_BUFFER_STATE yy_scan_buffer( base, size ) 1502 | char *base; 1503 | yy_size_t size; 1504 | #endif 1505 | { 1506 | YY_BUFFER_STATE b; 1507 | 1508 | if ( size < 2 || 1509 | base[size-2] != YY_END_OF_BUFFER_CHAR || 1510 | base[size-1] != YY_END_OF_BUFFER_CHAR ) 1511 | /* They forgot to leave room for the EOB's. */ 1512 | return 0; 1513 | 1514 | b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); 1515 | if ( ! b ) 1516 | YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); 1517 | 1518 | b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ 1519 | b->yy_buf_pos = b->yy_ch_buf = base; 1520 | b->yy_is_our_buffer = 0; 1521 | b->yy_input_file = 0; 1522 | b->yy_n_chars = b->yy_buf_size; 1523 | b->yy_is_interactive = 0; 1524 | b->yy_at_bol = 1; 1525 | b->yy_fill_buffer = 0; 1526 | b->yy_buffer_status = YY_BUFFER_NEW; 1527 | 1528 | yy_switch_to_buffer( b ); 1529 | 1530 | return b; 1531 | } 1532 | #endif 1533 | 1534 | 1535 | #ifndef YY_NO_SCAN_STRING 1536 | #ifdef YY_USE_PROTOS 1537 | YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str ) 1538 | #else 1539 | YY_BUFFER_STATE yy_scan_string( yy_str ) 1540 | yyconst char *yy_str; 1541 | #endif 1542 | { 1543 | int len; 1544 | for ( len = 0; yy_str[len]; ++len ) 1545 | ; 1546 | 1547 | return yy_scan_bytes( yy_str, len ); 1548 | } 1549 | #endif 1550 | 1551 | 1552 | #ifndef YY_NO_SCAN_BYTES 1553 | #ifdef YY_USE_PROTOS 1554 | YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len ) 1555 | #else 1556 | YY_BUFFER_STATE yy_scan_bytes( bytes, len ) 1557 | yyconst char *bytes; 1558 | int len; 1559 | #endif 1560 | { 1561 | YY_BUFFER_STATE b; 1562 | char *buf; 1563 | yy_size_t n; 1564 | int i; 1565 | 1566 | /* Get memory for full buffer, including space for trailing EOB's. */ 1567 | n = len + 2; 1568 | buf = (char *) yy_flex_alloc( n ); 1569 | if ( ! buf ) 1570 | YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); 1571 | 1572 | for ( i = 0; i < len; ++i ) 1573 | buf[i] = bytes[i]; 1574 | 1575 | buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; 1576 | 1577 | b = yy_scan_buffer( buf, n ); 1578 | if ( ! b ) 1579 | YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); 1580 | 1581 | /* It's okay to grow etc. this buffer, and we should throw it 1582 | * away when we're done. 1583 | */ 1584 | b->yy_is_our_buffer = 1; 1585 | 1586 | return b; 1587 | } 1588 | #endif 1589 | 1590 | 1591 | #ifndef YY_NO_PUSH_STATE 1592 | #ifdef YY_USE_PROTOS 1593 | static void yy_push_state( int new_state ) 1594 | #else 1595 | static void yy_push_state( new_state ) 1596 | int new_state; 1597 | #endif 1598 | { 1599 | if ( yy_start_stack_ptr >= yy_start_stack_depth ) 1600 | { 1601 | yy_size_t new_size; 1602 | 1603 | yy_start_stack_depth += YY_START_STACK_INCR; 1604 | new_size = yy_start_stack_depth * sizeof( int ); 1605 | 1606 | if ( ! yy_start_stack ) 1607 | yy_start_stack = (int *) yy_flex_alloc( new_size ); 1608 | 1609 | else 1610 | yy_start_stack = (int *) yy_flex_realloc( 1611 | (void *) yy_start_stack, new_size ); 1612 | 1613 | if ( ! yy_start_stack ) 1614 | YY_FATAL_ERROR( 1615 | "out of memory expanding start-condition stack" ); 1616 | } 1617 | 1618 | yy_start_stack[yy_start_stack_ptr++] = YY_START; 1619 | 1620 | BEGIN(new_state); 1621 | } 1622 | #endif 1623 | 1624 | 1625 | #ifndef YY_NO_POP_STATE 1626 | static void yy_pop_state() 1627 | { 1628 | if ( --yy_start_stack_ptr < 0 ) 1629 | YY_FATAL_ERROR( "start-condition stack underflow" ); 1630 | 1631 | BEGIN(yy_start_stack[yy_start_stack_ptr]); 1632 | } 1633 | #endif 1634 | 1635 | 1636 | #ifndef YY_NO_TOP_STATE 1637 | static int yy_top_state() 1638 | { 1639 | return yy_start_stack[yy_start_stack_ptr - 1]; 1640 | } 1641 | #endif 1642 | 1643 | #ifndef YY_EXIT_FAILURE 1644 | #define YY_EXIT_FAILURE 2 1645 | #endif 1646 | 1647 | #ifdef YY_USE_PROTOS 1648 | static void yy_fatal_error( yyconst char msg[] ) 1649 | #else 1650 | static void yy_fatal_error( msg ) 1651 | char msg[]; 1652 | #endif 1653 | { 1654 | (void) fprintf( stderr, "%s\n", msg ); 1655 | exit( YY_EXIT_FAILURE ); 1656 | } 1657 | 1658 | 1659 | 1660 | /* Redefine yyless() so it works in section 3 code. */ 1661 | 1662 | #undef yyless 1663 | #define yyless(n) \ 1664 | do \ 1665 | { \ 1666 | /* Undo effects of setting up yytext. */ \ 1667 | yytext[yyleng] = yy_hold_char; \ 1668 | yy_c_buf_p = yytext + n; \ 1669 | yy_hold_char = *yy_c_buf_p; \ 1670 | *yy_c_buf_p = '\0'; \ 1671 | yyleng = n; \ 1672 | } \ 1673 | while ( 0 ) 1674 | 1675 | 1676 | /* Internal utility routines. */ 1677 | 1678 | #ifndef yytext_ptr 1679 | #ifdef YY_USE_PROTOS 1680 | static void yy_flex_strncpy( char *s1, yyconst char *s2, int n ) 1681 | #else 1682 | static void yy_flex_strncpy( s1, s2, n ) 1683 | char *s1; 1684 | yyconst char *s2; 1685 | int n; 1686 | #endif 1687 | { 1688 | register int i; 1689 | for ( i = 0; i < n; ++i ) 1690 | s1[i] = s2[i]; 1691 | } 1692 | #endif 1693 | 1694 | #ifdef YY_NEED_STRLEN 1695 | #ifdef YY_USE_PROTOS 1696 | static int yy_flex_strlen( yyconst char *s ) 1697 | #else 1698 | static int yy_flex_strlen( s ) 1699 | yyconst char *s; 1700 | #endif 1701 | { 1702 | register int n; 1703 | for ( n = 0; s[n]; ++n ) 1704 | ; 1705 | 1706 | return n; 1707 | } 1708 | #endif 1709 | 1710 | 1711 | #ifdef YY_USE_PROTOS 1712 | static void *yy_flex_alloc( yy_size_t size ) 1713 | #else 1714 | static void *yy_flex_alloc( size ) 1715 | yy_size_t size; 1716 | #endif 1717 | { 1718 | return (void *) malloc( size ); 1719 | } 1720 | 1721 | #ifdef YY_USE_PROTOS 1722 | static void *yy_flex_realloc( void *ptr, yy_size_t size ) 1723 | #else 1724 | static void *yy_flex_realloc( ptr, size ) 1725 | void *ptr; 1726 | yy_size_t size; 1727 | #endif 1728 | { 1729 | /* The cast to (char *) in the following accommodates both 1730 | * implementations that use char* generic pointers, and those 1731 | * that use void* generic pointers. It works with the latter 1732 | * because both ANSI C and C++ allow castless assignment from 1733 | * any pointer type to void*, and deal with argument conversions 1734 | * as though doing an assignment. 1735 | */ 1736 | return (void *) realloc( (char *) ptr, size ); 1737 | } 1738 | 1739 | #ifdef YY_USE_PROTOS 1740 | static void yy_flex_free( void *ptr ) 1741 | #else 1742 | static void yy_flex_free( ptr ) 1743 | void *ptr; 1744 | #endif 1745 | { 1746 | free( ptr ); 1747 | } 1748 | 1749 | #if YY_MAIN 1750 | int main() 1751 | { 1752 | yylex(); 1753 | return 0; 1754 | } 1755 | #endif 1756 | #line 58 "threeaddress.l" 1757 | 1758 | 1759 | int yywrap() { 1760 | return 1; 1761 | } 1762 | -------------------------------------------------------------------------------- /lab4_中间代码生成/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | @author:qinxinpeng 3 | @time:2023.1.2 4 | !!!说明:本程序生成三地址代码 5 | */ 6 | 7 | #include 8 | #include "ast.h" 9 | #include "genthreeaddress.h" 10 | #include "threeaddress.tab.h" 11 | extern int temVarNum; 12 | past astRoot; 13 | 14 | 15 | void yyerror(char *s) { 16 | return; 17 | } 18 | 19 | int main() { 20 | yyparse(); 21 | //抽象语法树打印 22 | printf("==========抽象语法树结构==========\n\n"); 23 | showAst("|", astRoot->next, 0); 24 | past expr = astRoot->next; 25 | while( expr != NULL) { 26 | switch (get_sym(expr)) { 27 | case 1: genArithmeticExpr(expr, NULL); 28 | break; 29 | case 2: genLogicExpr(expr, NULL); 30 | break; 31 | case 3: genAssignStmt(expr, NULL); 32 | break; 33 | case 4: genIfStmt(expr, NULL); 34 | break; 35 | case 5: genWhileStmt(expr, NULL); 36 | break; 37 | default:printf("ERROR:node结点为空"); 38 | break; 39 | } 40 | expr = expr->next; 41 | } 42 | //三地址代码打印 43 | printf("\n\n"); 44 | printf("==========三地址代码==========\n\n"); 45 | print_func(); 46 | return 0; 47 | } 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /lab4_中间代码生成/test.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qxpBlog/Compiler_UESTC/f2c01bd42571d6d29479a196f36c76b81b954442/lab4_中间代码生成/test.exe -------------------------------------------------------------------------------- /lab4_中间代码生成/threeaddress.l: -------------------------------------------------------------------------------- 1 | %{ 2 | #include 3 | #include "ast.h" 4 | #include "threeaddress.tab.h" 5 | int type; 6 | 7 | %} 8 | 9 | /* Regular definition */ 10 | DELIM [\t ] 11 | WS {DELIM}+ 12 | DIGIT [0-9] 13 | LETTER [A-Za-z] 14 | 15 | %% 16 | 17 | (\/\/.*\n)|(\/\*.*\*\/) {/* noaction */} 18 | {WS} {/* noaction */} 19 | \n {return *yytext;} 20 | {DIGIT}+ {yylval.int_value = atoi(yytext); return num_INT;} 21 | {DIGIT}+"."{DIGIT}+ {yylval.float_value = (float)atof(yytext); return num_FLOAT;} 22 | int {type = Y_INT;return Y_INT;} 23 | float {type = Y_FLOAT;return Y_FLOAT;} 24 | void {type = Y_VOID;return Y_VOID;} 25 | const {return Y_CONST;} 26 | if {return Y_IF;} 27 | else {return Y_ELSE;} 28 | while {return Y_WHILE;} 29 | break {return Y_BREAK;} 30 | continue {return Y_CONTINUE;} 31 | return {return Y_RETURN;} 32 | ("_"|{LETTER})({DIGIT}|"_"|{LETTER})* {yylval.id_name = malloc(sizeof(char) * (yyleng + 1)); memcpy(yylval.id_name, yytext, yyleng); yylval.id_name[yyleng] = '\0'; return Y_ID;} 33 | "+" {return Y_ADD;} 34 | "-" {return Y_SUB;} 35 | "*" {return Y_MUL;} 36 | "/" {return Y_DIV;} 37 | "%" {return Y_MODULO;} 38 | "<" {return Y_LESS;} 39 | "<=" {return Y_LESSEQ;} 40 | ">" {return Y_GREAT;} 41 | ">=" {return Y_GREATEQ;} 42 | "!=" {return Y_NOTEQ;} 43 | "==" {return Y_EQ;} 44 | "!" {return Y_NOT;} 45 | "&&" {return Y_AND;} 46 | "||" {return Y_OR;} 47 | "=" {return Y_ASSIGN;} 48 | "(" {return Y_LPAR;} 49 | ")" {return Y_RPAR;} 50 | "[" {return Y_LSQUARE;} 51 | "]" {return Y_RSQUARE;} 52 | "{" {return Y_LBRACKET;} 53 | "}" {return Y_RBRACKET;} 54 | "," {return Y_COMMA;} 55 | ";" {return Y_SEMICOLON;} 56 | 57 | 58 | %% 59 | 60 | int yywrap() { 61 | return 1; 62 | } 63 | -------------------------------------------------------------------------------- /lab4_中间代码生成/threeaddress.tab.h: -------------------------------------------------------------------------------- 1 | 2 | /* A Bison parser, made by GNU Bison 2.4.1. */ 3 | 4 | /* Skeleton interface for Bison's Yacc-like parsers in C 5 | 6 | Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 7 | Free Software Foundation, Inc. 8 | 9 | This program is free software: you can redistribute it and/or modify 10 | it under the terms of the GNU General Public License as published by 11 | the Free Software Foundation, either version 3 of the License, or 12 | (at your option) any later version. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program. If not, see . */ 21 | 22 | /* As a special exception, you may create a larger work that contains 23 | part or all of the Bison parser skeleton and distribute that work 24 | under terms of your choice, so long as that work isn't itself a 25 | parser generator using the skeleton or a modified version thereof 26 | as a parser skeleton. Alternatively, if you modify or redistribute 27 | the parser skeleton itself, you may (at your option) remove this 28 | special exception, which will cause the skeleton and the resulting 29 | Bison output files to be licensed under the GNU General Public 30 | License without this special exception. 31 | 32 | This special exception was added by the Free Software Foundation in 33 | version 2.2 of Bison. */ 34 | 35 | 36 | /* Tokens. */ 37 | #ifndef YYTOKENTYPE 38 | # define YYTOKENTYPE 39 | /* Put the tokens into the symbol table, so that GDB and other debuggers 40 | know about them. */ 41 | enum yytokentype { 42 | num_INT = 258, 43 | Y_INT = 259, 44 | Y_VOID = 260, 45 | Y_CONST = 261, 46 | Y_IF = 262, 47 | Y_ELSE = 263, 48 | Y_WHILE = 264, 49 | Y_BREAK = 265, 50 | Y_CONTINUE = 266, 51 | Y_FLOAT = 267, 52 | Y_RETURN = 268, 53 | Y_ADD = 269, 54 | Y_COMMA = 270, 55 | Y_DIV = 271, 56 | Y_LPAR = 272, 57 | Y_SUB = 273, 58 | Y_LSQUARE = 274, 59 | Y_MODULO = 275, 60 | Y_MUL = 276, 61 | Y_NOT = 277, 62 | Y_RPAR = 278, 63 | Y_RSQUARE = 279, 64 | Y_RBRACKET = 280, 65 | Y_LESS = 281, 66 | Y_LESSEQ = 282, 67 | Y_GREAT = 283, 68 | Y_GREATEQ = 284, 69 | Y_NOTEQ = 285, 70 | Y_EQ = 286, 71 | Y_AND = 287, 72 | Y_OR = 288, 73 | Y_ASSIGN = 289, 74 | Y_LBRACKET = 290, 75 | Y_SEMICOLON = 291, 76 | num_FLOAT = 292, 77 | Y_ID = 293 78 | }; 79 | #endif 80 | 81 | 82 | 83 | #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED 84 | typedef union YYSTYPE 85 | { 86 | 87 | /* Line 1676 of yacc.c */ 88 | #line 12 "threeaddress.y" 89 | 90 | int token; 91 | int int_value; 92 | float float_value; 93 | char* id_name; 94 | past pAst; 95 | 96 | 97 | 98 | /* Line 1676 of yacc.c */ 99 | #line 100 "threeaddress.tab.h" 100 | } YYSTYPE; 101 | # define YYSTYPE_IS_TRIVIAL 1 102 | # define yystype YYSTYPE /* obsolescent; will be withdrawn */ 103 | # define YYSTYPE_IS_DECLARED 1 104 | #endif 105 | 106 | extern YYSTYPE yylval; 107 | 108 | 109 | -------------------------------------------------------------------------------- /lab4_中间代码生成/threeaddress.y: -------------------------------------------------------------------------------- 1 | %{ 2 | 3 | #include 4 | #include "ast.h" 5 | int yylex(void); 6 | void yyerror(char *); 7 | extern int type; 8 | extern past astRoot; //链表头结点(空结点),指向链表总结点,next为链表的第一个结点 9 | 10 | %} 11 | 12 | %union { 13 | int token; 14 | int int_value; 15 | float float_value; 16 | char* id_name; 17 | past pAst; 18 | }; 19 | 20 | 21 | %token num_INT Y_INT Y_VOID Y_CONST Y_IF Y_ELSE Y_WHILE Y_BREAK Y_CONTINUE Y_FLOAT Y_RETURN 22 | %token Y_ADD Y_COMMA Y_DIV Y_LPAR Y_SUB Y_LSQUARE Y_MODULO Y_MUL Y_NOT Y_RPAR Y_RSQUARE Y_RBRACKET 23 | %token Y_LESS Y_LESSEQ Y_GREAT Y_GREATEQ Y_NOTEQ Y_EQ Y_AND Y_OR Y_ASSIGN Y_LBRACKET Y_SEMICOLON 24 | %token num_FLOAT 25 | %token Y_ID 26 | %type program Exp AddExp MulExp UnaryExp CallParams PrimaryExp LVal ArraySubscripts 27 | %type RelExp EqExp LAndExp LOrExp Stmt Block BlockItem BlockItems 28 | 29 | 30 | %% 31 | program: Stmt {$$ = newList(NULL, $1); astRoot = $$;} 32 | | program Stmt {$$ = newList($1, $2);} 33 | ; 34 | 35 | Stmt: LVal Y_ASSIGN Exp Y_SEMICOLON {$$ = newBinaryOper("=", Y_ASSIGN, $1, $3);} 36 | | Y_SEMICOLON {$$ = NULL;} 37 | | Exp Y_SEMICOLON {$$ = $1;} 38 | | Block 39 | | Y_WHILE Y_LPAR LOrExp Y_RPAR Stmt {$$ = newWhileStmt($3, newCompoundStmt(NULL,$5));} 40 | | Y_IF Y_LPAR LOrExp Y_RPAR Stmt {$$ = newIfStmt($3, newCompoundStmt(NULL,$5), NULL);} 41 | | Y_IF Y_LPAR LOrExp Y_RPAR Stmt Y_ELSE Stmt {$$ = newIfStmt($3, newCompoundStmt(NULL,$5), newCompoundStmt(NULL,$7));} 42 | | Y_BREAK Y_SEMICOLON {$$ = newBreakStmt();} 43 | | Y_CONTINUE Y_SEMICOLON {$$ = newContinueStmt();} 44 | | Y_RETURN Exp Y_SEMICOLON {$$ = newReturnStmt($2, NULL);} 45 | | Y_RETURN Y_SEMICOLON {$$ = newReturnStmt(NULL, NULL);} 46 | ; 47 | 48 | Block: Y_LBRACKET BlockItems Y_RBRACKET {$$ = $2;} 49 | | Y_LBRACKET Y_RBRACKET {$$ = NULL;} 50 | ; 51 | 52 | BlockItems: BlockItem {$$ = newCompoundStmt($1, NULL);} 53 | | BlockItem BlockItems {past l = newCompoundStmt($1, NULL); l->right = $2; $$ = l;} 54 | ; 55 | 56 | BlockItem: Stmt 57 | ; 58 | 59 | RelExp: AddExp 60 | | AddExp Y_LESS RelExp {$$ = newBinaryOper("<", Y_LESS, $1, $3);} 61 | | AddExp Y_GREAT RelExp {$$ = newBinaryOper(">", Y_GREAT, $1, $3);} 62 | | AddExp Y_LESSEQ RelExp {$$ = newBinaryOper("<=", Y_LESSEQ, $1, $3);} 63 | | AddExp Y_GREATEQ RelExp {$$ = newBinaryOper("<=", Y_GREATEQ, $1, $3);} 64 | ; 65 | 66 | EqExp: RelExp 67 | | RelExp Y_EQ EqExp {$$ = newBinaryOper("==", Y_EQ, $1, $3);} 68 | | RelExp Y_NOTEQ EqExp {$$ = newBinaryOper("!=", Y_NOTEQ, $1, $3);} 69 | ; 70 | 71 | LAndExp: EqExp 72 | | EqExp Y_AND LAndExp {$$ = newBinaryOper("&&", Y_AND, $1, $3);} 73 | ; 74 | 75 | LOrExp: LAndExp 76 | | LAndExp Y_OR LOrExp {$$ = newBinaryOper("||", Y_OR, $1, $3);} 77 | ; 78 | 79 | Exp: AddExp 80 | ; 81 | 82 | AddExp: MulExp 83 | | AddExp Y_ADD MulExp {$$ = newBinaryOper("+", Y_ADD, $1, $3);} 84 | | AddExp Y_SUB MulExp {$$ = newBinaryOper("-", Y_SUB, $1, $3);} 85 | ; 86 | 87 | MulExp: UnaryExp 88 | | MulExp Y_MUL UnaryExp {$$ = newBinaryOper("*", Y_MUL, $1, $3);} 89 | | MulExp Y_DIV UnaryExp {$$ = newBinaryOper("/", Y_DIV, $1, $3);} 90 | | MulExp Y_MODULO UnaryExp {$$ = newBinaryOper("%", Y_MODULO, $1, $3);} 91 | ; 92 | 93 | UnaryExp: PrimaryExp 94 | | Y_ID Y_LPAR Y_RPAR {$$ = newCallExp(NULL, 0, $1, NULL, NULL);} 95 | | Y_ID Y_LPAR CallParams Y_RPAR {$$ = newCallExp(NULL, 0, $1, $3, NULL);} 96 | | Y_ADD UnaryExp {$$ = newBinaryOper("+", Y_ADD, NULL, $2);} 97 | | Y_SUB UnaryExp {$$ = newBinaryOper("-", Y_SUB, NULL, $2);} 98 | | Y_NOT UnaryExp {$$ = newBinaryOper("!", Y_NOT, NULL, $2);} 99 | ; 100 | 101 | CallParams: Exp 102 | | Exp Y_COMMA CallParams {$$ = newBinaryOper("-", Y_SUB, $1, $3);} 103 | ; 104 | 105 | PrimaryExp: Y_LPAR Exp Y_RPAR {$$ = $2;} 106 | | LVal 107 | | num_INT {$$ = newIntVal($1);} 108 | | num_FLOAT {$$ = newFloatVal($1);} 109 | ; 110 | 111 | LVal: Y_ID {$$ = newDeclRefExp($1, NULL, NULL);} 112 | | Y_ID ArraySubscripts {$$ = newDeclRefExp($1, NULL, NULL);} 113 | ; 114 | 115 | ArraySubscripts: Y_LSQUARE Exp Y_RSQUARE {$$ = $2} 116 | | Y_LSQUARE Exp Y_RSQUARE ArraySubscripts {$$ = newArraySubscriptsExp($2, $4);} 117 | ; 118 | 119 | %% 120 | --------------------------------------------------------------------------------