#include "parser.h" #include using namespace MM_PARSER; using namespace std; static void erreur(char *mesg) { printf("ERREUR PARSER : %s\n",mesg); exit(1); } static char Minuscule(char c) { if ((c<='Z') && (c>='A')) return (c-'A')+'a'; else return c; } // ************************************************ // LEXER // ************************************************ Lexer::Lexer(char *nom,int mode) { the_end=false; endline=((mode & EOL_TOKEN)!=0); nb_ligne=0; sensitive=((mode & CASE_SENSITIVE)!=0); if (!(f=fopen(nom,"r"))) erreur("OUVERTURE FICHIER"); SkipCar(); // SkipToken(); } Lexer::~Lexer() { printf("nb lignes analysee fichier = %d\n",nb_ligne); fclose(f); } bool Lexer::IsEnd() { return the_end; } bool Lexer::IsEol() { if ((le_token==INCONNU) && (la_chaine[0]==(char)10)) return true; else return false; } void Lexer::PasserEspaceLigne() { if (endline) while (le_car==' ') { SkipCar(); } else while ((le_car==' ') || (le_car==(char)10)) { if (le_car==(char)10) nb_ligne++; SkipCar(); } } void Lexer::LireLigne() { while (le_car!=(char)10) SkipCar(); SkipCar(); } bool Lexer::SkipCar() { if (feof(f)) { le_token=FIN; the_end=true; le_car='\0'; return false; } fscanf(f,"%c",&le_car); if (!sensitive) le_car=Minuscule(le_car); return true; } bool Lexer::IsDigit() { return (((le_car<='9') && (le_car>='0'))); } bool Lexer::EstSeparateur() { switch (le_car) { case '(': case ')': case';': case ' ': case '{': case '}': case (char)10: return true;break; default:return false; } } void Lexer::SkipNaturel() { le_int=0; int signe=1; if (le_car=='-') signe=-1; if ((le_car=='-') || (le_car=='+')) SkipCar(); if (!IsDigit()) erreur("SkipNaturel"); while (IsDigit()) { le_int=le_int*10+((int)(le_car-'0')); SkipCar(); } le_int=le_int*signe; } void Lexer::SkipNombre() { le_reel=0.0; double signe=1.0; if (le_car=='-') signe=-1.0; if (IsDigit() || (le_car=='-') || (le_car=='+')) SkipNaturel(); if (le_car=='.') { double frac,puis; frac=0.0; puis=1; le_token=REEL; SkipCar(); le_reel=(double)le_int; while (IsDigit()) { puis=puis/10.0; le_reel=le_reel+signe*(double)((int)(le_car-'0'))*puis; SkipCar(); } } else le_token=NATUREL; } void Lexer::Check() { if (nb_ligne<=1000) { switch(le_token) { case INCONNU:printf("sans semantique = %s\n",la_chaine);break; case REEL:printf("reel = %f\n",le_reel);break; case NATUREL:printf("naturel = %d\n",le_int);break; case FIN:printf("FIN\n");break; case CONST_CHAINE: printf("CONST CHAINE = %s\n",la_chaine); break; default: printf("semantique : %s\n",la_chaine); } } } void Lexer::SkipToken() { la_chaine[0]='\0'; int pos=0; PasserEspaceLigne(); if (the_end) { le_token=FIN; } else if (EstSeparateur()) { if (le_car==(char)10) nb_ligne++; la_chaine[pos]=le_car; la_chaine[pos+1]='\0'; le_token=INCONNU; SkipCar(); } else { if ((IsDigit()) || (le_car=='.') || (le_car=='+') || (le_car=='-')) { SkipNombre(); } else if (le_car=='"') { SkipCar(); while (le_car!='"') { if (IsEnd()) erreur("Lecture chaine constante non terminée\n"); la_chaine[pos++]=le_car; SkipCar(); } SkipCar(); le_token=CONST_CHAINE; la_chaine[pos]=0; } else { while (!EstSeparateur()) { la_chaine[pos++]=le_car; SkipCar(); } le_token=INCONNU; la_chaine[pos]='\0'; } } } // ********************************************************************* // PARSER // ********************************************************************* // mode -> CASE_SENSITIVE | EOL_TOKEN (non par défaut) Parser::Parser(char *nom,int mode) : lex(nom,mode) { // NE PAS FAIRE SKIPTOKEN ICI (le faire dans les classes dérivées) !!! printf("******************************\n"); printf("Parsing : %s\n",nom); } void Parser::Analyse() { while (!lex.IsEnd()) { lex.SkipToken(); lex.Check(); } printf("nb_ligne : %d\n",lex.NbLigne()); } Parser::~Parser() { printf("*******************************\n"); } int Parser::LireEntier() { int res; if (Lex().token()==NATUREL) { res=Lex().Entier(); } else erreur("entier attendu"); SkipToken(); return res; } double Parser::LireReel() { double res; if (Lex().token()==REEL) { res=Lex().Reel(); } else if (Lex().token()==NATUREL) { res=Lex().Entier(); } else erreur("reel attendu"); SkipToken(); return res; } Token &Parser::token() { return lex.token(); } void Parser::SkipToken() { lex.SkipToken(); if (Token()==INCONNU) { if (mots[lex.Chaine()]) lex.token()=mots[lex.Chaine()]; } } // *********************************************************************************** /*********************************************************/ /* PARSER BRP */ /*********************************************************/ void ParserBRP::Lire(MObjet *o) { int nbv; int nbf; nbv=LireEntier(); //+1; nbf=LireEntier(); SkipToken();SkipToken(); printf("%d,%d\n",nbv,nbf); int i; double x,y,z; for(i=0;ip=Point3D(x,y,z); o->v.push_back(vv); } cout << "nbre face du fichier = " << nbf << endl; // nbf=LireEntier();SkipToken(); int j; Facet *f; for(j=0;jf.push_back(f); int n=LireEntier();// SkipToken(); for(int h=0;hv.push_back(o->v[LireEntier()]); } SkipToken(); SkipToken(); } } MObjet *ParserBRP::Lire() { MObjet *res=new MObjet; this->Lire(res); return res; }