diff --git a/CMakeLists.txt b/CMakeLists.txt index ed99c37..3e62eeb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,6 +18,8 @@ set(CMAKE_CXX_STANDARD 17) set(SOURCE_FILES src/regular/RegularTree.cpp src/regular/RegularTreeNode.cpp + src/NFA/NFATree.cpp + src/NFA/NFATreeVertex.cpp ) set(TEST_FILES diff --git a/include/NFA/NFATree.hpp b/include/NFA/NFATree.hpp new file mode 100644 index 0000000..4358931 --- /dev/null +++ b/include/NFA/NFATree.hpp @@ -0,0 +1,38 @@ +#pragma once + +#include +#include +#include + +namespace NFA { +class NFATree { + public: + class Vertex { + public: + Vertex(); + Vertex(bool is_finale, bool is_start); + + bool IsFinal() const; + bool IsStart() const; + void SetFinal(bool value); + void SetStart(bool value); + + std::map>> transitions; + private: + bool is_final_ = false; + bool is_start_ = false; + }; + + void RemoveVertex(std::shared_ptr); + void RemoveFinalVertex(std::shared_ptr); + void RemoveStartVertex(std::shared_ptr); + + void Composition(NFATree&&, std::vector> + start_vertexes, std::vector> + final_vertexes); + private: + std::vector> vertexes_; + std::vector> final_vertexes_; + std::vector> start_vertexes_; +}; +} diff --git a/src/NFA/NFATree.cpp b/src/NFA/NFATree.cpp new file mode 100644 index 0000000..73bfb65 --- /dev/null +++ b/src/NFA/NFATree.cpp @@ -0,0 +1,65 @@ +#include "NFA/NFATree.hpp" +#include + +namespace NFA { +void NFATree::RemoveVertex(std::shared_ptr vertex) { + RemoveFinalVertex(vertex); + RemoveStartVertex(vertex); + for (size_t i = 0; i < vertexes_.size(); ++i) { + if (vertexes_[i] == vertex) { + std::swap(vertexes_[i], vertexes_.back()); + vertexes_.pop_back(); + break; + } + } +} + +void NFATree::RemoveFinalVertex(std::shared_ptr vertex) { + for (size_t i = 0; i < final_vertexes_.size(); ++i) { + if (final_vertexes_[i].lock() == vertex) { + final_vertexes_[i].lock()->SetFinal(false); + std::swap(final_vertexes_[i], final_vertexes_.back()); + final_vertexes_.pop_back(); + break; + } + } +} + +void NFATree::RemoveStartVertex(std::shared_ptr vertex) { + for (size_t i = 0; i < start_vertexes_.size(); ++i) { + if (start_vertexes_[i].lock() == vertex) { + start_vertexes_[i].lock()->SetStart(false); + std::swap(start_vertexes_[i], start_vertexes_.back()); + start_vertexes_.pop_back(); + break; + } + } +} + +void NFATree::Composition(NFATree&& tree, + std::vector> start_vertexes, + std::vector> final_vertexes) { + auto add_final_vertexes = tree.final_vertexes_; + auto add_start_vertexes = tree.start_vertexes_; + + vertexes_.insert(vertexes_.begin(), tree.vertexes_.begin(), tree.vertexes_.end()); + + for (auto& i: start_vertexes) { + for (auto& j: add_start_vertexes) { + i->transitions[' '].push_back(j); + } + } + for (auto& i: add_final_vertexes) { + for (auto& j: final_vertexes) { + i.lock()->transitions[' '].push_back(j); + } + } + for (auto& i: add_final_vertexes) { + i.lock()->SetFinal(false); + } + for (auto& i: add_start_vertexes) { + i.lock()->SetStart(false); + } +} +} + diff --git a/src/NFA/NFATreeVertex.cpp b/src/NFA/NFATreeVertex.cpp new file mode 100644 index 0000000..3f4f4bf --- /dev/null +++ b/src/NFA/NFATreeVertex.cpp @@ -0,0 +1,25 @@ +#include "NFA/NFATree.hpp" + +using Vertex = NFA::NFATree::Vertex; + +Vertex::Vertex() {} + +Vertex::Vertex(bool is_final, bool is_start) : is_final_(is_final), + is_start_(is_start) {} + +bool Vertex::IsFinal() const { + return is_final_; +} + +bool Vertex::IsStart() const { + return is_start_; +} + +void Vertex::SetFinal(bool value) { + is_final_ = value; +} + +void Vertex::SetStart(bool value) { + is_start_ = value; +} +