diff --git a/poincare/src/simplify/rules_generation/Makefile b/poincare/src/simplify/rules_generation/Makefile index 8c6b823e9..c552b6cd4 100644 --- a/poincare/src/simplify/rules_generation/Makefile +++ b/poincare/src/simplify/rules_generation/Makefile @@ -3,10 +3,8 @@ dir=poincare/src/simplify/rules_generation rulegen_objs := $(addprefix $(dir)/,\ rules_parser.o\ rules_lexer.o\ - builder.o\ node.o\ rule.o\ - selector.o\ ) $(dir)/rules_parser.cpp: $(dir)/rules_parser.y diff --git a/poincare/src/simplify/rules_generation/builder.cpp b/poincare/src/simplify/rules_generation/builder.cpp deleted file mode 100644 index 3b69a150d..000000000 --- a/poincare/src/simplify/rules_generation/builder.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include "builder.h" -#include "rule.h" -#include -#include - -Builder::Builder(Type type, std::string * name, std::vector * children) : - Node(name, (std::vector *)children), - m_type(type) -{ -} - -void Builder::generateFields(Rule * context, std::string &indentation) { - Selector * selector = context->selector(); - switch (m_type) { - case Type::ExpressionType: - std::cout << indentation << ".m_action = ExpressionBuilder::Action::BuildFromTypeAndValue," << std::endl; - std::cout << indentation << ".m_expressionType = Expression::Type::" << *m_name << "," << std::endl; - break; - case Type::Variable: - std::cout << indentation << ".m_action = ExpressionBuilder::Action::Clone," << std::endl; - assert(m_children->size() == 0); - std::cout << indentation << ".m_matchIndex = " << selector->flatIndexOfChildNamed(*m_name) << "," << std::endl; - break; - case Type::Wildcard: - std::cout << indentation << ".m_action = ExpressionBuilder::Action::BringUpWildcard," << std::endl; - assert(m_children->size() == 0); - std::cout << indentation << ".m_matchIndex = " << selector->flatIndexOfChildNamed(*m_name) << "," << std::endl; - break; - case Type::ExpressionGenerator: - assert(false); // Not implemented yet. - break; - } -} diff --git a/poincare/src/simplify/rules_generation/builder.h b/poincare/src/simplify/rules_generation/builder.h deleted file mode 100644 index 45c923273..000000000 --- a/poincare/src/simplify/rules_generation/builder.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef POINCARE_SIMPLIFY_RULES_GENERATION_BUILDER_H -#define POINCARE_SIMPLIFY_RULES_GENERATION_BUILDER_H - -#include "node.h" -#include - -class Builder : public Node { -public: - enum class Type { - ExpressionGenerator, - ExpressionType, - Variable, - Wildcard - }; - Builder(Type type, std::string * name, std::vector * children = nullptr); -protected: - void generateFields(Rule * context, std::string &indentation) override; -private: - Type m_type; -}; - -#endif diff --git a/poincare/src/simplify/rules_generation/node.cpp b/poincare/src/simplify/rules_generation/node.cpp index 76f64d5c5..94eea90f8 100644 --- a/poincare/src/simplify/rules_generation/node.cpp +++ b/poincare/src/simplify/rules_generation/node.cpp @@ -1,25 +1,113 @@ -#include "builder.h" +#include "node.h" +#include "rule.h" #include +#include #include -Node::Node(std::string * name, std::vector * children) : - m_name(name), - m_children(children) +Node::Node(Type type, std::string * typeName) : + m_type(type), + m_typeName(typeName), + m_referenceMode(ReferenceMode::None), + m_referenceName(nullptr), + m_value(nullptr), + m_parent(nullptr) { - if (children == nullptr) { - m_children = new std::vector(); - } - for (Node * child : *m_children) { - child->m_parent = this; - } + m_children = new std::vector(); } Node::~Node() { delete m_children; } +void Node::setReference(ReferenceMode mode, std::string * referenceName) { + assert(m_referenceName == nullptr); + m_referenceName = referenceName; + m_referenceMode = mode; +} + +void Node::setValue(std::string * value) { + assert(m_value == nullptr); + m_value = value; +} + +void Node::setChildren(std::vector * children) { + assert(m_children->size() == 0); + delete m_children; + m_children = children; + for (Node * child : *m_children) { + child->m_parent = this; + } +} + +// Generation + +std::string Node::generateSelectorConstructor(Rule * context) { + std::ostringstream result; + switch (m_type) { + case Node::Type::Any: + switch (m_referenceMode) { + case Node::ReferenceMode::None: + case Node::ReferenceMode::SingleNode: + result << "ExpressionSelector::Any("; + break; + case Node::ReferenceMode::Wildcard: + result << "ExpressionSelector::Wildcard("; + break; + } + break; + case Node::Type::Expression: + if (m_value == nullptr) { + result << "ExpressionSelector::Type(Expression::Type::" << *m_typeName << ", "; + } else { + result << "ExpressionSelector::TypeAndValue(Expression::Type::" << *m_typeName << ", " << *m_value << ","; + } + break; + case Node::Type::Generator: + //assert(false); + break; + } + result << m_children->size() << ")"; + return result.str(); +} + +std::string Node::generateBuilderConstructor(Rule * context) { + Node * selector = context->selector(); + std::ostringstream result; + switch (m_type) { + case Node::Type::Any: + switch (m_referenceMode) { + case Node::ReferenceMode::None: + assert(false); + break; + case Node::ReferenceMode::SingleNode: + assert(m_referenceName != nullptr); + result << "ExpressionBuilder::Clone(" << selector->flatIndexOfChildNamed(*m_referenceName) << ", " ; + break; + case Node::ReferenceMode::Wildcard: + result << "ExpressionBuilder::BringUpWildcard(" << selector->flatIndexOfChildNamed(*m_referenceName) << ", "; + break; + } + break; + case Node::Type::Expression: + if (m_value == nullptr) { + // Here we could assert that m_typeName is among the kinds that expect no value + result << "ExpressionBuilder::BuildFromType(Expression::Type::" << *m_typeName << ", "; + } else { + // Here we could assert that m_typeName is among the kinds that expect a value + result << "ExpressionBuilder::BuildFromTypeAndValue(Expression::Type::" << *m_typeName << ", " << *m_value << ", "; + } + break; + case Node::Type::Generator: + result << "ExpressionBuilder::CallExternalGenerator(SimplificationGenerator::" << *m_typeName << ", "; + //assert(false); + break; + } + result << m_children->size() << ")"; + return result.str(); +} + int Node::flatIndexOfChildNamed(std::string name) { - if (name == *m_name) { + if (m_referenceName != nullptr && *m_referenceName == name) { return 0; } int sum=1; @@ -54,17 +142,26 @@ std::string indentation_string(int i) { return result; } -int Node::generate(Rule * context, int index, int indentationLevel) { +void Node::generateSelectorTree(Rule * context) { + generateTree(true, context, 0, 0); +} + +void Node::generateBuilderTree(Rule * context) { + generateTree(false, context, 0, 0); +} + +int Node::generateTree(bool selector, Rule * context, int index, int indentationLevel) { std::string indentation = indentation_string(indentationLevel); - std::string nextIndentation = indentation_string(indentationLevel+1); - std::cout << indentation << "{" << std::endl; - std::cout << nextIndentation << "// #" << index << std::endl; - this->generateFields(context, nextIndentation); - std::cout << nextIndentation << ".m_numberOfChildren = " << m_children->size() << "," << std::endl; - std::cout << indentation << "}," << std::endl; + std::cout << indentation; + if (selector) { + std::cout << generateSelectorConstructor(context); + } else { + std::cout << generateBuilderConstructor(context); + } + std::cout << ", // #" << index << std::endl; int generatedCount = 1; for (Node * child : *m_children) { - generatedCount += child->generate(context, index+generatedCount, indentationLevel+1); + generatedCount += child->generateTree(selector, context, index+generatedCount, indentationLevel+1); } return generatedCount; } diff --git a/poincare/src/simplify/rules_generation/node.h b/poincare/src/simplify/rules_generation/node.h index fb2a689bb..2f070f510 100644 --- a/poincare/src/simplify/rules_generation/node.h +++ b/poincare/src/simplify/rules_generation/node.h @@ -8,14 +8,39 @@ class Rule; class Node { public: - Node(std::string * name, std::vector * m_children); + enum class Type { + Expression, + Generator, + Any + }; + enum class ReferenceMode { + None, + SingleNode, + Wildcard + }; + + // Creating Nodes + Node(Type type, std::string * typeName = nullptr); ~Node(); - int generate(Rule * context = nullptr, int index = 0, int indentationLevel = 0); + void setReference(ReferenceMode mode, std::string * referenceName); + void setValue(std::string * value); + void setChildren(std::vector * children); + int totalDescendantCountIncludingSelf(); int flatIndexOfChildNamed(std::string name); -protected: - virtual void generateFields(Rule * context, std::string &indentation) = 0; - std::string * m_name; + + void generateSelectorTree(Rule * context); + void generateBuilderTree(Rule * context); +private: + int generateTree(bool selector, Rule * context, int index, int indentationLevel); + std::string generateSelectorConstructor(Rule * context); + std::string generateBuilderConstructor(Rule * context); + + Type m_type; + std::string * m_typeName; + ReferenceMode m_referenceMode; + std::string * m_referenceName; + std::string * m_value; std::vector * m_children; Node * m_parent; }; diff --git a/poincare/src/simplify/rules_generation/rule.cpp b/poincare/src/simplify/rules_generation/rule.cpp index e01f5d319..176d3bde8 100644 --- a/poincare/src/simplify/rules_generation/rule.cpp +++ b/poincare/src/simplify/rules_generation/rule.cpp @@ -1,7 +1,7 @@ #include "rule.h" #include -Rule::Rule(Selector * selector, Builder * builder) : +Rule::Rule(Node * selector, Node * builder) : m_selector(selector), m_builder(builder) { } @@ -10,16 +10,16 @@ Rule::~Rule() { delete m_selector; } -Selector * Rule::selector() { +Node * Rule::selector() { return m_selector; } void Rule::generate(std::string rule_name) { - std::cout << "const ExpressionSelector " << rule_name << "Selector[" << m_selector->totalDescendantCountIncludingSelf() << "] = {" << std::endl; - m_selector->generate(this); + std::cout << "constexpr ExpressionSelector " << rule_name << "Selector[" << m_selector->totalDescendantCountIncludingSelf() << "] = {" << std::endl; + m_selector->generateSelectorTree(this); std::cout << "};" << std::endl; - std::cout << "const ExpressionBuilder " << rule_name << "Builder[" << m_builder->totalDescendantCountIncludingSelf() << "] = {" << std::endl; - m_builder->generate(this); + std::cout << "constexpr ExpressionBuilder " << rule_name << "Builder[" << m_builder->totalDescendantCountIncludingSelf() << "] = {" << std::endl; + m_builder->generateBuilderTree(this); std::cout << "};" << std::endl; } diff --git a/poincare/src/simplify/rules_generation/rule.h b/poincare/src/simplify/rules_generation/rule.h index de303e794..f6c57ae6f 100644 --- a/poincare/src/simplify/rules_generation/rule.h +++ b/poincare/src/simplify/rules_generation/rule.h @@ -1,18 +1,17 @@ #ifndef POINCARE_SIMPLIFY_RULES_GENERATION_RULE_H #define POINCARE_SIMPLIFY_RULES_GENERATION_RULE_H -#include "selector.h" -#include "builder.h" +#include "node.h" class Rule { public: - Rule(Selector * selector, Builder * builder); + Rule(Node * selector, Node * builder); ~Rule(); void generate(std::string rule_name); - Selector * selector(); + Node * selector(); private: - Selector * m_selector; - Builder * m_builder; + Node * m_selector; + Node * m_builder; }; #endif diff --git a/poincare/src/simplify/rules_generation/rules_lexer.l b/poincare/src/simplify/rules_generation/rules_lexer.l index 748a688ce..76d96f184 100644 --- a/poincare/src/simplify/rules_generation/rules_lexer.l +++ b/poincare/src/simplify/rules_generation/rules_lexer.l @@ -9,14 +9,18 @@ %% -[A-Z][a-z]+ { yylval.string = new std::string(yytext); return(EXPRESSION_TYPE); } -\$[a-zA-Z]+ { yylval.string = new std::string(yytext); return(EXPRESSION_GENERATOR); } -[a-z]+\* { yylval.string = new std::string(yytext); return(WILDCARD); } -[a-z]+ { yylval.string = new std::string(yytext); return(VARIABLE); } +[a-z]+ { yylval.string = new std::string(yytext); return (IDENTIFIER); } +[A-Za-z]+ { yylval.string = new std::string(yytext); return (CAPITALIZED_IDENTIFIER); } +[0-9]+ { yylval.string = new std::string(yytext); return (VALUE); } +\$ { return(DOLLAR); } +\* { return (ASTERISK); } \-\> { return(SIMPLIFIES_TO); } \( { return(LEFT_PARENTHESIS); } \) { return(RIGHT_PARENTHESIS); } +\[ { return(LEFT_BRACKET); } +\] { return(RIGHT_BRACKET); } \, { return(COMMA); } \; { return(SEMICOLON); } +\. { return(PERIOD); } %% diff --git a/poincare/src/simplify/rules_generation/rules_parser.y b/poincare/src/simplify/rules_generation/rules_parser.y index 497e562cb..2b369824a 100644 --- a/poincare/src/simplify/rules_generation/rules_parser.y +++ b/poincare/src/simplify/rules_generation/rules_parser.y @@ -23,39 +23,38 @@ int yyerror(std::vector ** rules, const char *s); * when parsing (a/b) we want to create a new Fraction), or a string (this will * be useful to retrieve the value of Integers for example). */ %union { - std::vector * builder_list; - std::vector * selector_list; std::vector * rule_list; + std::vector * node_list; Rule * rule; - Selector * selector; - Builder * builder; + Node * node; std::string * string; } -/* The INTEGER token uses the "string" part of the union to store its value */ -%token INTEGER -%token SYMBOL +/* The IDENTIFIER, CAPITALIZED_IDENTIFIER and VALUE token uses the "string" part + * of the union to store their value */ -%token EXPRESSION_TYPE -%token EXPRESSION_GENERATOR -%token WILDCARD -%token VARIABLE +%token IDENTIFIER +%token CAPITALIZED_IDENTIFIER +%token VALUE + +/* Some tokens don't store any value */ %token SIMPLIFIES_TO %token LEFT_PARENTHESIS %token RIGHT_PARENTHESIS +%token LEFT_BRACKET +%token RIGHT_BRACKET %token COMMA %token SEMICOLON +%token PERIOD +%token DOLLAR +%token ASTERISK +/* The "rule_list" symbol uses the "rule_list" part of the union, and so on */ %type rule_list; %type rule; -%type selector; -%type selector_list; -%type builder; -%type builder_list; - -/* The "exp" symbol uses the "expression" part of the union. */ -/*%type exp;*/ +%type node; +%type node_list; %% @@ -67,32 +66,39 @@ rule_list: | rule_list rule { $1->push_back($2); $$ = $1; } rule: - selector SIMPLIFIES_TO builder SEMICOLON { $$ = new Rule($1, $3); } + node SIMPLIFIES_TO node SEMICOLON { $$ = new Rule($1, $3); } -selector: - VARIABLE { $$ = new Selector(Selector::Type::Variable, $1); } - | WILDCARD { $$ = new Selector(Selector::Type::Wildcard, $1); } - | EXPRESSION_TYPE LEFT_PARENTHESIS selector_list RIGHT_PARENTHESIS { - $$ = new Selector(Selector::Type::ExpressionType, $1, $3); +node: + CAPITALIZED_IDENTIFIER { + $$ = new Node(Node::Type::Expression, $1); + } + | DOLLAR CAPITALIZED_IDENTIFIER { + $$ = new Node(Node::Type::Generator, $2); + } + | IDENTIFIER { + $$ = new Node(Node::Type::Any); + $$->setReference(Node::ReferenceMode::SingleNode, $1); + } + | IDENTIFIER ASTERISK { + $$ = new Node(Node::Type::Any); + $$->setReference(Node::ReferenceMode::Wildcard, $1); + } + | node PERIOD IDENTIFIER { + $$ = $1; + $$->setReference(Node::ReferenceMode::SingleNode, $3); + } + | node LEFT_BRACKET IDENTIFIER RIGHT_BRACKET { + $$ = $1; + $$->setValue($3); + } + | node LEFT_PARENTHESIS node_list RIGHT_PARENTHESIS { + $$ = $1; + $$->setChildren($3); } -selector_list: - selector { $$ = new std::vector(); $$->push_back($1); } - | selector_list COMMA selector { $1->push_back($3); $$ = $1; } - -builder: - VARIABLE { $$ = new Builder(Builder::Type::Variable, $1); } - | WILDCARD { $$ = new Builder(Builder::Type::Wildcard, $1); } - | EXPRESSION_GENERATOR LEFT_PARENTHESIS builder_list RIGHT_PARENTHESIS { - $$ = new Builder(Builder::Type::ExpressionGenerator, $1, $3); - } - | EXPRESSION_TYPE LEFT_PARENTHESIS builder_list RIGHT_PARENTHESIS { - $$ = new Builder(Builder::Type::ExpressionType, $1, $3); - } - -builder_list: - builder { $$ = new std::vector(); $$->push_back($1); } - | builder_list COMMA builder { $1->push_back($3); $$ = $1; } +node_list: + node { $$ = new std::vector(); $$->push_back($1); } + | node_list COMMA node { $1->push_back($3); $$ = $1; } %% @@ -120,20 +126,16 @@ int main(void) { rules->at(i)->generate(name.str()); std::cout << std::endl; } - std::cout << "const Simplification simplifications[" << rules->size() << "] = {" << std::endl; + std::cout << "constexpr Simplification simplifications[" << rules->size() << "] = {" << std::endl; for (int i=0; isize(); i++) { std::stringstream name; name << "rule" << i; - std::cout << " {" << std::endl; - std::cout << " .m_selector = (ExpressionSelector *)" << name.str() << "Selector," << std::endl; - std::cout << " .m_builder = (ExpressionBuilder *)" << name.str() << "Builder," << std::endl; - std::cout << " }," << std::endl; +std::cout << " Simplification((ExpressionSelector *)" << name.str() << "Selector, (ExpressionBuilder *)" << name.str() << "Builder)," << std::endl; } std::cout << "};" << std::endl; std::cout << std::endl; - std::cout << "const int knumberOfSimplifications = " << rules->size() << ";" << std::endl; - + std::cout << "constexpr int knumberOfSimplifications = " << rules->size() << ";" << std::endl; delete rules; return 0; diff --git a/poincare/src/simplify/rules_generation/selector.cpp b/poincare/src/simplify/rules_generation/selector.cpp deleted file mode 100644 index ef700302c..000000000 --- a/poincare/src/simplify/rules_generation/selector.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "selector.h" -#include -#include - -Selector::Selector(Type type, std::string * name, std::vector * children) : - Node(name, (std::vector *)children), - m_type(type) -{ -} - -void Selector::generateFields(Rule * context, std::string &indentation) { - Selector * parent = (Selector *)m_parent; - switch (m_type) { - case Type::Variable: - std::cout << indentation << ".m_match = ExpressionSelector::Match::Any," << std::endl; - break; - case Type::Wildcard: - std::cout << indentation << ".m_match = ExpressionSelector::Match::Wildcard," << std::endl; - // Wildcard should always be the last element of a parent - assert(parent->m_children->back() == this); - break; - case Type::ExpressionType: - std::cout << indentation << ".m_match = ExpressionSelector::Match::Type," << std::endl; - std::cout << indentation << ".m_expressionType = Expression::Type::" << *m_name << "," << std::endl; - break; - } -} diff --git a/poincare/src/simplify/rules_generation/selector.h b/poincare/src/simplify/rules_generation/selector.h deleted file mode 100644 index 730610e62..000000000 --- a/poincare/src/simplify/rules_generation/selector.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef POINCARE_SIMPLIFY_RULES_GENERATION_SELECTOR_H -#define POINCARE_SIMPLIFY_RULES_GENERATION_SELECTOR_H - -#include "node.h" -#include - -class Selector : public Node { -public: - enum class Type { - Variable, - Wildcard, - ExpressionType - }; - Selector(Type type, std::string * name, std::vector * children = nullptr); -protected: - void generateFields(Rule * context, std::string &indentation) override; -private: - Type m_type; -}; - -#endif