diff --git a/ArbreAbstrait.cpp b/ArbreAbstrait.cpp index d169a97..ada74bd 100644 --- a/ArbreAbstrait.cpp +++ b/ArbreAbstrait.cpp @@ -147,3 +147,13 @@ NoeudInstAppel::NoeudInstAppel(Symbole nom, vector parametres) void NoeudInstAppel::accepter(Visiteur& visiteur) { visiteur.visiterNoeudInstAppel(this); } + +//////////////////////////////////////////////////////////////////////////////// +// NoeudInstAlea +//////////////////////////////////////////////////////////////////////////////// + +NoeudAlea::NoeudAlea(Noeud* min, Noeud* max) : m_min(min), m_max(max) {} + +void NoeudAlea::accepter(Visiteur& visiteur) { + visiteur.visiterNoeudAlea(this); +} diff --git a/ArbreAbstrait.h b/ArbreAbstrait.h index 4b2f014..99155c0 100644 --- a/ArbreAbstrait.h +++ b/ArbreAbstrait.h @@ -203,7 +203,7 @@ class NoeudInstAppel : public Noeud { // Classe pour représenter un noeud "instruction appel" public: NoeudInstAppel(Symbole nom, vector parametres); - // Construit une "instruction appel" avec sa condition et sa séquence d'instruction + // Construit une "instruction appel" avec son nom et ses paramètres ~NoeudInstAppel() { } // A cause du destructeur virtuel de la classe Noeud @@ -217,4 +217,22 @@ class NoeudInstAppel : public Noeud { vector m_parametres; }; +//////////////////////////////////////////////////////////////////////////////// +class NoeudAlea : public Noeud { + // Classe pour représenter un noeud "alea" +public: + NoeudAlea(Noeud* min, Noeud* max); + // Construit un "alea" avec son min et son max + + ~NoeudAlea() { + } // A cause du destructeur virtuel de la classe Noeud + void accepter(Visiteur& visiteur) override; + + inline Noeud* getMin() const { return m_min; } + inline Noeud* getMax() const { return m_max; } + +private: + Noeud* m_min; + Noeud* m_max; +}; #endif /* ARBREABSTRAIT_H */ diff --git a/Interpreteur.cpp b/Interpreteur.cpp index fbfc554..4b733f9 100644 --- a/Interpreteur.cpp +++ b/Interpreteur.cpp @@ -218,7 +218,7 @@ Noeud* Interpreteur::expMult(){ } Noeud* Interpreteur::facteur() { - // ::= | | | | - | non | ( ) + // ::= | | | | - | non | ( ) | Noeud* fact = nullptr; if (m_lecteur.getSymbole() == "" || m_lecteur.getSymbole() == "" || m_lecteur.getSymbole() == "" || m_lecteur.getSymbole() == "") { fact = m_table.chercheAjoute(m_lecteur.getSymbole()); // on ajoute la variable ou l'entier à la table @@ -235,6 +235,8 @@ Noeud* Interpreteur::facteur() { m_lecteur.avancer(); fact = expression(); testerEtAvancer(")"); + } else if (m_lecteur.getSymbole() == "alea") { + fact = alea(); } else erreur("Facteur incorrect"); return fact; @@ -377,4 +379,16 @@ Noeud* Interpreteur::instAppel() { testerEtAvancer(";"); return new NoeudInstAppel(nom, parametres); +} + +Noeud* Interpreteur::alea() { + // ::= alea(, ) + testerEtAvancer("alea"); + testerEtAvancer("("); + Noeud* min = expression(); + testerEtAvancer(","); + Noeud* max = expression(); + testerEtAvancer(")"); + + return new NoeudAlea(min, max); } diff --git a/Interpreteur.h b/Interpreteur.h index 666cdc8..bca525c 100644 --- a/Interpreteur.h +++ b/Interpreteur.h @@ -38,7 +38,7 @@ class Interpreteur { Noeud* expComp(); // ::= { == | != | < | <= | > | >= } Noeud* expAdd(); // ::= { + | - } Noeud* expMult(); // ::= { * | / } - Noeud* facteur(); // ::= | | | | - | non | ( ) + Noeud* facteur(); // ::= | | | | - | non | ( ) | // ::= + | - | * | / | < | > | <= | >= | == | != | et | ou Noeud* instSi(); // ::= si ( ) { sinonsi () } [ sinon ] finsi Noeud* instPour(); // ::= pour ( [ ] ; ; [ ]) finpour @@ -47,6 +47,7 @@ class Interpreteur { Noeud* instEcrire(); // ::= ecrire ( | {, | } ); Noeud* instRepeter(); // ::= repeter jusqua ( ) Noeud* instAppel(); // ::= appel ([ {, }]); + Noeud* alea(); // ::= alea(, ) // outils pour simplifier l'analyse syntaxique void tester (const string & symboleAttendu) const; // Si symbole courant != symboleAttendu, on lève une exception diff --git a/Visiteur.h b/Visiteur.h index a9f7746..c2b592e 100644 --- a/Visiteur.h +++ b/Visiteur.h @@ -31,6 +31,7 @@ class Visiteur { virtual void visiterNoeudInstLire(NoeudInstLire* noeud) = 0; virtual void visiterNoeudInstEcrire(NoeudInstEcrire* noeud) = 0; virtual void visiterNoeudInstAppel(NoeudInstAppel* noeud) = 0; + virtual void visiterNoeudAlea(NoeudAlea* noeud) = 0; virtual void visiterSymboleValue(SymboleValue* symbole) = 0; }; diff --git a/VisiteurCompiler.cpp b/VisiteurCompiler.cpp index 7685a52..afdd1b5 100644 --- a/VisiteurCompiler.cpp +++ b/VisiteurCompiler.cpp @@ -162,6 +162,14 @@ void VisiteurCompiler::visiterNoeudInstAppel(NoeudInstAppel* noeud) { m_out << ")" << endl; } +void VisiteurCompiler::visiterNoeudAlea(NoeudAlea* noeud) { + m_out << "random.randint("; + noeud->getMin()->accepter(*this); + m_out << ","; + noeud->getMax()->accepter(*this); + m_out << ")" << endl; +} + void VisiteurCompiler::visiterSymboleValue(SymboleValue* symbole) { m_out << symbole->getChaine(); } \ No newline at end of file diff --git a/VisiteurCompiler.h b/VisiteurCompiler.h index 427db9d..0a0d8fa 100644 --- a/VisiteurCompiler.h +++ b/VisiteurCompiler.h @@ -19,6 +19,7 @@ class VisiteurCompiler : public Visiteur { void visiterNoeudInstLire(NoeudInstLire* noeud) override; void visiterNoeudInstEcrire(NoeudInstEcrire* noeud) override; void visiterNoeudInstAppel(NoeudInstAppel* noeud) override; + void visiterNoeudAlea(NoeudAlea* noeud) override; void visiterSymboleValue(SymboleValue* symbole) override; private: diff --git a/VisiteurExecuter.cpp b/VisiteurExecuter.cpp index 217d46d..57ac0b5 100644 --- a/VisiteurExecuter.cpp +++ b/VisiteurExecuter.cpp @@ -112,6 +112,14 @@ void VisiteurExecuter::visiterNoeudInstAppel(NoeudInstAppel* noeud) { TableProcedures::getTable()->executerProcedure(noeud->getNom(), noeud->getParametres(), *this); } +void VisiteurExecuter::visiterNoeudAlea(NoeudAlea* noeud) { + noeud->getMin()->accepter(*this); + int min = m_derniereValeur->getEntier(); + noeud->getMax()->accepter(*this); + int max = m_derniereValeur->getEntier(); + m_derniereValeur = new ValeurEntiere(rand() % (max - min) + min); +} + void VisiteurExecuter::visiterSymboleValue(SymboleValue* symbole) { if (!symbole->estDefini()) throw IndefiniException(); // on lève une exception si valeur non définie m_derniereValeur = symbole->getValeur(); diff --git a/VisiteurExecuter.h b/VisiteurExecuter.h index 68ef94b..6f85bb5 100644 --- a/VisiteurExecuter.h +++ b/VisiteurExecuter.h @@ -17,6 +17,7 @@ class VisiteurExecuter : public Visiteur { void visiterNoeudInstLire(NoeudInstLire* noeud) override; void visiterNoeudInstEcrire(NoeudInstEcrire* noeud) override; void visiterNoeudInstAppel(NoeudInstAppel* noeud) override; + void visiterNoeudAlea(NoeudAlea* noeud) override; void visiterSymboleValue(SymboleValue* symbole) override; inline Valeur* getDerniereValeur() { return m_derniereValeur; } diff --git a/main.cpp b/main.cpp index 4144333..9ac6f3e 100644 --- a/main.cpp +++ b/main.cpp @@ -12,6 +12,7 @@ using namespace std; void compiler(ostream& out, const TableSymboles& symboles, Noeud* arbre); int main(int argc, char* argv[]) { + srand (time(NULL)); bool compile = false; string nomFich; ofstream o; @@ -73,6 +74,7 @@ int main(int argc, char* argv[]) { } void compiler(ostream& out, const TableSymboles& symboles, Noeud* arbre) { + out << "import random" << endl; VisiteurCompiler visiteur(out, 0); TableProcedures::getTable()->compilerProcedures(visiteur); arbre->accepter(visiteur); diff --git a/motsCles.txt b/motsCles.txt index 7e5f609..2699be0 100644 --- a/motsCles.txt +++ b/motsCles.txt @@ -34,3 +34,4 @@ et ou non appel +alea \ No newline at end of file diff --git a/pom.txt b/pom.txt new file mode 100644 index 0000000..a4068eb --- /dev/null +++ b/pom.txt @@ -0,0 +1,18 @@ +procedure principale() + ecrire("Entrez le minimum et le maximum : "); + lire(min, max); + nbMyst = alea(min, max); + nbDevin = nbMyst - 1; + nbCoups = 0; + tantque (nbDevin != nbMyst) + lire(nbDevin); + nbCoups = nbCoups + 1; + si (nbMyst > nbDevin) + ecrire("C'est plus"); + sinonsi (nbMyst < nbDevin) + ecrire("C'est moins"); + finsi + fintantque + + ecrire("Bravo, vous avez trouvé en ", nbCoups, " coup(s)"); +finproc \ No newline at end of file diff --git a/testSi.txt b/test01-SiSinonSi.txt similarity index 100% rename from testSi.txt rename to test01-SiSinonSi.txt diff --git a/testTantQue.txt b/test02-TantQue.txt similarity index 100% rename from testTantQue.txt rename to test02-TantQue.txt diff --git a/testRepeter.txt b/test03-Repeter.txt similarity index 100% rename from testRepeter.txt rename to test03-Repeter.txt diff --git a/testPour.txt b/test04-Pour.txt similarity index 100% rename from testPour.txt rename to test04-Pour.txt diff --git a/testEcrire.txt b/test05-Ecrire.txt similarity index 100% rename from testEcrire.txt rename to test05-Ecrire.txt diff --git a/testLire.txt b/test06-Lire.txt similarity index 100% rename from testLire.txt rename to test06-Lire.txt diff --git a/testPourErreurSyntaxe.txt b/test07-PourErreurSyntaxe.txt similarity index 100% rename from testPourErreurSyntaxe.txt rename to test07-PourErreurSyntaxe.txt diff --git a/test08-alea.txt b/test08-alea.txt new file mode 100644 index 0000000..c744db8 --- /dev/null +++ b/test08-alea.txt @@ -0,0 +1,6 @@ +# Résultat attendu : +# i : Nombre entre 1 et 100 + +procedure principale() + i = alea(1, 100); +finproc diff --git a/testProcedure.txt b/test09-Procedure.txt similarity index 100% rename from testProcedure.txt rename to test09-Procedure.txt diff --git a/testAffectation.txt b/testAffectation.txt index b99bec6..cb02f7f 100644 --- a/testAffectation.txt +++ b/testAffectation.txt @@ -13,6 +13,7 @@ procedure principale() l = k + j; m = j + k; n = "Bla" * 2 + "Car"; + o = alea(3, 100); finproc diff --git a/tests/TestInstPour.cpp b/tests/TestInstPour.cpp index ed66fb2..c09bb1c 100644 --- a/tests/TestInstPour.cpp +++ b/tests/TestInstPour.cpp @@ -32,7 +32,7 @@ void TestInstPour::tearDown() { } void TestInstPour::testPour() { - std::ifstream fichier("testPour.txt"); + std::ifstream fichier("test04-Pour.txt"); if (!fichier) { CPPUNIT_ASSERT_MESSAGE("Fichier impossible à ouvrir", false); } @@ -43,12 +43,12 @@ void TestInstPour::testPour() { interpreteur.getArbre()->accepter(visiteur); const TableSymboles& table = interpreteur.getTable(); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Test valeur i", 11, table[3].getValeur()); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Test valeur j", 385, table[4].getValeur()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Test valeur i", 11, table[3].getValeur()->getEntier()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Test valeur j", 385, table[4].getValeur()->getEntier()); } void TestInstPour::testPourErreur() { - std::ifstream fichier("testPourErreurSyntaxe.txt"); + std::ifstream fichier("test07-PourErreurSyntaxe.txt"); if (!fichier) { CPPUNIT_ASSERT_MESSAGE("Fichier impossible à ouvrir", false); }