JXsKI2luY2x1ZGUgJmx0O3N0ZGlvLmgmZ3Q7CiNpbmNsdWRlICZsdDtzdGRsaWIuaCZndDsKI2luY2x1ZGUgJmx0O3N0cmluZy5oJmd0OwojaW5jbHVkZSAmbHQ7Y3R5cGUuaCZndDsKCi8qIEQmZWFjdXRlO2Zpbml0aW9uIGRlcyB0b2tlbnMgKi8KZW51bSBUT0tFTiB7IEZJTj0wLCBQViwgSUYsIEVHQUwsIEFTU0lHTiwgT1AsIFBBUkcsIFBBUkQsIElELCBOVU0gfTsKCi8qIFBvdXIgc3RvY2tlciBsZXMgYXR0cmlidXRzICovCmVudW0gQ09ERU9QRVJBVElPTiB7IFBMVVMsIE1PSU5TIH07Cgp1bmlvbiB7CiAgICBjaGFyICpub207ICAgICAgIC8qIFBvdXIgSUQgKi8KICAgIGludCB2YWxldXI7ICAgICAgLyogUG91ciBOVU0gKi8KICAgIGVudW0gQ09ERU9QRVJBVElPTiBjb3A7IC8qIFBvdXIgT1AgKi8KfSB5eWx2YWw7CgovKiBQcm90b3R5cGUgZGUgbGEgZm9uY3Rpb24gZCdlcnJldXIgKi8Kdm9pZCBlcnJldXJfbGV4aWNhbGUoKTsKJX0KCiVvcHRpb24geXlsaW5lbm8KCi8qIEQmZWFjdXRlO2Zpbml0aW9ucyByJmVhY3V0ZTtndWxpJmVncmF2ZTtyZXMgKi8KYmxhbmNzIFsgXHRcbl0rCmxldHRyZSBbQS1aYS16XQpjaGlmZnJlIFswLTldCmlkZW50IHtsZXR0cmV9KHtsZXR0cmV9fHtjaGlmZnJlfXxfKSoKCiUlCi8qIElnbm9yZXIgZXNwYWNlcyBldCBjb21tZW50YWlyZXMgKi8Ke2JsYW5jc30gOwoKXHtbXn1dKlx9IDsgICAgICAgLyogY29tbWVudGFpcmUgZW50cmUgeyBldCB9ICovCgovKiBSJmVncmF2ZTtnbGVzIGxleGljYWxlcyAqLwppZiAgICAgICAgICAgICAgeyByZXR1cm4gSUY7IH0KJnF1b3Q7OyZxdW90OyAgICAgICAgICAgICB7IHJldHVybiBQVjsgfQomcXVvdDs9PSZxdW90OyAgICAgICAgICAgIHsgcmV0dXJuIEVHQUw7IH0KJnF1b3Q7Oj0mcXVvdDsgICAgICAgICAgICB7IHJldHVybiBBU1NJR047IH0KWystXSAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoeXl0ZXh0WzBdID09ICcrJykgeXlsdmFsLmNvcCA9IFBMVVM7CiAgICAgICAgICAgICAgICAgICAgZWxzZSB5eWx2YWwuY29wID0gTU9JTlM7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE9QOwogICAgICAgICAgICAgICAgIH0KJnF1b3Q7KCZxdW90OyAgICAgICAgICAgICB7IHJldHVybiBQQVJHOyB9CiZxdW90OykmcXVvdDsgICAgICAgICAgICAgeyByZXR1cm4gUEFSRDsgfQoKe2NoaWZmcmV9KyAgICAgIHsKICAgICAgICAgICAgICAgICAgICB5eWx2YWwudmFsZXVyID0gYXRvaSh5eXRleHQpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBOVU07CiAgICAgICAgICAgICAgICB9Cgp7aWRlbnR9ICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHl5bHZhbC5ub20gPSAoY2hhciAqKW1hbGxvYyhzdHJsZW4oeXl0ZXh0KSsxKTsKICAgICAgICAgICAgICAgICAgICBzdHJjcHkoeXlsdmFsLm5vbSwgeXl0ZXh0KTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gSUQ7CiAgICAgICAgICAgICAgICB9CgovKiBDYXJhY3QmZWdyYXZlO3JlIGlsbCZlYWN1dGU7Z2FsICovCi4gICAgICAgICAgICAgICB7IGVycmV1cl9sZXhpY2FsZSgpOyB9CgolJQoKaW50IHl5d3JhcCgpIHsKICAgIHJldHVybiAxOwp9CgovKiBGb25jdGlvbiBkJ2VycmV1ciAqLwp2b2lkIGVycmV1cl9sZXhpY2FsZSgpIHsKICAgIHByaW50ZigmcXVvdDtMaWduZSAlZCA6IGVycmV1ciBsZXhpY2FsZSwgJyVjJyBjYXJhY3QmZWdyYXZlO3JlIGlsbCZlYWN1dGU7Z2FsLlxuJnF1b3Q7LCB5eWxpbmVubywgeXl0ZXh0WzBdKTsKICAgIGV4aXQoMSk7Cn0KCi8qIEZvbmN0aW9uIHByaW5jaXBhbGUgKi8KaW50IG1haW4oaW50IGFyZ2MsIGNoYXIgKiphcmd2KSB7CiAgICBlbnVtIFRPS0VOIHRjOwoKICAgIGlmIChhcmdjID09IDIpIHsKICAgICAgICBpZiAoKHl5aW4gPSBmb3Blbihhcmd2WzFdLCAmcXVvdDtyJnF1b3Q7KSkgPT0gTlVMTCkgewogICAgICAgICAgICBwcmludGYoJnF1b3Q7SW1wb3NzaWJsZSBkJ291dnJpciBsZSBmaWNoaWVyICZsdDslcyZndDsuXG4mcXVvdDssIGFyZ3ZbMV0pOwogICAgICAgICAgICBleGl0KDMpOwogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgcHJpbnRmKCZxdW90O1VzYWdlIDogJXMgW25vbV9kdV9maWNoaWVyXVxuJnF1b3Q7LCBhcmd2WzBdKTsKICAgICAgICBleGl0KDIpOwogICAgfQoKICAgIHdoaWxlICgodGMgPSB5eWxleCgpKSkgewogICAgICAgIHN3aXRjaCh0YykgewogICAgICAgICAgICBjYXNlIFBWOiAgICBwcmludGYoJnF1b3Q7Jmx0O1BWLCAmZ3Q7XG4mcXVvdDspOyBicmVhazsKICAgICAgICAgICAgY2FzZSBJRjogICAgcHJpbnRmKCZxdW90OyZsdDtJRiwgJmd0O1xuJnF1b3Q7KTsgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgRUdBTDogIHByaW50ZigmcXVvdDsmbHQ7RUdBTCwgJmd0O1xuJnF1b3Q7KTsgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgQVNTSUdOOnByaW50ZigmcXVvdDsmbHQ7QVNTSUdOLCAmZ3Q7XG4mcXVvdDspOyBicmVhazsKICAgICAgICAgICAgY2FzZSBPUDogICAgcHJpbnRmKCZxdW90OyZsdDtPUCwgJXMmZ3Q7XG4mcXVvdDssIHl5bHZhbC5jb3A9PVBMVVM/JnF1b3Q7UExVUyZxdW90OzomcXVvdDtNT0lOUyZxdW90Oyk7IGJyZWFrOwogICAgICAgICAgICBjYXNlIFBBUkc6ICBwcmludGYoJnF1b3Q7Jmx0O1BBUkcsICZndDtcbiZxdW90Oyk7IGJyZWFrOwogICAgICAgICAgICBjYXNlIFBBUkQ6ICBwcmludGYoJnF1b3Q7Jmx0O1BBUkQsICZndDtcbiZxdW90Oyk7IGJyZWFrOwogICAgICAgICAgICBjYXNlIElEOiAgICBwcmludGYoJnF1b3Q7Jmx0O0lELCAlcyZndDtcbiZxdW90OywgeXlsdmFsLm5vbSk7IGJyZWFrOwogICAgICAgICAgICBjYXNlIE5VTTogICBwcmludGYoJnF1b3Q7Jmx0O05VTSwgJWQmZ3Q7XG4mcXVvdDssIHl5bHZhbC52YWxldXIpOyBicmVhazsKICAgICAgICB9CiAgICB9CgogICAgcHJpbnRmKCZxdW90OyZsdDtGSU4sICZndDtcbiZxdW90Oyk7CiAgICByZXR1cm4gMDsKfQ==
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
/* Définition des tokens */
enum TOKEN { FIN=0, PV, IF, EGAL, ASSIGN, OP, PARG, PARD, ID, NUM };
/* Pour stocker les attributs */
enum CODEOPERATION { PLUS, MOINS };
union {
char *nom; /* Pour ID */
int valeur; /* Pour NUM */
enum CODEOPERATION cop; /* Pour OP */
} yylval;
/* Prototype de la fonction d'erreur */
void erreur_lexicale();
%}
%option yylineno
/* Définitions régulières */
blancs [ \t\n]+
lettre [A-Za-z]
chiffre [0-9]
ident {lettre}({lettre}|{chiffre}|_)*
%%
/* Ignorer espaces et commentaires */
{blancs} ;
\{[^}]*\} ; /* commentaire entre { et } */
/* Règles lexicales */
if { return IF; }
";" { return PV; }
"==" { return EGAL; }
":=" { return ASSIGN; }
[+-] {
if (yytext[0] == '+') yylval.cop = PLUS;
else yylval.cop = MOINS;
return OP;
}
"(" { return PARG; }
")" { return PARD; }
{chiffre}+ {
yylval.valeur = atoi(yytext);
return NUM;
}
{ident} {
yylval.nom = (char *)malloc(strlen(yytext)+1);
strcpy(yylval.nom, yytext);
return ID;
}
/* Caractère illégal */
. { erreur_lexicale(); }
%%
int yywrap() {
return 1;
}
/* Fonction d'erreur */
void erreur_lexicale() {
printf("Ligne %d : erreur lexicale, '%c' caractère illégal.\n", yylineno, yytext[0]);
exit(1);
}
/* Fonction principale */
int main(int argc, char **argv) {
enum TOKEN tc;
if (argc == 2) {
if ((yyin = fopen(argv[1], "r")) == NULL) {
printf("Impossible d'ouvrir le fichier <%s>.\n", argv[1]);
exit(3);
}
} else {
printf("Usage : %s [nom_du_fichier]\n", argv[0]);
exit(2);
}
while ((tc = yylex())) {
switch(tc) {
case PV: printf("<PV, >\n"); break;
case IF: printf("<IF, >\n"); break;
case EGAL: printf("<EGAL, >\n"); break;
case ASSIGN:printf("<ASSIGN, >\n"); break;
case OP: printf("<OP, %s>\n", yylval.cop==PLUS?"PLUS":"MOINS"); break;
case PARG: printf("<PARG, >\n"); break;
case PARD: printf("<PARD, >\n"); break;
case ID: printf("<ID, %s>\n", yylval.nom); break;
case NUM: printf("<NUM, %d>\n", yylval.valeur); break;
}
}
printf("<FIN, >\n");
return 0;
}