├── lexical.exe ├── syntaxique.exe ├── program.p ├── pascal.txt ├── README.md ├── lexical.c └── syntaxique.c /lexical.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khaouitiabdelhakim/Pascal-Compiler/HEAD/lexical.exe -------------------------------------------------------------------------------- /syntaxique.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khaouitiabdelhakim/Pascal-Compiler/HEAD/syntaxique.exe -------------------------------------------------------------------------------- /program.p: -------------------------------------------------------------------------------- 1 | program test11; 2 | const toto=21; 3 | var x, y; 4 | Begin 5 | x:=toto; 6 | read(y); 7 | write(x) 8 | end. -------------------------------------------------------------------------------- /pascal.txt: -------------------------------------------------------------------------------- 1 | program test11; 2 | const toto=21; 3 | var x, y; 4 | Begin 5 | x:=toto; 6 | read(y); 7 | write(x) 8 | end.. 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pascal Compiler (Lexical & Syntaxic) in C 2 | 3 | This repository contains a minimalistic Pascal compiler implemented in C, covering lexical and syntax analysis. It serves as a learning resource for understanding the fundamental aspects of compiler design. The code is intentionally kept concise to provide a clear insight into the key stages of lexical and syntax analysis in a compiler. 4 | 5 | ## Features: 6 | - Lexical analysis for Pascal language 7 | - Syntax analysis for Pascal language 8 | - Implemented in C for simplicity and clarity 9 | 10 | ## Getting Started: 11 | 1. Clone the repository. 12 | 2. Compile the source code using a C compiler. 13 | 3. Run the compiled executable with a Pascal source file as an argument. 14 | 15 | Feel free to explore and modify the code to enhance your understanding of compiler construction. Contributions and feedback are welcome! 16 | 17 | Happy coding! 18 | -------------------------------------------------------------------------------- /lexical.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | 7 | typedef enum { 8 | ID_TOKEN, PROGRAM_TOKEN, 9 | CONST_TOKEN, VAR_TOKEN, 10 | BEGIN_TOKEN, END_TOKEN, 11 | IF_TOKEN, THEN_TOKEN, 12 | WHILE_TOKEN, DO_TOKEN, 13 | READ_TOKEN, WRITE_TOKEN, 14 | PV_TOKEN, PT_TOKEN, 15 | PLUS_TOKEN, MOINS_TOKEN, 16 | MULT_TOKEN, DIV_TOKEN, 17 | VIR_TOKEN, AFF_TOKEN, 18 | INF_TOKEN, INFEG_TOKEN, 19 | SUP_TOKEN, SUPEG_TOKEN, 20 | DIFF_TOKEN, PO_TOKEN, 21 | PF_TOKEN, FIN_TOKEN, 22 | NUM_TOKEN, ERREUR_TOKEN, EOF_TOKEN,EG_TOKEN 23 | } CODES_LEX; 24 | 25 | FILE * fichier; 26 | 27 | char Car_Cour; //caractère courant 28 | 29 | void Lire_Car() { 30 | Car_Cour = fgetc(fichier); 31 | } 32 | 33 | typedef struct { CODES_LEX CODE; char NOM[20]; } TSym_Cour; 34 | 35 | TSym_Cour SYM_COUR; 36 | 37 | void lire_mot() { 38 | char mot[20]; 39 | int indice = 0; 40 | 41 | // Lecture du premier caractère (lettre) 42 | mot[indice++] = Car_Cour; 43 | Lire_Car(); 44 | 45 | // Lecture des caractères suivants (lettres ou chiffres) 46 | while (isalpha(Car_Cour) || isdigit(Car_Cour)) { 47 | mot[indice++] = Car_Cour; 48 | Lire_Car(); 49 | } 50 | 51 | // Ajout du caractère de fin de chaîne 52 | mot[indice] = '\0'; 53 | 54 | // Vérifier si le mot est un mot-clé 55 | if (stricmp(mot, "program") == 0) { 56 | SYM_COUR.CODE = PROGRAM_TOKEN; 57 | } else if (stricmp(mot, "const") == 0) { 58 | SYM_COUR.CODE = CONST_TOKEN; 59 | } else if (stricmp(mot, "var") == 0) { 60 | SYM_COUR.CODE = VAR_TOKEN; 61 | } else if (stricmp(mot, "begin") == 0) { 62 | SYM_COUR.CODE = BEGIN_TOKEN; 63 | } else if (stricmp(mot, "end") == 0) { 64 | SYM_COUR.CODE = END_TOKEN; 65 | } else if (stricmp(mot, "if") == 0) { 66 | SYM_COUR.CODE = IF_TOKEN; 67 | } else if (stricmp(mot, "then") == 0) { 68 | SYM_COUR.CODE = THEN_TOKEN; 69 | } else if (stricmp(mot, "while") == 0) { 70 | SYM_COUR.CODE = WHILE_TOKEN; 71 | } else if (stricmp(mot, "do") == 0) { 72 | SYM_COUR.CODE = DO_TOKEN; 73 | } else if (stricmp(mot, "read") == 0) { 74 | SYM_COUR.CODE = READ_TOKEN; 75 | } else if (stricmp(mot, "write") == 0) { 76 | SYM_COUR.CODE = WRITE_TOKEN; 77 | } else { 78 | // Si ce n'est pas un mot-clé, c'est un identifiant 79 | SYM_COUR.CODE = ID_TOKEN; 80 | } 81 | 82 | // Stockage du mot dans le jeton 83 | strcpy(SYM_COUR.NOM, mot); 84 | } 85 | 86 | 87 | void lire_nombre() { 88 | char nombre[11]; 89 | int indice = 0; 90 | 91 | // Lecture du premier chiffre 92 | nombre[indice++] = Car_Cour; 93 | Lire_Car(); 94 | 95 | // Lecture des chiffres suivants 96 | while (isdigit(Car_Cour)) { 97 | nombre[indice++] = Car_Cour; 98 | Lire_Car(); 99 | } 100 | 101 | // Ajout du caractère de fin de chaîne 102 | nombre[indice] = '\0'; 103 | 104 | // Stockage du nombre dans le jeton 105 | SYM_COUR.CODE = NUM_TOKEN; 106 | strcpy(SYM_COUR.NOM, nombre); 107 | } 108 | 109 | void Sym_Suiv() { 110 | while (Car_Cour == ' ' || Car_Cour == '\n' || Car_Cour == '\t') { 111 | Lire_Car(); 112 | } 113 | if (isalpha(Car_Cour)) { 114 | lire_mot(); 115 | } else if (isdigit(Car_Cour)) { 116 | lire_nombre(); 117 | } else { 118 | switch (Car_Cour) { 119 | case ';': 120 | SYM_COUR.CODE = PV_TOKEN; 121 | Lire_Car(); 122 | break; 123 | 124 | case '.': 125 | SYM_COUR.CODE = PT_TOKEN; 126 | Lire_Car(); 127 | break; 128 | 129 | case '+': 130 | SYM_COUR.CODE = PLUS_TOKEN; 131 | Lire_Car(); 132 | break; 133 | 134 | case '-': 135 | SYM_COUR.CODE = MOINS_TOKEN; 136 | Lire_Car(); 137 | break; 138 | 139 | case '*': 140 | SYM_COUR.CODE = MULT_TOKEN; 141 | Lire_Car(); 142 | break; 143 | 144 | case '/': 145 | SYM_COUR.CODE = DIV_TOKEN; 146 | Lire_Car(); 147 | break; 148 | 149 | case ',': 150 | SYM_COUR.CODE = VIR_TOKEN; 151 | Lire_Car(); 152 | break; 153 | 154 | case ':': 155 | Lire_Car(); 156 | if (Car_Cour == '=') { 157 | SYM_COUR.CODE = AFF_TOKEN; 158 | Lire_Car(); 159 | } else { 160 | SYM_COUR.CODE = ERREUR_TOKEN; 161 | } 162 | break; 163 | 164 | case '<': 165 | Lire_Car(); 166 | if (Car_Cour == '=') { 167 | SYM_COUR.CODE = INFEG_TOKEN; 168 | Lire_Car(); 169 | } else if (Car_Cour == '>') { 170 | SYM_COUR.CODE = DIFF_TOKEN; 171 | Lire_Car(); 172 | } else { 173 | SYM_COUR.CODE = INF_TOKEN; 174 | } 175 | break; 176 | 177 | case '>': 178 | Lire_Car(); 179 | if (Car_Cour == '=') { 180 | SYM_COUR.CODE = SUPEG_TOKEN; 181 | Lire_Car(); 182 | } else { 183 | SYM_COUR.CODE = SUP_TOKEN; 184 | } 185 | break; 186 | 187 | case '(': 188 | SYM_COUR.CODE = PO_TOKEN; 189 | Lire_Car(); 190 | break; 191 | case '=': 192 | SYM_COUR.CODE = EG_TOKEN; 193 | Lire_Car(); 194 | break; 195 | 196 | case ')': 197 | SYM_COUR.CODE = PF_TOKEN; 198 | Lire_Car(); 199 | break; 200 | 201 | case EOF: 202 | SYM_COUR.CODE = FIN_TOKEN; 203 | break; 204 | 205 | default: 206 | SYM_COUR.CODE = ERREUR_TOKEN; 207 | Lire_Car(); 208 | } 209 | } 210 | 211 | } 212 | 213 | 214 | const char * codeToString(CODES_LEX code) { 215 | switch (code) { 216 | case EG_TOKEN: return "EG_TOKEN"; 217 | case ID_TOKEN: return "ID_TOKEN"; 218 | case PROGRAM_TOKEN: return "PROGRAM_TOKEN"; 219 | case CONST_TOKEN: return "CONST_TOKEN"; 220 | case VAR_TOKEN: return "VAR_TOKEN"; 221 | case BEGIN_TOKEN: return "BEGIN_TOKEN"; 222 | case END_TOKEN: return "END_TOKEN"; 223 | case IF_TOKEN: return "IF_TOKEN"; 224 | case THEN_TOKEN: return "THEN_TOKEN"; 225 | case WHILE_TOKEN: return "WHILE_TOKEN"; 226 | case DO_TOKEN: return "DO_TOKEN"; 227 | case READ_TOKEN: return "READ_TOKEN"; 228 | case WRITE_TOKEN: return "WRITE_TOKEN"; 229 | case PV_TOKEN: return "PV_TOKEN"; 230 | case PT_TOKEN: return "PT_TOKEN"; 231 | case PLUS_TOKEN: return "PLUS_TOKEN"; 232 | case MOINS_TOKEN: return "MOINS_TOKEN"; 233 | case MULT_TOKEN: return "MULT_TOKEN"; 234 | case DIV_TOKEN: return "DIV_TOKEN"; 235 | case VIR_TOKEN: return "VIR_TOKEN"; 236 | case AFF_TOKEN: return "AFF_TOKEN"; 237 | case INF_TOKEN: return "INF_TOKEN"; 238 | case INFEG_TOKEN: return "INFEG_TOKEN"; 239 | case SUP_TOKEN: return "SUP_TOKEN"; 240 | case SUPEG_TOKEN: return "SUPEG_TOKEN"; 241 | case DIFF_TOKEN: return "DIFF_TOKEN"; 242 | case PO_TOKEN: return "PO_TOKEN"; 243 | case PF_TOKEN: return "PF_TOKEN"; 244 | case FIN_TOKEN: return "FIN_TOKEN"; 245 | case NUM_TOKEN: return "NUM_TOKEN"; 246 | case ERREUR_TOKEN: return "ERREUR_TOKEN"; 247 | case EOF_TOKEN: return "EOF_TOKEN"; 248 | default: return "UNKNOWN_TOKEN"; 249 | } 250 | } 251 | 252 | 253 | int main() { 254 | fichier = fopen("program.p", "r"); 255 | if (fichier == NULL) { 256 | perror("Erreur lors de l'ouverture du fichier"); 257 | return 1; 258 | } 259 | printf("Resulat:\n"); 260 | Lire_Car(); 261 | 262 | 263 | do { 264 | Sym_Suiv(); 265 | //printf("%d\n", SYM_COUR.CODE); 266 | printf("%s\n", codeToString(SYM_COUR.CODE)); 267 | } while (SYM_COUR.CODE != FIN_TOKEN && SYM_COUR.CODE != EOF_TOKEN); 268 | 269 | fclose(fichier); 270 | 271 | return 0; 272 | } 273 | -------------------------------------------------------------------------------- /syntaxique.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | typedef enum 7 | { 8 | ID_TOKEN, 9 | PROGRAM_TOKEN, 10 | CONST_TOKEN, 11 | VAR_TOKEN, 12 | BEGIN_TOKEN, 13 | END_TOKEN, 14 | IF_TOKEN, 15 | THEN_TOKEN, 16 | WHILE_TOKEN, 17 | DO_TOKEN, 18 | READ_TOKEN, 19 | WRITE_TOKEN, 20 | PV_TOKEN, 21 | PT_TOKEN, 22 | PLUS_TOKEN, 23 | MOINS_TOKEN, 24 | MULT_TOKEN, 25 | DIV_TOKEN, 26 | VIR_TOKEN, 27 | AFF_TOKEN, 28 | INF_TOKEN, 29 | INFEG_TOKEN, 30 | SUP_TOKEN, 31 | SUPEG_TOKEN, 32 | DIFF_TOKEN, 33 | PO_TOKEN, 34 | PF_TOKEN, 35 | FIN_TOKEN, 36 | NUM_TOKEN, 37 | ERREUR_TOKEN, 38 | EOF_TOKEN, 39 | EG_TOKEN,REPEAT_TOKEN,UNTIL_TOKEN,FOR_TOKEN,ELSE_TOKEN,CASE_TOKEN,OF_TOKEN, 40 | INTO_TOKEN,DOWNTO_TOKEN, 41 | DDOT_TOKEN 42 | } CODES_LEX; 43 | 44 | // erreur types 45 | typedef enum 46 | { 47 | ID_ERR, 48 | PROGRAM_ERR, 49 | CONST_ERR, 50 | VAR_ERR, 51 | BEGIN_ERR, 52 | END_ERR, 53 | IF_ERR, 54 | THEN_ERR, 55 | WHILE_ERR, 56 | DO_ERR, 57 | READ_ERR, 58 | WRITE_ERR, 59 | PV_ERR, 60 | PT_ERR, 61 | PLUS_ERR, 62 | MOINS_ERR, 63 | MULT_ERR, 64 | DIV_ERR, 65 | VIR_ERR, 66 | AFF_ERR, 67 | INF_ERR, 68 | INFEG_ERR, 69 | SUP_ERR, 70 | SUPEG_ERR, 71 | DIFF_ERR, 72 | PO_ERR, 73 | PF_ERR, 74 | FIN_ERR, 75 | NUM_ERR, 76 | ERREUR_ERR, 77 | EOF_ERR, 78 | EG_ERR, 79 | CONST_VAR_BEGIN_ERR, 80 | VAR_BEGIN_ERR,REPEAT_ERR,UNTIL_ERR,FOR_ERR,ELSE_ERR,CASE_ERR,OF_ERR, 81 | INTO_ERR,DOWNTO_ERR,DDOT_ERR 82 | } CODES_ERR; 83 | 84 | typedef struct 85 | { 86 | CODES_LEX CODE; 87 | char NOM[20]; 88 | } TSym_Cour; 89 | 90 | TSym_Cour SYM_COUR; 91 | 92 | FILE *fichier; 93 | 94 | char Car_Cour; // caractère courant 95 | 96 | // functions declaration 97 | void VARS(); 98 | void INSTS(); 99 | void INST(); 100 | void AFFEC(); 101 | void SI(); 102 | void TANTQUE(); 103 | void ECRIRE(); 104 | void LIRE(); 105 | void EXPR(); 106 | void TERM(); 107 | void FACT(); 108 | void MULOP(); 109 | void ADDOP(); 110 | void RELOP(); 111 | void COND(); 112 | void Lire_Car(); 113 | void Erreur(CODES_ERR code); 114 | void Test_Symbole(CODES_LEX cl, CODES_ERR COD_ERR); 115 | void PROGRAM(); 116 | void BLOCK(); 117 | void CONSTS(); 118 | void Sym_Suiv(); 119 | void lire_mot(); 120 | void lire_nombre(); 121 | void CAS(); 122 | void POUR(); 123 | void REPETER(); 124 | 125 | // functions definition 126 | 127 | void lire_mot() 128 | { 129 | char mot[20]; 130 | int indice = 0; 131 | 132 | // Lecture du premier caractère (lettre) 133 | mot[indice++] = Car_Cour; 134 | Lire_Car(); 135 | 136 | // Lecture des caractères suivants (lettres ou chiffres) 137 | while (isalpha(Car_Cour) || isdigit(Car_Cour)) 138 | { 139 | mot[indice++] = Car_Cour; 140 | Lire_Car(); 141 | } 142 | 143 | // Ajout du caractère de fin de chaîne 144 | mot[indice] = '\0'; 145 | 146 | // Vérifier si le mot est un mot-clé 147 | if (stricmp(mot, "program") == 0) 148 | { 149 | SYM_COUR.CODE = PROGRAM_TOKEN; 150 | } 151 | else if (stricmp(mot, "const") == 0) 152 | { 153 | SYM_COUR.CODE = CONST_TOKEN; 154 | } 155 | else if (stricmp(mot, "var") == 0) 156 | { 157 | SYM_COUR.CODE = VAR_TOKEN; 158 | } 159 | else if (stricmp(mot, "begin") == 0) 160 | { 161 | SYM_COUR.CODE = BEGIN_TOKEN; 162 | } 163 | else if (stricmp(mot, "end") == 0) 164 | { 165 | SYM_COUR.CODE = END_TOKEN; 166 | } 167 | else if (stricmp(mot, "if") == 0) 168 | { 169 | SYM_COUR.CODE = IF_TOKEN; 170 | } 171 | else if (stricmp(mot, "then") == 0) 172 | { 173 | SYM_COUR.CODE = THEN_TOKEN; 174 | } 175 | else if (stricmp(mot, "while") == 0) 176 | { 177 | SYM_COUR.CODE = WHILE_TOKEN; 178 | } 179 | else if (stricmp(mot, "do") == 0) 180 | { 181 | SYM_COUR.CODE = DO_TOKEN; 182 | } 183 | else if (stricmp(mot, "read") == 0) 184 | { 185 | SYM_COUR.CODE = READ_TOKEN; 186 | } 187 | else if (stricmp(mot, "write") == 0) 188 | { 189 | SYM_COUR.CODE = WRITE_TOKEN; 190 | } 191 | else if (stricmp(mot, "else") == 0) 192 | { 193 | SYM_COUR.CODE = ELSE_TOKEN; 194 | } 195 | else if (stricmp(mot, "repeat") == 0) 196 | { 197 | SYM_COUR.CODE = REPEAT_TOKEN; 198 | } 199 | else if (stricmp(mot, "until") == 0) 200 | { 201 | SYM_COUR.CODE = UNTIL_TOKEN; 202 | } 203 | else if (stricmp(mot, "for") == 0) 204 | { 205 | SYM_COUR.CODE = FOR_TOKEN; 206 | } 207 | else if (stricmp(mot, "case") == 0) 208 | { 209 | SYM_COUR.CODE = CASE_TOKEN; 210 | } 211 | else if (stricmp(mot, "of") == 0) 212 | { 213 | SYM_COUR.CODE = OF_TOKEN; 214 | } 215 | else 216 | { 217 | // If it's not a keyword, it's an identifier 218 | SYM_COUR.CODE = ID_TOKEN; 219 | } 220 | 221 | // Stockage du mot dans le jeton 222 | strcpy(SYM_COUR.NOM, mot); 223 | } 224 | 225 | void lire_nombre() 226 | { 227 | char nombre[11]; 228 | int indice = 0; 229 | 230 | // Lecture du premier chiffre 231 | nombre[indice++] = Car_Cour; 232 | Lire_Car(); 233 | 234 | // Lecture des chiffres suivants 235 | while (isdigit(Car_Cour)) 236 | { 237 | nombre[indice++] = Car_Cour; 238 | Lire_Car(); 239 | } 240 | 241 | // Ajout du caractère de fin de chaîne 242 | nombre[indice] = '\0'; 243 | 244 | // Stockage du nombre dans le jeton 245 | SYM_COUR.CODE = NUM_TOKEN; 246 | strcpy(SYM_COUR.NOM, nombre); 247 | } 248 | 249 | void Sym_Suiv() 250 | { 251 | while (Car_Cour == ' ' || Car_Cour == '\n' || Car_Cour == '\t') 252 | { 253 | Lire_Car(); 254 | } 255 | if (isalpha(Car_Cour)) 256 | { 257 | lire_mot(); 258 | } 259 | else if (isdigit(Car_Cour)) 260 | { 261 | lire_nombre(); 262 | } 263 | else 264 | { 265 | switch (Car_Cour) 266 | { 267 | case ';': 268 | SYM_COUR.CODE = PV_TOKEN; 269 | Lire_Car(); 270 | break; 271 | 272 | case '+': 273 | SYM_COUR.CODE = PLUS_TOKEN; 274 | Lire_Car(); 275 | break; 276 | 277 | case '-': 278 | SYM_COUR.CODE = MOINS_TOKEN; 279 | Lire_Car(); 280 | break; 281 | 282 | case '*': 283 | SYM_COUR.CODE = MULT_TOKEN; 284 | Lire_Car(); 285 | break; 286 | 287 | case '/': 288 | SYM_COUR.CODE = DIV_TOKEN; 289 | Lire_Car(); 290 | break; 291 | 292 | case ',': 293 | SYM_COUR.CODE = VIR_TOKEN; 294 | Lire_Car(); 295 | break; 296 | 297 | case ':': 298 | Lire_Car(); 299 | if (Car_Cour == '=') 300 | { 301 | SYM_COUR.CODE = AFF_TOKEN; 302 | Lire_Car(); 303 | } 304 | else 305 | { 306 | SYM_COUR.CODE = DDOT_TOKEN; 307 | } 308 | break; 309 | 310 | case '<': 311 | Lire_Car(); 312 | if (Car_Cour == '=') 313 | { 314 | SYM_COUR.CODE = INFEG_TOKEN; 315 | Lire_Car(); 316 | } 317 | else if (Car_Cour == '>') 318 | { 319 | SYM_COUR.CODE = DIFF_TOKEN; 320 | Lire_Car(); 321 | } 322 | else 323 | { 324 | SYM_COUR.CODE = INF_TOKEN; 325 | } 326 | break; 327 | 328 | case '>': 329 | Lire_Car(); 330 | if (Car_Cour == '=') 331 | { 332 | SYM_COUR.CODE = SUPEG_TOKEN; 333 | Lire_Car(); 334 | } 335 | else 336 | { 337 | SYM_COUR.CODE = SUP_TOKEN; 338 | } 339 | break; 340 | 341 | case '(': 342 | SYM_COUR.CODE = PO_TOKEN; 343 | Lire_Car(); 344 | break; 345 | case '=': 346 | SYM_COUR.CODE = EG_TOKEN; 347 | Lire_Car(); 348 | break; 349 | 350 | case ')': 351 | SYM_COUR.CODE = PF_TOKEN; 352 | Lire_Car(); 353 | break; 354 | 355 | case '.': 356 | SYM_COUR.CODE = PT_TOKEN; 357 | Lire_Car(); 358 | break; 359 | 360 | case EOF: 361 | SYM_COUR.CODE = FIN_TOKEN; 362 | break; 363 | 364 | default: 365 | SYM_COUR.CODE = ERREUR_TOKEN; 366 | Lire_Car(); 367 | } 368 | strcpy(SYM_COUR.NOM , Car_Cour); 369 | } 370 | 371 | printf("Symbol: %s\n", SYM_COUR.NOM); 372 | } 373 | 374 | void Lire_Car() 375 | { 376 | Car_Cour = fgetc(fichier); 377 | } 378 | 379 | void Erreur(CODES_ERR code) 380 | { 381 | printf("Erreur: %d\n", code); 382 | printf("Current Token: %d\n", SYM_COUR.CODE); 383 | printf("Current Lexeme: %s\n", SYM_COUR.NOM); 384 | exit(EXIT_FAILURE); 385 | } 386 | 387 | void Test_Symbole(CODES_LEX cl, CODES_ERR COD_ERR) 388 | { 389 | if (SYM_COUR.CODE == cl) 390 | { 391 | Sym_Suiv(); 392 | } 393 | else 394 | Erreur(COD_ERR); 395 | } 396 | 397 | void PROGRAM() 398 | { 399 | Test_Symbole(PROGRAM_TOKEN, PROGRAM_ERR); 400 | Test_Symbole(ID_TOKEN, ID_ERR); 401 | Test_Symbole(PV_TOKEN, PV_ERR); 402 | BLOCK(); 403 | Test_Symbole(PT_TOKEN, PT_ERR); 404 | 405 | } 406 | 407 | void BLOCK() 408 | { 409 | CONSTS(); 410 | 411 | VARS(); 412 | INSTS(); 413 | } 414 | 415 | void CONSTS() 416 | { 417 | switch (SYM_COUR.CODE) 418 | { 419 | case CONST_TOKEN: 420 | Sym_Suiv(); 421 | Test_Symbole(ID_TOKEN, ID_ERR); 422 | Test_Symbole(EG_TOKEN, EG_ERR); 423 | Test_Symbole(NUM_TOKEN, NUM_ERR); 424 | Test_Symbole(PV_TOKEN, PV_ERR); 425 | while (SYM_COUR.CODE == ID_TOKEN) 426 | { 427 | Sym_Suiv(); 428 | Test_Symbole(EG_TOKEN, EG_ERR); 429 | Test_Symbole(NUM_TOKEN, NUM_ERR); 430 | Test_Symbole(PV_TOKEN, PV_ERR); 431 | }; 432 | break; 433 | case VAR_TOKEN: 434 | break; 435 | case BEGIN_TOKEN: 436 | break; 437 | default: 438 | Erreur(CONST_VAR_BEGIN_ERR); 439 | break; 440 | } 441 | } 442 | 443 | void VARS() 444 | { 445 | switch (SYM_COUR.CODE) 446 | { 447 | case VAR_TOKEN: 448 | Sym_Suiv(); 449 | Test_Symbole(ID_TOKEN, ID_ERR); 450 | 451 | while (SYM_COUR.CODE == VIR_TOKEN) 452 | { 453 | Sym_Suiv(); 454 | Test_Symbole(ID_TOKEN, ID_ERR); 455 | } 456 | 457 | Test_Symbole(PV_TOKEN, PV_ERR); 458 | break; 459 | case BEGIN_TOKEN: 460 | break; 461 | default: 462 | Erreur(VAR_BEGIN_ERR); 463 | break; 464 | } 465 | } 466 | 467 | void INSTS() 468 | { 469 | //begin INST { ; INST } end 470 | if (SYM_COUR.CODE == BEGIN_TOKEN) 471 | { 472 | Sym_Suiv(); 473 | INST(); 474 | 475 | while (SYM_COUR.CODE == PV_TOKEN) 476 | { 477 | Sym_Suiv(); 478 | INST(); 479 | } 480 | 481 | if (SYM_COUR.CODE == END_TOKEN) 482 | { 483 | Sym_Suiv(); 484 | printf("rani wslt lhna"); 485 | printf("Current Token: %d\n", SYM_COUR.CODE); 486 | printf("Current Lexeme: %s\n", SYM_COUR.NOM); 487 | } 488 | else 489 | { 490 | Erreur(FIN_ERR); 491 | } 492 | } 493 | else 494 | { 495 | Erreur(BEGIN_ERR); 496 | } 497 | } 498 | 499 | void INST() 500 | 501 | { 502 | //INSTS | AFFEC | SI | TANTQUE | ECRIRE | LIRE | e 503 | switch (SYM_COUR.CODE) 504 | { 505 | case BEGIN_TOKEN: 506 | INSTS(); 507 | break; 508 | case ID_TOKEN: 509 | AFFEC(); 510 | break; 511 | case IF_TOKEN: 512 | SI(); 513 | break; 514 | case WHILE_TOKEN: 515 | TANTQUE(); 516 | break; 517 | case WRITE_TOKEN: 518 | ECRIRE(); 519 | break; 520 | case READ_TOKEN: 521 | LIRE(); 522 | break; 523 | case REPEAT_TOKEN: 524 | REPETER(); 525 | break; 526 | case FOR_TOKEN: 527 | POUR(); 528 | break; 529 | case CASE_TOKEN: 530 | CAS(); 531 | break; 532 | default: 533 | break; 534 | } 535 | } 536 | 537 | void AFFEC() 538 | { 539 | //ID := EXPR 540 | Test_Symbole(ID_TOKEN, ID_ERR); 541 | Test_Symbole(AFF_TOKEN, AFF_ERR); 542 | EXPR(); 543 | } 544 | 545 | void SI() 546 | { 547 | Test_Symbole(IF_TOKEN, IF_ERR); 548 | COND(); 549 | Test_Symbole(THEN_TOKEN, THEN_ERR); 550 | INST(); 551 | if (SYM_COUR.CODE == ELSE_TOKEN) 552 | { 553 | INST(); 554 | } 555 | } 556 | 557 | void TANTQUE() 558 | { 559 | Test_Symbole(WHILE_TOKEN, WHILE_ERR); 560 | COND(); 561 | Test_Symbole(DO_TOKEN, DO_ERR); 562 | INST(); 563 | } 564 | 565 | void ECRIRE() 566 | { 567 | Test_Symbole(WRITE_TOKEN, WRITE_ERR); 568 | Test_Symbole(PO_TOKEN, PO_ERR); 569 | EXPR(); 570 | 571 | while (SYM_COUR.CODE == VIR_TOKEN) 572 | { 573 | Sym_Suiv(); 574 | EXPR(); 575 | } 576 | 577 | Test_Symbole(PF_TOKEN, PF_ERR); 578 | } 579 | 580 | void LIRE() 581 | { 582 | Test_Symbole(READ_TOKEN, READ_ERR); 583 | Test_Symbole(PO_TOKEN, PO_ERR); 584 | Test_Symbole(ID_TOKEN, ID_ERR); 585 | 586 | while (SYM_COUR.CODE == VIR_TOKEN) 587 | { 588 | Sym_Suiv(); 589 | Test_Symbole(ID_TOKEN, ID_ERR); 590 | } 591 | 592 | Test_Symbole(PF_TOKEN, PF_ERR); 593 | } 594 | 595 | void COND() 596 | { 597 | EXPR(); 598 | RELOP(); 599 | EXPR(); 600 | } 601 | 602 | void EXPR() 603 | { 604 | //TERM { ADDOP TERM } 605 | TERM(); 606 | 607 | while (SYM_COUR.CODE == PLUS_TOKEN || SYM_COUR.CODE == MOINS_TOKEN) 608 | { 609 | ADDOP(); 610 | TERM(); 611 | } 612 | } 613 | 614 | void TERM() 615 | { 616 | FACT(); 617 | 618 | while (SYM_COUR.CODE == MULT_TOKEN || SYM_COUR.CODE == DIV_TOKEN) 619 | { 620 | MULOP(); 621 | FACT(); 622 | } 623 | } 624 | 625 | void FACT() 626 | { 627 | switch (SYM_COUR.CODE) 628 | { 629 | case ID_TOKEN: 630 | Test_Symbole(ID_TOKEN, ID_ERR); 631 | break; 632 | case NUM_TOKEN: 633 | Test_Symbole(NUM_TOKEN, NUM_ERR); 634 | break; 635 | case PO_TOKEN: 636 | Test_Symbole(PO_TOKEN, PO_ERR); 637 | EXPR(); 638 | Test_Symbole(PF_TOKEN, PF_ERR); 639 | break; 640 | default: 641 | Erreur(ERREUR_ERR); 642 | break; 643 | } 644 | } 645 | 646 | void RELOP() 647 | { 648 | switch (SYM_COUR.CODE) 649 | { 650 | case EG_TOKEN: 651 | case DIFF_TOKEN: 652 | case INF_TOKEN: 653 | case SUP_TOKEN: 654 | case INFEG_TOKEN: 655 | case SUPEG_TOKEN: 656 | Test_Symbole(EG_TOKEN, EG_ERR); 657 | break; 658 | default: 659 | Erreur(ERREUR_ERR); 660 | break; 661 | } 662 | } 663 | 664 | void ADDOP() 665 | { 666 | switch (SYM_COUR.CODE) 667 | { 668 | case PLUS_TOKEN: 669 | Test_Symbole(PLUS_TOKEN, PLUS_ERR); 670 | break; 671 | case MOINS_TOKEN: 672 | Test_Symbole(MOINS_TOKEN, MOINS_ERR); 673 | break; 674 | default: 675 | Erreur(ERREUR_ERR); 676 | break; 677 | } 678 | } 679 | 680 | void MULOP() 681 | { 682 | switch (SYM_COUR.CODE) 683 | { 684 | case MULT_TOKEN: 685 | Test_Symbole(MULT_TOKEN, MULT_ERR); 686 | break; 687 | case DIV_TOKEN: 688 | Test_Symbole(DIV_TOKEN, DIV_ERR); 689 | break; 690 | default: 691 | Erreur(ERREUR_ERR); 692 | break; 693 | } 694 | } 695 | 696 | void POUR() 697 | { 698 | Test_Symbole(FOR_TOKEN, FOR_ERR); 699 | Test_Symbole(ID_TOKEN, ID_ERR); 700 | Test_Symbole(AFF_TOKEN, AFF_ERR); 701 | 702 | switch (SYM_COUR.CODE) 703 | { 704 | case DOWNTO_TOKEN: 705 | Test_Symbole(DOWNTO_TOKEN, DOWNTO_ERR); 706 | break; 707 | case INTO_TOKEN: 708 | Test_Symbole(INTO_TOKEN, INTO_ERR); 709 | break; 710 | default: 711 | Erreur(ERREUR_ERR); 712 | break; 713 | } 714 | 715 | Test_Symbole(NUM_TOKEN, NUM_ERR); 716 | Test_Symbole(DO_TOKEN, DO_ERR); 717 | INST(); 718 | 719 | } 720 | 721 | /* 722 | REPEAT_TOKEN,UNTIL_TOKEN,FOR_TOKEN,ELSE_TOKEN,CASE_TOKEN,OF_TOKEN*/ 723 | 724 | void REPETER(){ 725 | Test_Symbole(REPEAT_TOKEN, REPEAT_ERR); 726 | INST(); 727 | Test_Symbole(UNTIL_TOKEN, UNTIL_ERR); 728 | COND(); 729 | } 730 | 731 | void CAS() 732 | { 733 | Test_Symbole(CASE_TOKEN, CASE_ERR); 734 | Test_Symbole(ID_TOKEN, ID_ERR); 735 | Test_Symbole(OF_TOKEN, OF_TOKEN); 736 | Test_Symbole(NUM_TOKEN, NUM_ERR); 737 | Test_Symbole(DDOT_TOKEN, DDOT_ERR); 738 | INST(); 739 | while (SYM_COUR.CODE == NUM_TOKEN) 740 | { 741 | Sym_Suiv(); 742 | Test_Symbole(DDOT_TOKEN, DDOT_ERR); 743 | INST(); 744 | } 745 | if (SYM_COUR.CODE == ELSE_TOKEN) { 746 | Sym_Suiv(); 747 | INST(); 748 | } 749 | 750 | Test_Symbole(END_TOKEN, END_ERR); 751 | } 752 | 753 | 754 | int main() 755 | { 756 | fichier = fopen("program.p", "r"); 757 | if (fichier == NULL) 758 | { 759 | perror("Erreur lors de l'ouverture du fichier"); 760 | return 1; 761 | } 762 | 763 | // PREMIER_SYM(); 764 | Lire_Car(); 765 | Sym_Suiv(); 766 | 767 | PROGRAM(); 768 | 769 | printf("Program execution completed.\n"); 770 | 771 | if (SYM_COUR.CODE == EOF_TOKEN) 772 | { 773 | printf("BRAVO: le programme est correcte!!!\n"); 774 | } 775 | else 776 | { 777 | printf("PAS BRAVO: fin de programme erronée!!!!\n"); 778 | printf("Current Token: %d\n", SYM_COUR.CODE); 779 | printf("Current Lexeme: %s\n", SYM_COUR.NOM); 780 | Sym_Suiv(); // Move this line inside the else block 781 | } 782 | 783 | fclose(fichier); 784 | 785 | return 0; 786 | } 787 | --------------------------------------------------------------------------------