Skip to content
This repository has been archived by the owner on May 17, 2024. It is now read-only.

Commit

Permalink
Merge pull request Feelzor#27 from FeelZoR/feature-demo
Browse files Browse the repository at this point in the history
Feature demo
  • Loading branch information
NilsKrattinger authored Nov 6, 2019
2 parents 89cc5ab + 4656e85 commit e7ce034
Show file tree
Hide file tree
Showing 41 changed files with 749 additions and 130 deletions.
22 changes: 22 additions & 0 deletions ArbreAbstrait.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,26 @@ void NoeudInstEcrire::ajoute(Noeud* instruction) {

void NoeudInstEcrire::accepter(Visiteur& visiteur) {
visiteur.visiterNoeudInstEcrire(this);
}

////////////////////////////////////////////////////////////////////////////////
// NoeudInstAppel
////////////////////////////////////////////////////////////////////////////////

NoeudInstAppel::NoeudInstAppel(Symbole nom, vector<Noeud*> parametres)
: m_nom(nom), m_parametres(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);
}
37 changes: 37 additions & 0 deletions ArbreAbstrait.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,4 +198,41 @@ class NoeudInstEcrire : public Noeud {
vector<Noeud*> m_ecritures;
};

////////////////////////////////////////////////////////////////////////////////
class NoeudInstAppel : public Noeud {
// Classe pour représenter un noeud "instruction appel"
public:
NoeudInstAppel(Symbole nom, vector<Noeud*> parametres);
// Construit une "instruction appel" avec son nom et ses paramètres

~NoeudInstAppel() {
} // A cause du destructeur virtuel de la classe Noeud
void accepter(Visiteur& visiteur) override;

inline Symbole getNom() const { return m_nom; }
inline vector<Noeud*> getParametres() const { return m_parametres; }

private:
Symbole m_nom;
vector<Noeud*> 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 */
2 changes: 1 addition & 1 deletion Instruction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Instruction::Instruction() {

bool Instruction::isInstruction(Symbole sym) {
int i = 0;
while (i < 7 && !(sym == m_instructions[i])) {
while (i < 8 && !(sym == m_instructions[i])) {
i++;
}
return sym == m_instructions[i];
Expand Down
2 changes: 1 addition & 1 deletion Instruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class Instruction {
Instruction();
bool isInstruction(Symbole sym);
private:
string m_instructions[7] = {"<VARIABLE>","ecrire","si","pour","tantque","repeter","lire"};
string m_instructions[8] = {"<VARIABLE>","ecrire","si","pour","tantque","repeter","lire","appel"};

};

Expand Down
95 changes: 83 additions & 12 deletions Interpreteur.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "Interpreteur.h"
#include "Instruction.h"
#include "TableProcedures.h"
#include <stdlib.h>
#include <iostream>
using namespace std;
Expand Down Expand Up @@ -44,17 +45,49 @@ void Interpreteur::erreur(const string & message) const {
}

Noeud* Interpreteur::programme() {
// <programme> ::= procedure principale() <seqInst> finproc FIN_FICHIER
testerEtAvancer("procedure");
testerEtAvancer("principale");
testerEtAvancer("(");
testerEtAvancer(")");
Noeud* sequence = seqInst();
testerEtAvancer("finproc");
tester("<FINDEFICHIER>");
return sequence;
// <programme> ::= {procedure <procedure>} procedure principale() <seqInst> finproc FIN_FICHIER
Noeud* sequence = nullptr;
while (sequence == nullptr) {
testerEtAvancer("procedure");
if (m_lecteur.getSymbole() == "<VARIABLE>") {
procedure();
} else {
testerEtAvancer("principale");
testerEtAvancer("(");
testerEtAvancer(")");
sequence = seqInst();
testerEtAvancer("finproc");
tester("<FINDEFICHIER>");
}
}
return sequence;
}

void Interpreteur::procedure() {
// <procedure> ::= <variable>([<variable> {, <variable> }]) <seqInst> finproc
TableSymboles table = m_table;
m_table = TableSymboles();
std::vector<SymboleValue*> parametres;

tester("<VARIABLE>");
Symbole nom = m_lecteur.getSymbole();
m_lecteur.avancer();
testerEtAvancer("(");
if (m_lecteur.getSymbole() == "<VARIABLE>") {
parametres.push_back(m_table.chercheAjoute(m_lecteur.getSymbole()));
m_lecteur.avancer();
while (m_lecteur.verifierPourAvancer(",")) {
tester("<VARIABLE>");
parametres.push_back(m_table.chercheAjoute(m_lecteur.getSymbole()));
}
}
testerEtAvancer(")");
Noeud* sequence = seqInst();
testerEtAvancer("finproc");
TableProcedures::getTable()->ajoutProcedure(nom, new Procedure(m_table, sequence, parametres));
m_table = table;
}

Noeud* Interpreteur::seqInst() {
// <seqInst> ::= <inst> { <inst> }
Instruction* instructions = new Instruction();
Expand Down Expand Up @@ -101,6 +134,9 @@ Noeud* Interpreteur::inst() {
else if(m_lecteur.getSymbole() == "lire"){
return instLire();
}
else if(m_lecteur.getSymbole() == "appel"){
return instAppel();
}
else {
erreur("Instruction incorrecte");
return nullptr;
Expand Down Expand Up @@ -182,9 +218,9 @@ Noeud* Interpreteur::expMult(){
}

Noeud* Interpreteur::facteur() {
// <facteur> ::= <entier> | <variable> | - <facteur> | non <facteur> | ( <expression> )
// <facteur> ::= <entier> | <reel> | <chaine> | <variable> | - <facteur> | non <facteur> | ( <expression> ) | <alea>
Noeud* fact = nullptr;
if (m_lecteur.getSymbole() == "<VARIABLE>" || m_lecteur.getSymbole() == "<ENTIER>") {
if (m_lecteur.getSymbole() == "<VARIABLE>" || m_lecteur.getSymbole() == "<ENTIER>" || m_lecteur.getSymbole() == "<REEL>" || m_lecteur.getSymbole() == "<CHAINE>") {
fact = m_table.chercheAjoute(m_lecteur.getSymbole()); // on ajoute la variable ou l'entier à la table
m_lecteur.avancer();
} else if (m_lecteur.getSymbole() == "-") { // - <facteur>
Expand All @@ -199,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;
Expand Down Expand Up @@ -320,4 +358,37 @@ Noeud* Interpreteur::instLire(){
testerEtAvancer(")");
testerEtAvancer(";");
return var;
}
}

Noeud* Interpreteur::instAppel() {
// <appel> ::= appel <variable>([<expression> {, <expression>}]);
testerEtAvancer("appel");
tester("<VARIABLE>");
Symbole nom = m_lecteur.getSymbole();
m_lecteur.avancer();
testerEtAvancer("(");

std::vector<Noeud*> parametres;
if (m_lecteur.getSymbole() != ")") {
parametres.push_back(expression());
while (m_lecteur.verifierPourAvancer(",")) {
parametres.push_back(expression());
}
}
testerEtAvancer(")");
testerEtAvancer(";");

return new NoeudInstAppel(nom, parametres);
}

Noeud* Interpreteur::alea() {
// <alea> ::= alea(<expression>, <expression>)
testerEtAvancer("alea");
testerEtAvancer("(");
Noeud* min = expression();
testerEtAvancer(",");
Noeud* max = expression();
testerEtAvancer(")");

return new NoeudAlea(min, max);
}
11 changes: 7 additions & 4 deletions Interpreteur.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@ class Interpreteur {
Lecteur m_lecteur; // Le lecteur de symboles utilisé pour analyser le fichier
TableSymboles m_table; // La table des symboles valués
Noeud* m_arbre; // L'arbre abstrait
bool m_erreur; // Etat de l'intrpreteur
bool m_erreur; // Etat de l'interpreteur

// Implémentation de la grammaire
Noeud* programme(); // <programme> ::= procedure principale() <seqInst> finproc FIN_FICHIER
Noeud* programme(); // <programme> ::= {procedure <procedure>} procedure principale() <seqInst> finproc FIN_FICHIER
void procedure(); // <procedure> ::= <variable>([<variable> {, <variable> }]) <seqInst> finproc

Noeud* seqInst(); // <seqInst> ::= <inst> { <inst> }
Noeud* inst(); // <inst> ::= <affectation> ; | <instSi>
Expand All @@ -37,14 +38,16 @@ class Interpreteur {
Noeud* expComp(); // <expComp> ::= <expAdd> { == | != | < | <= | > | >= <expAdd> }
Noeud* expAdd(); // <expAdd> ::= <expMult> { + | - <expMult> }
Noeud* expMult(); // <expMult> ::= <facteur> { * | / <facteur> }
Noeud* facteur(); // <facteur> ::= <entier> | <variable> | - <facteur> | non <facteur> | ( <expression> )
Noeud* facteur(); // <facteur> ::= <entier> | <reel> | <chaine> | <variable> | - <facteur> | non <facteur> | ( <expression> ) | <alea>
// <opBinaire> ::= + | - | * | / | < | > | <= | >= | == | != | et | ou
Noeud* instSi(); // <instSi> ::= si ( <expression> ) <seqInst> { sinonsi (<expression>) <seqInst> } [ sinon <seqInst> ] finsi
Noeud* instPour(); // <instPour> ::= pour ( [ <affectation> ] ; <expression> ; [ <affection> ]) <seqInst> finpour
Noeud* instTantQue(); // <instTantQue> ::= tantque ( <expression> ) <seqInst> fintantque
Noeud* instLire(); // <instLire> ::= lire (variable {, variable});
Noeud* instLire(); // <instLire> ::= lire (<variable> {, <variable>});
Noeud* instEcrire(); // <instEcrire> ::= ecrire ( <expression> | <chaine> {, <expression> | <chaine> } );
Noeud* instRepeter(); // <instRepeter> ::= repeter <seqInst> jusqua ( <expression> )
Noeud* instAppel(); // <appel> ::= appel <variable>([<expression> {, <expression>}]);
Noeud* alea(); // <alea> ::= alea(<expression>, <expression>)

// outils pour simplifier l'analyse syntaxique
void tester (const string & symboleAttendu) const; // Si symbole courant != symboleAttendu, on lève une exception
Expand Down
2 changes: 1 addition & 1 deletion Lecteur.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ string Lecteur::motSuivant() {
do {
s = s + m_lecteurCar.getCaractere();
m_lecteurCar.avancer();
} while (isdigit(m_lecteurCar.getCaractere()));
} while (isdigit(m_lecteurCar.getCaractere()) || m_lecteurCar.getCaractere() == '.');

else if (isalpha(m_lecteurCar.getCaractere()))
// c'est le début d'un mot
Expand Down
14 changes: 14 additions & 0 deletions Procedure.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include "Procedure.h"

Procedure::Procedure(TableSymboles table, Noeud* sequence, std::vector<SymboleValue*> parametres)
: m_table(table), m_sequence(sequence), m_params(parametres) {}

void Procedure::accepter(Visiteur& visiteur) {
m_sequence->accepter(visiteur);
}

void Procedure::empiler(std::vector<Valeur*> parametres) {
for (int i = 0; i < parametres.size() && i < m_params.size(); i++) {
m_params[i]->setValeur(parametres[i]);
}
}
21 changes: 21 additions & 0 deletions Procedure.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#ifndef PROCEDURE_H
#define PROCEDURE_H

#include "ArbreAbstrait.h"
#include "TableSymboles.h"
#include "SymboleValue.h"
#include <vector>

class Procedure : public Noeud {
public:
Procedure(TableSymboles table, Noeud* sequence, std::vector<SymboleValue*> parametres);
void accepter(Visiteur& visiteur) override;
void empiler(std::vector<Valeur*> parametres);
private:
TableSymboles m_table;
Noeud* m_sequence;
std::vector<SymboleValue*> m_params;
};

#endif /* PROCEDURE_H */

3 changes: 3 additions & 0 deletions Symbole.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const char * Symbole::FICHIER_MOTS_CLES = "motsCles.txt";
Symbole::Symbole(const string & s) : m_chaine(s) {
// attention : l'ordre des tests ci-dessous n'est pas innocent !
if (s == "") this->m_categorie = FINDEFICHIER;
else if (isdigit(s[0]) && s.find('.') != string::npos) this->m_categorie = REEL;
else if (isdigit(s[0])) this->m_categorie = ENTIER;
else if (s.size() >= 2 && s[0] == '"' && s[s.size() - 1] == '"') this->m_categorie = CHAINE;
else if (isMotCle(s)) this->m_categorie = MOTCLE;
Expand All @@ -22,6 +23,7 @@ bool Symbole::operator==(const string & ch) const {
return this->m_chaine == ch ||
(this->m_categorie == VARIABLE && (ch == "<VARIABLE>" || ch == "<variable>")) ||
(this->m_categorie == ENTIER && (ch == "<ENTIER>" || ch == "<entier>")) ||
(this->m_categorie == REEL && (ch == "<REEL>" || ch == "<reel>")) ||
(this->m_categorie == CHAINE && (ch == "<CHAINE>" || ch == "<chaine>")) ||
(this->m_categorie == INDEFINI && (ch == "<INDEFINI>" || ch == "<indefini>")) ||
(this->m_categorie == FINDEFICHIER && (ch == "<FINDEFICHIER>" || ch == "<findefichier>"));
Expand Down Expand Up @@ -56,6 +58,7 @@ ostream & operator<<(ostream & cout, const Symbole & symbole) {
if (symbole.m_categorie == Symbole::MOTCLE) cout << "<MOTCLE> ";
else if (symbole.m_categorie == Symbole::VARIABLE) cout << "<VARIABLE> ";
else if (symbole.m_categorie == Symbole::ENTIER) cout << "<ENTIER> ";
else if (symbole.m_categorie == Symbole::REEL) cout << "<REEL> ";
else if (symbole.m_categorie == Symbole::CHAINE) cout << "<CHAINE> ";
else if (symbole.m_categorie == Symbole::INDEFINI) cout << "<INDEFINI> ";
else if (symbole.m_categorie == Symbole::FINDEFICHIER) cout << "<FINDEFICHIER>";
Expand Down
2 changes: 1 addition & 1 deletion Symbole.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class Symbole {
friend ostream & operator <<(ostream & cout, const Symbole & symbole); // Fonction amie pour pouvoir afficher un symbole sur cout

private:
enum m_categorie { MOTCLE, VARIABLE, ENTIER, CHAINE, INDEFINI, FINDEFICHIER };
enum m_categorie { MOTCLE, VARIABLE, ENTIER, REEL, CHAINE, INDEFINI, FINDEFICHIER };
string m_chaine; // Chaîne du symbole
m_categorie m_categorie; // Categorie du symbole (voir type énuméré ci-dessus)
bool isMotCle(const string & s) const; // Renvoie vrai si s est un mot clé du langage
Expand Down
17 changes: 14 additions & 3 deletions SymboleValue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,19 @@
#include "Exceptions.h"
#include "Visiteur.h"
#include <stdlib.h>
#include "ValeurEntiere.h"
#include "ValeurReelle.h"
#include "ValeurChaine.h"

SymboleValue::SymboleValue(const Symbole & s) :
Symbole(s.getChaine()) {
if (s == "<ENTIER>") {
m_valeur = atoi(s.getChaine().c_str()); // c_str convertit une string en char*
m_defini = true;
setValeur(atoi(s.getChaine().c_str())); // c_str convertit une string en char*
} else if (s == "<CHAINE>") {
m_valeur = -1;
this->m_valeur = new ValeurChaine(s.getChaine().substr(1, s.getChaine().size() - 2));
m_defini = true;
} else if (s == "<REEL>") {
this->m_valeur = new ValeurReelle(stof(s.getChaine()));
m_defini = true;
} else {
m_defini = false;
Expand All @@ -26,3 +31,9 @@ ostream & operator<<(ostream & cout, const SymboleValue & symbole) {
else cout << "indefinie ";
return cout;
}


void SymboleValue::setValeur(int valeur) {
this->m_valeur=new ValeurEntiere(valeur);
m_defini=true;
}
Loading

0 comments on commit e7ce034

Please sign in to comment.