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

Commit

Permalink
feature-procedures: ajout des procédures
Browse files Browse the repository at this point in the history
  • Loading branch information
Feelzor committed Nov 4, 2019
1 parent 858e054 commit e19fee6
Show file tree
Hide file tree
Showing 17 changed files with 228 additions and 16 deletions.
12 changes: 12 additions & 0 deletions ArbreAbstrait.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,16 @@ 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);
}
19 changes: 19 additions & 0 deletions ArbreAbstrait.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,4 +198,23 @@ 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 sa condition et sa séquence d'instruction

~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;
};

#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
77 changes: 67 additions & 10 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 @@ -320,4 +356,25 @@ 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);
}
8 changes: 5 additions & 3 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 @@ -42,9 +43,10 @@ class Interpreteur {
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>}]);

// outils pour simplifier l'analyse syntaxique
void tester (const string & symboleAttendu) const; // Si symbole courant != symboleAttendu, on lève une exception
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 */

33 changes: 33 additions & 0 deletions TableProcedures.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include "TableProcedures.h"
#include "Procedure.h"
#include <algorithm>

TableProcedures* TableProcedures::table = nullptr;

TableProcedures::TableProcedures() {}

TableProcedures* TableProcedures::getTable() {
if (table == nullptr) {
table = new TableProcedures();
}

return table;
}

void TableProcedures::ajoutProcedure(Symbole nom, Procedure* procedure) {
std::string nomProcedure(nom.getChaine());
m_procedures.push_back(procedure);
m_noms.push_back(nom.getChaine());
}

void TableProcedures::executerProcedure(Symbole nom, std::vector<Noeud*> parametres, VisiteurExecuter& v) {
long i = std::distance(m_noms.begin(), std::find(m_noms.begin(), m_noms.end(), nom.getChaine()));
Procedure* p = m_procedures[i];
std::vector<Valeur*> params;
for (Noeud* noeud : parametres) {
noeud->accepter(v);
params.push_back(v.getDerniereValeur());
}
p->empiler(params);
p->accepter(v);
}
25 changes: 25 additions & 0 deletions TableProcedures.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef TABLEPROCEDURES_H
#define TABLEPROCEDURES_H

#include <map>
#include <vector>
#include <string>
#include "Symbole.h"
#include "Procedure.h"
#include "VisiteurExecuter.h"

class TableProcedures {
public:
static TableProcedures* getTable();
void ajoutProcedure(Symbole nom, Procedure* procedure);
void executerProcedure(Symbole nom, std::vector<Noeud*> parametres, VisiteurExecuter& v);
private:
TableProcedures();
static TableProcedures* table;

std::vector<Procedure*> m_procedures;
std::vector<std::string> m_noms;
};

#endif /* TABLEPROCEDURES_H */

1 change: 1 addition & 0 deletions Visiteur.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class Visiteur {
virtual void visiterNoeudInstTantQue(NoeudInstTantQue* noeud) = 0;
virtual void visiterNoeudInstLire(NoeudInstLire* noeud) = 0;
virtual void visiterNoeudInstEcrire(NoeudInstEcrire* noeud) = 0;
virtual void visiterNoeudInstAppel(NoeudInstAppel* noeud) = 0;
virtual void visiterSymboleValue(SymboleValue* symbole) = 0;
};

Expand Down
9 changes: 9 additions & 0 deletions VisiteurCompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,15 @@ void VisiteurCompiler::visiterNoeudInstEcrire(NoeudInstEcrire* noeud) {
m_out << indent << "print('')" << endl;
}

void VisiteurCompiler::visiterNoeudInstAppel(NoeudInstAppel* noeud) {
m_out << noeud->getNom().getChaine() << "(";
for(int i = 0; i < noeud->getParametres().size(); i++) {
if (i != 0) { m_out << ", "; }
noeud->getParametres()[i]->accepter(*this);
}
m_out << ")" << endl;
}

void VisiteurCompiler::visiterSymboleValue(SymboleValue* symbole) {
m_out << symbole->getChaine();
}
1 change: 1 addition & 0 deletions VisiteurCompiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class VisiteurCompiler : public Visiteur {
void visiterNoeudInstTantQue(NoeudInstTantQue* noeud) override;
void visiterNoeudInstLire(NoeudInstLire* noeud) override;
void visiterNoeudInstEcrire(NoeudInstEcrire* noeud) override;
void visiterNoeudInstAppel(NoeudInstAppel* noeud) override;
void visiterSymboleValue(SymboleValue* symbole) override;

private:
Expand Down
5 changes: 5 additions & 0 deletions VisiteurExecuter.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "VisiteurExecuter.h"
#include "ValeurEntiere.h"
#include "TableProcedures.h"

void VisiteurExecuter::visiterNoeudSeqInst(NoeudSeqInst* noeud) {
for (unsigned int i = 0; i < noeud->getInstructions().size(); i++)
Expand Down Expand Up @@ -103,6 +104,10 @@ void VisiteurExecuter::visiterNoeudInstEcrire(NoeudInstEcrire* noeud) {
}
}

void VisiteurExecuter::visiterNoeudInstAppel(NoeudInstAppel* noeud) {
TableProcedures::getTable()->executerProcedure(noeud->getNom(), noeud->getParametres(), *this);
}

void VisiteurExecuter::visiterSymboleValue(SymboleValue* symbole) {
if (!symbole->estDefini()) throw IndefiniException(); // on lève une exception si valeur non définie
m_derniereValeur = symbole->getValeur();
Expand Down
5 changes: 4 additions & 1 deletion VisiteurExecuter.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@ class VisiteurExecuter : public Visiteur {
void visiterNoeudInstTantQue(NoeudInstTantQue* noeud) override;
void visiterNoeudInstLire(NoeudInstLire* noeud) override;
void visiterNoeudInstEcrire(NoeudInstEcrire* noeud) override;
void visiterNoeudInstAppel(NoeudInstAppel* noeud) override;
void visiterSymboleValue(SymboleValue* symbole) override;

inline Valeur* getDerniereValeur() { return m_derniereValeur; }
private:
Valeur* m_derniereValeur = 0;
Valeur* m_derniereValeur;
};

#endif /* VISITEUREXECUTER_H */
Expand Down
1 change: 1 addition & 0 deletions motsCles.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,4 @@ ecrire
et
ou
non
appel
9 changes: 9 additions & 0 deletions testProcedure.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Résultat attendu : 9

procedure carre(a)
ecrire(a * a);
finproc

procedure principale()
appel carre(3);
finproc

0 comments on commit e19fee6

Please sign in to comment.