├── LICENSE.md ├── README.md ├── asmcode.cpp ├── comm.h ├── examples ├── helloworld.c ├── nqueen.c ├── sudoku.c └── sudoku_in.txt ├── images ├── helloworld1.png ├── helloworld2.png ├── helloworld3.png ├── nqueen1.png ├── nqueen2.png └── nqueen3.png ├── input.cpp ├── intermd.cpp ├── lex.cpp ├── lib.platform ├── bin │ ├── _io.h │ └── sys.h ├── elf32 │ ├── _io.h │ └── sys.h └── win32 │ ├── _io.h │ └── sys.h ├── lib ├── io.h ├── mem.h ├── op.h ├── rand.h └── sort.h ├── makefile ├── mycc.cpp ├── mycc.h ├── run.sh ├── syntax.cpp └── tests ├── 1.5function_call.c ├── 10goto.c ├── 11input.c ├── 12random.c ├── 13rec_depth.c ├── 14getc_exit.c ├── 15dfs.c ├── 1if_test.c ├── 2.5recursion_factorial.c ├── 2for.c ├── 3multi_for.c ├── 4pointer.c ├── 5mix_pointer.c ├── 6quick_sort.c ├── 7asm_embed_print_all_char.c ├── 8array.c └── 9array_constant_string_constant.c /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Yu Wang (wangyucn at gmail.com) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # mycc 2 | 3 | A tiny C compiler of 2k lines of codes, generates pure x86 asm code for DOS/Win32/Linux 3 backends. 4 | 5 | ![image](images/helloworld1.png) 6 | ![image](images/helloworld2.png) 7 | ![image](images/helloworld3.png) 8 | 9 | Mycc supports a reasonable subset of the C language. Check [tests](https://github.com/wangyu-/mycc/tree/master/tests) and [examples](https://github.com/wangyu-/mycc/tree/master/examples) folder to get an idea of what mycc can compile. Below are some examples: 10 | 11 | [nqueen.c](https://github.com/wangyu-/mycc/blob/master/examples/nqueen.c) is a mycc-compilable program that finds a solution for the n queen puzzle: 12 | 13 | ``` 14 | Q . . . . . . . 15 | . . . . Q . . . 16 | . . . . . . . Q 17 | . . . . . Q . . 18 | . . Q . . . . . 19 | . . . . . . Q . 20 | . Q . . . . . . 21 | . . . Q . . . . 22 | ``` 23 | 24 | [sudoku.c](https://github.com/wangyu-/mycc/blob/master/examples/sudoku.c) is a mycc-compilable program that fills the sudoku game for you: 25 | ``` 26 | input: output: 27 | 1 . 3 | . . . | 5 . 9 1 4 3 | 6 2 8 | 5 7 9 28 | . . 2 | 1 . 9 | 4 . . 5 7 2 | 1 3 9 | 4 6 8 29 | . . . | 7 . 4 | . . . 9 8 6 | 7 5 4 | 2 3 1 30 | -------+-------+------ -------+-------+------ 31 | 3 . . | 5 . 2 | . . 6 3 9 1 | 5 4 2 | 7 8 6 32 | . 6 . | . . . | . 5 . 4 6 8 | 9 1 7 | 3 5 2 33 | 7 . . | 8 . 3 | . . 4 7 2 5 | 8 6 3 | 9 1 4 34 | -------+-------+------ -------+-------+------ 35 | . . . | 4 . 1 | . . . 2 3 7 | 4 8 1 | 6 9 5 36 | . . 9 | 2 . 5 | 8 . . 6 1 9 | 2 7 5 | 8 4 3 37 | 8 . 4 | . . . | 1 . 7 8 5 4 | 3 9 6 | 1 2 7 38 | ```` 39 | 40 | 41 | Mycc supports the syntax of embeding asm codes into C, mycc compiled programs are able to do syscall directly on their own: 42 | 43 | ``` 44 | char getc() 45 | { 46 | char a; 47 | a=0; 48 | __asm 49 | { 50 | mov eax, 3 ;the syscall num of "read()" on linux 51 | mov ebx, 0 ;read from stdin, 0 is the fd of stdin 52 | mov ecx, a@getc ;save the result to the address of variable "a" inside function "getc" 53 | mov edx, 1 ;read 1 character 54 | int 0x80 55 | } 56 | return a; 57 | } 58 | ``` 59 | 60 | Mycc is shipped with a built-in library (check [lib](https://github.com/wangyu-/mycc/tree/master/lib) and [lib.platform](https://github.com/wangyu-/mycc/tree/master/lib.platform)), implemented in the language of mycc itself. Becasue of this, unlike most other tiny compilers, mycc generates "pure asm" codes that runs independently, without the need of linking to external libraries (e.g. libc). 61 | 62 | # How to use 63 | make sure you have `nasm` installed. 64 | ##### 1 build mycc with make: 65 | ``` 66 | make 67 | ``` 68 | ##### 2a To compile for Linux backend: 69 | ``` 70 | ./mycc 2) 31 | { 32 | if(s[0]=='?'&&s[1]=='q')//it's a variable related to pointer 33 | { 34 | string r; 35 | write_asm("mov ebx,[$%s]\n",s.c_str()); //indirect addressing 36 | r="?"; 37 | return "[ebx]"; //another indirect addressing 38 | } 39 | 40 | } 41 | if(s.length()>=1) 42 | { 43 | if(s[0]=='\''||s[0]>='0'&&s[0]<='9') //it's integer or char 44 | { 45 | return s; 46 | } 47 | else//it's a normal variable 48 | { 49 | string r="["; 50 | r+="$"; 51 | r+=s; 52 | r+="]"; 53 | return r; //only one indirect addressing 54 | } 55 | } 56 | return s; 57 | } 58 | string creat_lb() 59 | { 60 | label_count++; 61 | //addr0++; 62 | char s[100]; 63 | string r = "?LB"; // LB for label generated by asm_gen, lb for quat_gen 64 | var_type_t typetmp; 65 | typetmp.s = "temp_label"; 66 | //typetmp.addr=addr0; 67 | sprintf(s, "%d", label_count); 68 | r += s; 69 | return r; 70 | } 71 | 72 | int run(map asmmp,map vb,vector quat,asm_format_t asm_format,string output_name) 73 | { 74 | vector::iterator it; 75 | map ::iterator it2; 76 | //char output_name[]="output.asm"; 77 | fp=fopen(output_name.c_str(),"w"); 78 | if(asm_format==format_bin) 79 | { 80 | write_asm(";;format: bin\n\n"); 81 | write_asm("section .text\n"); 82 | write_asm("\norg 100h\n"); 83 | } 84 | else if(asm_format==format_elf32) 85 | { 86 | write_asm(";;format: elf32\n\n"); 87 | write_asm("section .text\n"); 88 | write_asm("global _start\n"); 89 | write_asm("_start:\n"); 90 | } 91 | else if(asm_format==format_win32) 92 | { 93 | write_asm(";;format: win32\n\n"); 94 | write_asm("section .text\n"); 95 | write_asm("global _main\n"); //gnu ld (native/cygwin/mingw) 96 | write_asm("global start\n"); //golink 97 | write_asm("_main:\n"); 98 | write_asm("start:\n"); 99 | } 100 | write_asm("call _?db_init\n"); 101 | write_asm("call main\n"); 102 | 103 | if(asm_format==format_bin) 104 | { 105 | //write_asm("mov ah,01h\n"); 106 | //write_asm("int 21h\n"); 107 | write_asm("mov ah,0x4c\n"); 108 | write_asm("int 21h\n"); 109 | } 110 | else if(asm_format==format_elf32) 111 | { 112 | write_asm("xor ebx, ebx\n"); 113 | write_asm("mov eax, 0x1\n"); 114 | write_asm("int 0x80\n"); 115 | } 116 | else if(asm_format==format_win32) 117 | { 118 | write_asm("ret\n"); 119 | } 120 | 121 | vector arr; 122 | for(it2=vb.begin();it2!=vb.end();it2++) 123 | { 124 | if(it2->second.s=="int_arr"||it2->second.s=="string_constant"||it2->second.s=="array_constant") arr.push_back(it2->first); 125 | } 126 | write_asm("\n"); 127 | write_asm("_?db_init:\n"); 128 | for(int i=0;is1)=="call") write_asm("call %s\n",it->s4.c_str()); 163 | else if(cut(it->s1)=="ret") write_asm("ret\n"); 164 | else if(cut(it->s1)=="rts") write_asm("rts\n"); 165 | else if(cut(it->s1)=="func") write_asm("%s:\n",it->s4.c_str()); 166 | else if(cut(it->s1)=="lb") write_asm("%s:\n",it->s4.c_str()); 167 | else if(cut(it->s1)=="asm")write_asm("%s\n",asmmp.find(it->s4)->second.c_str()); //write_asm("pusha\n%s\npopa\n",asmmp.find(it->s4)->second.c_str()); 168 | else if(cut(it->s1)=="pushnow") 169 | { 170 | map::iterator it3; 171 | for(it3=vb.begin();it3!=vb.end();it3++) 172 | { 173 | if(it3->second.func==it->s4) 174 | { 175 | write_asm("push dword [$%s]\n",it3->first.c_str());//push,pop的总是变量的内容 176 | //write_asm("push eax\n"); 177 | if(it3->second.s=="int_arr"&&it3->second.n!=0) 178 | { 179 | write_asm("mov eax,$arr?%s\n",it3->first.c_str()); 180 | write_asm("mov ebx,%d\n",it3->second.n); 181 | write_asm("call _?batch_push\n"); 182 | } 183 | 184 | } 185 | } 186 | } 187 | else if(cut(it->s1)=="popnow") 188 | { 189 | map::iterator it3; 190 | for(it3=vb.end();;) 191 | { 192 | it3--; 193 | if(it3->second.func==it->s4) 194 | { 195 | if(it3->second.s=="int_arr"&&it3->second.n!=0) 196 | { 197 | write_asm("mov eax,$arr?%s\n",it3->first.c_str()); 198 | write_asm("mov ebx,%d\n",it3->second.n); 199 | write_asm("call _?batch_pop\n"); 200 | } 201 | //write_asm("pop eax\n"); 202 | write_asm("pop dword [$%s]\n",it3->first.c_str()); 203 | } 204 | if(it3==vb.begin()) break; 205 | } 206 | } 207 | else if(cut(it->s1)=="+") 208 | { 209 | write_asm("mov eax,%s\n",mod(it->s2).c_str()); 210 | write_asm("add eax,%s\n",mod(it->s3).c_str()); 211 | write_asm("mov [%s],eax\n",it->s4.c_str()); 212 | } 213 | else if(cut(it->s1)=="-") 214 | { 215 | write_asm("mov eax,%s\n",mod(it->s2).c_str()); 216 | write_asm("sub eax,%s\n",mod(it->s3).c_str()); 217 | write_asm("mov [%s],eax\n",it->s4.c_str()); 218 | } 219 | else if(cut(it->s1)=="*") 220 | { 221 | write_asm("mov eax,%s\n",mod(it->s2).c_str()); 222 | write_asm("mov ecx,%s\n",mod(it->s3).c_str()); 223 | write_asm("mov edx,0\n"); 224 | write_asm("imul ecx\n"); 225 | write_asm("mov [%s],eax\n",it->s4.c_str()); 226 | } 227 | else if(cut(it->s1)=="/") 228 | { 229 | write_asm("mov eax,%s\n",mod(it->s2).c_str()); 230 | write_asm("mov ecx,%s\n",mod(it->s3).c_str()); 231 | write_asm("mov edx,0\n"); 232 | write_asm("idiv ecx\n"); 233 | write_asm("mov [%s],eax\n",it->s4.c_str()); 234 | } 235 | else if(cut(it->s1)=="%") 236 | { 237 | write_asm("mov eax,%s\n",mod(it->s2).c_str()); 238 | write_asm("mov ecx,%s\n",mod(it->s3).c_str()); 239 | write_asm("mov edx,0\n"); 240 | write_asm("idiv ecx\n"); 241 | write_asm("mov [%s],edx\n",it->s4.c_str()); 242 | } 243 | else if(cut(it->s1)=="=")//特殊的运算符 244 | { 245 | write_asm("mov eax,%s\n",mod(it->s3).c_str()); 246 | write_asm("mov %s,eax\n",mod(it->s2).c_str()); 247 | } 248 | else if(cut(it->s1)=="!=") 249 | { 250 | write_asm("mov eax,%s\n",mod(it->s3).c_str()); 251 | write_asm("cmp eax,%s\n",mod(it->s2).c_str()); 252 | write_asm("LAHF\n"); 253 | write_asm("SHR EAX,14\n"); 254 | write_asm("not EAX\n"); 255 | write_asm("and EAX,1\n"); 256 | write_asm("mov [%s],eax\n",it->s4.c_str()); 257 | } 258 | else if(cut(it->s1)=="==") 259 | { 260 | write_asm("mov eax,%s\n",mod(it->s3).c_str()); 261 | write_asm("cmp eax,%s\n",mod(it->s2).c_str()); 262 | write_asm("LAHF\n"); 263 | write_asm("SHR EAX,14\n"); 264 | write_asm("and EAX,1\n"); 265 | write_asm("mov [%s],eax\n",it->s4.c_str()); 266 | } 267 | else if(cut(it->s1)==">") 268 | { 269 | write_asm("xor eax,eax\n"); 270 | write_asm("mov [%s],eax\n",it->s4.c_str()); 271 | write_asm("mov eax,%s\n",mod(it->s2).c_str()); 272 | write_asm("cmp eax,%s\n",mod(it->s3).c_str()); 273 | string lb1=creat_lb(); 274 | write_asm("jle %s\n",lb1.c_str()); 275 | write_asm("mov eax,1\n"); 276 | write_asm("mov [%s],eax\n",it->s4.c_str()); 277 | write_asm("%s:\n",lb1.c_str()); 278 | } 279 | else if(cut(it->s1)=="<") 280 | { 281 | write_asm("xor eax,eax\n"); 282 | write_asm("mov [%s],eax\n",it->s4.c_str()); 283 | write_asm("mov eax,%s\n",mod(it->s2).c_str()); 284 | write_asm("cmp eax,%s\n",mod(it->s3).c_str()); 285 | string lb1=creat_lb(); 286 | write_asm("jge %s\n",lb1.c_str()); 287 | write_asm("mov eax,1\n"); 288 | write_asm("mov [%s],eax\n",it->s4.c_str()); 289 | write_asm("%s:\n",lb1.c_str()); 290 | } 291 | else if(cut(it->s1)==">=") 292 | { 293 | write_asm("xor eax,eax\n"); 294 | write_asm("mov [%s],eax\n",it->s4.c_str()); 295 | write_asm("mov eax,%s\n",mod(it->s2).c_str()); 296 | write_asm("cmp eax,%s\n",mod(it->s3).c_str()); 297 | string lb1=creat_lb(); 298 | write_asm("jl %s\n",lb1.c_str()); 299 | write_asm("mov eax,1\n"); 300 | write_asm("mov [%s],eax\n",it->s4.c_str()); 301 | write_asm("%s:\n",lb1.c_str()); 302 | } 303 | else if(cut(it->s1)=="<=") 304 | { 305 | write_asm("xor eax,eax\n"); 306 | write_asm("mov [%s],eax\n",it->s4.c_str()); 307 | write_asm("mov eax,%s\n",mod(it->s2).c_str()); 308 | write_asm("cmp eax,%s\n",mod(it->s3).c_str()); 309 | string lb1=creat_lb(); 310 | write_asm("jg %s\n",lb1.c_str()); 311 | write_asm("mov eax,1\n"); 312 | write_asm("mov [%s],eax\n",it->s4.c_str()); 313 | write_asm("%s:\n",lb1.c_str()); 314 | } 315 | else if(cut(it->s1)=="&&") 316 | { 317 | string lb1=creat_lb(),lb2=creat_lb(); 318 | write_asm("mov eax,1\n"); 319 | write_asm("mov [%s],eax\n",it->s4.c_str()); 320 | 321 | write_asm("mov eax,%s\n",mod(it->s2).c_str()); 322 | write_asm("cmp eax,0\n"); 323 | write_asm("jne %s\n",lb1.c_str()); 324 | write_asm("mov eax,0\n"); 325 | write_asm("mov [%s],eax\n",it->s4.c_str()); 326 | write_asm("%s:\n",lb1.c_str()); 327 | 328 | write_asm("mov eax,%s\n",mod(it->s3).c_str()); 329 | write_asm("cmp eax,0\n"); 330 | write_asm("jne %s\n",lb2.c_str()); 331 | write_asm("mov eax,0\n"); 332 | write_asm("mov [%s],eax\n",it->s4.c_str()); 333 | write_asm("%s:\n",lb2.c_str()); 334 | 335 | } 336 | else if(cut(it->s1)=="||") 337 | { 338 | string lb1=creat_lb(),lb2=creat_lb(); 339 | write_asm("mov eax,0\n"); 340 | write_asm("mov [%s],eax\n",it->s4.c_str()); 341 | 342 | write_asm("mov eax,%s\n",mod(it->s2).c_str()); 343 | write_asm("cmp eax,0\n"); 344 | write_asm("je %s\n",lb1.c_str()); 345 | write_asm("mov eax,1\n"); 346 | write_asm("mov [%s],eax\n",it->s4.c_str()); 347 | write_asm("%s:\n",lb1.c_str()); 348 | 349 | write_asm("mov eax,%s\n",mod(it->s3).c_str()); 350 | write_asm("cmp eax,0\n"); 351 | write_asm("je %s\n",lb2.c_str()); 352 | write_asm("mov eax,1\n"); 353 | write_asm("mov [%s],eax\n",it->s4.c_str()); 354 | write_asm("%s:\n",lb2.c_str()); 355 | } 356 | else if(cut(it->s1)=="!") 357 | { 358 | write_asm("xor eax,eax\n"); 359 | write_asm("mov [%s],eax\n",it->s4.c_str()); 360 | write_asm("mov eax,0\n"); 361 | write_asm("cmp eax,%s\n",mod(it->s2).c_str()); 362 | string lb1=creat_lb(); 363 | write_asm("jne %s\n",lb1.c_str()); 364 | write_asm("mov eax,1\n"); 365 | write_asm("mov [%s],eax\n",it->s4.c_str()); 366 | write_asm("%s:\n",lb1.c_str()); 367 | } 368 | else if(cut(it->s1)=="&") 369 | { 370 | if(it->s2.length()>2&&it->s2[0]=='?'&&it->s2[1]=='q')//对引用取地址特殊处理 371 | { 372 | write_asm("mov eax,[%s]\n",it->s2.c_str()); 373 | } 374 | else write_asm("mov eax,%s\n",it->s2.c_str());//只能对变量取地址 375 | write_asm("mov [%s],eax\n",it->s4.c_str()); 376 | } 377 | else if(cut(it->s1)=="**") 378 | { 379 | write_asm("mov eax,%s\n",mod(it->s2).c_str()); 380 | write_asm("mov [%s],eax\n",it->s4.c_str());//引用 381 | } 382 | else if(cut(it->s1)=="[]") 383 | { 384 | write_asm("mov eax,%s\n",mod(it->s2).c_str()); 385 | //write_asm("mov ecx,eax\n"); 386 | write_asm("add eax,%s\n",mod(it->s3).c_str()); 387 | write_asm("add eax,%s\n",mod(it->s3).c_str()); 388 | write_asm("add eax,%s\n",mod(it->s3).c_str()); 389 | write_asm("add eax,%s\n",mod(it->s3).c_str()); 390 | write_asm("mov [%s],eax\n",it->s4.c_str()); 391 | //write_asm("mov [%s],eax\n",it->s4.c_str());//引用 392 | } 393 | else if(cut(it->s1)=="jpz") 394 | { 395 | write_asm("mov eax,%s\n",mod(it->s2).c_str()); 396 | write_asm("cmp eax,0\n"); 397 | write_asm("je %s\n",it->s4.c_str()); 398 | } 399 | else if(cut(it->s1)=="jmp") 400 | { 401 | write_asm("jmp %s\n",it->s4.c_str()); 402 | } 403 | else {printf("\n",it->s1.c_str());exit(-1);} 404 | } 405 | //////////////////////////////////////////////////////////数据区在后面 406 | write_asm("\n"); 407 | write_asm("section .data\n"); 408 | for(it2=vb.begin();it2!=vb.end();it2++) 409 | { 410 | if(it2->second.s=="int"||it2->second.s=="tmp_int"||it2->second.s=="quo_int") write_asm("%s dd 0\n",it2->first.c_str()); 411 | else if(it2->second.s=="int_arr") 412 | { 413 | write_asm("arr?%s times %d dd 0\n",it2->first.c_str(),it2->second.n); 414 | write_asm("%s dd 0\n",it2->first.c_str()); 415 | arr.push_back(it2->first); 416 | } 417 | else if(it2->second.s=="string_constant") 418 | { 419 | write_asm("arr?%s dd ",it2->first.c_str()); 420 | string t=it2->second.para[0]; 421 | for(int i=1;ifirst.c_str()); 427 | arr.push_back(it2->first); 428 | } 429 | else if(it2->second.s=="array_constant") 430 | { 431 | write_asm("arr?%s dd ",it2->first.c_str()); 432 | for(int i=0;isecond.para.size();i++) 433 | { 434 | 435 | write_asm("%s,",it2->second.para[i].c_str()); 436 | } 437 | write_asm("0\n"); 438 | write_asm("%s dd 0\n",it2->first.c_str()); 439 | arr.push_back(it2->first); 440 | } 441 | } 442 | ///////////////////////////////////////////////////////////////////// 443 | fclose(fp); 444 | //execlp("nasm", "nasm", "-f", "bin","temp.txt","-o","temp.exe" ,(char *)NULL); 445 | //WinExec(".\\nasm\\nasm.exe temp.txt -o temp.exe",SW_SHOW); 446 | //WinExec("d:\\windows\\notepad.exe c:\\wycc.txt",SW_SHOW); 447 | //getchar(); 448 | /* 449 | for(;;) 450 | { 451 | getchar(); 452 | }*/ 453 | printf("done\n"); 454 | printf("format:%s\n",format_name_table[asm_format]); 455 | printf("wrote to \"%s\"\n",output_name.c_str()); 456 | return 0; 457 | } 458 | }; 459 | int asm_code_gen(const map &asmmp,const map &vb,const vector &quat,asm_format_t asm_format,string output_name) 460 | { 461 | asm_gen_t asm_gen; 462 | return asm_gen.run(asmmp,vb,quat,asm_format,output_name); 463 | } 464 | -------------------------------------------------------------------------------- /comm.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | using namespace std; 16 | const int _out=1; 17 | 18 | enum asm_format_t{format_bin=0,format_elf32,format_win32}; 19 | const char format_name_table[][100]={"bin","elf32","win32"}; 20 | 21 | typedef char* cptr; 22 | 23 | struct token_t //struct of token 24 | { 25 | string s; 26 | int n; 27 | int p; 28 | int line; 29 | }; 30 | struct grammar_t; 31 | typedef grammar_t* gptr; 32 | struct grammar_t //struct of grammar tree 33 | { 34 | string n; 35 | int v; 36 | int p;//格式,横排 竖排 37 | //quater *qp; 38 | vector l; 39 | void c() 40 | { 41 | n=""; 42 | v=0; 43 | p=0; 44 | l.clear(); 45 | } 46 | grammar_t() 47 | { 48 | n=""; 49 | v=0; 50 | p=0; 51 | l.clear(); 52 | } 53 | int prt(int level=0) 54 | { 55 | int i,j; 56 | for(j=0;jn=="quat") 59 | { 60 | g->qp->prt(n+1); 61 | } 62 | else*/ 63 | for(i=0;iprt(level+1); 66 | } 67 | return 0; 68 | } 69 | }; 70 | 71 | struct quat_t //quaternion 72 | { 73 | string s1,s2,s3,s4; 74 | }; 75 | 76 | struct var_type_t //type for variable table 77 | { 78 | string s; 79 | int addr; 80 | string func; 81 | vector para; 82 | int n; 83 | void clear() 84 | { 85 | n=0; 86 | s=""; 87 | addr=-1; 88 | func=""; 89 | para.clear(); 90 | } 91 | }; 92 | -------------------------------------------------------------------------------- /examples/helloworld.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main() 3 | { 4 | puts("hello world!"); 5 | newline(); 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /examples/nqueen.c: -------------------------------------------------------------------------------- 1 | //nquee.c 2 | /* 3 | finds a solution for the n queen puzzle 4 | */ 5 | #include 6 | int board0[10000]; 7 | int *board[100]; 8 | int n; 9 | int out_board(int r,int c) 10 | { 11 | if(r>=n||c>=n||r<0||c<0) return 1; 12 | return 0; 13 | } 14 | int okay(int r,int c) 15 | { 16 | int i; 17 | for(i=1;;i=i+1) 18 | { 19 | if(out_board(r-i,c)) break; //test break 20 | if(board[r-i][c]) return 0; 21 | } 22 | for(i=1;;i=i+1) 23 | { 24 | if(out_board(r-i,c-i)) goto out_loop; //test goto 25 | if(board[r-i][c-i]) return 0; 26 | } 27 | out_loop: 28 | for(i=1;!out_board(r-i,c+i);i=i+1) 29 | if(board[r-i][c+i]) return 0; 30 | return 1; 31 | } 32 | int dfs(int row) 33 | { 34 | int i; 35 | if (row==n) 36 | return 1; 37 | for (i=0;i 6 | 7 | int num[10]; 8 | int pnt_x[100]; 9 | int pnt_y[100]; 10 | int pcnt; 11 | 12 | char mat0[81]; 13 | char * mat[9]; 14 | 15 | int pretty_print; 16 | 17 | int zero(int *a,int n) 18 | { 19 | int i; 20 | for(i=0;;i=i+1) 21 | { 22 | if(i==n) break; //test break 23 | a[i]=0; 24 | } 25 | } 26 | int okay(int x,int y) 27 | { 28 | int i;int j;int k;int u;int v; 29 | i=x; 30 | zero(num,10); 31 | for(j=0;j<9;j=j+1) 32 | { 33 | if(!mat[i][j]) continue; //test continue 34 | if(num[ mat[i][j] ]) return 0; 35 | num[ mat[i][j] ]=1; 36 | } 37 | i=y; 38 | zero(num,10); 39 | for(j=0;j<9;j=j+1) 40 | { 41 | if(mat[j][i]) 42 | { 43 | if(num[ mat[j][i] ]) goto end_func; /* test goto */ 44 | num[ mat[j][i] ]=1; 45 | } 46 | } 47 | i=x/3; 48 | j=y/3; 49 | zero(num,10); 50 | for(u=0;u<3;u=u+1) 51 | for(v=0;v<3;v=v+1) 52 | { 53 | if(mat[i*3+u][j*3+v]) 54 | { 55 | if(num[ mat[i*3+u][j*3+v] ]) return 0; 56 | num[ mat[i*3+u][j*3+v] ]=1; 57 | } 58 | } 59 | return 1; 60 | end_func: 61 | return 0; 62 | } 63 | int dfs(int s) 64 | { 65 | int i; 66 | if(s==pcnt) return 1; 67 | for(i=1;i<=9;i=i+1) 68 | { 69 | mat[pnt_x[s]][pnt_y[s]]=i; 70 | if(okay(pnt_x[s],pnt_y[s])) 71 | { 72 | if(dfs(s+1)==1) return 1; 73 | } 74 | mat[pnt_x[s]][pnt_y[s]]=0; 75 | } 76 | return 0; 77 | } 78 | int prt() 79 | { 80 | int i;int j; 81 | for(i=0;i<9;i=i+1) 82 | { 83 | if(pretty_print) 84 | if(i==3||i==6) {puts("-------+-------+------");newline();} 85 | for(j=0;j<9;j=j+1) 86 | { 87 | if(pretty_print) 88 | { 89 | if(j==3||j==6) puts(" |"); 90 | putc(' '); 91 | } 92 | if(mat[i][j]) 93 | put32(mat[i][j]); 94 | else(putc('.')); 95 | } 96 | newline(); 97 | } 98 | } 99 | int main() 100 | { 101 | 102 | int i;int j; 103 | pretty_print=1; 104 | pcnt=0; 105 | for(i=0;i<9;i=i+1) 106 | mat[i]=&mat0[i*9]; 107 | for(i=0;i<9;i=i+1) 108 | gets(mat[i]); 109 | 110 | for(i=8;i>=0;i=i-1) 111 | for(j=8;j>=0;j=j-1) 112 | { 113 | 114 | if(mat[i][j]>='1'&&mat[i][j]<='9') 115 | { 116 | mat[i][j]=mat[i][j]-48; 117 | } 118 | else 119 | { 120 | mat[i][j]=0; 121 | pnt_x[pcnt]=i; 122 | pnt_y[pcnt]=j; 123 | pcnt=pcnt+1; 124 | } 125 | } 126 | puts("input:");newline(); 127 | prt(); 128 | newline(); 129 | if (dfs(0)==0) {puts("no solution");newline();} 130 | else 131 | { 132 | 133 | puts("output:");newline(); 134 | prt(); 135 | } 136 | 137 | return 0; 138 | } 139 | -------------------------------------------------------------------------------- /examples/sudoku_in.txt: -------------------------------------------------------------------------------- 1 | 1.3...5.9 2 | ..21.94.. 3 | ...7.4... 4 | 3..5.2..6 5 | .6.....5. 6 | 7..8.3..4 7 | ...4.1... 8 | ..92.58.. 9 | 8.4...1.7 10 | -------------------------------------------------------------------------------- /images/helloworld1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangyu-/mycc/72e5869845c61862493a04935e3ace6f23303433/images/helloworld1.png -------------------------------------------------------------------------------- /images/helloworld2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangyu-/mycc/72e5869845c61862493a04935e3ace6f23303433/images/helloworld2.png -------------------------------------------------------------------------------- /images/helloworld3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangyu-/mycc/72e5869845c61862493a04935e3ace6f23303433/images/helloworld3.png -------------------------------------------------------------------------------- /images/nqueen1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangyu-/mycc/72e5869845c61862493a04935e3ace6f23303433/images/nqueen1.png -------------------------------------------------------------------------------- /images/nqueen2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangyu-/mycc/72e5869845c61862493a04935e3ace6f23303433/images/nqueen2.png -------------------------------------------------------------------------------- /images/nqueen3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangyu-/mycc/72e5869845c61862493a04935e3ace6f23303433/images/nqueen3.png -------------------------------------------------------------------------------- /input.cpp: -------------------------------------------------------------------------------- 1 | #include "comm.h" 2 | //struct getcode_t // get source code from stdin, do macro expansion, return the final code 3 | //{ 4 | string read_all(istream &in) 5 | { 6 | string res; 7 | string line; 8 | while (getline(in, line)) 9 | { 10 | res+=line; 11 | res+="\n"; 12 | } 13 | return res; 14 | } 15 | string trim(string &s) 16 | { 17 | string res; 18 | for(int i=0;i'||s[i]=='"'||s[i]=='"') continue; 22 | res+=s[i]; 23 | } 24 | return res; 25 | } 26 | string expand_macro(string &s,asm_format_t asm_format) 27 | { 28 | set pragma_once; 29 | string res; 30 | string line; 31 | istringstream stream(s); 32 | string format_name=format_name_table[asm_format]; 33 | while (getline(stream, line)) 34 | { 35 | string target="#include"; 36 | if(line.length()>=target.size() && strncmp(line.c_str(),target.c_str(),target.size())==0 ) 37 | { 38 | 39 | string filename=line.substr(target.size()); 40 | filename=trim(filename); 41 | if(pragma_once.find(filename)!=pragma_once.end()) 42 | { 43 | continue; 44 | } 45 | pragma_once.insert(filename); 46 | string path1=string("")+"./lib.platform/"+format_name+"/"+filename; 47 | string path2="./lib/"+filename; 48 | ifstream myfile(path1); 49 | if(myfile.good()) 50 | { 51 | res+=read_all(myfile); 52 | res+="\n"; 53 | } 54 | else 55 | { 56 | myfile.open(path2); 57 | if(myfile.good()) 58 | { 59 | res+=read_all(myfile); 60 | res+="\n"; 61 | } 62 | else 63 | { 64 | printf("error: can't find file %s\n",filename.c_str()); 65 | exit(-1); 66 | } 67 | } 68 | } 69 | else 70 | { 71 | res+=line; 72 | res+="\n"; 73 | } 74 | } 75 | return res; 76 | } 77 | string getcode(const asm_format_t asm_format) 78 | { 79 | string s=read_all(cin); 80 | if(_out)printf("-----------original file----------\n"); 81 | if(_out)printf("%s\n",s.c_str()); 82 | 83 | string after; 84 | int ok=0; 85 | for(int i=0;i<100;i++) 86 | { 87 | after=expand_macro(s,asm_format); 88 | if(after==s) {ok=1;s=after;break;} 89 | s=after; 90 | } 91 | if(!ok) 92 | { 93 | printf("error: max deepth of expansion exceed\n"); 94 | exit(-1); 95 | } 96 | 97 | if(_out)printf("-----------after expension----------\n"); 98 | if(_out)printf("%s\n",s.c_str()); 99 | return s; 100 | } 101 | //}; 102 | -------------------------------------------------------------------------------- /intermd.cpp: -------------------------------------------------------------------------------- 1 | #include "comm.h" 2 | struct symbol_table_t 3 | { 4 | int addr0; 5 | int count; 6 | int count2; 7 | int count3; 8 | int count4; 9 | int count5; 10 | map gv;//全局变量 11 | //map fn;//函数名称 12 | void ins(string s,var_type_t t) 13 | { 14 | if(gv.find(s)!=gv.end()) {printf("identifier %s name not unique\n",s.c_str());exit(-1) ;} 15 | else 16 | { 17 | addr0++; 18 | t.addr=addr0; 19 | gv.insert(pair(s,t)); 20 | } 21 | } 22 | void cut_tree(gptr gm)//简化语法树 23 | { 24 | int i,j,k; 25 | vector ::iterator it,it2; 26 | for(it=gm->l[1]->l.begin();it!=gm->l[1]->l.end();it++) 27 | { 28 | (*it)->l.erase((*it)->l.begin()); 29 | (*it)->l.erase((*it)->l.begin()); 30 | (*it)->l.erase((*it)->l.begin()); 31 | for(i=0;i<(*it)->l[0]->l.size();i++) 32 | { 33 | (*it)->l.push_back((*it)->l[0]->l[i]); 34 | } 35 | (*it)->l.erase((*it)->l.begin()); 36 | } 37 | gm->l.erase(gm->l.begin());//删掉变量声明区 38 | //gm->l[0]=gm->l[0]->l[0]; 39 | for(it=gm->l[0]->l.begin();it!=gm->l[0]->l.end();it++) 40 | { 41 | gm->l.push_back(*it); 42 | } 43 | gm->l.erase(gm->l.begin()); 44 | } 45 | void prt() 46 | { 47 | map::iterator i; 48 | int j; 49 | printf("var list:\n"); 50 | for(i=gv.begin();i!=gv.end();i++) 51 | { 52 | printf("%s:%s:%d\n",i->first.c_str(),i->second.s.c_str(),i->second.addr); 53 | for(j=0;jsecond.para.size();j++) 54 | { 55 | printf("->%s\n",i->second.para[j].c_str()); 56 | } 57 | } 58 | } 59 | string creat_tmp(string now) 60 | { 61 | count++; 62 | //addr0++; 63 | char s[100]; 64 | string r="?t"; 65 | var_type_t typetmp; 66 | typetmp.s="tmp_int"; 67 | typetmp.func=now; 68 | //typetmp.addr=addr0; 69 | sprintf(s,"%d",count); 70 | r+=s;//r+="@";r+=now; 71 | ins(r,typetmp); 72 | return r; 73 | } 74 | string creat_quo(string now) 75 | { 76 | count3++; 77 | //addr0++; 78 | char s[100]; 79 | string r="?q"; 80 | var_type_t typetmp; 81 | typetmp.s="quo_int"; 82 | typetmp.func=now; 83 | sprintf(s,"%d",count3); 84 | r+=s;//r+="@";r+=now; 85 | ins(r,typetmp); 86 | return r; 87 | } 88 | string creat_lb() 89 | { 90 | count2++; 91 | //addr0++; 92 | char s[100]; 93 | string r="?lb"; 94 | var_type_t typetmp; 95 | typetmp.s="temp_label"; 96 | //typetmp.addr=addr0; 97 | sprintf(s,"%d",count2); 98 | r+=s; 99 | ins(r,typetmp); 100 | return r; 101 | } 102 | string creat_str(string text) 103 | { 104 | count4++; 105 | //addr0++; 106 | char s[100]; 107 | string r="?s"; 108 | var_type_t typetmp; 109 | typetmp.s="string_constant"; 110 | //typetmp.addr=addr0; 111 | sprintf(s,"%d",count4); 112 | r+=s; 113 | typetmp.para.push_back(text); 114 | ins(r,typetmp); 115 | return r; 116 | } 117 | string creat_arr(vector sl) 118 | { 119 | count5++; 120 | char s[100]; 121 | string r="?arr"; 122 | var_type_t typetmp; 123 | typetmp.s="array_constant"; 124 | //typetmp.addr=addr0; 125 | sprintf(s,"%d",count5); 126 | r+=s; 127 | typetmp.para=sl; 128 | ins(r,typetmp); 129 | return r; 130 | } 131 | symbol_table_t() 132 | { 133 | count=-1; 134 | count2=-1; 135 | addr0=-1; 136 | count3=-1; 137 | count4=-1; 138 | count5=-1; 139 | } 140 | int ston(string a) 141 | { 142 | int r; 143 | sscanf(a.c_str(),"%d",&r); 144 | return r; 145 | } 146 | string ntos(int a) 147 | { 148 | static char tmp[100]; 149 | sprintf(tmp,"%d",a); 150 | return tmp; 151 | } 152 | void makelist(gptr gm) 153 | { 154 | vector ::iterator it,it2; 155 | var_type_t tmptype; 156 | for(it=gm->l[0]->l.begin();it!=gm->l[0]->l.end();it++) 157 | { 158 | tmptype.clear(); 159 | tmptype.s=(*it)->l[0]->n; 160 | if((*it)->l.size()>1) 161 | { 162 | tmptype.s+="_arr"; 163 | int t=1; 164 | for(int i=1;i<(*it)->l.size();i++) 165 | { 166 | t*=ston((*it)->l[i]->n); 167 | } 168 | tmptype.n=t; 169 | } 170 | ins((*it)->n,tmptype);//加入全局变量表 171 | } 172 | for(it=gm->l[1]->l.begin();it!=gm->l[1]->l.end();it++) 173 | { 174 | tmptype.clear(); 175 | string func_name=(*it)->n; 176 | tmptype.s="function_pointer"; 177 | ins((*it)->n,tmptype); 178 | tmptype.s=(*it)->l[0]->n; 179 | tmptype.func="";//暂定.. 180 | string stmp="?r"; 181 | ins(stmp+"@"+func_name,tmptype); 182 | 183 | for(it2=(*it)->l[1]->l.begin();it2!=(*it)->l[1]->l.end();it2++) 184 | { 185 | tmptype.clear(); 186 | tmptype.s=(*it2)->l[0]->n; 187 | if((*it2)->l.size()>1) 188 | { 189 | tmptype.s+="_arr"; 190 | int t=1; 191 | for(int i=1;i<(*it2)->l.size();i++) 192 | { 193 | t*=ston((*it2)->l[i]->n); 194 | } 195 | tmptype.n=t; 196 | } 197 | tmptype.func=func_name; 198 | ins((*it2)->n+"@"+func_name,tmptype); 199 | gv.find(func_name)->second.para.push_back((*it2)->n+"@"+func_name); 200 | } 201 | for(it2=(*it)->l[2]->l.begin();it2!=(*it)->l[2]->l.end();it2++) 202 | { 203 | tmptype.clear(); 204 | tmptype.func=func_name; 205 | tmptype.s=(*it2)->l[0]->n; 206 | if((*it2)->l.size()>1) 207 | { 208 | tmptype.s+="_arr"; 209 | int t=1; 210 | for(int i=1;i<(*it2)->l.size();i++) 211 | { 212 | t*=ston((*it2)->l[i]->n); 213 | } 214 | tmptype.n=t; 215 | } 216 | ins((*it2)->n+"@"+func_name,tmptype); 217 | } 218 | } 219 | } 220 | string nowfunc; 221 | vector lb_goto; 222 | void deep(gptr gm) 223 | { 224 | int i,j,k; 225 | if(gm->n=="empty") ; 226 | else if(gm->n=="empty_statement") ; 227 | else if(gm->n=="parameter") ; 228 | else if(gm->n[0]>='0'&&gm->n[0]<='9') ; 229 | else if(gm->n[0]=='\'') ; 230 | else if(gm->n.length()>4&&gm->n[0]=='?'&&gm->n[1]=='a') ; 231 | else if(gm->n=="break"); 232 | else if(gm->n=="continue"); 233 | else if(gm->n=="block_statement"&&gm->l.size()==0) ; 234 | else if(gm->l.size()==0&&gm->n[0]=='"') 235 | { 236 | string t=creat_str(gm->n); 237 | gm->n=t; 238 | } 239 | else if(gm->n=="array_constant") 240 | { 241 | vector tmp; 242 | for(i=0;il.size();i++) 243 | { 244 | tmp.push_back(gm->l[i]->n); 245 | } 246 | string t=creat_arr(tmp); 247 | gm->n=t; 248 | } 249 | else if(gm->l.size()==0) 250 | { 251 | string t=nowfunc+"@"+gm->n; 252 | //printf("[%s]",t.c_str()); 253 | if(gv.find(gm->n+"@"+nowfunc)!=gv.end()) 254 | { 255 | gm->n=( gm->n+"@"+nowfunc ); 256 | } 257 | else if(gv.find(gm->n)!=gv.end()) 258 | { 259 | } 260 | else {printf("",gm->n.c_str());exit(-1);} 261 | } 262 | else if(gm->n=="label") 263 | { 264 | var_type_t typetmp; 265 | typetmp.s="label"; 266 | ins(gm->l[0]->n,typetmp); 267 | return ; 268 | } 269 | else if(gm->n=="goto") 270 | { 271 | lb_goto.push_back(gm->l[0]->n); 272 | 273 | return ; 274 | } 275 | for(i=0;il.size();i++) 276 | { 277 | deep(gm->l[i]); 278 | } 279 | } 280 | void replace_vb(gptr gm) 281 | { 282 | vector ::iterator it,it2; 283 | for(it=gm->l.begin();it!=gm->l.end();it++) 284 | { 285 | nowfunc=(*it)->n; 286 | //printf("<<%s>>",nowfunc.c_str()); 287 | for(it2=(*it)->l.begin();it2!=(*it)->l.end();it2++) 288 | { 289 | deep(*it2); 290 | } 291 | } 292 | for(int i=0;i",lb_goto[i].c_str());exit(-1);} 295 | } 296 | } 297 | }; 298 | 299 | struct quat_gen_t 300 | { 301 | symbol_table_t *_st; 302 | struct loop 303 | { 304 | string ctn; 305 | string brk; 306 | }; 307 | string now_func; 308 | stack loopstack; 309 | // string creat(gptr gm); 310 | vector quat; 311 | string result; 312 | void clear() 313 | { 314 | quat.clear(); 315 | } 316 | void ins(string s1,string s2,string s3,string s4) 317 | { 318 | quat_t temp; 319 | temp.s1=s1;temp.s2=s2;temp.s3=s3;temp.s4=s4; 320 | quat.push_back(temp); 321 | } 322 | void prt() 323 | { 324 | vector::iterator it; 325 | printf("\n"); 326 | printf("Quaternion:\n"); 327 | for(it=quat.begin();it!=quat.end();it++) 328 | { 329 | printf(">quat(%s,%s,%s,%s)\n",(it)->s1.c_str(),(it)->s2.c_str(),(it)->s3.c_str(),(it)->s4.c_str()); 330 | } 331 | } 332 | string creat_op(gptr gm) 333 | { 334 | //printf("<@<%s>>",gm->n.c_str()); 335 | if(gm->n=="+"||gm->n=="-"||gm->n=="*"&&gm->l.size()==2||gm->n=="/"||gm->n=="%"||gm->n==">"||gm->n=="<"||gm->n==">="||gm->n=="<=" 336 | ||gm->n=="=="||gm->n=="!="||gm->n=="&&"||gm->n=="||") 337 | { 338 | string left=creat_op(gm->l[0]); 339 | string right=creat_op(gm->l[1]); 340 | string result=_st->creat_tmp(now_func); 341 | ins(gm->n,left,right,result); 342 | return result; 343 | } 344 | if(gm->n=="!"||gm->n=="&") 345 | { 346 | string left=creat_op(gm->l[0]); 347 | string right=" "; 348 | string result=_st->creat_tmp(now_func); 349 | ins(gm->n,left,right,result); 350 | return result; 351 | } 352 | if(gm->n=="*") 353 | { 354 | string left=creat_op(gm->l[0]); 355 | string right=" "; 356 | string result=_st->creat_quo(now_func); 357 | ins(gm->n+"*",left,right,result); 358 | return result; 359 | } 360 | if(gm->n=="[]") 361 | { 362 | string left=creat_op(gm->l[0]); 363 | string right=creat_op(gm->l[1]); 364 | string result=_st->creat_quo(now_func); 365 | ins(gm->n,left,right,result); 366 | return result; 367 | } 368 | if(gm->n=="=") 369 | { 370 | string left=creat_op(gm->l[0]); 371 | string right=creat_op(gm->l[1]);; 372 | string result=left; 373 | ins(gm->n,left,right,result); 374 | return result; 375 | } 376 | if(gm->l.size()==1) 377 | { 378 | // printf("asdasd"); 379 | if(gm->l[0]->n=="parameter") 380 | return creat_ft(gm); 381 | } 382 | return gm->n; 383 | 384 | } 385 | string creat_ft(gptr gm) 386 | { 387 | vector::iterator it; 388 | vector::iterator it2; 389 | string ft_func=gm->n; 390 | string stmp="?r@"; 391 | if(_st->gv.find(ft_func)==_st->gv.end()) 392 | { 393 | printf("\n",ft_func.c_str()); 394 | exit(-1); 395 | } 396 | //printf("<<<函数调用%s 当前函数%s>>>",ft_func.c_str(),now_func.c_str()); 397 | if(gm->l[0]->l.size()!=_st->gv.find(ft_func)->second.para.size()) 398 | { 399 | //printf("<<%d %d>>",gm->l[0]->l.size(),_st->gv.find(ft_func)->second.para.size()); 400 | printf("\n",ft_func.c_str()); 401 | exit(-1); 402 | return ""; 403 | } 404 | ins("pushnow"," "," ",now_func); 405 | for(it=gm->l[0]->l.begin(),it2=_st->gv.find(ft_func)->second.para.begin();it!=gm->l[0]->l.end();it++,it2++) 406 | { 407 | string r1=creat_op(*it); 408 | ins("=",(*it2),r1,(*it2)); 409 | } 410 | ins("call"," "," ",ft_func); 411 | ins("popnow"," "," ",now_func); 412 | return stmp+ft_func; 413 | } 414 | string creat_if(gptr gm) 415 | { 416 | if(gm->l.size()==3) 417 | { 418 | //printf("asdasdasd"); 419 | string lb1=_st->creat_lb(); 420 | string lb2=_st->creat_lb(); 421 | string r1=creat_op(gm->l[0]->l[0]); 422 | ins("jpz/if-else",r1," ",lb1); 423 | creat(gm->l[1]); 424 | ins("jmp/if-else"," "," ",lb2); 425 | ins("lb/if-else"," "," ",lb1); 426 | creat(gm->l[2]); 427 | ins("lb/if-else"," "," ",lb2); 428 | return ""; 429 | } 430 | else if(gm->l.size()==2) 431 | { 432 | //printf("asdasdas"); 433 | string lb1=_st->creat_lb(); 434 | string r1=creat_op(gm->l[0]->l[0]); 435 | ins("jpz/if",r1," ",lb1); 436 | creat(gm->l[1]); 437 | ins("lb/if"," "," ",lb1); 438 | return ""; 439 | } 440 | else {printf("if parmeter incorrect\n");exit(-1);return "";} 441 | } 442 | string creat_label(gptr gm) 443 | { 444 | ins("lb"," "," ",gm->l[0]->n); 445 | return ""; 446 | } 447 | string creat_goto(gptr gm) 448 | { 449 | ins("jmp/goto"," "," ",gm->l[0]->n); 450 | return ""; 451 | } 452 | string creat_for(gptr gm) 453 | { 454 | loop lptmp; 455 | string r; 456 | string lb1=_st->creat_lb(); 457 | string lb2=_st->creat_lb(); 458 | string lb3=_st->creat_lb(); 459 | lptmp.brk=lb3; 460 | lptmp.ctn=lb2; 461 | if(gm->l[0]->n!="empty") 462 | creat_op(gm->l[0]->l[0]); 463 | ins("jmp/for"," "," ",lb1); 464 | ins("lb/for"," "," ",lb2); 465 | if(gm->l[2]->n!="empty") 466 | creat_op(gm->l[2]->l[0]); 467 | ins("lb/for"," "," ",lb1); 468 | if(gm->l[1]->n!="empty") 469 | r=creat_op(gm->l[1]->l[0]); 470 | else r="1"; 471 | ins("jpz/for",r," ",lb3); 472 | //printf(">>",gm->l[3]->n.c_str()); 473 | 474 | loopstack.push(lptmp); 475 | 476 | creat(gm->l[3]); 477 | loopstack.pop(); 478 | ins("jmp/for"," "," ",lb2); 479 | ins("lb/for"," "," ",lb3); 480 | //creat_op(gm->l[0]->l[0]); 481 | return ""; 482 | } 483 | string creat_break(gptr gm) 484 | { 485 | if(!loopstack.empty()) 486 | ins("jmp/break"," "," ",loopstack.top().brk); 487 | else {printf("incorrect break\n");exit(-1);} 488 | return ""; 489 | } 490 | string creat_continue(gptr gm) 491 | { 492 | if(!loopstack.empty()) 493 | ins("jmp/continue"," "," ",loopstack.top().ctn); 494 | else {printf("incorrect continue");exit(-1);} 495 | return ""; 496 | } 497 | string creat_return(gptr gm) 498 | { 499 | string r=creat_op(gm->l[0]->l[0]); 500 | string stemp="?r"; 501 | ins("=",stemp+"@"+now_func,r,stemp+"@"+now_func); 502 | ins("ret/return"," "," "," "); 503 | return ""; 504 | } 505 | string creat_asm(gptr gm) 506 | { 507 | ins("asm"," "," ",gm->l[0]->n); 508 | return ""; 509 | } 510 | string creat(gptr gm) 511 | { 512 | vector::iterator it; 513 | //printf("<<<%s>>>",gm->n.c_str()); 514 | string r; 515 | if(gm->n=="asm_statement") r=creat_asm(gm); 516 | if(gm->n=="for") r=creat_for(gm); 517 | if(gm->n=="if_statement") r=creat_if(gm); 518 | if(gm->n=="goto") r=creat_goto(gm); 519 | if(gm->n=="label") r=creat_label(gm); 520 | //if(gm->n=="if_statement") r=creat_if(gm); 521 | if(gm->n=="break") r=creat_break(gm); 522 | if(gm->n=="continue") r=creat_continue(gm); 523 | if(gm->n=="return") r=creat_return(gm); 524 | if(gm->n=="block_statement") 525 | { 526 | for(it=gm->l.begin();it!=gm->l.end();it++) 527 | { 528 | r=creat((*it)); 529 | } 530 | } 531 | if(gm->n=="expression_statement"||gm->n=="expression") r=creat_op(gm->l[0]); 532 | //for(it=gm->l.begin();it!=gm->l.end();it++) 533 | // { 534 | //if((*it)->n=="for") {r=creat_for((*it));} 535 | //if((*it)->n=="if_statement") {r=creat_if((*it));} 536 | //if((*it)->n=="goto") {r=creat_goto((*it)->l[0]);} 537 | //if((*it)->n=="label") {r=creat_label((*it)->l[0]);} 538 | //if((*it)->n=="empty") {r="1";} 539 | //else if(gm->n=="expression") 540 | //if((*it)->n=="expression_statement"||(*it)->n=="expression") {r=creat_op((*it)->l[0]);} 541 | //printf("%s)",(*it)->n.c_str()); 542 | //} 543 | return r; 544 | } 545 | string func(gptr gm) 546 | { 547 | int i; 548 | now_func=gm->n; 549 | ins("func"," "," ",gm->n); 550 | for(i=0;il.size();i++) 551 | creat(gm->l[i]); 552 | ins("ret/func"," "," ",gm->n); 553 | return ""; 554 | } 555 | string proc(gptr gm,symbol_table_t &st) 556 | { 557 | _st=&st; 558 | int i; 559 | //ins("call"," "," ","main"); 560 | //ins("rts"," "," "," "); 561 | for(i=0;il.size();i++) 562 | { 563 | func(gm->l[i]); 564 | } 565 | return ""; 566 | } 567 | }; 568 | 569 | int intermd_gen(gptr grammer_tree,map &gv,vector &quat) 570 | { 571 | symbol_table_t symbol_table; 572 | symbol_table.makelist(grammer_tree); 573 | if(_out)symbol_table.prt(); 574 | //if(_out) printf("trim grammer tree&&var rename\n"); 575 | symbol_table.cut_tree(grammer_tree); //trim grammer tree, remove the variable declaritions 576 | symbol_table.replace_vb(grammer_tree);//replace variales names to unique ones 577 | 578 | quat_gen_t quat_gen; //intermediate code generator 579 | quat_gen.proc(grammer_tree,symbol_table); //generate quaternions from grammer_tree and symbol_table 580 | 581 | quat=quat_gen.quat; 582 | gv=symbol_table.gv; 583 | 584 | if(_out)quat_gen.prt(); 585 | if(_out)symbol_table.prt(); 586 | if(_out)grammer_tree->prt(); 587 | } 588 | -------------------------------------------------------------------------------- /lex.cpp: -------------------------------------------------------------------------------- 1 | #include "comm.h" 2 | struct lexical_analyzer_t 3 | { 4 | int isnum(char c) //判断是否是数字 //is number 5 | { 6 | return c>='0'&&c<='9'; 7 | } 8 | int islet(char c) //判断是否是英文字母或下滑线 //is letter or underscore 9 | { 10 | return c=='_'||c>='a'&&c<='z'||c>='A'&&c<='Z'; 11 | } 12 | int issy(char c) //判断是符号 //is symbol 13 | { 14 | return c=='.'||c=='+'||c=='-'||c=='*'||c=='/'||c=='='||c=='>'||c=='<'||c=='!'||c=='|'||c=='&'||c=='%'||c=='~'||c=='('||c==')'||c=='{'||c=='}'||c==';'||c==','||c=='['||c==']'||c==':'; 15 | } 16 | int ifconstant(char *c) //如果c所指向的文本是常数,返回常数占的长度,否则返回0 17 | { 18 | int i,j,k; 19 | if(c[0]=='\"') 20 | { 21 | for(i=1;c[i]!=0;i++) 22 | { 23 | if(c[i]=='\"') {i++;break;} 24 | } 25 | return i; 26 | } 27 | if(c[0]=='\'') 28 | { 29 | for(i=1;c[i]!=0;i++) 30 | { 31 | if(c[i]=='\'') {i++;break;} 32 | } 33 | return i; 34 | } 35 | 36 | if(!isnum(c[0])) return 0; 37 | for(i=1;;i++) 38 | { 39 | if(!isnum(c[i])&&c[i]!='.') break; 40 | } 41 | if(islet(c[i])) 42 | { 43 | //printf(""); 44 | } 45 | return i; 46 | } 47 | int ifsymbol(char *c)//如果c所指向的文本是符号,返回0 48 | { 49 | int i,j,k; 50 | if(!issy(c[0])) return 0; 51 | return 1; 52 | } 53 | int ifword(char *c)//如果c所指向的文本是单词,返回单词占的长度,否则返回 (单词包括保留字和自定义字符) 54 | { 55 | int i,j,k; 56 | if(!islet(c[0])) return 0; 57 | for(i=1;;i++) 58 | { 59 | if(!isnum(c[i])&&!islet(c[i])) break; 60 | } 61 | return i; 62 | } 63 | int ifasm(char *c) 64 | { 65 | int i,j,k; 66 | if(memcmp(c,"__asm",5)!=0) return 0; 67 | return 5; 68 | } 69 | int note1(char *c) //single line comment 70 | { 71 | int i; 72 | if(memcmp(c,"//",2)==0) 73 | { 74 | for(i=2;c[i]!='\n'&&c[i]!=0;i++) ; 75 | return i; 76 | } 77 | return 0; 78 | } 79 | int note2(char *c,int &n) //multi line comment 80 | { 81 | int i; 82 | n=0; 83 | if(memcmp(c,"/*",2)==0) 84 | { 85 | for(i=1;!(c[i+1]=='*'&&c[i+2]=='/');i++) 86 | { 87 | if(c[i]=='\n') n+=1; 88 | if(c[i]==0) return i; 89 | } 90 | return i+3; 91 | } 92 | return 0; 93 | } 94 | string cut(char *c,int n)//截取c所指向的n个字符 95 | { 96 | //static char s[100*1000]; //asm token can be very large 97 | //memcpy(s,c,n); 98 | //s[n]=0; 99 | return string(c,c+n); 100 | } 101 | vector token; 102 | 103 | int run(char *s,cptr &out,vector &tok) 104 | { 105 | int i,j,k; 106 | static string output; 107 | char keyword[100][100]= 108 | { 109 | "if","else","for","break","continue","return","goto", 110 | "int","long","char","short","bool","float","double", 111 | "$end" 112 | };//关键字列表 113 | //char s[1000]; 114 | map mp; //关键字映射表 115 | //vector token; //token序列 116 | for(i=0;strcmp(keyword[i],"$end")!=0;i++) 117 | { 118 | mp[keyword[i]]=i+3; 119 | } 120 | //gets(s); 121 | int l=strlen(s); 122 | int line=0; 123 | token_t ttmp; 124 | for(i=0;i0) 128 | { 129 | ttmp.p=i; 130 | ttmp.line=line; 131 | ttmp.n=-1; 132 | //i+=r; 133 | for(j=0;;j++) 134 | { 135 | if(s[i+j]=='{') break; 136 | if(i+j==l-1) 137 | { 138 | printf("__asm token incorrect1\n"); 139 | out=""; 140 | exit(-1); 141 | } 142 | } 143 | for(k=0;;k++) 144 | { 145 | if(s[i+k]=='}'&&(s[i+k+1]=='\n'||s[i+k+1]==0)) break; 146 | if(i+k==l-1) 147 | { 148 | printf("__asm token incorrect2\n"); 149 | out=""; 150 | exit(-1); 151 | } 152 | } 153 | ttmp.s=cut(s+i+j+1,k-j-1); 154 | token.push_back(ttmp); 155 | output+='#'; 156 | i+=(k+1); 157 | //printf("<%s>",ttmp.s.c_str()); 158 | } 159 | if((r=ifsymbol(s+i))>0) //如果是分界符 160 | { 161 | int r2,n2; 162 | if((r2=note1(s+i))>0) 163 | { 164 | i+=r2; 165 | continue; 166 | } 167 | if((r2=note2(s+i,n2))>0) 168 | { 169 | i+=r2; 170 | line+=n2; 171 | continue; 172 | } 173 | ttmp.s=cut(s+i,r); 174 | ttmp.n=mp[ttmp.s]; 175 | ttmp.p=i; 176 | ttmp.line=line; 177 | token.push_back(ttmp); 178 | output+=ttmp.s.c_str()[0]; 179 | i+=r; 180 | continue; 181 | } 182 | if((r=ifconstant(s+i))>0) //如果是常量 183 | { 184 | ttmp.s=cut(s+i,r); 185 | ttmp.n=2; 186 | ttmp.p=i; 187 | ttmp.line=line; 188 | token.push_back(ttmp); 189 | if(ttmp.s.c_str()[0]=='\"') 190 | output+='$'; //字符串常量 191 | else output+='@';//普通常量 192 | 193 | i+=r; 194 | continue; 195 | } 196 | if((r=ifword(s+i))>0) //如果是单词 197 | { 198 | ttmp.s=cut(s+i,r); 199 | ttmp.n=mp[ttmp.s]; 200 | ttmp.p=i; 201 | //printf("<%s>",ttmp.s.c_str()); 202 | ttmp.line=line; 203 | if(ttmp.n==0) 204 | { 205 | ttmp.n=1; 206 | output+='w'; 207 | } 208 | else 209 | { 210 | if(ttmp.s=="int"||ttmp.s=="long") output+='l'; 211 | else if(ttmp.s=="char"||ttmp.s=="bool"||ttmp.s=="short") output+='l'; 212 | else if(ttmp.s=="double"||ttmp.s=="float") output+='d'; 213 | else output+=ttmp.s.c_str()[0]; 214 | } 215 | token.push_back(ttmp); 216 | i+=r; 217 | continue; 218 | } 219 | if(s[i]==' '||s[i]==' ') {i++;continue;} 220 | if(s[i]=='\n') {i+=1;line+=1;/*output+='\n';*/continue;} 221 | printf("\n",(int)s[i]); 222 | exit(-1); 223 | output+='?'; 224 | i++; 225 | } 226 | /*printf("%s\n",output.c_str()); 227 | for(;;) 228 | { 229 | getchar(); 230 | }*/ 231 | tok=token; 232 | //out=new char[1000*1000]; 233 | //strcpy(out,output.c_str()); 234 | out=(char*)output.c_str(); 235 | return 0; 236 | } 237 | }; 238 | 239 | int lexical_analyze(char *s,cptr &out,vector &tok) 240 | { 241 | lexical_analyzer_t lexical_analyzer; 242 | lexical_analyzer.run(s,out,tok); 243 | return 0; 244 | } 245 | -------------------------------------------------------------------------------- /lib.platform/bin/_io.h: -------------------------------------------------------------------------------- 1 | #include 2 | int putc(char a) 3 | { 4 | __asm 5 | { 6 | mov eax,[a@putc] 7 | mov dl,al 8 | MOV AH,02H 9 | INT 21H 10 | } 11 | 12 | } 13 | 14 | char getc() 15 | { 16 | char a; 17 | __asm 18 | { 19 | xor eax,eax 20 | mov ah,01h 21 | int 21h 22 | xor ah,ah 23 | mov [a@getc],eax 24 | } 25 | if(a==13) return 10; // in dos "enter" produces \r (no \n) 26 | if(a==3) exit(255); //dos doesn't recongize ctrl-c, we need a way to quit 27 | return a; 28 | } 29 | -------------------------------------------------------------------------------- /lib.platform/bin/sys.h: -------------------------------------------------------------------------------- 1 | int exit(int a) 2 | { 3 | __asm 4 | { 5 | mov ah,0x4c 6 | int 21h 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib.platform/elf32/_io.h: -------------------------------------------------------------------------------- 1 | int putc(char a) 2 | { 3 | __asm 4 | { 5 | mov eax,4 6 | mov ebx,1 7 | mov ecx,[a@putc] 8 | push ecx 9 | mov ecx,esp 10 | mov edx,1 11 | int 80h 12 | add esp, 4 13 | } 14 | 15 | } 16 | 17 | char getc() 18 | { 19 | char a; 20 | a=0; 21 | __asm 22 | { 23 | mov eax, 3 ;the syscall num of "read()" on linux 24 | mov ebx, 0 ;read from stdin, 0 is the fd of stdin 25 | mov ecx, a@getc ;save the result to the address of variable "a" inside function "getc" 26 | mov edx, 1 ;read 1 character 27 | int 0x80 28 | } 29 | return a; 30 | } 31 | -------------------------------------------------------------------------------- /lib.platform/elf32/sys.h: -------------------------------------------------------------------------------- 1 | int exit(int a) 2 | { 3 | __asm 4 | { 5 | mov eax,1 6 | mov ebx,[a@exit] 7 | int 0x80 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /lib.platform/win32/_io.h: -------------------------------------------------------------------------------- 1 | int putc(char a) 2 | { 3 | /* 4 | __asm 5 | { 6 | extern _putchar 7 | push eax 8 | call _putchar 9 | add esp, 4 10 | }*/ 11 | int buffer2[2]; 12 | __asm 13 | { 14 | extern _GetStdHandle@4 15 | extern _WriteConsoleA@20 16 | push -11 17 | call _GetStdHandle@4 18 | push 0 19 | push arr?buffer2@putc 20 | push 1 21 | push a@putc 22 | push eax 23 | call _WriteConsoleA@20 24 | } 25 | 26 | 27 | } 28 | 29 | char getc() 30 | { 31 | /* 32 | int a; 33 | __asm 34 | { 35 | extern _getchar 36 | call _getchar 37 | mov [a@getc],eax 38 | }*/ 39 | char a; 40 | int buffer2[2]; 41 | a=0; 42 | __asm 43 | { 44 | extern _GetStdHandle@4 45 | extern _ReadConsoleA@20 46 | push -10 47 | call _GetStdHandle@4 48 | 49 | push 0 50 | push arr?buffer2@getc 51 | push 1 52 | push a@getc 53 | push eax 54 | call _ReadConsoleA@20 55 | } 56 | if(a==13) {getc();return 10;} //on windows "enter" produces \r\n .. 57 | return a; 58 | } 59 | -------------------------------------------------------------------------------- /lib.platform/win32/sys.h: -------------------------------------------------------------------------------- 1 | int exit(int a) 2 | { 3 | __asm 4 | { 5 | extern _ExitProcess@4 6 | mov eax,[a@exit] 7 | push eax 8 | call _ExitProcess@4 9 | } 10 | 11 | 12 | } 13 | 14 | -------------------------------------------------------------------------------- /lib/io.h: -------------------------------------------------------------------------------- 1 | #include <_io.h> 2 | #include 3 | int newline() 4 | { 5 | putc(10); 6 | } 7 | int putb(int a) 8 | { 9 | int i; 10 | int tmp; 11 | int arr[40]; 12 | if(a<0) 13 | { 14 | arr[0]='1'; 15 | /* 16 | __asm 17 | { 18 | mov eax,[a@putb] 19 | and eax,7fffffffh 20 | mov [a@putb],eax 21 | }*/ 22 | a=and(a,2147483647); //and with 7fffffffh 23 | } 24 | else arr[0]='0'; 25 | for(i=0;i<31;i=i+1) 26 | { 27 | tmp=a%2; 28 | a=a/2; 29 | arr[31-i]=tmp+48; 30 | } 31 | for(i=0;i<32;i=i+1) 32 | putc(arr[i]); 33 | } 34 | 35 | int put32(int a) 36 | { 37 | int b;int c;int d; 38 | if(a==0) {putc('0');return 0;} 39 | d=a; 40 | c=0; 41 | if(a<0) {putc('-');a=0-a;d=0-d;} 42 | for(;;) 43 | { 44 | if(c==0) c=1; 45 | else c=c*10; 46 | a=a/10; 47 | if(a==0) break; 48 | } 49 | a=d; 50 | for(;;) 51 | { 52 | if(c==0) break; 53 | putc(a/c+48); 54 | a=a-(a/c)*c; 55 | c=c/10; 56 | 57 | } 58 | return 0; 59 | } 60 | 61 | int get32() 62 | { 63 | int a[100]; 64 | int i;int sign;int rr; 65 | rr=0; 66 | i=0; 67 | gets(a); 68 | if(a[0]==0) return 0; 69 | sign=1; 70 | if(a[i]=='+') {sign=1;i=i+1;} 71 | else if(a[i]=='-') {sign=0-1;i=i+1;} 72 | for(;a[i]>='0'&&a[i]<='9';i=i+1) 73 | { 74 | rr=rr*10; 75 | rr=rr+(a[i]-'0'); 76 | } 77 | return sign*rr; 78 | } 79 | int puts(char * a) 80 | { 81 | int i; 82 | for(i=0;a[i]!=0;i=i+1) 83 | { 84 | putc(a[i]); 85 | } 86 | } 87 | int gets(char *a) 88 | { 89 | int i; 90 | for(i=0;;i=i+1) 91 | { 92 | a[i]=getc(); 93 | if(a[i]==10/*||a[i]==13*/) {a[i]=0;break;} 94 | } 95 | } 96 | /* 97 | int new(int a) 98 | { 99 | __asm 100 | { 101 | mov eax,a@new 102 | mov bx,ax 103 | mov ah,48h 104 | int 21h 105 | jnc line@a; 106 | } 107 | puts("error"); 108 | __asm 109 | { 110 | line@a: 111 | } 112 | }*/ 113 | -------------------------------------------------------------------------------- /lib/mem.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangyu-/mycc/72e5869845c61862493a04935e3ace6f23303433/lib/mem.h -------------------------------------------------------------------------------- /lib/op.h: -------------------------------------------------------------------------------- 1 | int and(int a,int b) 2 | { 3 | int r; 4 | __asm 5 | { 6 | mov eax,[a@and] 7 | and eax,[b@and] 8 | mov [r@and],eax 9 | } 10 | return r; 11 | } 12 | 13 | int xor(int a,int b) 14 | { 15 | int r; 16 | __asm 17 | { 18 | mov eax,[a@and] 19 | xor eax,[b@and] 20 | mov [r@and],eax 21 | } 22 | return r; 23 | } 24 | 25 | int or(int a,int b) 26 | { 27 | int r; 28 | __asm 29 | { 30 | mov eax,[a@and] 31 | or eax,[b@and] 32 | mov [r@and],eax 33 | } 34 | return r; 35 | } 36 | -------------------------------------------------------------------------------- /lib/rand.h: -------------------------------------------------------------------------------- 1 | int g_rand_seed; 2 | int srand(int seed) 3 | { 4 | g_rand_seed=seed; 5 | } 6 | int rand() 7 | { 8 | g_rand_seed=g_rand_seed*214013 +2531011; 9 | g_rand_seed=and(g_rand_seed/65536,32767); 10 | return g_rand_seed; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /lib/sort.h: -------------------------------------------------------------------------------- 1 | int swap(int *a,int *b) 2 | { 3 | int t; 4 | t=*a;*a=*b;*b=t; 5 | } 6 | int sort_partition(int* a,int p,int rr) 7 | { 8 | int i; 9 | int j;int x; 10 | int t; 11 | i=p;j=rr+1; 12 | x=a[p]; 13 | for(;;) 14 | { 15 | i=i+1; 16 | for(;a[i]x;) j=j-1; 19 | if(i>=j) break; 20 | t=a[i];a[i]=a[j];a[j]=t; 21 | } 22 | a[p]=a[j]; 23 | a[j]=x; 24 | return j; 25 | 26 | } 27 | int sort(int *a,int p,int r) 28 | { 29 | __sort(a,p,r-1); 30 | } 31 | int __sort(int * a,int p,int rr) 32 | { 33 | int _q; 34 | if(p 2 | //#include 3 | #include "comm.h" 4 | #include "mycc.h" 5 | using namespace std; 6 | 7 | void print_help() 8 | { 9 | printf("usage:\n./this_program token;//token 36 | char *token_s;//char stream of token 37 | lexical_analyze(code_s,token_s,token);//lexical analysis, generate token_s and token 38 | if(_out) printf("result of lexical analysis:%s\n",token_s); 39 | //====step3 syntax_analyze==== 40 | map asm_table; //table of embedded asm code 41 | gptr grammer_tree; //grammer tree 42 | syntax_analyze(token_s,token,grammer_tree,asm_table); 43 | //====step4 gen intermediate representation==== 44 | map var_table; //variable table 45 | vector quaternions; //quaternions representation of code 46 | intermd_gen(grammer_tree,var_table,quaternions); 47 | //====step5 gen asm code==== 48 | asm_code_gen(asm_table,var_table,quaternions,asm_format,"output.asm"); 49 | 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /mycc.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "comm.h" 3 | string getcode(asm_format_t asm_format); 4 | int lexical_analyze(char *s,cptr &out,vector &tok); 5 | int syntax_analyze(char *s,const vector &token_in,gptr &gm, map &asm_mp); 6 | int intermd_gen(gptr grammer_tree,map &gv,vector &quat); 7 | int asm_code_gen(const map &asmmp,const map &vb,const vector &quat,asm_format_t asm_format,string output_name); 8 | -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | asm_format=`head -n1 output.asm |sed 's/;;format: //'` 3 | if [ "$asm_format" = "bin" ]; then 4 | nasm -f bin output.asm -o output.exe 5 | dosbox -c "mount c ." -c "c:" -c "output.exe" 6 | elif [ "$asm_format" = "elf32" ]; then 7 | nasm -f elf32 output.asm 8 | ld -m elf_i386 output.o -o output 9 | ./output 10 | elif [ "$asm_format" = "win32" ]; then 11 | nasm -f win32 output.asm 12 | ld -m i386pe output.obj kernel32.dll -o output32.exe #to run this you need a copy of your kernel32.dll, typically from C:\Windows\SysWOW64\kernel32.dll 13 | #i686-w64-mingw32-gcc output.obj -o output32.exe 14 | #./GoLink.exe /console output.obj kernel32.dll 15 | wine output32.exe 16 | stty sane 17 | else 18 | echo "error: unknown format $asm_format" 19 | fi; 20 | -------------------------------------------------------------------------------- /syntax.cpp: -------------------------------------------------------------------------------- 1 | #include "comm.h" 2 | struct syntax_analyzer_t 3 | { 4 | vector token; //token from lexical_analyzer 5 | char * _s0; //original char begining for input s 6 | int asm0; //counter to generate name for asm block 7 | map asm_mp; //table for embedded asm code 8 | 9 | syntax_analyzer_t() 10 | { 11 | asm0=-1; 12 | } 13 | 14 | string gen_asm() 15 | { 16 | asm0++; 17 | char tmp[100]; 18 | sprintf(tmp,"%d",asm0); 19 | string r="?asm"; 20 | return r+tmp; 21 | } 22 | /////////////////////////////// 23 | int rd(cptr &s,char c) 24 | { 25 | if(*s==c) {s+=1;return 1;} 26 | return 0; 27 | } 28 | int rd(cptr &s,char *c,int &t) 29 | { 30 | int l=strlen(c); 31 | if(memcmp(s,c,l)==0) {s+=l;t=l;return 1;} 32 | return 0; 33 | } 34 | int rd(cptr &s,char *c,string &t) 35 | { 36 | int l=strlen(c); 37 | t=c; 38 | if(memcmp(s,c,l)==0) {s+=l;return 1;} 39 | return 0; 40 | } 41 | int rd(cptr &s,char *c) 42 | { 43 | int l=strlen(c); 44 | if(memcmp(s,c,l)==0) {s+=l;return 1;} 45 | return 0; 46 | } 47 | int okop/*表达式语句*/(cptr &s,gptr &g) //expression_statement 48 | { 49 | g=new grammar_t; 50 | gptr gt; 51 | g->n="expression_statement"; 52 | cptr t=s; 53 | if(okS(s,gt)) 54 | if( rd(s,';') ) 55 | { 56 | g->l.push_back(gt); 57 | return 1; 58 | } 59 | s=t;return 0; 60 | } 61 | int tb/*变量声明区*/(cptr &s,gptr &g) //variable declare zone 62 | { 63 | g=new grammar_t; 64 | g->n="var_declare_zone"; 65 | gptr gt; 66 | while(okts(s,gt)) {g->l.push_back(gt);} 67 | return 1; 68 | } 69 | int fb/*函数区*/(cptr &s,gptr &g) // function zone 70 | { 71 | g=new grammar_t; 72 | g->n="function_zone"; 73 | gptr gt; 74 | while(okfs(s,gt)) {g->l.push_back(gt);} 75 | return 1; 76 | } 77 | int okif/*if语句*/(cptr &s,gptr &g) //if statement 78 | { 79 | cptr t=s; 80 | g=new grammar_t;gptr gt; 81 | g->n="if_statement"; 82 | if(rd(s,'i')) 83 | if(rd(s,'(')) 84 | if(okS(s,gt)) 85 | { 86 | gptr g2=new grammar_t;g2->n="expression";g->l.push_back(g2);g2->l.push_back(gt); 87 | //g->l.push_back(gt); 88 | //运算语句 89 | if(rd(s,')')) 90 | if(oks(s,gt)) 91 | { 92 | g->l.push_back(gt); 93 | cptr t2=s; 94 | if(rd(s,'e')) 95 | if(oks(s,gt)) 96 | { 97 | g->l.push_back(gt); 98 | return 1; 99 | } 100 | s=t2;return 1; 101 | } 102 | } 103 | s=t;return 0; 104 | } 105 | int okfor/*for语句*/(cptr &s,gptr &g) // for statement 106 | { 107 | cptr t=s; 108 | gptr gt; 109 | g=new grammar_t; 110 | g->n="for"; 111 | if(rd(s,"f(")) 112 | { 113 | if(okS(s,gt)){gptr g2=new grammar_t;g2->n="expression";g->l.push_back(g2);g2->l.push_back(gt);} 114 | else {gptr g2=new grammar_t;g2->n="empty";g->l.push_back(g2);} 115 | if(rd(s,';')) 116 | { 117 | if(okS(s,gt)) {gptr g2=new grammar_t;g2->n="expression";g->l.push_back(g2);g2->l.push_back(gt);} 118 | else {gptr g2=new grammar_t;g2->n="empty";g->l.push_back(g2);} 119 | if(rd(s,';')) 120 | { 121 | if(okS(s,gt)) {gptr g2=new grammar_t;g2->n="expression";g->l.push_back(g2);g2->l.push_back(gt);} 122 | else {gptr g2=new grammar_t;g2->n="empty";g->l.push_back(g2);} 123 | if(rd(s,')')) 124 | { 125 | if(oks(s,gt)){g->l.push_back(gt); return 1;} 126 | } 127 | } 128 | } 129 | } 130 | s=t;return 0; 131 | } 132 | int okms(cptr &s,gptr &g) //code block 133 | { 134 | cptr t=s; 135 | g=new grammar_t; 136 | g->n="block_statement"; 137 | gptr gt; 138 | if(rd(s,'{')) 139 | { 140 | while(oks(s,gt)) g->l.push_back(gt); 141 | if(rd(s,'}')) return 1; 142 | } 143 | s=t;return 0; 144 | } 145 | int okre(cptr &s,gptr &g)//return 146 | { 147 | cptr t=s; 148 | gptr gt; 149 | g=new grammar_t; 150 | g->n="return"; 151 | if(rd(s,'r')) 152 | { 153 | 154 | if(okS(s,gt)) 155 | { 156 | gptr g2=new grammar_t; 157 | g2->n="expression"; 158 | g2->l.push_back(gt); 159 | g->l.push_back(g2); 160 | if(rd(s,';')) 161 | return 1; 162 | } 163 | } 164 | s=t; 165 | return 0; 166 | } 167 | int okctn(cptr &s,gptr &g)//continue 168 | { 169 | cptr t=s; 170 | gptr gt; 171 | g=new grammar_t; 172 | g->n="continue"; 173 | if(rd(s,'c')) 174 | { 175 | if(rd(s,';')) 176 | return 1; 177 | } 178 | s=t; 179 | return 0; 180 | } 181 | int okbrk(cptr &s,gptr &g)//break 182 | { 183 | cptr t=s; 184 | gptr gt; 185 | g=new grammar_t; 186 | g->n="break"; 187 | if(rd(s,'b')) 188 | { 189 | if(rd(s,';')) 190 | return 1; 191 | } 192 | s=t; 193 | return 0; 194 | } 195 | int oklb(cptr &s,gptr &g)//label 196 | { 197 | cptr t=s; 198 | g=new grammar_t; 199 | g->n="label"; 200 | gptr g1; 201 | g1=new grammar_t; 202 | // g1->n=token[s-_s0].s; //原位置 有bug 203 | //g->l.push_back(g1); 204 | if(rd(s,'w')) 205 | if(rd(s,':')) 206 | { 207 | g1->n=token[s-_s0-1-1].s; 208 | g->l.push_back(g1); 209 | return 1; 210 | } 211 | s=t;return 0; 212 | } 213 | int okgt(cptr &s,gptr &g)//goto 214 | { 215 | cptr t=s; 216 | g=new grammar_t; 217 | g->n="goto"; 218 | gptr g1; 219 | g1=new grammar_t; 220 | 221 | if(rd(s,'g')) 222 | { 223 | g1->n=token[s-_s0].s; 224 | g->l.push_back(g1); 225 | if(rd(s,'w')) 226 | { 227 | if(rd(s,';')) 228 | return 1; 229 | } 230 | 231 | } 232 | s=t;return 0; 233 | } 234 | int okasm(cptr &s,gptr &g)//embed asm 235 | { 236 | cptr t=s; 237 | g=new grammar_t; 238 | g->n="asm_statement"; 239 | gptr g2; 240 | if(rd(s,'#')) 241 | { 242 | string t1=gen_asm(); 243 | g2=new grammar_t; 244 | g2->n=t1; 245 | g->l.push_back(g2); 246 | string t2=token[s-_s0-1].s; 247 | asm_mp.insert(pair(t1,t2)); 248 | return 1; 249 | } 250 | s=t;return 0; 251 | } 252 | int oks(cptr &s,gptr &g)//statement 253 | { 254 | cptr t=s; 255 | g=new grammar_t; 256 | g->n="undecided_statement"; 257 | gptr gt; 258 | if(okasm(s,gt)){g=gt;return 1;} 259 | if(oklb(s,gt)) {g=gt;return 1;} 260 | if(okgt(s,gt)) {g=gt;return 1;} 261 | if(okif(s,gt)) {g=gt;return 1;}//if语句 262 | if(okfor(s,gt)){g=gt;return 1;}//for语句 263 | 264 | if(okop(s,gt)) {g=gt;return 1;} 265 | if(okms(s,gt)) {g=gt;return 1;} 266 | if(okre(s,gt)) {g=gt;return 1;} 267 | if(okctn(s,gt)){g=gt;return 1;} 268 | if(okbrk(s,gt)){g=gt;return 1;} 269 | if(rd(s,';')){g=new grammar_t;g->n="empty_statement";return 1;} 270 | s=t; 271 | return 0; 272 | } 273 | int sb/*语句区*/(cptr &s,gptr &g) //statement zone 274 | { 275 | 276 | cptr t=s; 277 | gptr gt; 278 | g=new grammar_t; 279 | g->n="statement_zone"; 280 | while(oks(s,gt)) g->l.push_back(gt); 281 | 282 | return 1; 283 | } 284 | int okproc/*程序*/(cptr &s,gptr &g) //the whole program 285 | { 286 | cptr t=s; 287 | gptr gt; 288 | g=new grammar_t; 289 | g->n="program"; 290 | //line1: 291 | // int sign=0; 292 | if(tb(s,gt)) {g->l.push_back(gt);} 293 | if(fb(s,gt)) {g->l.push_back(gt);} 294 | line1: 295 | int sign=0; 296 | if(tb(s,gt)) 297 | { 298 | if(gt->l.size())sign=1; 299 | for(int i=0;il.size();i++) 300 | g->l[0]->l.push_back(gt->l[i]); 301 | } 302 | if(fb(s,gt)) 303 | { 304 | if(gt->l.size())sign=1; 305 | for(int i=0;il.size();i++) 306 | g->l[1]->l.push_back(gt->l[i]); 307 | } 308 | if(sign) goto line1; 309 | 310 | //if(okft(s,gt)) g->l.push_back(gt); 311 | return 1; 312 | } 313 | int okfe/*变量声明*/(cptr &s,gptr &g) //variable declare zone 314 | { 315 | cptr t=s; 316 | gptr gt,gt1; 317 | if(okt(s,gt)) 318 | { 319 | gt1=gt; 320 | if(okse(s,gt)) 321 | { 322 | g=gt;g->l.push_back(gt1); 323 | while(rd(s,"[@]")) 324 | { 325 | gt1=new grammar_t; 326 | gt1->n=token[s-_s0-2].s; 327 | g->l.push_back(gt1); 328 | } 329 | return 1; 330 | } 331 | } 332 | s=t;g=0;return 0; 333 | } 334 | int okfl/*函数参数表*/(cptr &s,gptr &g) //function parameter list 335 | { 336 | cptr t=s; 337 | gptr gt; 338 | g=new grammar_t; 339 | g->n="parameter_list"; 340 | if(okfe(s,gt)) 341 | { 342 | g->l.push_back(gt); 343 | while(rd(s,',')) 344 | { 345 | if(okfe(s,gt)){g->l.push_back(gt);continue;} 346 | s-=1;break; 347 | } 348 | return 1; 349 | } 350 | s=t;return 1;//一定能接受 351 | } 352 | int okfs/*函数*/(cptr &s,gptr &g) //function 353 | { 354 | cptr t=s; 355 | g=new grammar_t;gptr gt; 356 | //g->n="function"; 357 | if(okt(s,gt)) 358 | { 359 | g->l.push_back(gt); 360 | if(rd(s,'w')) 361 | { 362 | g->n=token[s-_s0-1].s; 363 | if(rd(s,'(')) 364 | if(okfl(s,gt)) 365 | { 366 | g->l.push_back(gt); 367 | if(rd(s,')')) 368 | { 369 | if(rd(s,'{')) 370 | { 371 | if(tb(s,gt)) g->l.push_back(gt); 372 | if(sb(s,gt)) g->l.push_back(gt); 373 | if(rd(s,'}')) 374 | return 1; 375 | } 376 | } 377 | } 378 | } 379 | } 380 | s=t;return 0; 381 | } 382 | int okt/*数据类型*/(cptr &s,gptr &g) //data type 383 | { 384 | cptr t=s; 385 | gptr gt; 386 | g=new grammar_t; 387 | if(rd(s,'l')){while(rd(s,'*')); g->n="int";return 1;}//忽略掉所有* 388 | s=t;return 0; 389 | } 390 | int okse/*变量名*/(cptr &s,gptr &g)//variable name 391 | { 392 | cptr t=s; 393 | gptr gt; 394 | g=new grammar_t; 395 | g->n=token[int(s-_s0)].s; 396 | if(rd(s,'w')) {return 1;} 397 | s=t;return 0; 398 | } 399 | int okts/*变量声明*/(cptr &s,gptr &g)//variable declare 400 | { 401 | cptr t=s; 402 | gptr gt,gt1; 403 | if(okt(s,gt)) 404 | { 405 | gt1=gt; 406 | if(okse(s,gt)) 407 | { 408 | g=gt;g->l.push_back(gt1); 409 | while(rd(s,"[@]")) 410 | { 411 | gt1=new grammar_t; 412 | gt1->n=token[s-_s0-2].s; 413 | g->l.push_back(gt1); 414 | } 415 | if(rd(s,';')){ return 1;} 416 | } 417 | } 418 | s=t;g=0;return 0; 419 | } 420 | 421 | 422 | int okft/*函数调用*/(cptr &s,gptr &g)//function call 423 | { 424 | cptr t=s; 425 | gptr gt; 426 | g=new grammar_t; 427 | if(rd(s,'w')) 428 | { 429 | g->n=token[s-_s0-1].s; 430 | if(rd(s,'(')) 431 | if(okftl(s,gt))//参数表 432 | { 433 | g->l.push_back(gt); 434 | if(rd(s,')')) 435 | return 1; 436 | } 437 | } 438 | s=t;return 0; 439 | } 440 | int okftl/*函数调用参数表*/(cptr &s,gptr &g)//function call parameter list 441 | { 442 | cptr t=s; 443 | gptr gt; 444 | g=new grammar_t; 445 | g->n="parameter"; 446 | if(okS(s,gt)) 447 | { 448 | g->l.push_back(gt); 449 | while(rd(s,',')) 450 | { 451 | if(okS(s,gt)) {g->l.push_back(gt);continue;}//函数调用是表达式 452 | s-=1;break; 453 | } 454 | return 1; 455 | } 456 | g->c();g->n="parameter";s=t;return 1;//肯定会接受 457 | } 458 | 459 | 460 | int okS/*&&||*/(cptr &s,gptr &g) 461 | { 462 | cptr t=s; 463 | gptr gt,g1,g2; 464 | string o; 465 | if(okA(s,gt)) 466 | { 467 | gptr g1=gt; 468 | while(rd(s,"||",o)||rd(s,"&&",o)) 469 | { 470 | if(okA(s,gt)) 471 | { 472 | g2=new grammar_t; 473 | g2->n=o; 474 | g2->l.push_back(g1); 475 | g2->l.push_back(gt); 476 | g1=g2; 477 | continue; 478 | } 479 | s-=o.length();break; 480 | } 481 | g=g1; 482 | return 1; 483 | } 484 | s=t;return 0; 485 | } 486 | int okA_notused/*=*/(cptr &s,gptr &g) //left associate version 487 | { 488 | cptr t=s; 489 | gptr gt,g1,g2; 490 | string o; 491 | if(okE(s,gt)) 492 | { 493 | gptr g1=gt; 494 | while(rd(s,"=",o)) 495 | { 496 | if(okE(s,gt)) 497 | { 498 | g2=new grammar_t; 499 | g2->n=o; 500 | g2->l.push_back(g1); 501 | g2->l.push_back(gt); 502 | g1=g2; 503 | continue; 504 | } 505 | s-=o.length();break; 506 | } 507 | g=g1; 508 | return 1; 509 | } 510 | s=t;return 0; 511 | } 512 | int okA/*=*/(cptr &s,gptr &g) //right associate version 513 | { 514 | cptr t=s; 515 | gptr gt,g1,g2; 516 | string o; 517 | if(okE(s,gt)) 518 | { 519 | gptr g1=gt; 520 | if(rd(s,"=",o)) 521 | { 522 | if(okA(s,gt)) 523 | { 524 | g2=new grammar_t; 525 | g2->n=o; 526 | g2->l.push_back(g1); 527 | g2->l.push_back(gt); 528 | g=g2; 529 | return 1; 530 | } 531 | } 532 | else 533 | { 534 | g=gt; 535 | return 1; 536 | } 537 | } 538 | s=t;return 0; 539 | } 540 | int okE/*== !=*/(cptr &s,gptr &g) 541 | { 542 | cptr t=s; 543 | gptr gt,g1,g2; 544 | string o; 545 | if(okF(s,gt)) 546 | { 547 | gptr g1=gt; 548 | while(rd(s,"==",o)||rd(s,"!=",o)) 549 | { 550 | if(okF(s,gt)) 551 | { 552 | g2=new grammar_t; 553 | g2->n=o; 554 | g2->l.push_back(g1); 555 | g2->l.push_back(gt); 556 | g1=g2; 557 | continue; 558 | } 559 | s-=o.length();break; 560 | } 561 | g=g1; 562 | return 1; 563 | } 564 | s=t;return 0; 565 | } 566 | int okF/*<><=>=*/(cptr &s,gptr &g) 567 | { 568 | cptr t=s; 569 | gptr gt,g1,g2; 570 | string o; 571 | if(okH(s,gt)) 572 | { 573 | gptr g1=gt; 574 | while(rd(s,"<=",o)||rd(s,">=",o)||rd(s,"<",o)||rd(s,">",o)) 575 | { 576 | if(okH(s,gt)) 577 | { 578 | g2=new grammar_t; 579 | g2->n=o; 580 | g2->l.push_back(g1); 581 | g2->l.push_back(gt); 582 | g1=g2; 583 | continue; 584 | } 585 | s-=o.length();break; 586 | } 587 | g=g1; 588 | return 1; 589 | } 590 | s=t;return 0; 591 | } 592 | int okH/*+-*/(cptr &s,gptr &g) 593 | { 594 | cptr t=s; 595 | gptr gt,g1,g2; 596 | string o; 597 | if(okI(s,gt)) 598 | { 599 | gptr g1=gt; 600 | while(rd(s,"+",o)||rd(s,"-",o)) 601 | { 602 | if(okI(s,gt)) 603 | { 604 | g2=new grammar_t; 605 | g2->n=o; 606 | g2->l.push_back(g1); 607 | g2->l.push_back(gt); 608 | g1=g2; 609 | continue; 610 | } 611 | s-=o.length();break; 612 | } 613 | g=g1; 614 | return 1; 615 | } 616 | s=t;return 0; 617 | } 618 | int okI/** /%*/(cptr &s,gptr &g) 619 | { 620 | cptr t=s; 621 | gptr gt,g1,g2; 622 | string o; 623 | if(okJ(s,gt)) 624 | { 625 | gptr g1=gt; 626 | while(rd(s,"*",o)||rd(s,"/",o)||rd(s,"%",o)) 627 | { 628 | if(okJ(s,gt)) 629 | { 630 | g2=new grammar_t; 631 | g2->n=o; 632 | g2->l.push_back(g1); 633 | g2->l.push_back(gt); 634 | g1=g2; 635 | continue; 636 | } 637 | s-=o.length();break; 638 | } 639 | g=g1; 640 | return 1; 641 | } 642 | s=t;return 0; 643 | } 644 | int okJ/*!&*-*/(cptr &s,gptr &g) 645 | { 646 | gptr gt,g1,g2; 647 | cptr t=s; 648 | string o; 649 | if(rd(s,"!",o)||rd(s,"&",o)||rd(s,"*",o)||rd(s,"-",o)) 650 | if(okL(s,gt)) 651 | { 652 | g=new grammar_t; 653 | g->n=o; 654 | if(o=="-") 655 | { 656 | g1=new grammar_t; 657 | g1->n="0"; 658 | g->l.push_back(g1); 659 | } 660 | g->l.push_back(gt); 661 | return 1; 662 | } 663 | s=t; 664 | return okL(s,g); 665 | } 666 | int okL_notused/*[]*/(cptr &s,gptr &g) //old 667 | { 668 | gptr gt,gt2,g1,g2; 669 | cptr t=s; 670 | string o; 671 | if(okZ(s,gt)) 672 | { 673 | if(rd(s,'[')) 674 | if(okS(s,gt2)) 675 | if(rd(s,']')) 676 | { 677 | g=new grammar_t; 678 | g->n="[]"; 679 | g->l.push_back(gt); 680 | g->l.push_back(gt2); 681 | return 1; 682 | } 683 | } 684 | s=t; 685 | return okZ(s,g); 686 | } 687 | int okL/*[]*/(cptr &s,gptr &g) //support multi array 688 | { 689 | gptr gt,gt2,g1,g2; 690 | cptr t=s; 691 | string o; 692 | if(okZ(s,gt)) 693 | { 694 | gptr g1=gt; 695 | while(rd(s,"[",o)) 696 | { 697 | cptr t2=s; 698 | if(okS(s,gt)&&rd(s,']')) 699 | { 700 | g2=new grammar_t; 701 | g2->n="[]"; 702 | g2->l.push_back(g1); 703 | g2->l.push_back(gt); 704 | g1=g2; 705 | } 706 | else 707 | { 708 | s=t2;//recover okS + "]" 709 | s-=o.length();//recover "[" 710 | break; 711 | } 712 | } 713 | g=g1; 714 | return 1; 715 | } 716 | s=t; 717 | return 0; 718 | } 719 | int okZ(cptr &s,gptr &g)//terminate elements, or expression inside parenthesis 720 | { 721 | g=new grammar_t; 722 | cptr t=s; 723 | gptr gt; 724 | if(rd(s,'@')) {g->n=token[s-_s0-1].s;return 1;} //number 725 | if(rd(s,'$')) {g->n=token[s-_s0-1].s;return 1;} //char const 726 | if(rd(s,'(')) //expression inside operator 727 | if(okS(s,gt)) 728 | if(rd(s,')')) 729 | { 730 | g=gt; 731 | return 1; 732 | } 733 | s=t; 734 | if(okft(s,gt)) {g=gt;return 1;} //function call 735 | if(rd(s,'w')) {g->n=token[s-_s0-1].s;return 1;} //variable name 736 | s=t; 737 | if(okZZ(s,gt)) {g=gt;return 1;} //array constant 738 | s=t;return 0; 739 | } 740 | int okZZ(cptr &s,gptr &g)//array constant 741 | { 742 | cptr t=s; 743 | gptr g1; 744 | g=new grammar_t; 745 | g->n="array_constant"; 746 | if(rd(s,'{')) 747 | if(rd(s,'@')) 748 | { 749 | g1=new grammar_t; 750 | g1->n=token[s-_s0-1].s; 751 | g->l.push_back(g1); 752 | while(rd(s,",@")) 753 | { 754 | g1=new grammar_t; 755 | g1->n=token[s-_s0-1].s; 756 | g->l.push_back(g1); 757 | } 758 | if(rd(s,'}')) 759 | return 1; 760 | } 761 | s=t;return 0; 762 | } 763 | int prt(gptr g,int n=0) 764 | { 765 | int i,j; 766 | for(j=0;jn.c_str()); 768 | for(i=0;il.size();i++) 769 | { 770 | prt(g->l[i],n+1); 771 | } 772 | return 0; 773 | } 774 | int run(char *s,const vector &token_in,gptr &gm) 775 | { 776 | token=token_in; 777 | _s0=s; 778 | int sign=1; 779 | if(okproc(s,gm)&&(*s)==0) 780 | printf("Accepted by grammar analysis\n"); 781 | else 782 | { 783 | sign=0; 784 | printf("Not accepted by grammar analysis\n"); 785 | exit(-1); 786 | } 787 | if(_out)prt(gm); 788 | return sign; 789 | } 790 | }; 791 | 792 | int syntax_analyze(char *s,const vector &token_in,gptr &gm, map &asm_mp) 793 | { 794 | struct syntax_analyzer_t syntax_analyzer; 795 | syntax_analyzer.run(s,token_in,gm); 796 | asm_mp=syntax_analyzer.asm_mp; 797 | return 0; 798 | } 799 | -------------------------------------------------------------------------------- /tests/1.5function_call.c: -------------------------------------------------------------------------------- 1 | #include 2 | int max(int a,int b) 3 | { 4 | if(a>b) return a; 5 | else return b; 6 | } 7 | int main() 8 | { 9 | put32(max(2,3)); 10 | } 11 | -------------------------------------------------------------------------------- /tests/10goto.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main() 3 | { 4 | puts("1") ; 5 | goto line1; 6 | puts("2") ; 7 | line1:; 8 | puts("3") ; 9 | } 10 | -------------------------------------------------------------------------------- /tests/11input.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main() 3 | { 4 | int i; 5 | int j; 6 | for(j=0;j<999999;j=j+1) 7 | { 8 | puts("input a number:"); 9 | i=get32(); 10 | puts("the number is:"); 11 | put32(i); 12 | putc(10); 13 | puts("binary form:"); 14 | putb(i); 15 | putc(10); 16 | putc(10); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/12random.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | int main() 6 | { 7 | int arr[10005]; 8 | int i; 9 | srand(0); 10 | for(i=0;i<10000;i=i+1) 11 | { 12 | arr[i]=rand(); 13 | } 14 | sort(arr,0,10000); 15 | for(i=0;i<10000;i=i+1) 16 | { 17 | put32(arr[i]); 18 | newline(); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /tests/13rec_depth.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | int rec(int depth) 6 | { 7 | if(depth%100==0) 8 | { 9 | puts("depth="); 10 | put32(depth); 11 | newline(); 12 | } 13 | rec(depth+1); 14 | } 15 | int main() 16 | { 17 | rec(0); 18 | } 19 | -------------------------------------------------------------------------------- /tests/14getc_exit.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | int main() 4 | { 5 | char i; 6 | puts("press a key"); 7 | newline(); 8 | for(;;) 9 | { 10 | i=getc(); 11 | puts("got char:"); 12 | put32(i); 13 | newline(); 14 | if(i<10) exit(0); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/15dfs.c: -------------------------------------------------------------------------------- 1 | #include 2 | int dfs(int n) 3 | { 4 | int a[10];int i; 5 | if(n==10) return 0; 6 | for(i=0;i<10;i=i+1) 7 | { 8 | a[i]=n; 9 | } 10 | dfs(n+1); 11 | for(i=0;i<10;i=i+1) 12 | { 13 | put32(a[i]); 14 | putc(' '); 15 | } 16 | newline(); 17 | return 0; 18 | } 19 | int dfs2(int n) 20 | { 21 | int a;int b;int c;int d;int r; 22 | if(n==4) return 1; 23 | //a=n;b=n;c=n;d=n; 24 | a=b=c=d=n; 25 | r=(a+b)*dfs2(n+1)*(c+d); 26 | put32(a+b); 27 | putc(' '); 28 | put32(c+d); 29 | putc(' '); 30 | put32(r); 31 | newline(); 32 | return r; 33 | } 34 | int main() 35 | { 36 | int *x; 37 | x={1,2,3}; 38 | dfs(0); 39 | dfs2(0); 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /tests/1if_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | int max(int a,int b) 3 | { 4 | if(a>b) return a; 5 | else return b; 6 | } 7 | int k; 8 | int main() 9 | { 10 | int i;int j; 11 | i=-2;j=-3; 12 | k=max(i,j); 13 | put32(k); 14 | } 15 | -------------------------------------------------------------------------------- /tests/2.5recursion_factorial.c: -------------------------------------------------------------------------------- 1 | #include 2 | int cal(int a) 3 | { 4 | if(a==1) return 1; 5 | else return cal(a-1)*a; 6 | } 7 | int main() 8 | { 9 | put32( cal(5) ); 10 | } 11 | -------------------------------------------------------------------------------- /tests/2for.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main() 3 | { 4 | int i; 5 | for(i=65;i!=85;i=i+1) 6 | putc(i); 7 | } 8 | -------------------------------------------------------------------------------- /tests/3multi_for.c: -------------------------------------------------------------------------------- 1 | #include 2 | int cal(int a) 3 | { 4 | if(a==1) return 1; 5 | else return a*cal(a-1); 6 | } 7 | int main() 8 | { 9 | int i;int j; 10 | for(i=1;i<=9;i=i+1) 11 | { 12 | for(j=1;j<=9;j=j+1) 13 | { 14 | put32(i);putc('*');put32(j);putc('=');put32(i*j);putc(' '); 15 | } 16 | newline(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/4pointer.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main() 3 | { 4 | int a;int b;int c;int d; 5 | a=&c; 6 | b=&d; 7 | *a=3; 8 | *b=4; 9 | put32(*a); 10 | put32(*b); 11 | put32(c); 12 | put32(d); 13 | } 14 | -------------------------------------------------------------------------------- /tests/5mix_pointer.c: -------------------------------------------------------------------------------- 1 | #include 2 | int ***cal(int ******a) 3 | { 4 | int *b; 5 | b=&a; 6 | if(*b==1) return 1; 7 | else return *b*cal(*b-1); 8 | } 9 | int main() 10 | { 11 | int i;int j; 12 | int *a;int *b; 13 | a=&i;b=&j; 14 | for(*a=1;*a<=9;*a=*a+1) 15 | { 16 | for(*b=1;*b<=9;*b=*b+1) 17 | { 18 | put32(*a);putc('*');put32(*b);putc('!');putc('=');put32(cal(*a**b));putc(' '); 19 | } 20 | newline(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/6quick_sort.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | int main() 4 | { 5 | int r; 6 | char *a; 7 | a="2134567890"; 8 | sortn(a,0,9); 9 | puts(a); 10 | } 11 | -------------------------------------------------------------------------------- /tests/7asm_embed_print_all_char.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main() 3 | { 4 | int i; 5 | for(i=0;i<254;) 6 | { 7 | __asm 8 | { 9 | mov ecx,[i@main] 10 | mov [a@putc],ecx 11 | inc ecx 12 | mov [i@main],ecx 13 | call putc 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/8array.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main() 3 | { 4 | int i; 5 | int a[100]; 6 | for(i=0;i<100;i=i+1) 7 | a[i]=i; 8 | for(i=0;i<100;i=i+1) 9 | { 10 | put32(a[i]); 11 | putc(' '); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/9array_constant_string_constant.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main() 3 | { 4 | char *a;int *b;char c;int i; 5 | a="hello world"; 6 | b={0,1,2,3,4,5,6,7}; 7 | c='z'; 8 | puts(a); 9 | putc(10); 10 | for(i=0;i<8;i=i+1) 11 | { 12 | put32(b[i]); 13 | putc(' '); 14 | } 15 | putc(10); 16 | putc(c); 17 | putc(10); 18 | 19 | } 20 | --------------------------------------------------------------------------------