├── 103062121_report.pdf ├── Makefile ├── README.md ├── SelfTest.sh ├── advance.c ├── advance.out └── scanner.l /103062121_report.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tim70036/c99-scanner/59d3364571df4cf15187f31044f334b28defb6de/103062121_report.pdf -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | LEX = flex 2 | C = gcc 3 | SCANNER = scanner.l 4 | FILE = lex.yy.c 5 | OUT = scanner 6 | LIB = -lfl 7 | 8 | # Default Target 9 | build: 10 | $(LEX) $(SCANNER) 11 | $(C) -o $(OUT) $(FILE) $(LIB) 12 | 13 | clean: 14 | rm -f $(FILE) 15 | rm -f $(OUT) 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 扯王扯王扯蛋王,巭孬嫑夯尻 2 | 隨手按個星星有益身心健康,祝大家越尻越順 3 | -------------------------------------------------------------------------------- /SelfTest.sh: -------------------------------------------------------------------------------- 1 | ./scanner test0_1.c > fuck.out ; diff -s fuck.out test0_1.out 2 | ./scanner test0_2.c > fuck.out ; diff -s fuck.out test0_2.out 3 | ./scanner pragma_source_off.c > fuck.out ; diff -s fuck.out pragma_source_off.out 4 | ./scanner pragma_source_off_1.c > fuck.out ; diff -s fuck.out pragma_source_off_1.out 5 | ./scanner pragma_token_off.c > fuck.out ; diff -s fuck.out pragma_token_off.out 6 | ./scanner test0_1_error.c 1>trivial.out 2>fuck.out ; diff -s fuck.out test0_1_error.out 7 | ./scanner advance.c > fuck.out ; diff -s fuck.out advance.out 8 | -------------------------------------------------------------------------------- /advance.c: -------------------------------------------------------------------------------- 1 | /* String and Char */ 2 | L"ABCD" 3 | L'A' 4 | 5 | /* Floating */ 6 | 1234. 7 | 01234. 8 | 01234.01234 9 | .1234 10 | 11 | /* Floating suffix */ 12 | 1234.L 13 | 1234.l 14 | 1234.F 15 | 1234.f 16 | 17 | /* Scientific */ 18 | 12E0123 19 | 12e0123 20 | 01234E01 21 | 01234e01 22 | 23 | /* Scientific suffix */ 24 | 12E0123l 25 | 12e0123L 26 | 01234E01f 27 | 01234e01F 28 | 29 | /* Integer suffix */ 30 | 1234u 31 | 1234l 32 | 1234ll 33 | 1234LL 34 | 1234L 35 | 1234U 36 | 37 | 1234uLL 38 | 1234uL 39 | 1234ul 40 | 1234ull 41 | 1234ULL 42 | 1234UL 43 | 1234Ul 44 | 1234Ull 45 | 46 | 1234lu 47 | 1234llu 48 | 1234Lu 49 | 1234LLu 50 | 51 | 1234lU 52 | 1234llU 53 | 1234LU 54 | 1234LLU 55 | -------------------------------------------------------------------------------- /advance.out: -------------------------------------------------------------------------------- 1 | 1:/* String and Char */ 2 | #string:ABCD 3 | 2:L"ABCD" 4 | #char:L'A' 5 | 3:L'A' 6 | 4: 7 | 5:/* Floating */ 8 | #double:1234. 9 | 6:1234. 10 | #double:01234. 11 | 7:01234. 12 | #double:01234.01234 13 | 8:01234.01234 14 | #double:.1234 15 | 9:.1234 16 | 10: 17 | 11:/* Floating suffix */ 18 | #double:1234.L 19 | 12:1234.L 20 | #double:1234.l 21 | 13:1234.l 22 | #double:1234.F 23 | 14:1234.F 24 | #double:1234.f 25 | 15:1234.f 26 | 16: 27 | 17:/* Scientific */ 28 | #sci:12E0123 29 | 18:12E0123 30 | #sci:12e0123 31 | 19:12e0123 32 | #sci:01234E01 33 | 20:01234E01 34 | #sci:01234e01 35 | 21:01234e01 36 | 22: 37 | 23:/* Scientific suffix */ 38 | #sci:12E0123l 39 | 24:12E0123l 40 | #sci:12e0123L 41 | 25:12e0123L 42 | #sci:01234E01f 43 | 26:01234E01f 44 | #sci:01234e01F 45 | 27:01234e01F 46 | 28: 47 | 29:/* Integer suffix */ 48 | #integer:1234u 49 | 30:1234u 50 | #integer:1234l 51 | 31:1234l 52 | #integer:1234ll 53 | 32:1234ll 54 | #integer:1234LL 55 | 33:1234LL 56 | #integer:1234L 57 | 34:1234L 58 | #integer:1234U 59 | 35:1234U 60 | 36: 61 | #integer:1234uLL 62 | 37:1234uLL 63 | #integer:1234uL 64 | 38:1234uL 65 | #integer:1234ul 66 | 39:1234ul 67 | #integer:1234ull 68 | 40:1234ull 69 | #integer:1234ULL 70 | 41:1234ULL 71 | #integer:1234UL 72 | 42:1234UL 73 | #integer:1234Ul 74 | 43:1234Ul 75 | #integer:1234Ull 76 | 44:1234Ull 77 | 45: 78 | #integer:1234lu 79 | 46:1234lu 80 | #integer:1234llu 81 | 47:1234llu 82 | #integer:1234Lu 83 | 48:1234Lu 84 | #integer:1234LLu 85 | 49:1234LLu 86 | 50: 87 | #integer:1234lU 88 | 51:1234lU 89 | #integer:1234llU 90 | 52:1234llU 91 | #integer:1234LU 92 | 53:1234LU 93 | #integer:1234LLU 94 | 54:1234LLU 95 | -------------------------------------------------------------------------------- /scanner.l: -------------------------------------------------------------------------------- 1 | /* Definition Section */ 2 | 3 | %{ 4 | #include 5 | #include 6 | #include 7 | 8 | int numL = 1; 9 | char buf[1000]; 10 | int bufIndex = 0; 11 | 12 | int tokenOn = 1; 13 | int sourceOn = 1; 14 | %} 15 | 16 | %x COMMENT 17 | 18 | DIGIT [0-9] 19 | DIGIT_SEQ {DIGIT}+ 20 | FRAC ({DIGIT_SEQ}?"."{DIGIT_SEQ})|({DIGIT_SEQ}".") 21 | FS (f|F|l|L) 22 | 23 | DOUBLE {FRAC}{FS}? 24 | 25 | E [Ee][+-]?{DIGIT_SEQ} 26 | SCI ({FRAC}|{DIGIT_SEQ}){E}{FS}? 27 | 28 | L (l|L|ll|LL) 29 | U (u|U) 30 | IS ({U}|{L}|{L}{U}|{U}{L}) 31 | 32 | INT ({DIGIT}|[1-9]{DIGIT}*){IS}? 33 | 34 | 35 | CHAR L?'([^'\\\n]|\\(n|t))' 36 | STR L?\"(\\(n|t)|[^"\\\n])*\" 37 | 38 | ID [a-zA-Z_]+[a-zA-Z_0-9]* 39 | 40 | PUNC ":"|";"|","|"."|"["|"]"|"("|")"|"{"|"}" 41 | OP "+"|"-"|"*"|"/"|"%"|"++"|"--"|"<"|"<="|">"|">="|"=="|"!="|"="|"&&"|"||"|"!"|"&" 42 | KEY "void"|"int"|"double"|"bool"|"char"|"null"|"for"|"while"|"do"|"if"|"else"|"switch"|"return"|"break"|"continue"|"const"|"true"|"false"|"struct"|"case"|"default" 43 | STDIO "remove"|"rename"|"tmpfile"|"tmpnam"|"fclose"|"fflush"|"fopen"|"freopen"|"setbuf"|"setvbuf"|"fprintf"|"fscanf"|"printf"|"scanf"|"sprintf"|"sscanf"|"vfprintf"|"vprintf"|"vsprintf"|"fgetc"|"fgets"|"fputc"|"fputs"|"getc"|"getchar"|"gets"|"putc"|"putchar"|"puts"|"ungetc"|"fread"|"fwrite"|"fgetpos"|"fseek"|"fsetpos"|"ftell"|"rewind"|"clearerr"|"feof"|"ferror"|"perror" 44 | SPACE [ \f\t\r\v]+ 45 | 46 | SOURCE_ON #{SPACE}?"pragma"{SPACE}"source"{SPACE}"on"{SPACE}?\n 47 | SOURCE_OFF #{SPACE}?"pragma"{SPACE}"source"{SPACE}"off"{SPACE}?\n 48 | TOKEN_ON #{SPACE}?"pragma"{SPACE}"token"{SPACE}"on"{SPACE}?\n 49 | TOKEN_OFF #{SPACE}?"pragma"{SPACE}"token"{SPACE}"off"{SPACE}?\n 50 | 51 | %% 52 | 53 | {SOURCE_ON} { 54 | sourceOn = 1; 55 | 56 | /* Fuck \n */ 57 | yytext[yyleng-1] = 0; strcpy(&(buf[bufIndex]), yytext); bufIndex += (yyleng-1); 58 | unput('\n'); 59 | } 60 | 61 | {SOURCE_OFF} { 62 | sourceOn = 0; 63 | 64 | /* Fuck \n */ 65 | yytext[yyleng-1] = 0; strcpy(&(buf[bufIndex]), yytext); bufIndex += (yyleng-1); 66 | unput('\n'); 67 | } 68 | 69 | {TOKEN_ON} { 70 | tokenOn = 1; 71 | 72 | /* Fuck \n */ 73 | yytext[yyleng-1] = 0; strcpy(&(buf[bufIndex]), yytext); bufIndex += (yyleng-1); 74 | unput('\n'); 75 | } 76 | 77 | {TOKEN_OFF} { 78 | tokenOn = 0; 79 | 80 | /* Fuck \n */ 81 | yytext[yyleng-1] = 0; strcpy(&(buf[bufIndex]), yytext); bufIndex += (yyleng-1); 82 | unput('\n'); 83 | } 84 | 85 | "/*" { 86 | BEGIN(COMMENT); 87 | 88 | strcpy(&(buf[bufIndex]), yytext); 89 | bufIndex += yyleng; 90 | } 91 | "*/" { 92 | /* End of Comment */ 93 | BEGIN(INITIAL); 94 | 95 | strcpy(&(buf[bufIndex]), yytext); 96 | bufIndex += yyleng; 97 | } 98 | \n { 99 | /* Comment newline print it out */ 100 | 101 | /* Check pragma */ 102 | if(sourceOn == 1) printf("%d:%s\n",numL,buf); 103 | 104 | numL++; /* Enter newline */ 105 | 106 | buf[0] = 0; /* Clean Buffer */ 107 | bufIndex = 0; 108 | } 109 | . { 110 | /* If use .* then it will eat the ending of comment */ 111 | 112 | strcpy(&(buf[bufIndex]), yytext); 113 | bufIndex += yyleng; 114 | } 115 | 116 | "//".* { 117 | /* Single line comment , simply copy to buf, and wait for \n to handle*/ 118 | strcpy(&(buf[bufIndex]), yytext); 119 | bufIndex += yyleng; 120 | } 121 | 122 | {KEY} { 123 | /* Check pragma */ 124 | if(tokenOn == 1) printf("#key:%s\n",yytext); 125 | 126 | strcpy(&(buf[bufIndex]), yytext); 127 | bufIndex += yyleng; 128 | } 129 | 130 | {STDIO} { 131 | /* Check pragma */ 132 | if(tokenOn == 1) printf("#key:%s\n",yytext); 133 | 134 | strcpy(&(buf[bufIndex]), yytext); 135 | bufIndex += yyleng; 136 | } 137 | 138 | 0{INT} { 139 | /* In order to make TA happy */ 140 | fprintf(stderr, "Error at line %d: %s\n", numL, yytext); exit(1); 141 | } 142 | 143 | {INT} { 144 | /* Check pragma */ 145 | if(tokenOn == 1) printf("#integer:%s\n",yytext); 146 | 147 | strcpy(&(buf[bufIndex]), yytext); 148 | bufIndex += yyleng; 149 | } 150 | 151 | {DOUBLE} { 152 | /* Check pragma */ 153 | if(tokenOn == 1) printf("#double:%s\n",yytext); 154 | 155 | strcpy(&(buf[bufIndex]), yytext); 156 | bufIndex += yyleng; 157 | } 158 | 159 | {SCI} { 160 | /* Check pragma */ 161 | if(tokenOn == 1) printf("#sci:%s\n",yytext); 162 | 163 | strcpy(&(buf[bufIndex]), yytext); 164 | bufIndex += yyleng; 165 | } 166 | 167 | {PUNC} { 168 | /* Check pragma */ 169 | if(tokenOn == 1) printf("#punc:%s\n",yytext); 170 | 171 | strcpy(&(buf[bufIndex]), yytext); 172 | bufIndex += yyleng; 173 | } 174 | 175 | {OP} { 176 | /* Check pragma */ 177 | if(tokenOn == 1) printf("#op:%s\n",yytext); 178 | 179 | strcpy(&(buf[bufIndex]), yytext); 180 | bufIndex += yyleng; 181 | } 182 | 183 | {CHAR} { 184 | 185 | /* Error Detect? */ 186 | 187 | /* Check pragma */ 188 | if(tokenOn == 1) printf("#char:%s\n",yytext); 189 | 190 | strcpy(&(buf[bufIndex]), yytext); 191 | bufIndex += yyleng; 192 | } 193 | 194 | 195 | {STR} { 196 | /* Extract String */ 197 | char str[1000]; 198 | if(yytext[0] == 'L') 199 | { 200 | strcpy(str,yytext+2); /* The first " is gone */ 201 | str[yyleng-3] = 0; /* The last " is gone */ 202 | } 203 | else 204 | { 205 | strcpy(str,yytext+1); 206 | str[yyleng-2] = 0; /* The last " is gone */ 207 | } 208 | 209 | 210 | /* Error Detect? */ 211 | 212 | /* Check pragma */ 213 | if(tokenOn == 1) printf("#string:%s\n",str); 214 | 215 | strcpy(&(buf[bufIndex]), yytext); 216 | bufIndex += yyleng; 217 | } 218 | 219 | [0-9]+{ID} { 220 | /* In order to make TA happy */ 221 | fprintf(stderr, "Error at line %d: %s\n", numL, yytext); exit(1); 222 | } 223 | 224 | {ID} { 225 | /* Check pragma */ 226 | if(tokenOn == 1) printf("#id:%s\n",yytext); 227 | 228 | strcpy(&(buf[bufIndex]), yytext); 229 | bufIndex += yyleng; 230 | } 231 | 232 | {SPACE} { 233 | strcpy(&(buf[bufIndex]), yytext); 234 | bufIndex += yyleng; 235 | } 236 | 237 | \n { 238 | 239 | /* Check pragma */ 240 | if(sourceOn == 1) printf("%d:%s\n",numL,buf); 241 | 242 | numL++; /* Enter newline */ 243 | 244 | buf[0] = 0; /* Clean Buffer */ 245 | bufIndex = 0; 246 | 247 | } 248 | 249 | . { 250 | fprintf(stderr, "Error at line %d: %s\n", numL, yytext); exit(1); 251 | 252 | strcpy(&(buf[bufIndex]), yytext); 253 | bufIndex += yyleng; 254 | } 255 | 256 | 257 | %% 258 | 259 | /* C code Section */ 260 | 261 | int main(int argc, char* argv[]) 262 | { 263 | ++argv; --argc; /* Skip program name */ 264 | yyin = ( argc > 0 ) ? fopen(argv[0], "r") : stdin; 265 | 266 | yylex(); 267 | 268 | return 0; 269 | } 270 | --------------------------------------------------------------------------------