#ifndef AUTOMATON_H // voorkomt dat dit bestand meerdere keren #define AUTOMATON_H // ge-include wordt #include <vector> #include <utility> #include <string> #include "transition.h" class Automaton { public: /** * @brief Default constructor die automaton initialiseert door er een * Transition in te zetten die tegelijk de begintoestand en eindtoestand is, * zodat er makkelijk toestanden kan worden toegevoegd. */ Automaton(); void setCorrectAutomaton(bool const correctAutomaton); /** * @brief Maakt de vector automaton leeg */ void clear(); /** * @brief Geeft de size van de automaton vector die de transitie-object bevat * @return int De size van de vector */ int getSize() const; /** * @brief Functie die een eerste transitie toevoegt aan de automaat, * dit gebeurt alleen als de automaat nog 'leeg' is. * Bij een letter wordt gewoon een transitie gemaakt die van begintoestand naar eindtoestand * gaat met de meegegeven letter. * Bij een '$' wordt er een knoop toegevoegd die begintoestand en eindtoestand is. * Er wordt dus een automaat gemaakt die alleen de lege string accepteerd. * @param letter De letter van de transitie die wordt toegevoegd of '$' */ void firstTransition(char const letter); /** * @brief Geeft het transition-object terug op de meegegeven index in de automaton * vector, maar alleen als de index geldig is voor de lengte van de vector * @param index De index waarin het transition-object zit die gereturned wordt * @return Transition Het transition object dat teruggegeven wordt */ Transition getTransition(int const index) const; /** * @brief Stuurt de DOT-notatie van deze automaton naar std::cout wat in main is gezet naar * een ofstream. Dit wordt gedaan door door de vector af te gaan waar de automaton in is opgeslagen */ void dotAutomaton() const; /** * @brief Voert de concat operatie uit met auto1. Het huidige laatste transitie-element * wordt overwritten door een kopie van het eerste transitie-element van auto1, daarna worden * alle transitie-elementen van auto1 in volgorde gekopieerd en toegevoegd aan de vector automaton, * met de juiste transitiewaardes. * @param auto1 De automaat waarmee geconcateneerd wordt */ void concat(Automaton auto1); /** * @brief Voert de plus operatie uit met auto1 en auto2. Dit wordt alleen gedaan op een lege automaat * er wordt een nieuwe transitie gemaakt die gezet wordt op de state type, zodat deze naar twee andere * elementen kan wijzen. Daarna wordt een lege transitie toegevoegd waarmee auto1 wordt geconcateneerd. * Hetzelfde wordt gedaan met auto2. Het element dat we op state type hadden gezet zal wijzen naar deze * transities waarop auto1 of auto2 is geconcateneerd. Op het laatste worden de eindes van auto1 en auto2 * gewezen naar een nieuwe eindtoestand met type final via lambda transities. * @param auto1 De eerste automaat voor in de plus operatie * @param auto2 De tweede automaat voor in de plus operatie */ void plus(Automaton auto1, Automaton auto2); /** * @brief Voert de ster operatie uit op huidige automaton. Eerst wordt het huidige laatste * transitie-element type aangepast naar type state, zodat deze kan wijzen naar het huidige eerste * element en het nog komende nieuwe laatste element. Daarna worden alle transitie waarden van het * huidige automaton verhoogd met 1, zodat er aan het begin van het automaton een nieuw element kan worden * toegevoegd. Dit nieuwe element gaat wijzen naar het nieuwe laatste element. */ void star(); /** * @brief Publieke functie die de private functie aanroept met de juiste parameters en een string retourneert * die aangeeft of de expressie door de automaat geaccepteerd wordt * @param expressie String waarvan gecontroleerd moet worden of die wordt gecontroleerd door de automaat. * Deze waarde wordt niet veranderd * @return std::string Als er "match" wordt geretourneerd dan wordt expressie geaccepteerd door automaat en * anders wordt "geen match" geretourneerd */ std::string match(std::string const expressie) const; private: /** * @brief Deze vector van Transitie objecten stelt het automaton voor. De vector bevat * in volgorde de Transitie-elementen. Zo staat transitie-element 0 op plek 0 en * transitie-element 5 op plek 5 in de vector. */ std::vector<Transition> automaton; /** * @brief Deze boolean geeft aan of er een automaton is ingelezen en of die automaton klopt. Als * er geen automaton is ingelezen of als de invoer niet klopte dan is deze boolean false, anders true */ bool correctAutomaton; /** * @brief Deze functie initialiseert de waarden die nodig zijn om de e-afsluiting te bereken * en roept dan een andere functie aan die de e-afsluiting berekent * @param state Deze waarde is de naam van de toestand waar de e-afsluiting berekend van moet worden * @return std::vector<int> Vector die de toestanden bevat waar je vanuit toestand "state" naartoe * kan gaan met e-transities */ std::vector<int> getEClosure(int state) const; /** * @brief Berekent recursief de e-afsluiting van een knoop waarbij in de gaten wordt gehouden * of knopen niet al bezocht zijn en er daardoor geen oneindinge loop ontstaat * @param state Toestand van de automaat waar de functie zich op dat moment in bevind * @param eClosure Vector die de e-afsluiting bijhoudt * @param visited Vector die bijhoudt van elke toestand of die al bezocht is */ void getEClosureRec(int const state, std::vector<int> &eClosure, std::vector<bool> &visited) const; /** * @brief Bekijkt of de string expressie wordt geaccepteerd door de automaat door er recursief met een pointer * position langs te gaan en telkens bij te houden in welke node je zou kunnen zijn in de automaat * @param expressie Expressie waarvan gecontroleerd moet worden of die wordt geaccepteerd en die onveranderd blijft * @param position Getal dat aangeeft welke letter van de expressie op dat moment door match geëvalueerd wordt * en die onveranderd blijft * @param states Vector waarin met integers bijgehouden wordt in welke node je op dat moment zou kunnen zijn * in de automaat * @return true Als de expressie wordt geaccepteerd door de automaat * @return false Als de expressie niet wordt geaccepteerd door de automaat */ bool match(std::string const expressie, int const position, std::vector<int> &states) const; /** * @brief Kijkt eerst of de integer state al in de vector states zit. Als dat zo is dan gebeurd er * niks en als die er nog niet in zit dan wordt die achteraan toegevoegd. Dit is om te voorkomen dat * de state er meerdere keren in zit en andere functies meerdere keren naar die state kijken * @param states Vector van integers waar state misschien aan wordt toegevoegd * @param state Integer die een toestand voorstelt en die onveranderd blijft */ void addState(std::vector<int> &states, int const state) const; /** * @brief Controleert of in de e-afsluiting van een van de toestanden in vector states de * accepterende toestand zit. Dit gebeurd door voor elke toestand in states de e-afsluiting * te berekenen en dan te kijken voor elke van die toestanden of het een eindtoestand is * @param states Vector die alle toestanden bevat waarin de automaat zou kunnen eindigen * en waarvan gecontreleerd moet worden of je daarmee in de accepterende toestand terecht komt * @return true Als je in de accepterende toestand eindigt * @return false Als je niet in de accepterende toestand eindigt */ bool checkFinal(std::vector<int> const states) const; }; #endif