diff --git a/ArbreAbstrait.cpp b/ArbreAbstrait.cpp index a413ace..5e95d9e 100644 --- a/ArbreAbstrait.cpp +++ b/ArbreAbstrait.cpp @@ -13,14 +13,6 @@ NoeudSeqInst::NoeudSeqInst() : m_instructions() { } -void NoeudSeqInst::compiler(ostream & out, int indentation) { - for (unsigned int i = 0; i < m_instructions.size(); i++) { - cout << std::string(indentation * 4, ' '); - m_instructions[i]->compiler(out, indentation); - cout << endl; - } -} - void NoeudSeqInst::accepter(Visiteur& visiteur) { visiteur.visiterNoeudSeqInst(this); } @@ -37,19 +29,6 @@ NoeudAffectation::NoeudAffectation(Noeud* variable, Noeud* expression) : m_variable(variable), m_expression(expression) { } -void NoeudAffectation::compiler(ostream & out, int indentation) { - bool instructionSeule = true; - if (indentation < 0) { - indentation = 0; - instructionSeule = false; - } - - m_variable->compiler(out, -1); - out << "="; - m_expression->compiler(out, -1); - if (instructionSeule) out << ";"; -} - void NoeudAffectation::accepter(Visiteur& visiteur) { visiteur.visiterNoeudAffectation(this); } @@ -62,24 +41,6 @@ NoeudOperateurBinaire::NoeudOperateurBinaire(Symbole operateur, Noeud* operandeG : m_operateur(operateur), m_operandeGauche(operandeGauche), m_operandeDroit(operandeDroit) { } -void NoeudOperateurBinaire::compiler(ostream & out, int indentation) { - std::string op = m_operateur.getChaine(); - - out << "("; - if (op == "non") { - out << "!"; - m_operandeGauche->compiler(out, -1); - } else { - if (op == "et") op = "&&"; - else if (op == "ou") op = "||"; - - m_operandeGauche->compiler(out, -1); - out << op; - m_operandeDroit->compiler(out, -1); - } - out << ")"; -} - void NoeudOperateurBinaire::accepter(Visiteur& visiteur) { visiteur.visiterNoeudOperateurBinaire(this); } @@ -92,27 +53,6 @@ NoeudInstSi::NoeudInstSi(Noeud* condition, Noeud* sequence) : m_condition(condition), m_sequence(sequence), m_prochaineCondition(nullptr), m_isPremiereCondition(true) { } -void NoeudInstSi::compiler(ostream & out, int indentation) { - std::string indent(indentation * 4, ' '); - if (m_condition != nullptr) { - if (!m_isPremiereCondition) { out << ' '; } - out << "if ("; - m_condition->compiler(out, -1); - out << ")"; - } - - out << " {" << endl; - m_sequence->compiler(out, indentation + 1); - out << indent << "}"; - - if (m_prochaineCondition != nullptr) { - out << " else"; - m_prochaineCondition->compiler(out, indentation); - } else { - out << endl; - } -} - void NoeudInstSi::ajoute(Noeud* condition) { ((NoeudInstSi*) condition)->setIsPremiereCondition(false); if (m_prochaineCondition == nullptr) { @@ -138,15 +78,6 @@ NoeudInstRepeter::NoeudInstRepeter(Noeud* instruction, Noeud* condition) : m_seq } -void NoeudInstRepeter::compiler(ostream & out, int indentation) { - std::string indent(indentation * 4, ' '); - out << "do {" << endl; - m_sequence->compiler(out, indentation + 1); - out << indent << "} while (!("; - m_condition->compiler(out, -1); - out << "));" << endl; -} - void NoeudInstRepeter::accepter(Visiteur& visiteur) { visiteur.visiterNoeudInstRepeter(this); } @@ -159,19 +90,6 @@ NoeudInstPour::NoeudInstPour(Noeud* init, Noeud* condition, Noeud* affect, Noeud : m_init(init), m_condition(condition), m_affectation(affect), m_sequence(sequence) { } -void NoeudInstPour::compiler(ostream & out, int indentation) { - std::string indent(4 * indentation, ' '); - out << "for ("; - if (m_init != nullptr) m_init->compiler(out, -1); - out << ";"; - m_condition->compiler(out, -1); - out << ";"; - if (m_affectation != nullptr) m_affectation->compiler(out, -1); - out << ") {" << endl; - m_sequence->compiler(out, indentation + 1); - out << indent << "}" << endl; -} - void NoeudInstPour::accepter(Visiteur& visiteur) { visiteur.visiterNoeudInstPour(this); } @@ -184,15 +102,6 @@ NoeudInstTantQue::NoeudInstTantQue(Noeud* condition, Noeud* sequence) : m_condition(condition), m_sequence(sequence) { } -void NoeudInstTantQue::compiler(ostream & out, int indentation) { - std::string indent(indentation * 4, ' '); - out << "while " ; - m_condition->compiler(out,indentation); - out << " {" << endl; - m_sequence->compiler(out,indentation+1); - out << indent << "}" << endl; -} - void NoeudInstTantQue::accepter(Visiteur& visiteur) { visiteur.visiterNoeudInstTantQue(this); } @@ -204,16 +113,6 @@ NoeudInstLire::NoeudInstLire() { m_variables = vector(); } -void NoeudInstLire::compiler(ostream & out, int indentation) { - out << "std::cin"; - for (Noeud* var : m_variables) { - out << " >> "; - var->compiler(out, -1); - } - - out << ";"; -} - void NoeudInstLire::accepter(Visiteur& visiteur) { visiteur.visiterNoeudInstLire(this); } @@ -233,19 +132,6 @@ void NoeudInstEcrire::ajoute(Noeud* instruction) { m_ecritures.push_back(instruction); } -void NoeudInstEcrire::compiler(ostream & out, int indentation) { - out << "std::cout"; - for (Noeud* inst : m_ecritures) { - out << " << "; - if ((typeid (*inst) == typeid (SymboleValue) && *((SymboleValue*) inst) == "")) { - out << ((SymboleValue*) inst)->getChaine(); - } else { - inst->compiler(out, -1); - } - } - out << ";"; -} - void NoeudInstEcrire::accepter(Visiteur& visiteur) { visiteur.visiterNoeudInstEcrire(this); } \ No newline at end of file diff --git a/ArbreAbstrait.h b/ArbreAbstrait.h index e472a22..662bd4c 100644 --- a/ArbreAbstrait.h +++ b/ArbreAbstrait.h @@ -19,7 +19,6 @@ class Noeud { // Classe abstraite dont dériveront toutes les classes servant à représenter l'arbre abstrait // Remarque : la classe ne contient aucun constructeur public: - virtual void compiler(ostream & out, int indentation) =0 ; virtual void accepter(Visiteur& visiteur) = 0; virtual void ajoute(Noeud* instruction) { throw OperationInterditeException(); } virtual ~Noeud() {} // Présence d'un destructeur virtuel conseillée dans les classes abstraites @@ -32,7 +31,6 @@ class NoeudSeqInst : public Noeud { public: NoeudSeqInst(); // Construit une séquence d'instruction vide ~NoeudSeqInst() {} // A cause du destructeur virtuel de la classe Noeud - void compiler(ostream & out, int indentation) override; void accepter(Visiteur& visiteur) override; void ajoute(Noeud* instruction) override; // Ajoute une instruction à la séquence inline vector getInstructions() const { return m_instructions; } @@ -48,7 +46,6 @@ class NoeudAffectation : public Noeud { public: NoeudAffectation(Noeud* variable, Noeud* expression); // construit une affectation ~NoeudAffectation() {} // A cause du destructeur virtuel de la classe Noeud - void compiler(ostream & out, int indentation) override; void accepter(Visiteur& visiteur) override; inline Noeud* getVariable() const { return m_variable; } @@ -67,7 +64,6 @@ class NoeudOperateurBinaire : public Noeud { NoeudOperateurBinaire(Symbole operateur, Noeud* operandeGauche, Noeud* operandeDroit); // Construit une opération binaire : operandeGauche operateur OperandeDroit ~NoeudOperateurBinaire() {} // A cause du destructeur virtuel de la classe Noeud - void compiler(ostream & out, int indentation) override; void accepter(Visiteur& visiteur) override; inline Symbole getOperateur() const { return m_operateur; } @@ -87,7 +83,6 @@ class NoeudInstSi : public Noeud { NoeudInstSi(Noeud* condition, Noeud* sequence); // Construit une "instruction si" avec sa condition et sa séquence d'instruction ~NoeudInstSi() {} // A cause du destructeur virtuel de la classe Noeud - void compiler(ostream & out, int indentation) override; void accepter(Visiteur& visiteur) override; void ajoute(Noeud* condition) override; @@ -96,7 +91,7 @@ class NoeudInstSi : public Noeud { inline Noeud* getCondition() const { return m_condition; } inline Noeud* getSequence() const { return m_sequence; } inline Noeud* getProchaineCondition() const { return m_prochaineCondition; } - inline bool getisPremiereCondition() const { return m_isPremiereCondition; } + inline bool isPremiereCondition() const { return m_isPremiereCondition; } private: Noeud* m_condition; @@ -112,7 +107,6 @@ public : NoeudInstRepeter(Noeud* instruction, Noeud* condition); ~NoeudInstRepeter() {} - void compiler(ostream & out, int indentation) override; void accepter(Visiteur& visiteur) override; inline Noeud* getCondition() const { return m_condition; } @@ -132,7 +126,6 @@ class NoeudInstPour : public Noeud { ~NoeudInstPour() { } // A cause du destructeur virtuel de la classe Noeud - void compiler(ostream & out, int indentation) override; void accepter(Visiteur& visiteur) override; inline Noeud* getInit() const { return m_init; } @@ -157,7 +150,6 @@ class NoeudInstTantQue : public Noeud { ~NoeudInstTantQue() { } // A cause du destructeur virtuel de la classe Noeud - void compiler(ostream & out, int indentation) override; void accepter(Visiteur& visiteur) override; inline Noeud* getCondition() const { return m_condition; } @@ -178,7 +170,6 @@ class NoeudInstLire : public Noeud { } - void compiler(ostream & out, int indentation) override; void accepter(Visiteur& visiteur) override; void ajoute(Noeud* var) override; @@ -195,12 +186,11 @@ class NoeudInstEcrire : public Noeud { public: NoeudInstEcrire(); // Construit une "instruction ecrire" avec sa condition et sa séquence d'instruction - virtual void ajoute(Noeud* instruction); ~NoeudInstEcrire() { } // A cause du destructeur virtuel de la classe Noeud - void compiler(ostream & out, int indentation) override; void accepter(Visiteur& visiteur) override; + virtual void ajoute(Noeud* instruction); inline vector getEcritures() const { return m_ecritures; } diff --git a/SymboleValue.cpp b/SymboleValue.cpp index bd04244..12a2260 100644 --- a/SymboleValue.cpp +++ b/SymboleValue.cpp @@ -16,10 +16,6 @@ Symbole(s.getChaine()) { } } -void SymboleValue::compiler(ostream & out, int indentation) { - out << getChaine(); -} - void SymboleValue::accepter(Visiteur& visiteur) { visiteur.visiterSymboleValue(this); } diff --git a/SymboleValue.h b/SymboleValue.h index 78cc700..863699d 100644 --- a/SymboleValue.h +++ b/SymboleValue.h @@ -15,7 +15,6 @@ class SymboleValue : public Symbole, // Un symbole valué est un symbole qui a public: SymboleValue(const Symbole & s); // Construit un symbole valué à partir d'un symbole existant s ~SymboleValue( ) {} - void compiler(ostream & out, int indentation) override; void accepter(Visiteur& visiteur) override; inline void setValeur(int valeur) { this->m_valeur=valeur; m_defini=true; } // accesseur inline bool estDefini() { return m_defini; } // accesseur diff --git a/VisiteurCompiler.cpp b/VisiteurCompiler.cpp new file mode 100644 index 0000000..13abcf7 --- /dev/null +++ b/VisiteurCompiler.cpp @@ -0,0 +1,151 @@ +#include "VisiteurCompiler.h" + +VisiteurCompiler::VisiteurCompiler(std::ostream& out, int indentation) +: m_out(out), m_indentation(indentation) {} + +void VisiteurCompiler::visiterNoeudSeqInst(NoeudSeqInst* noeud) { + for (unsigned int i = 0; i < noeud->getInstructions().size(); i++) { + m_out << std::string(m_indentation * 4, ' '); + noeud->getInstructions()[i]->accepter(*this); + m_out << endl; + } +} + +void VisiteurCompiler::visiterNoeudAffectation(NoeudAffectation* noeud) { + bool instructionSeule = true; + if (m_indentation < 0) { + instructionSeule = false; + } + + int indent = m_indentation; + m_indentation = -1; + noeud->getVariable()->accepter(*this); + m_out << "="; + noeud->getExpression()->accepter(*this); + + m_indentation = indent; + if (instructionSeule) m_out << ";"; +} + +void VisiteurCompiler::visiterNoeudOperateurBinaire(NoeudOperateurBinaire* noeud) { + std::string op = noeud->getOperateur().getChaine(); + int indent = m_indentation; + m_indentation = -1; + + m_out << "("; + if (op == "non") { + m_out << "!"; + noeud->getOperandeGauche()->accepter(*this); + } else { + if (op == "et") op = "&&"; + else if (op == "ou") op = "||"; + + noeud->getOperandeGauche()->accepter(*this); + m_out << op; + noeud->getOperandeDroit()->accepter(*this); + } + m_out << ")"; + + m_indentation = indent; +} + +void VisiteurCompiler::visiterNoeudInstSi(NoeudInstSi* noeud) { + std::string indent(m_indentation * 4, ' '); + if (noeud->getCondition() != nullptr) { + if (!noeud->isPremiereCondition()) { m_out << ' '; } + m_out << "if ("; + int indentOrigine = m_indentation; + m_indentation = -1; + noeud->getCondition()->accepter(*this); + m_indentation = indentOrigine; + m_out << ")"; + } + + m_out << " {" << endl; + m_indentation++; + noeud->getSequence()->accepter(*this); + m_indentation--; + m_out << indent << "}"; + + if (noeud->getProchaineCondition() != nullptr) { + m_out << " else"; + noeud->getProchaineCondition()->accepter(*this); + } else { + m_out << endl; + } +} + +void VisiteurCompiler::visiterNoeudInstRepeter(NoeudInstRepeter* noeud) { + std::string indent(m_indentation * 4, ' '); + m_out << "do {" << endl; + m_indentation++; + noeud->getSequence()->accepter(*this); + m_indentation--; + m_out << indent << "} while (!("; + int indentOrigine = m_indentation; + m_indentation = -1; + noeud->getCondition()->accepter(*this); + m_indentation = indentOrigine; + m_out << "));" << endl; +} + +void VisiteurCompiler::visiterNoeudInstPour(NoeudInstPour* noeud) { + std::string indent(4 * m_indentation, ' '); + int indentOrigine = m_indentation; + m_indentation = -1; + m_out << "for ("; + if (noeud->getInit() != nullptr) noeud->getInit()->accepter(*this); + m_out << ";"; + noeud->getCondition()->accepter(*this); + m_out << ";"; + if (noeud->getAffectation() != nullptr) noeud->getAffectation()->accepter(*this); + m_out << ") {" << endl; + m_indentation = indentOrigine + 1; + noeud->getSequence()->accepter(*this); + m_indentation--; + m_out << indent << "}" << endl; +} + +void VisiteurCompiler::visiterNoeudInstTantQue(NoeudInstTantQue* noeud) { + std::string indent(m_indentation * 4, ' '); + m_out << "while " ; + noeud->getCondition()->accepter(*this); + m_out << " {" << endl; + m_indentation++; + noeud->getSequence()->accepter(*this); + m_indentation--; + m_out << indent << "}" << endl; +} + +void VisiteurCompiler::visiterNoeudInstLire(NoeudInstLire* noeud) { + m_out << "std::cin"; + for (Noeud* var : noeud->getVariables()) { + m_out << " >> "; + int indent = m_indentation; + m_indentation = -1; + var->accepter(*this); + m_indentation = indent; + } + + m_out << ";"; +} + +void VisiteurCompiler::visiterNoeudInstEcrire(NoeudInstEcrire* noeud) { + m_out << "std::cout"; + for (Noeud* inst : noeud->getEcritures()) { + m_out << " << "; + if ((typeid (*inst) == typeid (SymboleValue) && *((SymboleValue*) inst) == "")) { + m_out << ((SymboleValue*) inst)->getChaine(); + } else { + int indent = m_indentation; + m_indentation = -1; + inst->accepter(*this); + m_indentation = indent; + } + } + m_out << ";"; +} + +void VisiteurCompiler::visiterSymboleValue(SymboleValue* symbole) { + m_out << symbole->getChaine(); +} \ No newline at end of file diff --git a/VisiteurCompiler.h b/VisiteurCompiler.h new file mode 100644 index 0000000..7b5d885 --- /dev/null +++ b/VisiteurCompiler.h @@ -0,0 +1,40 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/* + * File: VisiteurCompiler.h + * Author: feelzor + * + * Created on October 30, 2019, 3:10 PM + */ + +#ifndef VISITEURCOMPILER_H +#define VISITEURCOMPILER_H + +#include "Visiteur.h" + +class VisiteurCompiler : public Visiteur { +public: + VisiteurCompiler(std::ostream& out, int indentation); + + void visiterNoeudSeqInst(NoeudSeqInst* noeud) override; + void visiterNoeudAffectation(NoeudAffectation* noeud) override; + void visiterNoeudOperateurBinaire(NoeudOperateurBinaire* noeud) override; + void visiterNoeudInstSi(NoeudInstSi* noeud) override; + void visiterNoeudInstRepeter(NoeudInstRepeter* noeud) override; + void visiterNoeudInstPour(NoeudInstPour* noeud) override; + void visiterNoeudInstTantQue(NoeudInstTantQue* noeud) override; + void visiterNoeudInstLire(NoeudInstLire* noeud) override; + void visiterNoeudInstEcrire(NoeudInstEcrire* noeud) override; + void visiterSymboleValue(SymboleValue* symbole) override; + +private: + std::ostream& m_out; + int m_indentation; +}; + +#endif /* VISITEURCOMPILER_H */ + diff --git a/main.cpp b/main.cpp index df12ab8..997fa4f 100644 --- a/main.cpp +++ b/main.cpp @@ -4,6 +4,7 @@ using namespace std; #include "Interpreteur.h" #include "Exceptions.h" #include "VisiteurExecuter.h" +#include "VisiteurCompiler.h" void compiler(ostream& out, const TableSymboles& symboles, Noeud* arbre); @@ -77,6 +78,7 @@ void compiler(ostream& out, const TableSymboles& symboles, Noeud* arbre) { out << indentationBasique << "int " << s.getChaine() << ";" << endl; } } - arbre->compiler(out, 1); + VisiteurCompiler visiteur(out, 1); + arbre->accepter(visiteur); out << "}" << endl; } \ No newline at end of file