Reformat
This commit is contained in:
parent
8e014193cc
commit
65fffffe8e
|
@ -17,6 +17,7 @@ set(CMAKE_CXX_STANDARD 17)
|
||||||
|
|
||||||
set(SOURCE_FILES
|
set(SOURCE_FILES
|
||||||
src/regular/RegularTree.cpp
|
src/regular/RegularTree.cpp
|
||||||
|
src/regular/RegularTreeNode.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(TEST_FILES
|
set(TEST_FILES
|
||||||
|
|
|
@ -1,190 +1,6 @@
|
||||||
#include "regular/RegularTree.hpp"
|
#include "regular/RegularTree.hpp"
|
||||||
#include <iostream>
|
|
||||||
#include <exception>
|
|
||||||
|
|
||||||
namespace regular {
|
namespace regular {
|
||||||
RegularTree::Node::Node() {}
|
|
||||||
RegularTree::Node::Node(Type type) : type(type) {}
|
|
||||||
|
|
||||||
void RegularTree::Node::Parse(const std::string& regular) {
|
|
||||||
type = Type::Addition;
|
|
||||||
ParseCurrentType(std::string_view(regular.c_str(), regular.size()));
|
|
||||||
Compression();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RegularTree::Node::Print() const {
|
|
||||||
Print(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RegularTree::Node::ParseCurrentType(const std::string_view regular) {
|
|
||||||
const size_t n = regular.size();
|
|
||||||
children.clear();
|
|
||||||
word.clear();
|
|
||||||
|
|
||||||
auto AddChild = [this](const std::string_view regular) {
|
|
||||||
this->children.push_back(std::make_unique<Node>(Type::Addition));
|
|
||||||
this->children.back()->ParseCurrentType(regular);
|
|
||||||
};
|
|
||||||
|
|
||||||
if (n == 1) {
|
|
||||||
type = Type::Word;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type == Type::Addition) {
|
|
||||||
int balance = 0;
|
|
||||||
int begin_child = 0;
|
|
||||||
bool wrapped_brackets = (regular[0] == '(');
|
|
||||||
|
|
||||||
for (size_t i = 0; i < n; ++i) {
|
|
||||||
if (regular[i] == '(') {
|
|
||||||
++balance;
|
|
||||||
} else if (regular[i] == ')') {
|
|
||||||
--balance;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (regular[i] == '|') {
|
|
||||||
if (balance == 0) {
|
|
||||||
AddChild(regular.substr(begin_child + wrapped_brackets, i -
|
|
||||||
begin_child - 2 *
|
|
||||||
wrapped_brackets));
|
|
||||||
begin_child = i + 1;
|
|
||||||
|
|
||||||
if (i + 1 < n)
|
|
||||||
wrapped_brackets = (regular[i + 1] == '(');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (i + 1 == n) {
|
|
||||||
if (children.size() == 0) {
|
|
||||||
type = Type::Concatenation;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
AddChild(regular.substr(begin_child + wrapped_brackets, i -
|
|
||||||
begin_child + 1 - 2 *
|
|
||||||
wrapped_brackets));
|
|
||||||
begin_child = i + 1;
|
|
||||||
if (i + 1 < n)
|
|
||||||
wrapped_brackets = (regular[i + 1] == '(');
|
|
||||||
}
|
|
||||||
} else if (balance == 0) {
|
|
||||||
wrapped_brackets = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type == Type::Concatenation) {
|
|
||||||
int balance = 0;
|
|
||||||
int begin_child = 0;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < n; ++i) {
|
|
||||||
if (regular[i] == '(') {
|
|
||||||
++balance;
|
|
||||||
if (balance == 1) {
|
|
||||||
if (begin_child < i) {
|
|
||||||
AddChild(regular.substr(begin_child, i - begin_child));
|
|
||||||
begin_child = i + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (regular[i] == ')') {
|
|
||||||
--balance;
|
|
||||||
if (balance == 0) {
|
|
||||||
AddChild(regular.substr(begin_child + 1, i - begin_child - 1));
|
|
||||||
begin_child = i + 1;
|
|
||||||
}
|
|
||||||
} else if (i + 1 == n) {
|
|
||||||
if (balance != 0) {
|
|
||||||
throw std::logic_error("invalid regular");
|
|
||||||
}
|
|
||||||
if (children.size() == 0) {
|
|
||||||
type = Type::Word;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
AddChild(regular.substr(begin_child, i - begin_child + 1));
|
|
||||||
begin_child = i + 1;
|
|
||||||
}
|
|
||||||
} else if (balance == 0) {
|
|
||||||
if (regular[i] == '+') {
|
|
||||||
if (begin_child < i) {
|
|
||||||
AddChild(regular.substr(begin_child, i - begin_child));
|
|
||||||
}
|
|
||||||
children.back()->modifier = Modifier::Plus;
|
|
||||||
begin_child = i + 1;
|
|
||||||
} else if (regular[i] == '*') {
|
|
||||||
if (begin_child < i) {
|
|
||||||
AddChild(regular.substr(begin_child, i - begin_child));
|
|
||||||
}
|
|
||||||
children.back()->modifier = Modifier::Star;
|
|
||||||
begin_child = i + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type == Type::Word) {
|
|
||||||
bool exist_modifire = regular.back() == '+' || regular.back() == '*';
|
|
||||||
if (regular.back() == '+') {
|
|
||||||
modifier = Modifier::Plus;
|
|
||||||
} else if (regular.back() == '*') {
|
|
||||||
modifier = Modifier::Star;
|
|
||||||
}
|
|
||||||
for (size_t i = 0; i < n - exist_modifire; ++i) {
|
|
||||||
if (regular[i] == '|' || regular[i] == '(' || regular[i] == ')') {
|
|
||||||
throw std::logic_error("invalid regular");
|
|
||||||
}
|
|
||||||
word += regular[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RegularTree::Node::Compression() {
|
|
||||||
for (auto& i: children) {
|
|
||||||
i->Compression();
|
|
||||||
}
|
|
||||||
if (children.size() == 1 && modifier == Modifier::None) {
|
|
||||||
auto tmp = std::move(*children[0]);
|
|
||||||
*this = std::move(tmp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RegularTree::Node::Print(int nesting_level) const {
|
|
||||||
auto PrintNesingLevel = [](int nesting_level) {
|
|
||||||
for (int i = 0; i < nesting_level; ++i) {
|
|
||||||
std::cout << " ";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
PrintNesingLevel(nesting_level);
|
|
||||||
if (type == Type::Addition) {
|
|
||||||
std::cout << "Addition";
|
|
||||||
if (modifier == Modifier::Plus) {
|
|
||||||
std::cout << "+";
|
|
||||||
} else if (modifier == Modifier::Star) {
|
|
||||||
std::cout << "*";
|
|
||||||
}
|
|
||||||
std::cout << " " << std::to_string(children.size()) << ":" << std::endl;
|
|
||||||
} else if (type == Type::Concatenation) {
|
|
||||||
std::cout << "Concatenation";
|
|
||||||
if (modifier == Modifier::Plus) {
|
|
||||||
std::cout << "+";
|
|
||||||
} else if (modifier == Modifier::Star) {
|
|
||||||
std::cout << "*";
|
|
||||||
}
|
|
||||||
std::cout << " " << children.size() << ":" << std::endl;
|
|
||||||
} else if (type == Type::Word) {
|
|
||||||
std::cout << "Word";
|
|
||||||
if (modifier == Modifier::Plus) {
|
|
||||||
std::cout << "+";
|
|
||||||
} else if (modifier == Modifier::Star) {
|
|
||||||
std::cout << "*";
|
|
||||||
}
|
|
||||||
std::cout << ": " << word << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& i: children) {
|
|
||||||
i->Print(nesting_level + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RegularTree::RegularTree(const std::string& regular) {
|
RegularTree::RegularTree(const std::string& regular) {
|
||||||
node_.Parse(regular);
|
node_.Parse(regular);
|
||||||
}
|
}
|
||||||
|
|
185
src/regular/RegularTreeNode.cpp
Normal file
185
src/regular/RegularTreeNode.cpp
Normal file
|
@ -0,0 +1,185 @@
|
||||||
|
#include "regular/RegularTree.hpp"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using Node = regular::RegularTree::Node;
|
||||||
|
Node::Node() {}
|
||||||
|
Node::Node(Type type) : type(type) {}
|
||||||
|
|
||||||
|
void Node::Parse(const std::string& regular) {
|
||||||
|
type = Type::Addition;
|
||||||
|
ParseCurrentType(std::string_view(regular.c_str(), regular.size()));
|
||||||
|
Compression();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Node::Print() const {
|
||||||
|
Print(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Node::ParseCurrentType(const std::string_view regular) {
|
||||||
|
const size_t n = regular.size();
|
||||||
|
children.clear();
|
||||||
|
word.clear();
|
||||||
|
|
||||||
|
auto AddChild = [this](const std::string_view regular) {
|
||||||
|
this->children.push_back(std::make_unique<Node>(Type::Addition));
|
||||||
|
this->children.back()->ParseCurrentType(regular);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (n == 1) {
|
||||||
|
type = Type::Word;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == Type::Addition) {
|
||||||
|
int balance = 0;
|
||||||
|
int begin_child = 0;
|
||||||
|
bool wrapped_brackets = (regular[0] == '(');
|
||||||
|
|
||||||
|
for (size_t i = 0; i < n; ++i) {
|
||||||
|
if (regular[i] == '(') {
|
||||||
|
++balance;
|
||||||
|
} else if (regular[i] == ')') {
|
||||||
|
--balance;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (regular[i] == '|') {
|
||||||
|
if (balance == 0) {
|
||||||
|
AddChild(regular.substr(begin_child + wrapped_brackets, i -
|
||||||
|
begin_child - 2 *
|
||||||
|
wrapped_brackets));
|
||||||
|
begin_child = i + 1;
|
||||||
|
|
||||||
|
if (i + 1 < n)
|
||||||
|
wrapped_brackets = (regular[i + 1] == '(');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (i + 1 == n) {
|
||||||
|
if (children.size() == 0) {
|
||||||
|
type = Type::Concatenation;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
AddChild(regular.substr(begin_child + wrapped_brackets, i -
|
||||||
|
begin_child + 1 - 2 *
|
||||||
|
wrapped_brackets));
|
||||||
|
begin_child = i + 1;
|
||||||
|
if (i + 1 < n)
|
||||||
|
wrapped_brackets = (regular[i + 1] == '(');
|
||||||
|
}
|
||||||
|
} else if (balance == 0) {
|
||||||
|
wrapped_brackets = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == Type::Concatenation) {
|
||||||
|
int balance = 0;
|
||||||
|
int begin_child = 0;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < n; ++i) {
|
||||||
|
if (regular[i] == '(') {
|
||||||
|
++balance;
|
||||||
|
if (balance == 1) {
|
||||||
|
if (begin_child < i) {
|
||||||
|
AddChild(regular.substr(begin_child, i - begin_child));
|
||||||
|
begin_child = i + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (regular[i] == ')') {
|
||||||
|
--balance;
|
||||||
|
if (balance == 0) {
|
||||||
|
AddChild(regular.substr(begin_child + 1, i - begin_child - 1));
|
||||||
|
begin_child = i + 1;
|
||||||
|
}
|
||||||
|
} else if (i + 1 == n) {
|
||||||
|
if (balance != 0) {
|
||||||
|
throw std::logic_error("invalid regular");
|
||||||
|
}
|
||||||
|
if (children.size() == 0) {
|
||||||
|
type = Type::Word;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
AddChild(regular.substr(begin_child, i - begin_child + 1));
|
||||||
|
begin_child = i + 1;
|
||||||
|
}
|
||||||
|
} else if (balance == 0) {
|
||||||
|
if (regular[i] == '+') {
|
||||||
|
if (begin_child < i) {
|
||||||
|
AddChild(regular.substr(begin_child, i - begin_child));
|
||||||
|
}
|
||||||
|
children.back()->modifier = Modifier::Plus;
|
||||||
|
begin_child = i + 1;
|
||||||
|
} else if (regular[i] == '*') {
|
||||||
|
if (begin_child < i) {
|
||||||
|
AddChild(regular.substr(begin_child, i - begin_child));
|
||||||
|
}
|
||||||
|
children.back()->modifier = Modifier::Star;
|
||||||
|
begin_child = i + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == Type::Word) {
|
||||||
|
bool exist_modifire = regular.back() == '+' || regular.back() == '*';
|
||||||
|
if (regular.back() == '+') {
|
||||||
|
modifier = Modifier::Plus;
|
||||||
|
} else if (regular.back() == '*') {
|
||||||
|
modifier = Modifier::Star;
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < n - exist_modifire; ++i) {
|
||||||
|
if (regular[i] == '|' || regular[i] == '(' || regular[i] == ')') {
|
||||||
|
throw std::logic_error("invalid regular");
|
||||||
|
}
|
||||||
|
word += regular[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Node::Compression() {
|
||||||
|
for (auto& i: children) {
|
||||||
|
i->Compression();
|
||||||
|
}
|
||||||
|
if (children.size() == 1 && modifier == Modifier::None) {
|
||||||
|
auto tmp = std::move(*children[0]);
|
||||||
|
*this = std::move(tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Node::Print(int nesting_level) const {
|
||||||
|
auto PrintNesingLevel = [](int nesting_level) {
|
||||||
|
for (int i = 0; i < nesting_level; ++i) {
|
||||||
|
std::cout << " ";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintNesingLevel(nesting_level);
|
||||||
|
if (type == Type::Addition) {
|
||||||
|
std::cout << "Addition";
|
||||||
|
if (modifier == Modifier::Plus) {
|
||||||
|
std::cout << "+";
|
||||||
|
} else if (modifier == Modifier::Star) {
|
||||||
|
std::cout << "*";
|
||||||
|
}
|
||||||
|
std::cout << " " << std::to_string(children.size()) << ":" << std::endl;
|
||||||
|
} else if (type == Type::Concatenation) {
|
||||||
|
std::cout << "Concatenation";
|
||||||
|
if (modifier == Modifier::Plus) {
|
||||||
|
std::cout << "+";
|
||||||
|
} else if (modifier == Modifier::Star) {
|
||||||
|
std::cout << "*";
|
||||||
|
}
|
||||||
|
std::cout << " " << children.size() << ":" << std::endl;
|
||||||
|
} else if (type == Type::Word) {
|
||||||
|
std::cout << "Word";
|
||||||
|
if (modifier == Modifier::Plus) {
|
||||||
|
std::cout << "+";
|
||||||
|
} else if (modifier == Modifier::Star) {
|
||||||
|
std::cout << "*";
|
||||||
|
}
|
||||||
|
std::cout << ": " << word << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& i: children) {
|
||||||
|
i->Print(nesting_level + 1);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue