-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor parser #346
Refactor parser #346
Changes from all commits
b1d52c6
536d4e9
08cf090
47e0c86
3c05412
d93ed34
ef48e39
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,11 +20,11 @@ | |
#include "mata/parser/inter-aut.hh" | ||
|
||
namespace { | ||
bool has_atmost_one_auto_naming(const mata::IntermediateAut& aut) | ||
{ | ||
return !(!(aut.node_naming == mata::IntermediateAut::Naming::AUTO && | ||
aut.symbol_naming == mata::IntermediateAut::Naming::AUTO) && | ||
(aut.state_naming == mata::IntermediateAut::Naming::AUTO)); | ||
|
||
bool has_atmost_one_auto_naming(const mata::IntermediateAut& aut) { | ||
return !(!(aut.node_naming == mata::IntermediateAut::Naming::AUTO && | ||
aut.symbol_naming == mata::IntermediateAut::Naming::AUTO) && | ||
(aut.state_naming == mata::IntermediateAut::Naming::AUTO)); | ||
} | ||
|
||
bool is_logical_operator(char ch) | ||
|
@@ -111,7 +111,7 @@ namespace { | |
if (graph.children.size() == 1) { // unary operator | ||
const auto& child = graph.children.front(); | ||
std::string child_name = child.node.is_operand() ? child.node.raw : | ||
"(" + serialize_graph(child.node) + ")"; | ||
"(" + serialize_graph(mata::FormulaGraph{ std::move(child.node) }) + ")"; | ||
return graph.node.raw + child_name; | ||
} | ||
|
||
|
@@ -130,7 +130,7 @@ namespace { | |
return lhs + " " + graph.node.raw + " " + rhs; | ||
} | ||
|
||
mata::FormulaNode create_node(const mata::IntermediateAut &mata, const std::string &token) { | ||
mata::FormulaNode create_node(const mata::IntermediateAut &mata, const std::string& token) { | ||
if (is_logical_operator(token[0])) { | ||
switch (token[0]) { | ||
case '&': | ||
|
@@ -206,8 +206,8 @@ namespace { | |
* @param tokens Series of tokens representing transition formula parsed from the input text | ||
* @return A postfix notation for input | ||
*/ | ||
std::vector<mata::FormulaNode> infix_to_postfix( | ||
const mata::IntermediateAut &aut, const std::vector<std::string>& tokens) { | ||
std::vector<mata::FormulaNode> infix_to_postfix(const mata::IntermediateAut &aut, | ||
const std::vector<std::string>& tokens) { | ||
std::vector<mata::FormulaNode> opstack; | ||
std::vector<mata::FormulaNode> output; | ||
|
||
|
@@ -229,13 +229,14 @@ namespace { | |
break; | ||
case mata::FormulaNode::Type::OPERATOR: | ||
for (int j = static_cast<int>(opstack.size())-1; j >= 0; --j) { | ||
size_t j_size_t{ static_cast<size_t>(j) }; | ||
assert(!opstack[j_size_t].is_operand()); | ||
if (opstack[j_size_t].is_leftpar()) | ||
auto formula_node_opstack_it{ opstack.begin() + j }; | ||
Comment on lines
231
to
+232
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't this just iterating from end to begin? So we could have There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you are right. It should be possible to refactor this as you say. I will investigate. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The int arithmetic is there so you can do There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it could be done somehow with |
||
assert(!formula_node_opstack_it->is_operand()); | ||
if (formula_node_opstack_it->is_leftpar()) { | ||
break; | ||
if (lower_precedence(node.operator_type, opstack[j_size_t].operator_type)) { | ||
output.emplace_back(std::move(opstack[j_size_t])); | ||
opstack.erase(opstack.begin()+j); | ||
} | ||
if (lower_precedence(node.operator_type, formula_node_opstack_it->operator_type)) { | ||
output.emplace_back(std::move(*formula_node_opstack_it)); | ||
opstack.erase(formula_node_opstack_it); | ||
} | ||
} | ||
opstack.emplace_back(std::move(node)); | ||
|
@@ -269,35 +270,41 @@ namespace { | |
std::vector<mata::FormulaGraph> opstack{}; | ||
opstack.reserve(4); | ||
for (mata::FormulaNode& node: postfix) { | ||
mata::FormulaGraph gr(std::move(node)); | ||
switch (gr.node.type) { | ||
switch (node.type) { | ||
case mata::FormulaNode::Type::OPERAND: | ||
opstack.emplace_back(std::move(gr)); | ||
opstack.emplace_back(std::move(node)); | ||
break; | ||
case mata::FormulaNode::Type::OPERATOR: | ||
switch (gr.node.operator_type) { | ||
case mata::FormulaNode::OperatorType::NEG: | ||
case mata::FormulaNode::Type::OPERATOR: { | ||
switch (node.operator_type) { | ||
case mata::FormulaNode::OperatorType::NEG: { // 1 child: graph will be a NEG node. | ||
assert(!opstack.empty()); | ||
gr.children.emplace_back(std::move(opstack.back())); | ||
mata::FormulaGraph child{ std::move(opstack.back()) }; | ||
opstack.pop_back(); | ||
opstack.emplace_back(std::move(gr)); | ||
mata::FormulaGraph& gr{ opstack.emplace_back(std::move(node)) }; | ||
gr.children.emplace_back(std::move(child)); | ||
break; | ||
default: | ||
} | ||
default: { // 2 children: Graph will be either an AND node, or an OR node. | ||
assert(opstack.size() > 1); | ||
mata::FormulaGraph second_child{ std::move(opstack.back()) }; | ||
opstack.pop_back(); | ||
gr.children.emplace_back(std::move(opstack.back())); | ||
mata::FormulaGraph first_child{ std::move(opstack.back()) }; | ||
opstack.pop_back(); | ||
mata::FormulaGraph& gr{ opstack.emplace_back(std::move(node)) }; | ||
gr.children.emplace_back(std::move(first_child)); | ||
gr.children.emplace_back(std::move(second_child)); | ||
opstack.emplace_back(std::move(gr)); | ||
break; | ||
} | ||
} | ||
break; | ||
default: assert(false && "Unknown type of node"); | ||
} | ||
default: | ||
assert(false && "Unknown type of node"); | ||
} | ||
} | ||
|
||
assert(opstack.size() == 1); | ||
return std::move(opstack[0]); | ||
return std::move(*opstack.begin()); | ||
} | ||
|
||
/** | ||
|
@@ -307,9 +314,9 @@ namespace { | |
* @param postfix Postfix to which operators are eventually added | ||
* @return A postfix with eventually added operators | ||
*/ | ||
std::vector<mata::FormulaNode> add_disjunction_implicitly(std::vector<mata::FormulaNode> postfix) | ||
{ | ||
if (postfix.size() == 1) // no need to add operators | ||
std::vector<mata::FormulaNode> add_disjunction_implicitly(std::vector<mata::FormulaNode> postfix) { | ||
const size_t postfix_size{ postfix.size() }; | ||
if (postfix_size == 1) // no need to add operators | ||
return postfix; | ||
|
||
for (const auto& op : postfix) { | ||
|
@@ -318,15 +325,15 @@ namespace { | |
} | ||
|
||
std::vector<mata::FormulaNode> res; | ||
if (postfix.size() >= 2) { | ||
res.push_back(postfix[0]); | ||
res.push_back(postfix[1]); | ||
if (postfix_size >= 2) { | ||
res.push_back(std::move(postfix[0])); | ||
res.push_back(std::move(postfix[1])); | ||
res.emplace_back( | ||
mata::FormulaNode::Type::OPERATOR, "|", "|", mata::FormulaNode::OperatorType::OR); | ||
} | ||
|
||
for (size_t i = 2; i < postfix.size(); ++i) { | ||
res.push_back(postfix[i]); | ||
for (size_t i{ 2 }; i < postfix_size; ++i) { | ||
res.push_back(std::move(postfix[i])); | ||
res.emplace_back( | ||
mata::FormulaNode::Type::OPERATOR, "|", "|", mata::FormulaNode::OperatorType::OR); | ||
} | ||
|
@@ -375,20 +382,19 @@ namespace { | |
for (const auto& keypair : section.dict) { | ||
const std::string &key = keypair.first; | ||
|
||
if (key.find("Initial") != std::string::npos) { | ||
if (key.starts_with("Initial")) { | ||
auto postfix = infix_to_postfix(aut, keypair.second); | ||
if (no_operators(postfix)) { | ||
aut.initial_enumerated = true; | ||
postfix = add_disjunction_implicitly(std::move(postfix)); | ||
} | ||
aut.initial_formula = postfix_to_graph(std::move(postfix)); | ||
} else if (key.find("Final") != std::string::npos) { | ||
} else if (key.starts_with("Final")) { | ||
auto postfix = infix_to_postfix(aut, keypair.second); | ||
if (no_operators(postfix)) { | ||
postfix = add_disjunction_implicitly(std::move(postfix)); | ||
aut.final_enumerated = true; | ||
} | ||
|
||
aut.final_formula = postfix_to_graph(std::move(postfix));; | ||
} | ||
} | ||
|
@@ -403,7 +409,7 @@ namespace { | |
|
||
return aut; | ||
} | ||
} // anonymous | ||
} // Anonymous namespace. | ||
|
||
size_t mata::IntermediateAut::get_number_of_disjuncts() const | ||
{ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -199,14 +199,14 @@ std::vector<std::pair<std::string, bool>> tokenize_line(const std::string& line) | |
|
||
std::vector<std::pair<std::string, bool>> split_tokens(std::vector<std::pair<std::string, bool>> tokens) { | ||
std::vector<std::pair<std::string, bool>> result; | ||
for (const auto& token : tokens) { | ||
for (auto& token: tokens) { | ||
if (token.second) { // is quoted? | ||
result.push_back(std::move(token)); | ||
continue; | ||
} | ||
|
||
const std::string_view token_string = token.first; | ||
size_t last_operator = 0; | ||
const std::string_view token_string{ token.first }; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why this everywhere actually? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I mena why to initialize things with the curly brackets {bla} instead of = bla? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it is some C++ idiom, that is advised to use. I myself don't like it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is to prevent narrowing of the types (https://stackoverflow.com/a/27755143), but naturally, C++ community has to make sure it is ugly as pug's arse. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Exactly as you say. It is a good idea, only horribly implemented as far as visualization goes. But it helps indeed and warns you about potential implicit conversion bugs. In modern C++, it should always be preferred over assignment operator. |
||
size_t last_operator{ 0 }; | ||
for (size_t i = 0, token_string_size{ token_string.size() }; i < token_string_size; ++i) { | ||
if (is_logical_operator(token_string[i])) { | ||
const std::string_view token_candidate = token_string.substr(last_operator, i - last_operator); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just wandering, can you put the two alredy to the the line 129 with the declaration?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, vector has no such constructor, unfortunately. It can be done with a lambda or a named function inside the parentheses in the initialization list. Something like