Chronoklazm | Voila j'ai deux petits problemes avec mon lexer (pas de flex) pour le petit langage Logo. La reconnaissance des operateurs '<< ' se fait correctement mais dès que il y a un nombre (ou autre à part un espace) tout de suite apres ... ça gouille.
exemple : '<<20' donnera 'operateur nombre' au lieu de 'operateur operateur nombre'
alors que
'<<' donne bien 'operateur operateur' Et ma deuxième question concerne la gestion des identificateurs (qui sont à priori gerés dans le meme état que les mot-cle et le sens), en fait il faut pouvoir reconnaitre le lexeme le plus long (par convention) donc par exemple le motcle "avancer" devra etre reconnu au lieu d'une suite d'identificateurs "a","v","a","n"...
Je pense qu'il faut d'abord que je teste la correspondance avec un motcle puis si elle echoue tester la reconnaisance d'un id.
Voici le source :
Code :
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- /* Macros pour les mots clef */
- #define IDENTIFICATEUR 1
- #define MOTCLE 2
- #define SENS 3
- #define OPERATEUR 4
- #define ANGLE 5
- #define NOMBRE 6
- #define FIN 7
- #define ERROR 0
- /* La fonction getkar */
- int getkar(FILE* fp){
- int x = fgetc(fp);
- if((x == '\n') || (x == '\r')) printf("\n" );
- if(isspace(x))
- printf("" );
- else
- printf("\n :- %c\n ", x); //afficher le lexeme lus
- return x;
-
- }
- /* La fonction lexer */
- int lexer(FILE* fp){
- int s, z, i = 0; /* z est le carac lus et i indice du buffer */
- char etat = 'a';
- short exception1=0; /* Variable pour gerer l'exception du lexeme ANGLE */
- char buf[50]="";
- char temp;
-
- while(s<= 12){
- printf("Etat => %c", etat);
-
- if(feof(fp) || z==EOF) return FIN;
- s++;
- z=getkar(fp);
- if(isspace(z)){
- i=0;
- //continue;
- }
- if(isalpha(z)){ etat='h';}
- if(z =='.') etat='d';
- if(z =='<') { etat='e';}
- if(z =='>') { etat='g';}
- if(z == ':') { etat = 'i';}
- if(strchr("+-*/(){}", z)) { etat = 'f'; }
- if(isdigit(z) || exception1==1) {exception1=0; etat='b'; }
- /* Pour le caractere '=' on definit l'etat selon le caractere temporisé precedement */
- if(z == '=')
- {
- if (temp==':') etat='i';
- else if (temp=='<') etat='e';
- else if (temp=='>') etat='g';
- else etat = 'f';
- }
- /* A PARTIR D'ICI ON A LA GESTION DES ETATS */
-
- /* Si on se trouve dans cet etat c'est que on a deja lu un nombre.
- Donc si on lit autre chose qu'un nombre (à part g ou d ou r)
- alors on renvoi un nombre etc ... */
- if(etat=='b'){
- if(isdigit(z)){
- exception1=1;
- continue;
- }
- else{
- if(strchr("gdr",z)) return ANGLE;
- else return NOMBRE;
- }
- }
- /* Etat pour detecter les motcle, id et sens */
- if (etat=='h'){
- if (isalnum(z)){
- buf[i]=z;
- i++;
- //printf(" buffer : %s\n", buf);
- if ((strcmp(buf, "avancer" ) == 0) ||
- (strcmp(buf, "lever" ) == 0) ||
- (strcmp(buf, "poser" ) == 0) ||
- (strcmp(buf, "tourner" ) == 0) ||
- (strcmp(buf, "pour" ) == 0) ||
- (strcmp(buf, "sinon" ) == 0) ||
- (strcmp(buf, "tantque" ) == 0) ||
- (strcmp(buf, "si" ) == 0))
- {
-
- //printf(" buffer : %s\n", buf);
- return MOTCLE;
- }
-
- else if ((strcmp(buf,"gauche" )==0) || (strcmp(buf, "droite" ) == 0)) return SENS;
- else continue;
- }
- else{
- ungetc(z, fp);
- continue;
- }
-
- }
- /* - Gestion de l'operateur '<' et '<=' */
- if (etat=='e'){
- if(!isspace(z)){
- if(z=='=' && temp=='<') return OPERATEUR;
- else if(z!='=' && temp=='<') {ungetc(z, fp); return OPERATEUR;}
- else {temp='<'; continue;}
- }
- else{
- if(temp=='<') return OPERATEUR;
- else continue;
- }
- }
- /* - Gestion de l'operateur '>' et '>=' */
- if (etat=='g'){
- if(!isspace(z)){
- if(z=='=' && temp=='>') return OPERATEUR;
- else if(z!='=' && temp=='>') {ungetc(z, fp); return OPERATEUR;}
- else {temp='>'; continue;}
- }
- else{
- if(temp=='>') return OPERATEUR;
- else continue;
- }
- }
- /* Gestion de l'operateur ':=' */
- if (etat=='i'){
- if(!isspace(z)){
- if(z=='=' && temp==':') return OPERATEUR;
- else if(z!='=' && temp==':') {ungetc(z, fp); return ERROR;}
- else {temp=':'; continue;}
- }
- else{
- if(temp==':') return ERROR;
- else continue;
- }
- }
- /* Gestion de l'operateur '.' et '..' */
- if (etat=='d'){
- if(!isspace(z)){
- if(z=='.' && temp=='.') return OPERATEUR;
- else if(z!='.' && temp=='.') {ungetc(z, fp); return ERROR;}
- else {temp='.'; continue;}
- }
- else{
- if(temp=='.') return ERROR;
- else continue;
- }
- }
-
- if (etat=='f') return OPERATEUR;
-
- }
- return FIN;
- }
- int main(int argc, char *argv[]){
- FILE* fp = fopen("source.txt", "r" );
-
- int x=0;
- while(x!=FIN){
-
- x = lexer(fp);
- printf(" " );
- if (x==ERROR) printf("Erreur! " );
- switch (x)
- {
- case IDENTIFICATEUR:
- printf("ident " );
- break;
- case MOTCLE :
- printf("mot-cle " );
- break;
- case SENS :
- printf("sens " );
- break;
- case OPERATEUR :
- printf("operateur " );
- break;
- case NOMBRE :
- printf("nombre " );
- break;
- case ANGLE :
- printf("angle " );
- break;
-
- }
- }
- exit(0);
- }
|
Message édité par Chronoklazm le 24-02-2005 à 21:40:45 ---------------
Scheme is a programmable programming language ! I heard it through the grapevine !
|