NoeudSeqInst* LecteurPhraseSimple::seqInst() { // <seqInst> ::= <inst> ; { <inst> ; } NoeudSeqInst* si = new NoeudSeqInst(); for(;;) //HACK permet de reprendre si on tombe sur quelque chose qui est : ni une instruction ni un début de block ni une fin de block //Pas très propre de faire comme ça mais sinon je suis obligé de faire une condition pour le while absolument énorme { while ( ls.getSymCour() =="<VARIABLE>" || ls.getSymCour() =="si" || ls.getSymCour() =="tantque"|| ls.getSymCour() =="repeter" || ls.getSymCour() =="lire" || ls.getSymCour() =="ecrire" ) { //tant qu'on est au debut d'une instruction try { si->ajouteInstruction ( inst() ); sauterSymCour ( ";" ); } catch(const SyntaxError& e) { traitementErreur(e); } } if( ls.getSymCour()=="<FINDEFICHIER>"||ls.getSymCour()=="fin"||ls.getSymCour()=="fintantque"||ls.getSymCour()=="sinonsi"||ls.getSymCour()=="sinon"||ls.getSymCour()=="finsi"||ls.getSymCour()=="jusqua" ) //Si on est sur un symbole indiquant la fin d'un block, on remonte d'un niveau return si; else // Y a un problème, on attendait une instruction ou une fin de block et on a autre chose { string buf; buf+="Attendu : Instruction ou Fin de block"; buf+="\nTrouve : "; buf+=ls.getSymCour().getChaine(); traitementErreur(SyntaxError(ls.getLigne(),ls.getColonne(),buf)); } } }
Noeud* Interpreteur::seqInst() { // <seqInst> ::= <inst> { <inst> } NoeudSeqInst* sequence = new NoeudSeqInst(); do { sequence->ajoute(inst()); } while (m_lecteur.getSymbole() == "<VARIABLE>" || m_lecteur.getSymbole() == "si" || m_lecteur.getSymbole() == "tantque" || m_lecteur.getSymbole() == "repeter" || m_lecteur.getSymbole() == "pour" || m_lecteur.getSymbole() == "ecrire" || m_lecteur.getSymbole() == "lire" || m_lecteur.getSymbole() == "appel"); // Tant que le symbole courant est un début possible d'instruction... // Il faut compléter cette condition chaque fois qu'on rajoute une nouvelle instruction return sequence; }
Noeud* LecteurPhraseSimple::instSi() { /** NOTE * Le Si/SinonSi/Sinon est décomposé en Si/Sinon * Le SinonSi est alors transformé en Sinon Si * Un exemple: * Si(a) * SinonSi(b) * Sinon * FinSi * sera transformé en arbre de cette forme: * Si(a) * Sinon * Si(b) * Sinon * FinSi * FinSi * * Dans le code c++, -SeqInstVrai représente les instructions éxécutés si la condition est vrai * -SeqInstFaux représente les instructions éxécutés si la condition est faux * */ bool sinonsi=ls.getSymCour() =="sinonsi"; suivant(); sauterSymCour ( "(" ); Noeud* Condition=expBool(); sauterSymCour ( ")" ); NoeudSeqInst* seqInstVrai=seqInst(); NoeudSeqInst* seqInstFaux; if ( ls.getSymCour() =="sinonsi" ) { seqInstFaux=new NoeudSeqInst(); seqInstFaux->ajouteInstruction ( instSi() ); } else if ( ls.getSymCour() =="sinon" ) { suivant(); seqInstFaux=seqInst(); } else { seqInstFaux=new NoeudSeqInst(); } testerSymCour ( "finsi" ); if ( !sinonsi ) sauterSymCour ( "finsi" ); return new NoeudSi ( Condition,seqInstVrai,seqInstFaux ); }
// <seqInst> ::= <inst> ; { <inst> ; } Noeud* LecteurPhraseAvecArbre::seqInst() { // tant que le symbole courant est un debut possible d'instruction... NoeudSeqInst *si = new NoeudSeqInst(); do { si->ajouteInstruction(inst()); sauterSymCour(";"); } while (ls.getSymCour() != "fin" && ls.getSymCour() != "finsi" && ls.getSymCour() != "sinonsi" && ls.getSymCour() != "sinon" && ls.getSymCour() != "fintantque" && ls.getSymCour() != "jusqua" && ls.getSymCour() != "finpour" && ls.getSymCour() != "case" && ls.getSymCour() != "finswitch"); return si; }