Add files
This commit is contained in:
430
core/include/bertini2/io/parsing/classic_utilities.hpp
Normal file
430
core/include/bertini2/io/parsing/classic_utilities.hpp
Normal file
@@ -0,0 +1,430 @@
|
||||
//This file is part of Bertini 2.
|
||||
//
|
||||
//bertini2/io/parsers.hpp is free software: you can redistribute it and/or modify
|
||||
//it under the terms of the GNU General Public License as published by
|
||||
//the Free Software Foundation, either version 3 of the License, or
|
||||
//(at your option) any later version.
|
||||
//
|
||||
//bertini2/io/parsing/classic_utilities.hpp is distributed in the hope that it will be useful,
|
||||
//but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
//GNU General Public License for more details.
|
||||
//
|
||||
//You should have received a copy of the GNU General Public License
|
||||
//along with bertini2/io/parsing/classic_utilities.hpp. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// Copyright(C) 2015 - 2017 by Bertini2 Development Team
|
||||
//
|
||||
// See <http://www.gnu.org/licenses/> for a copy of the license,
|
||||
// as well as COPYING. Bertini2 is provided with permitted
|
||||
// additional terms in the b2/licenses/ directory.
|
||||
|
||||
|
||||
/**
|
||||
\file bertini2/io/parsing/classic_utilities.hpp
|
||||
|
||||
\brief Provides utility functions for parsing classic bertini input files.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
|
||||
#include "bertini2/io/parsing/qi_files.hpp"
|
||||
#include "bertini2/io/file_utilities.hpp"
|
||||
|
||||
|
||||
|
||||
namespace bertini {
|
||||
namespace parsing {
|
||||
namespace classic {
|
||||
|
||||
namespace qi = ::boost::spirit::qi;
|
||||
namespace ascii = ::boost::spirit::ascii;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
\class SplitInputFile
|
||||
|
||||
\brief Storage class for input file that splits up the config portion from the input portion.
|
||||
|
||||
## Use
|
||||
|
||||
SplitFileInputConfig parser return an instance of this class. The user can then parse the config and input portions separately using the appropriate parser.
|
||||
|
||||
*/
|
||||
class SplitInputFile
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
std::string Config() const
|
||||
{
|
||||
return config_;
|
||||
}
|
||||
|
||||
std::string Input() const
|
||||
{
|
||||
return input_;
|
||||
}
|
||||
|
||||
bool Readable() const
|
||||
{
|
||||
return readable_;
|
||||
}
|
||||
|
||||
|
||||
void SetInput(std::string new_input)
|
||||
{
|
||||
input_ = new_input;
|
||||
}
|
||||
|
||||
void SetConfig(std::string new_config)
|
||||
{
|
||||
config_ = new_config;
|
||||
}
|
||||
|
||||
void SetConfigInput(std::string c, std::string i)
|
||||
{
|
||||
config_ = c;
|
||||
input_ = i;
|
||||
}
|
||||
|
||||
void SetReadable(bool read)
|
||||
{
|
||||
readable_ = read;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// void StripComments()
|
||||
// {
|
||||
// std::string::const_iterator iter = config_.begin();
|
||||
// std::string::const_iterator end = config_.end();
|
||||
//
|
||||
// CommentStripper<std::string::const_iterator> S;
|
||||
//
|
||||
// phrase_parse(iter, end, S,boost::spirit::ascii::space, config_);
|
||||
//
|
||||
// iter = input_.begin();
|
||||
// end = input_.end();
|
||||
//
|
||||
// phrase_parse(iter, end, S,boost::spirit::ascii::space, input_);
|
||||
// }
|
||||
|
||||
|
||||
friend std::ostream& operator<<(std::ostream & out, SplitInputFile const& printme)
|
||||
{
|
||||
out << "--------config-----------\n\n" << printme.Config() << "\n\n-------input--------\n\n" << printme.Input();
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private:
|
||||
std::string config_;
|
||||
std::string input_;
|
||||
|
||||
bool readable_ = true; //Input file can be split accurately
|
||||
|
||||
}; //re: SplitInputFile class
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Qi Parser object for parsing text into the SplitInputfile class. This ensures we can provide backwards compatibility with Bertini Classic input files.
|
||||
|
||||
To use this parser, construct an object of its type, then use it to parse.
|
||||
|
||||
\code
|
||||
System sys;
|
||||
std::string str = "variable_group x, y, z; \nfunction f1, f2;\n f1 = x*y*z;\n f2 = x+y+z;\n";
|
||||
|
||||
std::string::const_iterator iter = str.begin();
|
||||
std::string::const_iterator end = str.end();
|
||||
|
||||
|
||||
bertini::SystemParser<std::string::const_iterator> S;
|
||||
|
||||
|
||||
bool s = phrase_parse(iter, end, S,boost::spirit::ascii::space, sys);
|
||||
|
||||
\endcode
|
||||
|
||||
\brief Qi Parser object for parsing text into the SplitInputFile class.
|
||||
|
||||
CON END IN END (1 1 1 1) 15
|
||||
CON END IN -- (1 1 1 0) 14
|
||||
CON END -- END (1 1 0 1) 13
|
||||
CON END -- -- (1 1 0 0) 12
|
||||
CON -- IN END (1 0 1 1) 11
|
||||
CON -- IN -- (1 0 1 0) 10
|
||||
-- -- IN END (0 0 1 1) 3
|
||||
-- -- IN -- (0 0 1 0) 2
|
||||
-- -- --END (0 0 0 1) 1
|
||||
-- -- -- -- (0 0 0 0) 0
|
||||
*/
|
||||
template<typename Iterator, typename Skipper = ascii::space_type> //boost::spirit::unused_type
|
||||
struct SplitInputFileParser : qi::grammar<Iterator, SplitInputFile(), Skipper>
|
||||
{
|
||||
|
||||
|
||||
SplitInputFileParser() : SplitInputFileParser::base_type(root_rule_, "SplitInputFile")
|
||||
{
|
||||
namespace phx = boost::phoenix;
|
||||
using qi::_1;
|
||||
using qi::_2;
|
||||
using qi::_3;
|
||||
using qi::_4;
|
||||
using qi::_val;
|
||||
using qi::eps;
|
||||
using qi::lit;
|
||||
using qi::char_;
|
||||
using qi::omit;
|
||||
using boost::spirit::lexeme;
|
||||
using boost::spirit::as_string;
|
||||
using boost::spirit::ascii::no_case;
|
||||
|
||||
root_rule_.name("SplitInputFile_root_rule");
|
||||
|
||||
root_rule_ = both_ | unreadable_ |only_input_ ;
|
||||
|
||||
// NOTE ON CONVENTIONS CURRENTLY USED:
|
||||
// the various rules are constructed to obtain the text BEFORE the named marker, so e.g, rule config_ gets all text in the string before 'CONFIG'. similarly for 'END;' and 'INPUT'.
|
||||
|
||||
both_.name("have_both_config_and_input");
|
||||
both_ = (
|
||||
(omit[config_] >> end_ >> omit[input_] >> end_ >> omit[no_decl_]) [phx::bind(&SplitInputFile::SetConfigInput, _val, _1, _2)]// 15
|
||||
|
|
||||
(omit[config_] >> end_ >> omit[input_] >> no_decl_) [phx::bind(&SplitInputFile::SetConfigInput, _val, _1, _2)] // 14
|
||||
|
|
||||
(omit[config_] >> end_ >> end_ >> omit[no_decl_]) [phx::bind(&SplitInputFile::SetConfigInput, _val, _1, _2)] // 13
|
||||
|
|
||||
(omit[config_] >> input_ >> end_ >> omit[no_decl_]) [phx::bind(&SplitInputFile::SetConfigInput, _val, _1, _2)] // 11
|
||||
|
|
||||
(omit[config_] >> end_ >> no_decl_) [phx::bind(&SplitInputFile::SetConfigInput, _val, _1, _2)] // 12
|
||||
|
|
||||
(omit[config_] >> input_ >> no_decl_) [phx::bind(&SplitInputFile::SetConfigInput, _val, _1, _2)] // 10
|
||||
)
|
||||
;
|
||||
|
||||
// the rule for number 11 does not currently correctly parse text which matches it... why???
|
||||
|
||||
//this attempt for the both_ rule doesn't work because the ends are optional...
|
||||
// (omit[config_] >> end_ >> omit[input_] >> end_ >> omit[no_decl_]) [phx::bind(&SplitInputFile::SetConfigInput, _val, _1, _2)]
|
||||
// |
|
||||
// (omit[config_] >> omit[!end_] >> input_ >> end_ >> omit[no_decl_]) [phx::bind(&SplitInputFile::SetConfigInput, _val, _1, _2)]
|
||||
// |
|
||||
// (omit[config_] >> end_ >> omit[!input_] >> end_ >> omit[no_decl_]) [phx::bind(&SplitInputFile::SetConfigInput, _val, _1, _2)]
|
||||
// |
|
||||
// (omit[config_] >> omit[!end_] >> input_ >> no_decl_) [phx::bind(&SplitInputFile::SetConfigInput, _val, _1, _2)]
|
||||
// |
|
||||
// (omit[config_] >> end_ >> omit[!input_] >> omit[!end_] >> no_decl_) [phx::bind(&SplitInputFile::SetConfigInput, _val, _1, _2)]
|
||||
// )
|
||||
|
||||
|
||||
only_input_.name("have_only_input");
|
||||
only_input_ = (
|
||||
(omit[input_] >> end_ >> omit[no_decl_]) // 3
|
||||
|
|
||||
(omit[input_] >> no_decl_) // 2
|
||||
|
|
||||
(end_ >> omit[no_decl_]) // 1
|
||||
|
|
||||
(no_decl_) // 0
|
||||
)
|
||||
[phx::bind(&SplitInputFile::SetInput, _val, _1)];
|
||||
|
||||
unreadable_.name("unreadable_input"); //9 and 4 same as 12 and 1 to parser
|
||||
unreadable_ = (
|
||||
(omit[config_] >> no_decl_) // 8
|
||||
|
|
||||
(end_ >> omit[input_] >> end_ >> omit[no_decl_]) // 7
|
||||
|
|
||||
(end_ >> omit[input_] >> omit[no_decl_]) // 6
|
||||
|
|
||||
(end_ >> end_ >> omit[no_decl_]) // 5
|
||||
)
|
||||
[phx::bind(&SplitInputFile::SetReadable, _val, false)];
|
||||
|
||||
config_.name("config_");
|
||||
config_ = no_case[*(char_ - "CONFIG") >> "CONFIG"];
|
||||
|
||||
end_.name("end_");
|
||||
end_ = no_case[lexeme[*(char_ - "END;")] >> "END;"];
|
||||
|
||||
input_.name("input_");
|
||||
input_ = no_case[lexeme[*(char_ - "INPUT")] >> "INPUT"];
|
||||
|
||||
|
||||
|
||||
no_decl_.name("no_decl_");
|
||||
no_decl_ = lexeme[*(char_)];
|
||||
|
||||
|
||||
// debug(root_rule_);
|
||||
// debug(both_); debug(only_input_);
|
||||
// debug(config_);
|
||||
// debug(end_);
|
||||
// debug(input_);
|
||||
// debug(no_decl_);
|
||||
|
||||
// BOOST_SPIRIT_DEBUG_NODES((root_rule_)
|
||||
// (both_) (only_input_)
|
||||
// (config_) (end_) (input_)
|
||||
// (no_decl_) )
|
||||
|
||||
|
||||
|
||||
using phx::val;
|
||||
using phx::construct;
|
||||
using namespace qi::labels;
|
||||
qi::on_error<qi::fail>
|
||||
( root_rule_ ,
|
||||
std::cout<<
|
||||
val("config/input split parser could not complete parsing. Expecting ")<<
|
||||
_4<<
|
||||
val(" here: ")<<
|
||||
construct<std::string>(_3,_2)<<
|
||||
std::endl
|
||||
);
|
||||
}
|
||||
|
||||
private:
|
||||
qi::rule<Iterator, SplitInputFile(), ascii::space_type > root_rule_, both_, only_input_, unreadable_;
|
||||
qi::rule<Iterator, ascii::space_type, std::string()> end_, input_, no_decl_;
|
||||
qi::rule<Iterator, ascii::space_type> config_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Qi Parser object for removing comments from a line of text and then returns the uncommented line.
|
||||
|
||||
To use this parser, construct an object of its type, then use it to parse.
|
||||
|
||||
*/
|
||||
template<typename Iterator, typename Skipper = ascii::space_type> //boost::spirit::unused_type
|
||||
struct CommentStripper : qi::grammar<Iterator, std::string(), Skipper>
|
||||
{
|
||||
|
||||
|
||||
CommentStripper() : CommentStripper::base_type(root_rule_, "CommentStripper")
|
||||
{
|
||||
namespace phx = boost::phoenix;
|
||||
using qi::_1;
|
||||
using qi::_2;
|
||||
using qi::_3;
|
||||
using qi::_4;
|
||||
using qi::_val;
|
||||
using qi::eol;
|
||||
using qi::eoi;
|
||||
using qi::eps;
|
||||
using qi::lit;
|
||||
using qi::char_;
|
||||
using qi::omit;
|
||||
using boost::spirit::lexeme;
|
||||
using boost::spirit::as_string;
|
||||
|
||||
root_rule_.name("CommentStripper_root_rule");
|
||||
|
||||
root_rule_ = eps[_val = ""] >> *line_[_val = _val + _1 + "\n"] >> -last_line_[_val = _val + _1 + "\n"];//+line_ | qi::eoi;
|
||||
|
||||
|
||||
line_.name("line_of_commented_input");
|
||||
line_ = lexeme[*(char_ - eol - "%") >> omit[-( "%" >> lexeme[*(char_ - eol)] )] >> (eol ) ];
|
||||
|
||||
last_line_.name("line_of_commented_input_with_no_eol");
|
||||
last_line_ = lexeme[*(char_ - "%") >> omit[-( "%" >> lexeme[*(char_ - eol)] )]] ;
|
||||
|
||||
|
||||
// debug(root_rule_);
|
||||
// debug(line_);
|
||||
// debug(last_line_);
|
||||
//
|
||||
// BOOST_SPIRIT_DEBUG_NODES((root_rule_)
|
||||
// (line_) (last_line_) )
|
||||
|
||||
|
||||
|
||||
using phx::val;
|
||||
using phx::construct;
|
||||
using namespace qi::labels;
|
||||
qi::on_error<qi::fail>
|
||||
( root_rule_ ,
|
||||
std::cout<<
|
||||
val("config/input split parser could not complete parsing. Expecting ")<<
|
||||
_4<<
|
||||
val(" here: ")<<
|
||||
construct<std::string>(_3,_2)<<
|
||||
std::endl
|
||||
);
|
||||
}
|
||||
|
||||
private:
|
||||
qi::rule<Iterator, std::string(), ascii::space_type > root_rule_;
|
||||
qi::rule<Iterator, ascii::space_type, std::string()> line_, last_line_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
SplitInputFile ParseInputFile(std::string str_input_file)
|
||||
{
|
||||
std::string::const_iterator iter = str_input_file.begin();
|
||||
std::string::const_iterator end = str_input_file.end();
|
||||
|
||||
std::string uncommented_str_input;
|
||||
CommentStripper<std::string::const_iterator> commentparser;
|
||||
phrase_parse(iter, end, commentparser,boost::spirit::ascii::space, uncommented_str_input);
|
||||
|
||||
iter = uncommented_str_input.begin();
|
||||
end = uncommented_str_input.end();
|
||||
|
||||
SplitInputFileParser<std::string::const_iterator> spliter;
|
||||
|
||||
SplitInputFile input_file;
|
||||
phrase_parse(iter, end, spliter,boost::spirit::ascii::space, input_file);
|
||||
|
||||
return input_file;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
\brief Function for splitting a Bertini Classic style input file into `config` and `input`.
|
||||
*/
|
||||
std::tuple<std::string, std::string> SplitIntoConfigAndInput(Path const& input_file)
|
||||
{
|
||||
auto file_as_string = FileToString(input_file);
|
||||
|
||||
SplitInputFileParser<std::string::const_iterator> parser;
|
||||
SplitInputFile config_and_input;
|
||||
std::string::const_iterator iter = file_as_string.begin();
|
||||
std::string::const_iterator end = file_as_string.end();
|
||||
phrase_parse(iter, end, parser, boost::spirit::ascii::space, config_and_input);
|
||||
|
||||
return std::make_tuple(config_and_input.Config(), config_and_input.Input());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Function for splitting a Bertini Classic style input file into `config` and `input`.
|
||||
*/
|
||||
void SplitIntoConfigAndInput(std::string & config_section, std::string & input_section, Path const& input_file)
|
||||
{
|
||||
std::tie(config_section, input_section) = SplitIntoConfigAndInput(input_file);
|
||||
}
|
||||
|
||||
|
||||
} // re: namespace classic
|
||||
|
||||
}// re: namespace parsing
|
||||
}// re: namespace bertini
|
||||
70
core/include/bertini2/io/parsing/function_parsers.hpp
Normal file
70
core/include/bertini2/io/parsing/function_parsers.hpp
Normal file
@@ -0,0 +1,70 @@
|
||||
//This file is part of Bertini 2.
|
||||
//
|
||||
//bertini2/io/parsers.hpp is free software: you can redistribute it and/or modify
|
||||
//it under the terms of the GNU General Public License as published by
|
||||
//the Free Software Foundation, either version 3 of the License, or
|
||||
//(at your option) any later version.
|
||||
//
|
||||
//bertini2/io/parsing/function_parsers.hpp is distributed in the hope that it will be useful,
|
||||
//but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
//GNU General Public License for more details.
|
||||
//
|
||||
//You should have received a copy of the GNU General Public License
|
||||
//along with bertini2/io/parsing/function_parsers.hpp. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// Copyright(C) 2015 - 2017 by Bertini2 Development Team
|
||||
//
|
||||
// See <http://www.gnu.org/licenses/> for a copy of the license,
|
||||
// as well as COPYING. Bertini2 is provided with permitted
|
||||
// additional terms in the b2/licenses/ directory.
|
||||
|
||||
|
||||
/**
|
||||
\file bertini2/io/parsing/function_parsers.hpp
|
||||
|
||||
\brief Provides the parsers for functions in bertini2.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
|
||||
#include "bertini2/io/parsing/function_rules.hpp"
|
||||
|
||||
|
||||
|
||||
namespace bertini {
|
||||
namespace parsing {
|
||||
namespace classic {
|
||||
|
||||
|
||||
|
||||
template <typename Iterator>
|
||||
bool parse(Iterator first, Iterator last, std::shared_ptr<bertini::node::Node>& func)
|
||||
{
|
||||
using boost::spirit::qi::double_;
|
||||
using boost::spirit::qi::_1;
|
||||
using boost::spirit::qi::phrase_parse;
|
||||
using boost::spirit::ascii::space;
|
||||
using boost::phoenix::ref;
|
||||
|
||||
FunctionParser<Iterator> S;
|
||||
|
||||
std::shared_ptr<bertini::node::Node> f{};
|
||||
bool r = phrase_parse(first, last,
|
||||
S,
|
||||
space,
|
||||
f);
|
||||
|
||||
if (!r || first != last) // fail if we did not get a full match
|
||||
return false;
|
||||
|
||||
func = f;
|
||||
return r;
|
||||
}
|
||||
} // re: namespace classic
|
||||
|
||||
}// re: namespace parsing
|
||||
}// re: namespace bertini
|
||||
309
core/include/bertini2/io/parsing/function_rules.hpp
Normal file
309
core/include/bertini2/io/parsing/function_rules.hpp
Normal file
@@ -0,0 +1,309 @@
|
||||
//This file is part of Bertini 2.
|
||||
//
|
||||
//bertini2/io/parsers.hpp is free software: you can redistribute it and/or modify
|
||||
//it under the terms of the GNU General Public License as published by
|
||||
//the Free Software Foundation, either version 3 of the License, or
|
||||
//(at your option) any later version.
|
||||
//
|
||||
//bertini2/io/parsing/function_rules.hpp is distributed in the hope that it will be useful,
|
||||
//but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
//GNU General Public License for more details.
|
||||
//
|
||||
//You should have received a copy of the GNU General Public License
|
||||
//along with bertini2/io/parsing/function_rules.hpp. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// Copyright(C) 2015 - 2017 by Bertini2 Development Team
|
||||
//
|
||||
// See <http://www.gnu.org/licenses/> for a copy of the license,
|
||||
// as well as COPYING. Bertini2 is provided with permitted
|
||||
// additional terms in the b2/licenses/ directory.
|
||||
|
||||
|
||||
/**
|
||||
\file bertini2/io/parsing/function_rules.hpp
|
||||
|
||||
\brief Provides the parsing rules for functions in bertini2.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
|
||||
#include "bertini2/io/parsing/qi_files.hpp"
|
||||
|
||||
#include "bertini2/function_tree/node.hpp"
|
||||
#include "bertini2/function_tree/roots/function.hpp"
|
||||
|
||||
#include "bertini2/function_tree/operators/arithmetic.hpp"
|
||||
#include "bertini2/function_tree/operators/trig.hpp"
|
||||
|
||||
#include "bertini2/function_tree/symbols/number.hpp"
|
||||
#include "bertini2/function_tree/symbols/variable.hpp"
|
||||
|
||||
#include "bertini2/io/parsing/number_rules.hpp"
|
||||
|
||||
|
||||
|
||||
// see the following link for reading from arbitrary streams without putting the content into a std::string first
|
||||
//http://boost-spirit.com/home/articles/qi-example/tracking-the-input-position-while-parsing/
|
||||
|
||||
|
||||
|
||||
namespace {
|
||||
// this solution for *lazy* make shared comes from the SO forum, asked by polytheme, answered by user sehe.
|
||||
// https://stackoverflow.com/questions/21516201/how-to-create-boost-phoenix-make-shared
|
||||
// post found using google search terms `phoenix construct shared_ptr`
|
||||
// the code has been adapted slightly to fit the naming conventions of this project.
|
||||
template <typename T>
|
||||
struct MakeSharedFunctor
|
||||
{
|
||||
template <typename... A>
|
||||
struct result
|
||||
{
|
||||
typedef std::shared_ptr<T> type;
|
||||
};
|
||||
|
||||
template <typename... A>
|
||||
typename result<A...>::type operator()(A&&... a) const
|
||||
{
|
||||
return T::Make(std::forward<A>(a)...);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using make_shared_ = boost::phoenix::function<MakeSharedFunctor<T> >;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//////
|
||||
//
|
||||
// the following code adapts the trig functions and other special functions to be phoenix-callable.
|
||||
//
|
||||
/////////
|
||||
|
||||
// http://www.boost.org/doc/libs/1_58_0/libs/phoenix/doc/html/phoenix/modules/function/adapting_functions.html
|
||||
|
||||
//
|
||||
// form is as follows:
|
||||
//
|
||||
//BOOST_PHOENIX_ADAPT_FUNCTION(
|
||||
// RETURN_TYPE
|
||||
// , LAZY_FUNCTION
|
||||
// , FUNCTION
|
||||
// , FUNCTION_ARITY
|
||||
// )
|
||||
|
||||
|
||||
|
||||
BOOST_PHOENIX_ADAPT_FUNCTION(std::shared_ptr<bertini::node::Node>, cos_lazy, cos, 1);
|
||||
BOOST_PHOENIX_ADAPT_FUNCTION(std::shared_ptr<bertini::node::Node>, sin_lazy, sin, 1);
|
||||
BOOST_PHOENIX_ADAPT_FUNCTION(std::shared_ptr<bertini::node::Node>, tan_lazy, tan, 1);
|
||||
|
||||
BOOST_PHOENIX_ADAPT_FUNCTION(std::shared_ptr<bertini::node::Node>, log_lazy, log, 1);
|
||||
BOOST_PHOENIX_ADAPT_FUNCTION(std::shared_ptr<bertini::node::Node>, exp_lazy, exp, 1);
|
||||
BOOST_PHOENIX_ADAPT_FUNCTION(std::shared_ptr<bertini::node::Node>, sqrt_lazy, sqrt, 1);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
namespace bertini {
|
||||
namespace parsing {
|
||||
namespace classic {
|
||||
|
||||
|
||||
|
||||
namespace qi = ::boost::spirit::qi;
|
||||
namespace ascii = ::boost::spirit::ascii;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
A Qi grammar parser for parsing text into function trees. Currently called from the SystemParser.
|
||||
|
||||
\todo Improve error detection and reporting for the FunctionParser.
|
||||
|
||||
\brief A Qi grammar parser for parsing text into function trees.
|
||||
|
||||
This parser could not have been written without the generous help of SO user sehe.
|
||||
*/
|
||||
template<typename Iterator>
|
||||
struct FunctionParser : qi::grammar<Iterator, std::shared_ptr<node::Node>(), boost::spirit::ascii::space_type>
|
||||
{
|
||||
using Node = node::Node;
|
||||
using Function = node::Function;
|
||||
using Float = node::Float;
|
||||
using Integer = node::Integer;
|
||||
using Rational = node::Rational;
|
||||
|
||||
FunctionParser(qi::symbols<char,std::shared_ptr<Node> > * encountered_symbols) : FunctionParser::base_type(root_rule_,"FunctionParser")
|
||||
{
|
||||
namespace phx = boost::phoenix;
|
||||
using qi::_1;
|
||||
using qi::_2;
|
||||
using qi::_3;
|
||||
using qi::_4;
|
||||
using qi::_val;
|
||||
using qi::eps;
|
||||
using qi::lit;
|
||||
|
||||
using std::pow;
|
||||
using ::pow;
|
||||
|
||||
root_rule_.name("function_");
|
||||
root_rule_ = expression_ [ _val = make_shared_<Function>()(_1)];
|
||||
|
||||
|
||||
///////////////////
|
||||
expression_.name("expression_");
|
||||
expression_ =
|
||||
term_ [_val = _1]
|
||||
>> *( (lit('+') > term_ [_val += _1])
|
||||
| (lit('-') > term_ [_val -= _1])
|
||||
)
|
||||
;
|
||||
|
||||
term_.name("term_");
|
||||
term_ =
|
||||
factor_ [_val = _1]
|
||||
>> *( (lit('*') > factor_ [_val *= _1])
|
||||
| (lit('/') > factor_ [_val /= _1])
|
||||
)
|
||||
;
|
||||
|
||||
factor_.name("factor_");
|
||||
factor_ =
|
||||
exp_elem_ [_val = _1]
|
||||
>> *(lit('^') // any number of ^somethings
|
||||
> exp_elem_ [ phx::bind( []
|
||||
(std::shared_ptr<Node> & B, std::shared_ptr<Node> P)
|
||||
{
|
||||
B = pow(B,P);
|
||||
},
|
||||
_val,_1)] )
|
||||
;
|
||||
|
||||
exp_elem_.name("exp_elem_");
|
||||
exp_elem_ =
|
||||
(symbol_ >> !qi::alnum) [_val = _1]
|
||||
| ( '(' > expression_ [_val = _1] > ')' ) // using the > expectation here.
|
||||
| (lit('-') > expression_ [_val = -_1])
|
||||
| (lit('+') > expression_ [_val = _1])
|
||||
| (lit("sin") > '(' > expression_ [_val = sin_lazy(_1)] > ')' )
|
||||
| (lit("cos") > '(' > expression_ [_val = cos_lazy(_1)] > ')' )
|
||||
| (lit("tan") > '(' > expression_ [_val = tan_lazy(_1)] > ')' )
|
||||
| (lit("exp") > '(' > expression_ [_val = exp_lazy(_1)] > ')' )
|
||||
| (lit("log") > '(' > expression_ [_val = log_lazy(_1)] > ')' )
|
||||
| (lit("sqrt") > '(' > expression_ [_val = sqrt_lazy(_1)] > ')' )
|
||||
;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
symbol_.name("symbol_");
|
||||
symbol_ %=
|
||||
(*encountered_symbols) // the star here is the dereferencing of the encountered_symbols parameter to the constructor.
|
||||
|
|
||||
number_
|
||||
;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
number_.name("number_");
|
||||
number_ =
|
||||
mpfr_rules_.long_number_string_ [ _val = make_shared_<Float>()(_1) ]
|
||||
|
|
||||
mpfr_rules_.integer_string_ [ _val = make_shared_<Integer>()(_1) ];
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
using qi::on_error;
|
||||
using boost::phoenix::val;
|
||||
using boost::phoenix::construct;
|
||||
|
||||
|
||||
on_error<qi::fail>
|
||||
(
|
||||
root_rule_
|
||||
, std::cout
|
||||
<< val("Function parser error: expecting ")
|
||||
<< _4
|
||||
<< val(" here: \"")
|
||||
<< construct<std::string>(_3, _2)
|
||||
<< val("\"")
|
||||
<< std::endl
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// debug(root_rule_);
|
||||
// debug(expression_);
|
||||
// debug(term_);
|
||||
// debug(factor_);
|
||||
// debug(exp_elem_);
|
||||
// debug(number_);
|
||||
// debug(number_with_no_point_);
|
||||
// debug(number_with_digits_after_point_);
|
||||
// debug(number_with_digits_before_point_);
|
||||
// debug(exponent_notation_);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
qi::rule<Iterator, std::shared_ptr<Node>(), ascii::space_type > root_rule_;
|
||||
// the rule for kicking the entire thing off
|
||||
|
||||
qi::rule<Iterator, std::shared_ptr<Node>(), ascii::space_type> expression_, term_, factor_, exp_elem_;
|
||||
// rules for how to turn +-*/^ into operator nodes.
|
||||
|
||||
|
||||
|
||||
qi::rule<Iterator, std::shared_ptr<Node>(), ascii::space_type > symbol_;
|
||||
// any of the variables and numbers will be symbols.
|
||||
|
||||
qi::rule<Iterator, std::shared_ptr<Node>(), ascii::space_type > variable_; // finds a previously encountered number, and associates the correct variable node with it.
|
||||
|
||||
// the number_ rule wants to find strings from the various other number_ rules, and produces a Number node
|
||||
qi::rule<Iterator, std::shared_ptr<Node>(), ascii::space_type > number_;
|
||||
|
||||
parsing::rules::LongNum<Iterator> mpfr_rules_;
|
||||
};
|
||||
|
||||
} // re: namespace classic
|
||||
|
||||
} // re: namespace parsing
|
||||
|
||||
} // re: namespace bertini
|
||||
284
core/include/bertini2/io/parsing/number_parsers.hpp
Normal file
284
core/include/bertini2/io/parsing/number_parsers.hpp
Normal file
@@ -0,0 +1,284 @@
|
||||
//This file is part of Bertini 2.
|
||||
//
|
||||
//bertini2/io/parsers.hpp is free software: you can redistribute it and/or modify
|
||||
//it under the terms of the GNU General Public License as published by
|
||||
//the Free Software Foundation, either version 3 of the License, or
|
||||
//(at your option) any later version.
|
||||
//
|
||||
//bertini2/io/parsing/number_parsers.hpp is distributed in the hope that it will be useful,
|
||||
//but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
//GNU General Public License for more details.
|
||||
//
|
||||
//You should have received a copy of the GNU General Public License
|
||||
//along with bertini2/io/parsing/number_parsers.hpp. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// Copyright(C) 2015 - 2017 by Bertini2 Development Team
|
||||
//
|
||||
// See <http://www.gnu.org/licenses/> for a copy of the license,
|
||||
// as well as COPYING. Bertini2 is provided with permitted
|
||||
// additional terms in the b2/licenses/ directory.
|
||||
|
||||
|
||||
/**
|
||||
\file bertini2/io/parsing/number_parsers.hpp
|
||||
|
||||
\brief Provides parsers for numbers in bertini.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "bertini2/io/parsing/number_rules.hpp"
|
||||
|
||||
|
||||
|
||||
namespace bertini{
|
||||
namespace parsing{
|
||||
|
||||
namespace classic{
|
||||
template<typename Iterator, typename Skipper = ascii::space_type>
|
||||
struct MpfrFloatParser : qi::grammar<Iterator, mpfr_float(), boost::spirit::ascii::space_type>
|
||||
{
|
||||
MpfrFloatParser() : MpfrFloatParser::base_type(root_rule_,"MpfrFloatParser")
|
||||
{
|
||||
using std::max;
|
||||
namespace phx = boost::phoenix;
|
||||
using qi::_1;
|
||||
using qi::_2;
|
||||
using qi::_3;
|
||||
using qi::_4;
|
||||
using qi::_val;
|
||||
|
||||
root_rule_.name("mpfr_float");
|
||||
root_rule_ = mpfr_rules_.number_string_
|
||||
[ phx::bind(
|
||||
[]
|
||||
(mpfr_float & B, std::string const& P)
|
||||
{
|
||||
using std::max;
|
||||
auto prev_prec = DefaultPrecision();
|
||||
auto asdf = max(prev_prec,LowestMultiplePrecision());
|
||||
auto digits = max(P.size(),static_cast<decltype(P.size())>(asdf));
|
||||
|
||||
B.precision(digits);
|
||||
B = mpfr_float(P,digits);
|
||||
},
|
||||
_val,_1
|
||||
)
|
||||
];
|
||||
|
||||
using phx::val;
|
||||
using phx::construct;
|
||||
using namespace qi::labels;
|
||||
qi::on_error<qi::fail>
|
||||
( root_rule_ ,
|
||||
std::cout<<
|
||||
val("mpfr_float parser could not complete parsing. Expecting ")<<
|
||||
_4<<
|
||||
val(" here: ")<<
|
||||
construct<std::string>(_3,_2)<<
|
||||
std::endl
|
||||
);
|
||||
}
|
||||
|
||||
qi::rule<Iterator, mpfr_float(), Skipper > root_rule_;
|
||||
rules::LongNum<Iterator> mpfr_rules_;
|
||||
};
|
||||
|
||||
|
||||
template<typename Iterator, typename Skipper = ascii::space_type>
|
||||
struct MpfrComplexParser : qi::grammar<Iterator, mpfr_complex(), boost::spirit::ascii::space_type>
|
||||
{
|
||||
MpfrComplexParser() : MpfrComplexParser::base_type(root_rule_,"MpfrComplexParser")
|
||||
{
|
||||
using std::max;
|
||||
namespace phx = boost::phoenix;
|
||||
using qi::_1;
|
||||
using qi::_2;
|
||||
using qi::_val;
|
||||
|
||||
root_rule_ =
|
||||
(mpfr_float_ >> mpfr_float_)
|
||||
[ phx::bind(
|
||||
[]
|
||||
(mpfr_complex & B, mpfr_float const& P, mpfr_float const& Q)
|
||||
{
|
||||
auto prev_prec = DefaultPrecision();
|
||||
auto digits = max(P.precision(),Q.precision());
|
||||
|
||||
B.precision(digits);
|
||||
|
||||
B.real(P);
|
||||
B.imag(Q);
|
||||
},
|
||||
_val,_1,_2
|
||||
)
|
||||
];
|
||||
}
|
||||
|
||||
qi::rule<Iterator, mpfr_complex(), Skipper > root_rule_;
|
||||
MpfrFloatParser<Iterator> mpfr_float_;
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
static bool parse(Iterator first, Iterator last, double& c)
|
||||
{
|
||||
using boost::spirit::qi::double_;
|
||||
using boost::spirit::qi::_1;
|
||||
using boost::spirit::qi::phrase_parse;
|
||||
using boost::spirit::ascii::space;
|
||||
using boost::phoenix::ref;
|
||||
|
||||
double rN = 0.0;
|
||||
bool r = phrase_parse(first, last,
|
||||
(
|
||||
double_[ref(rN) = _1]
|
||||
),
|
||||
space);
|
||||
|
||||
if (!r || first != last) // fail if we did not get a full match
|
||||
return false;
|
||||
|
||||
c = rN;
|
||||
return r;
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
static bool parse(Iterator first, Iterator last, std::complex<double>& c)
|
||||
{
|
||||
using boost::spirit::qi::double_;
|
||||
using boost::spirit::qi::_1;
|
||||
using boost::spirit::qi::phrase_parse;
|
||||
using boost::spirit::ascii::space;
|
||||
using boost::phoenix::ref;
|
||||
|
||||
double rN = 0.0;
|
||||
double iN = 0.0;
|
||||
bool r = phrase_parse(first, last,
|
||||
(
|
||||
double_[ref(rN) = _1]
|
||||
>> -(double_[ref(iN) = _1])
|
||||
| double_[ref(rN) = _1]
|
||||
),
|
||||
space);
|
||||
|
||||
if (!r || first != last) // fail if we did not get a full match
|
||||
return false;
|
||||
c = std::complex<double>(rN, iN);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template <typename Iterator>
|
||||
static bool parse(Iterator first, Iterator last, mpfr_float& c)
|
||||
{
|
||||
using boost::spirit::qi::double_;
|
||||
using boost::spirit::qi::_1;
|
||||
using boost::spirit::qi::phrase_parse;
|
||||
using boost::spirit::ascii::space;
|
||||
using boost::phoenix::ref;
|
||||
|
||||
MpfrFloatParser<Iterator> S;
|
||||
|
||||
mpfr_float rN {0};
|
||||
bool r = phrase_parse(first, last,
|
||||
S,
|
||||
space,
|
||||
rN
|
||||
);
|
||||
|
||||
if (!r || first != last) // fail if we did not get a full match
|
||||
return false;
|
||||
c.precision(rN.precision());
|
||||
c = rN;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template <typename Iterator>
|
||||
static bool parse(Iterator first, Iterator last, mpfr_complex& c)
|
||||
{
|
||||
using boost::spirit::qi::double_;
|
||||
using boost::spirit::qi::_1;
|
||||
using boost::spirit::qi::phrase_parse;
|
||||
using boost::spirit::ascii::space;
|
||||
using boost::phoenix::ref;
|
||||
|
||||
MpfrComplexParser<Iterator> S;
|
||||
|
||||
mpfr_complex rN {};
|
||||
bool r = phrase_parse(first, last,
|
||||
S,
|
||||
space,
|
||||
rN);
|
||||
|
||||
if (!r || first != last) // fail if we did not get a full match
|
||||
return false;
|
||||
c.precision(rN.precision());
|
||||
c = rN;
|
||||
return r;
|
||||
}
|
||||
|
||||
} // re: namespace classic
|
||||
|
||||
|
||||
|
||||
namespace cplusplus{
|
||||
|
||||
template <typename Iterator>
|
||||
static bool parse(Iterator first, Iterator last, double& c)
|
||||
{
|
||||
using boost::spirit::qi::double_;
|
||||
using boost::spirit::qi::_1;
|
||||
using boost::spirit::qi::phrase_parse;
|
||||
using boost::spirit::ascii::space;
|
||||
using boost::phoenix::ref;
|
||||
|
||||
double rN = 0.0;
|
||||
bool r = phrase_parse(first, last,
|
||||
(
|
||||
double_[ref(rN) = _1]
|
||||
),
|
||||
space);
|
||||
|
||||
if (!r || first != last) // fail if we did not get a full match
|
||||
return false;
|
||||
|
||||
c = rN;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
template <typename Iterator>
|
||||
static bool parse(Iterator first, Iterator last, std::complex<double>& c)
|
||||
{
|
||||
using boost::spirit::qi::double_;
|
||||
using boost::spirit::qi::_1;
|
||||
using boost::spirit::qi::phrase_parse;
|
||||
using boost::spirit::ascii::space;
|
||||
using boost::phoenix::ref;
|
||||
|
||||
double rN = 0.0;
|
||||
double iN = 0.0;
|
||||
bool r = phrase_parse(first, last,
|
||||
(
|
||||
'(' >> double_[ref(rN) = _1]
|
||||
>> -(',' >> double_[ref(iN) = _1]) >> ')'
|
||||
| double_[ref(rN) = _1]
|
||||
),
|
||||
space);
|
||||
|
||||
if (!r || first != last) // fail if we did not get a full match
|
||||
return false;
|
||||
c = std::complex<double>(rN, iN);
|
||||
return r;
|
||||
}
|
||||
} // re: namespace cplusplus
|
||||
} //re: namespace parsing
|
||||
} //re: namespace bertini
|
||||
182
core/include/bertini2/io/parsing/number_rules.hpp
Normal file
182
core/include/bertini2/io/parsing/number_rules.hpp
Normal file
@@ -0,0 +1,182 @@
|
||||
//This file is part of Bertini 2.
|
||||
//
|
||||
//bertini2/io/parsers.hpp is free software: you can redistribute it and/or modify
|
||||
//it under the terms of the GNU General Public License as published by
|
||||
//the Free Software Foundation, either version 3 of the License, or
|
||||
//(at your option) any later version.
|
||||
//
|
||||
//bertini2/io/parsing/number_rules.hpp is distributed in the hope that it will be useful,
|
||||
//but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
//GNU General Public License for more details.
|
||||
//
|
||||
//You should have received a copy of the GNU General Public License
|
||||
//along with bertini2/io/parsing/number_rules.hpp. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// Copyright(C) 2015 - 2017 by Bertini2 Development Team
|
||||
//
|
||||
// See <http://www.gnu.org/licenses/> for a copy of the license,
|
||||
// as well as COPYING. Bertini2 is provided with permitted
|
||||
// additional terms in the b2/licenses/ directory.
|
||||
|
||||
|
||||
/**
|
||||
\file bertini2/io/parsing/number_rules.hpp
|
||||
|
||||
\brief Provides the parsersing rules for numbers in bertini2.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
|
||||
#include "bertini2/io/parsing/qi_files.hpp"
|
||||
|
||||
#include "bertini2/mpfr_complex.hpp"
|
||||
|
||||
#include "bertini2/num_traits.hpp"
|
||||
|
||||
|
||||
BOOST_FUSION_ADAPT_ADT(
|
||||
bertini::mpfr_complex,
|
||||
(obj.real(), obj.real(val))
|
||||
(obj.imag(), obj.imag(val)))
|
||||
|
||||
|
||||
namespace bertini{
|
||||
namespace parsing{
|
||||
|
||||
|
||||
|
||||
namespace qi = ::boost::spirit::qi;
|
||||
namespace ascii = ::boost::spirit::ascii;
|
||||
|
||||
namespace rules{
|
||||
/**
|
||||
/brief Struct that holds the rules for parsing mpfr numbers
|
||||
|
||||
Use: Include this struct with the rest of your rules.
|
||||
*/
|
||||
template<typename Iterator>
|
||||
struct LongNum
|
||||
{
|
||||
LongNum()
|
||||
{
|
||||
namespace phx = boost::phoenix;
|
||||
using qi::_1;
|
||||
using qi::_2;
|
||||
using qi::_3;
|
||||
using qi::_4;
|
||||
using qi::_val;
|
||||
using qi::eps;
|
||||
using qi::lit;
|
||||
using qi::char_;
|
||||
using qi::omit;
|
||||
using boost::spirit::lexeme;
|
||||
using boost::spirit::as_string;
|
||||
using boost::spirit::ascii::no_case;
|
||||
|
||||
number_string_.name("number_");
|
||||
number_string_ =
|
||||
long_number_string_
|
||||
|
|
||||
integer_string_;
|
||||
|
||||
integer_string_.name("integer_string_");
|
||||
integer_string_ = eps[_val = std::string()] >>
|
||||
-(qi::lit('-'))[_val += "-"] >>
|
||||
number_with_no_point_ [_val += _1]
|
||||
>> -exponent_notation_ [_val += _1];
|
||||
|
||||
|
||||
long_number_string_.name("long_number_string_");
|
||||
long_number_string_ = eps[_val = std::string()] >>
|
||||
-(qi::lit('-'))[_val += "-"] >>
|
||||
(
|
||||
// 1. Read possible numbers before decimal, with possible negative
|
||||
(number_with_digits_after_point_ [_val += _1]
|
||||
|
|
||||
number_with_digits_before_point_ [_val += _1] )
|
||||
>> // reminder -- the - before the exponent_notation here means optional
|
||||
-exponent_notation_ [_val+=_1]// Possible scientific notation, with possible negative in exponent.
|
||||
);
|
||||
|
||||
|
||||
|
||||
number_with_digits_after_point_.name("number_with_digits_after_point_");
|
||||
number_with_digits_after_point_ = eps[_val = std::string()]
|
||||
>>
|
||||
*(qi::char_(L'0',L'9')[_val += _1])
|
||||
>>
|
||||
qi::lit('.')[_val += "."] // find a decimal point
|
||||
>>
|
||||
+(qi::char_(L'0',L'9')[_val += _1]) // find at least one digit after the point
|
||||
;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
number_with_digits_before_point_.name("number_with_digits_before_point_");
|
||||
number_with_digits_before_point_ = eps[_val = std::string()]
|
||||
>>
|
||||
+(qi::char_(L'0',L'9')[_val += _1])
|
||||
>>
|
||||
qi::lit('.')[_val += "."] // find a decimal point
|
||||
>>
|
||||
*(qi::char_(L'0',L'9')[_val += _1]) // find any number of digits after the point
|
||||
;
|
||||
|
||||
|
||||
number_with_no_point_.name("number_with_no_point_");
|
||||
number_with_no_point_ = eps[_val = std::string()]
|
||||
>>
|
||||
(-(qi::lit('-')[_val += "-"]) // then an optional minus sign
|
||||
>>
|
||||
+(qi::char_(L'0',L'9'))[_val += _1])
|
||||
;
|
||||
|
||||
|
||||
|
||||
|
||||
exponent_notation_.name("exponent_notation_");
|
||||
exponent_notation_ = eps[_val = std::string()]
|
||||
>> ( // start what the rule actually does
|
||||
(
|
||||
qi::lit('e')[_val += "e"] // get an opening 'e'
|
||||
|
|
||||
qi::lit('E')[_val += "e"] // get an opening 'e'
|
||||
)
|
||||
>>
|
||||
-(qi::lit('-')[_val += "-"]) // then an optional minus sign
|
||||
>>
|
||||
+(qi::char_(L'0',L'9')[_val += _1]) // then at least one number
|
||||
); // finish the rule off
|
||||
|
||||
rational.name("long_rational");
|
||||
rational =
|
||||
(number_string_
|
||||
|
|
||||
(number_string_ >> char_('/') >> number_string_));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// these rules all produce strings which are fed into numbers.
|
||||
qi::rule<Iterator, std::string()> number_string_, integer_string_, long_number_string_, number_with_digits_before_point_,
|
||||
number_with_digits_after_point_, number_with_no_point_, exponent_notation_, rational;
|
||||
|
||||
|
||||
}; //re: LongNum
|
||||
|
||||
|
||||
} // namespace rules
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
53
core/include/bertini2/io/parsing/qi_files.hpp
Normal file
53
core/include/bertini2/io/parsing/qi_files.hpp
Normal file
@@ -0,0 +1,53 @@
|
||||
//This file is part of Bertini 2.
|
||||
//
|
||||
//bertini2/nag_algorithms/zero_dim_solve.hpp is free software: you can redistribute it and/or modify
|
||||
//it under the terms of the GNU General Public License as published by
|
||||
//the Free Software Foundation, either version 3 of the License, or
|
||||
//(at your option) any later version.
|
||||
//
|
||||
//bertini2/io/parsing/qi_files.hpp is distributed in the hope that it will be useful,
|
||||
//but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
//GNU General Public License for more details.
|
||||
//
|
||||
//You should have received a copy of the GNU General Public License
|
||||
//along with bertini2/io/parsing/qi_files.hpp. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// Copyright(C) 2015 - 2017 by Bertini2 Development Team
|
||||
//
|
||||
// See <http://www.gnu.org/licenses/> for a copy of the license,
|
||||
// as well as COPYING. Bertini2 is provided with permitted
|
||||
// additional terms in the b2/licenses/ directory.
|
||||
|
||||
|
||||
/**
|
||||
\file bertini2/io/parsing/qi_files.hpp
|
||||
|
||||
\brief Provides all the include files needed to develop a parsing file that uses boost qi.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define BOOST_SPIRIT_USE_PHOENIX_V3 1
|
||||
|
||||
#include <boost/fusion/adapted.hpp>
|
||||
#include <boost/fusion/include/adapted.hpp>
|
||||
|
||||
#include <boost/spirit/include/qi.hpp>
|
||||
#include <boost/phoenix.hpp>
|
||||
|
||||
|
||||
#include <boost/spirit/include/qi.hpp>
|
||||
#include <boost/spirit/include/qi_core.hpp>
|
||||
#include <boost/phoenix/core.hpp>
|
||||
#include <boost/phoenix/operator.hpp>
|
||||
#include <boost/fusion/include/std_pair.hpp>
|
||||
|
||||
#include <boost/phoenix/bind/bind_function.hpp>
|
||||
#include <boost/phoenix/object/construct.hpp>
|
||||
#include <boost/bind/bind.hpp>
|
||||
|
||||
#include <boost/fusion/adapted/adt/adapt_adt.hpp>
|
||||
#include <boost/fusion/include/adapt_adt.hpp>
|
||||
|
||||
#include <boost/spirit/include/support_istream_iterator.hpp>
|
||||
149
core/include/bertini2/io/parsing/settings_parsers.hpp
Normal file
149
core/include/bertini2/io/parsing/settings_parsers.hpp
Normal file
@@ -0,0 +1,149 @@
|
||||
//This file is part of Bertini 2.
|
||||
//
|
||||
//bertini2/io/parsers.hpp is free software: you can redistribute it and/or modify
|
||||
//it under the terms of the GNU General Public License as published by
|
||||
//the Free Software Foundation, either version 3 of the License, or
|
||||
//(at your option) any later version.
|
||||
//
|
||||
//bertini2/io/parsing/settings_parsers.hpp is distributed in the hope that it will be useful,
|
||||
//but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
//GNU General Public License for more details.
|
||||
//
|
||||
//You should have received a copy of the GNU General Public License
|
||||
//along with bertini2/io/parsing/settings_parsers.hpp. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// Copyright(C) 2015 - 2017 by Bertini2 Development Team
|
||||
//
|
||||
// See <http://www.gnu.org/licenses/> for a copy of the license,
|
||||
// as well as COPYING. Bertini2 is provided with permitted
|
||||
// additional terms in the b2/licenses/ directory.
|
||||
|
||||
|
||||
/**
|
||||
\file bertini2/io/parsing/settings_parsers.hpp
|
||||
|
||||
\brief Provides the parsers for settings in bertini2.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
#include "bertini2/detail/typelist.hpp"
|
||||
|
||||
#include "bertini2/io/parsing/settings_parsers/tracking.hpp"
|
||||
#include "bertini2/io/parsing/settings_parsers/endgames.hpp"
|
||||
#include "bertini2/io/parsing/settings_parsers/algorithm.hpp"
|
||||
|
||||
|
||||
|
||||
|
||||
namespace bertini {
|
||||
namespace parsing {
|
||||
|
||||
namespace classic {
|
||||
|
||||
/**
|
||||
\brief Helper function to fill a single configuration struct by parsing a config input file.
|
||||
|
||||
\param config_str The comment-stripped configuration string from a Bertini classic input file.
|
||||
|
||||
\tparam ConfigT The config ConfigT type
|
||||
\tparam RT Real number type
|
||||
|
||||
\returns The config struct filled with data from the input file.
|
||||
*/
|
||||
|
||||
template<typename ConfigT>
|
||||
ConfigT FillConfigStruct(std::string const& config_str)
|
||||
{
|
||||
std::string::const_iterator iter = config_str.begin();
|
||||
std::string::const_iterator end = config_str.end();
|
||||
ConfigT settings;
|
||||
ConfigSettingParser<std::string::const_iterator, ConfigT> parser;
|
||||
auto parse_success = phrase_parse(iter, end, parser,boost::spirit::ascii::space, settings);
|
||||
if (!parse_success || iter!=end)
|
||||
throw std::runtime_error("failed to parse into config struct from file");
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
\brief Base variadic parser for parsing many config structs at once.
|
||||
|
||||
A specialization for a typelist of configs appears below.
|
||||
|
||||
\tparam RT Real number type
|
||||
\tparam Ts Configuration structures to be filled by the parser
|
||||
*/
|
||||
template<typename ...Ts>
|
||||
struct ConfigParser
|
||||
{
|
||||
/**
|
||||
The primary idea for filling a tuple using variadic templates comes from:
|
||||
http://stackoverflow.com/questions/10014713/build-tuple-using-variadic-templates
|
||||
|
||||
|
||||
\brief Reads in a comment-stripped, config portion of a Bertini classic input file. Parses the config settings and returns the structures passed into the template parameters with the relevant config settings.
|
||||
|
||||
\param config The string containing the comment-stripped config portion of the Bertini classic input file.
|
||||
|
||||
\return A tuple containing all the required config structures.
|
||||
*/
|
||||
static
|
||||
std::tuple<Ts...> Parse(std::string const& config)
|
||||
{
|
||||
return std::make_tuple<Ts...>(FillConfigStruct<Ts>(config)...);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
\brief Specialization of ConfigParser for a single config struct
|
||||
|
||||
\tparam ConfigT The config ConfigT type
|
||||
\tparam RT Real number type
|
||||
*/
|
||||
template<typename ConfigT>
|
||||
struct ConfigParser <ConfigT>
|
||||
{
|
||||
|
||||
/**
|
||||
\brief Fill a single configuration struct by parsing a config input file.
|
||||
|
||||
\param config The comment-stripped configuration string from a Bertini classic input file.
|
||||
|
||||
\returns The config struct filled with data from the input file.
|
||||
*/
|
||||
static
|
||||
ConfigT Parse(std::string const& config)
|
||||
{
|
||||
return FillConfigStruct<ConfigT>(config);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
\brief Specialization of ConfigParser for a typelist, returning a thing passed down from the base variadic case.
|
||||
|
||||
\tparam ConfigT The config ConfigT type
|
||||
\tparam RT Real number type
|
||||
*/
|
||||
template<typename ...Ts>
|
||||
struct ConfigParser<detail::TypeList<Ts...>>
|
||||
{
|
||||
static
|
||||
auto Parse(std::string const& config)
|
||||
{
|
||||
return ConfigParser<Ts...>::Parse(config);
|
||||
}
|
||||
};
|
||||
} // re: namespace classic
|
||||
|
||||
}// re: namespace parsing
|
||||
}// re: namespace bertini
|
||||
934
core/include/bertini2/io/parsing/settings_parsers/algorithm.hpp
Normal file
934
core/include/bertini2/io/parsing/settings_parsers/algorithm.hpp
Normal file
@@ -0,0 +1,934 @@
|
||||
//This file is part of Bertini 2.
|
||||
//
|
||||
//bertini2/io/parsing/settings_parsers/algorithm.hpp is free software: you can redistribute it and/or modify
|
||||
//it under the terms of the GNU General Public License as published by
|
||||
//the Free Software Foundation, either version 3 of the License, or
|
||||
//(at your option) any later version.
|
||||
//
|
||||
//bertini2/io/parsing/settings_parsers/algorithm.hpp is distributed in the hope that it will be useful,
|
||||
//but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
//GNU General Public License for more details.
|
||||
//
|
||||
//You should have received a copy of the GNU General Public License
|
||||
//along with bertini2/io/parsing/settings_parsers/algorithm.hpp. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// Copyright(C) 2015 - 2017 by Bertini2 Development Team
|
||||
//
|
||||
// See <http://www.gnu.org/licenses/> for a copy of the license,
|
||||
// as well as COPYING. Bertini2 is provided with permitted
|
||||
// additional terms in the b2/licenses/ directory.
|
||||
|
||||
|
||||
/**
|
||||
\file bertini2/io/parsing/settings_parsers/algorithm.hpp
|
||||
|
||||
\brief Provides the parsing rules for algorithm-related settings in bertini2.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "bertini2/io/parsing/settings_parsers/base.hpp"
|
||||
#include "bertini2/nag_algorithms/common/config.hpp"
|
||||
|
||||
namespace bertini {
|
||||
namespace parsing {
|
||||
namespace classic {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
*/
|
||||
template<typename Iterator, typename Skipper>
|
||||
struct ConfigSettingParser<Iterator, algorithm::TolerancesConfig, Skipper> : qi::grammar<Iterator, algorithm::TolerancesConfig(), Skipper>
|
||||
{
|
||||
using T = double;
|
||||
|
||||
ConfigSettingParser() : ConfigSettingParser::base_type(root_rule_, "config::TolerancesType")
|
||||
{
|
||||
namespace phx = boost::phoenix;
|
||||
using qi::_1;
|
||||
using qi::_2;
|
||||
using qi::_3;
|
||||
using qi::_4;
|
||||
using qi::_val;
|
||||
using qi::eps;
|
||||
using qi::lit;
|
||||
using qi::char_;
|
||||
using qi::omit;
|
||||
using boost::spirit::lexeme;
|
||||
using boost::spirit::as_string;
|
||||
using boost::spirit::ascii::no_case;
|
||||
|
||||
|
||||
|
||||
std::string newton_before_name = "tracktolbeforeeg";
|
||||
std::string newton_during_name = "tracktolduringeg";
|
||||
std::string final_tol_name = "finaltol";
|
||||
std::string path_trunc_name = "pathtruncationthreshold";
|
||||
|
||||
|
||||
root_rule_.name("config::Tolerances");
|
||||
|
||||
root_rule_ = ((newton_before_endgame_[phx::bind( [this](algorithm::TolerancesConfig & S, T l)
|
||||
{
|
||||
S.newton_before_endgame = l;
|
||||
}, _val, _1 )]
|
||||
^ newton_during_endgame_[phx::bind( [this](algorithm::TolerancesConfig & S, T num)
|
||||
{
|
||||
S.newton_during_endgame = num;
|
||||
}, _val, _1 )]
|
||||
^ final_tol_[phx::bind( [this](algorithm::TolerancesConfig & S, T num)
|
||||
{
|
||||
S.final_tolerance = num;
|
||||
}, _val, _1 )]
|
||||
^ path_trunc_threshold_[phx::bind( [this](algorithm::TolerancesConfig & S, T num)
|
||||
{
|
||||
S.path_truncation_threshold = num;
|
||||
}, _val, _1 )])
|
||||
|
||||
>> -no_setting_)
|
||||
| no_setting_;
|
||||
|
||||
|
||||
all_names_ = (no_case[newton_before_name] >> ':') | (no_case[newton_during_name] >> ':')| (no_case[final_tol_name] >> ':')
|
||||
| (no_case[path_trunc_name] >> ':');
|
||||
|
||||
newton_before_endgame_.name("newton_before_endgame_");
|
||||
newton_before_endgame_ = *(char_ - all_names_) >> (no_case[newton_before_name] >> ':')
|
||||
>> mpfr_rules.number_string_[phx::bind( [this](T & num, std::string str)
|
||||
{
|
||||
num = bertini::NumTraits<T>::FromString(str);
|
||||
}, _val, _1 )] >> ';';
|
||||
|
||||
newton_during_endgame_.name("newton_during_endgame_");
|
||||
newton_during_endgame_ = *(char_ - all_names_) >> (no_case[newton_during_name] >>':')
|
||||
>> mpfr_rules.number_string_[phx::bind( [this](T & num, std::string str)
|
||||
{
|
||||
num = bertini::NumTraits<T>::FromString(str);
|
||||
}, _val, _1 )] >> ';';
|
||||
|
||||
final_tol_.name("final_tol_");
|
||||
final_tol_ = *(char_ - all_names_) >> (no_case[final_tol_name] >> ':')
|
||||
>> mpfr_rules.number_string_[phx::bind( [this](T & num, std::string str)
|
||||
{
|
||||
num = bertini::NumTraits<T>::FromString(str);
|
||||
}, _val, _1 )] >> ';';
|
||||
|
||||
path_trunc_threshold_.name("path_trunc_threshold_");
|
||||
path_trunc_threshold_ = *(char_ - all_names_) >> (no_case[path_trunc_name] >> ':')
|
||||
>> mpfr_rules.number_string_[phx::bind( [this](T & num, std::string str)
|
||||
{
|
||||
num = bertini::NumTraits<T>::FromString(str);
|
||||
}, _val, _1 )] >> ';';
|
||||
|
||||
no_setting_.name("no_setting_");
|
||||
no_setting_ = *(char_ - all_names_);
|
||||
|
||||
no_decl_.name("no_decl_");
|
||||
no_decl_ = *(char_);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
using phx::val;
|
||||
using phx::construct;
|
||||
using namespace qi::labels;
|
||||
qi::on_error<qi::fail>
|
||||
( root_rule_ ,
|
||||
std::cout<<
|
||||
val("config parser could not complete parsing. Expecting ")<<
|
||||
_4<<
|
||||
val(" here: ")<<
|
||||
construct<std::string>(_3,_2)<<
|
||||
std::endl
|
||||
);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
qi::rule<Iterator, algorithm::TolerancesConfig(), ascii::space_type > root_rule_;
|
||||
qi::rule<Iterator, T(), ascii::space_type > newton_before_endgame_, newton_during_endgame_,
|
||||
final_tol_, path_trunc_threshold_;
|
||||
qi::rule<Iterator, ascii::space_type, std::string()> no_decl_, no_setting_, all_names_;
|
||||
rules::LongNum<Iterator> mpfr_rules;
|
||||
|
||||
|
||||
|
||||
}; //re: Tolerances
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template<typename Iterator, typename ComplexT, typename Skipper>
|
||||
struct ConfigSettingParser<Iterator, algorithm::ZeroDimConfig<ComplexT>, Skipper> : qi::grammar<Iterator, algorithm::ZeroDimConfig<ComplexT>(), Skipper>
|
||||
{
|
||||
|
||||
ConfigSettingParser() : ConfigSettingParser::base_type(root_rule_, "algorithm::ZeroDimConfig")
|
||||
{
|
||||
namespace phx = boost::phoenix;
|
||||
using qi::_1;
|
||||
using qi::_2;
|
||||
using qi::_3;
|
||||
using qi::_4;
|
||||
using qi::_val;
|
||||
using qi::eps;
|
||||
using qi::lit;
|
||||
using qi::char_;
|
||||
using qi::omit;
|
||||
using boost::spirit::lexeme;
|
||||
using boost::spirit::as_string;
|
||||
using boost::spirit::ascii::no_case;
|
||||
|
||||
|
||||
|
||||
std::string init_prec_name = "initialprec";
|
||||
std::string max_cross_resolve_name = "maxcrossedpathresolves";
|
||||
std::string start_time_name = "starttime";
|
||||
std::string endgame_boundary_name = "endgamebdry";
|
||||
std::string target_time_name = "targettime";
|
||||
std::string path_variable_name_name = "pathvarname";
|
||||
|
||||
|
||||
root_rule_.name("config::ZeroDim");
|
||||
|
||||
root_rule_ = ((init_prec_[phx::bind( [this](algorithm::ZeroDimConfig<ComplexT> & S, int num)
|
||||
{
|
||||
S.initial_ambient_precision = num;
|
||||
}, _val, _1 )]
|
||||
^ path_variable_name_[phx::bind( [this](algorithm::ZeroDimConfig<ComplexT> & S, std::string omnom)
|
||||
{
|
||||
S.path_variable_name = omnom;
|
||||
}, _val, _1 )]
|
||||
^ max_cross_resolve_[phx::bind( [this](algorithm::ZeroDimConfig<ComplexT> & S, int num)
|
||||
{
|
||||
S.max_num_crossed_path_resolve_attempts = num;
|
||||
}, _val, _1 )]
|
||||
^ start_time_[phx::bind( [this](algorithm::ZeroDimConfig<ComplexT> & S, ComplexT num)
|
||||
{
|
||||
S.start_time = num;
|
||||
}, _val, _1 )]
|
||||
^ endgame_boundary_[phx::bind( [this](algorithm::ZeroDimConfig<ComplexT> & S, ComplexT num)
|
||||
{
|
||||
S.endgame_boundary = num;
|
||||
}, _val, _1 )]
|
||||
^ target_time_[phx::bind( [this](algorithm::ZeroDimConfig<ComplexT> & S, ComplexT num)
|
||||
{
|
||||
S.target_time = num;
|
||||
}, _val, _1 )]
|
||||
)
|
||||
>> -no_setting_) | no_setting_;
|
||||
|
||||
all_names_ = (no_case[init_prec_name] >> ':') |
|
||||
(no_case[target_time_name] >> ':') |
|
||||
(no_case[path_variable_name_name] >> ':') |
|
||||
(no_case[max_cross_resolve_name] >> ':') |
|
||||
(no_case[start_time_name] >> ':') |
|
||||
(no_case[endgame_boundary_name] >> ':')
|
||||
;
|
||||
|
||||
|
||||
auto str_to_ComplexT = [this](ComplexT & num, std::string str)
|
||||
{
|
||||
num = bertini::NumTraits<ComplexT>::FromString(str);
|
||||
};
|
||||
|
||||
|
||||
|
||||
valid_variable_name_.name("valid_variable_name_");
|
||||
valid_variable_name_ = +qi::alpha >> *(qi::alnum | qi::char_("[]_") );
|
||||
|
||||
|
||||
path_variable_name_.name("path_variable_name_");
|
||||
path_variable_name_ = *(char_ - all_names_) >> (no_case[path_variable_name_name] >> ':') >> valid_variable_name_ >> ';';
|
||||
|
||||
init_prec_.name("init_prec_");
|
||||
init_prec_ = *(char_ - all_names_) >> (no_case[init_prec_name] >> ':') >> qi::int_[_val=_1] >> ';';
|
||||
|
||||
max_cross_resolve_.name("max_cross_resolve_");
|
||||
max_cross_resolve_ = *(char_ - all_names_) >> (no_case[max_cross_resolve_name] >> ':') >> qi::int_[_val=_1] >> ';';
|
||||
|
||||
start_time_.name("start_time_");
|
||||
start_time_ = *(char_ - all_names_) >> (no_case[start_time_name] >> ':')
|
||||
>> mpfr_rules.number_string_[phx::bind( str_to_ComplexT, _val, _1 )] >> ';';
|
||||
|
||||
endgame_boundary_.name("endgame_boundary_");
|
||||
endgame_boundary_ = *(char_ - all_names_) >> (no_case[endgame_boundary_name] >> ':')
|
||||
>> mpfr_rules.number_string_[phx::bind( str_to_ComplexT, _val, _1 )] >> ';';
|
||||
|
||||
target_time_.name("target_time_");
|
||||
target_time_ = *(char_ - all_names_) >> (no_case[target_time_name] >> ':')
|
||||
>> mpfr_rules.number_string_[phx::bind( str_to_ComplexT, _val, _1 )] >> ';';
|
||||
|
||||
|
||||
|
||||
no_setting_.name("no_setting_");
|
||||
no_setting_ = *(char_ - all_names_);
|
||||
|
||||
no_decl_.name("no_decl_");
|
||||
no_decl_ = *(char_);
|
||||
|
||||
|
||||
|
||||
|
||||
using phx::val;
|
||||
using phx::construct;
|
||||
using namespace qi::labels;
|
||||
qi::on_error<qi::fail>
|
||||
( root_rule_ ,
|
||||
std::cout<<
|
||||
val("config parser could not complete parsing. Expecting ")<<
|
||||
_4<<
|
||||
val(" here: ")<<
|
||||
construct<std::string>(_3,_2)<<
|
||||
std::endl
|
||||
);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
qi::rule<Iterator, algorithm::ZeroDimConfig<ComplexT>(), ascii::space_type > root_rule_;
|
||||
|
||||
qi::rule<Iterator, ComplexT(), ascii::space_type > start_time_, target_time_, endgame_boundary_;
|
||||
qi::rule<Iterator, int(), ascii::space_type > init_prec_, max_cross_resolve_;
|
||||
qi::rule<Iterator, std::string(), ascii::space_type > valid_variable_name_, path_variable_name_;
|
||||
|
||||
|
||||
qi::rule<Iterator, ascii::space_type, std::string()> no_decl_, no_setting_, all_names_;
|
||||
rules::LongNum<Iterator> mpfr_rules;
|
||||
|
||||
|
||||
|
||||
}; //re: ZeroDim
|
||||
|
||||
template<typename Iterator, typename Skipper>
|
||||
struct ConfigSettingParser<Iterator, algorithm::MidPathConfig, Skipper> : qi::grammar<Iterator, algorithm::MidPathConfig(), Skipper>
|
||||
{
|
||||
using T = double;
|
||||
|
||||
ConfigSettingParser() : ConfigSettingParser::base_type(root_rule_, "config::MidPath")
|
||||
{
|
||||
namespace phx = boost::phoenix;
|
||||
using qi::_1;
|
||||
using qi::_2;
|
||||
using qi::_3;
|
||||
using qi::_4;
|
||||
using qi::_val;
|
||||
using qi::eps;
|
||||
using qi::lit;
|
||||
using qi::char_;
|
||||
using qi::omit;
|
||||
using boost::spirit::lexeme;
|
||||
using boost::spirit::as_string;
|
||||
using boost::spirit::ascii::no_case;
|
||||
|
||||
|
||||
|
||||
std::string same_point_tol_name = "midpathtol";
|
||||
|
||||
|
||||
root_rule_.name("config::MidPath");
|
||||
|
||||
root_rule_ = ((same_point_tol_[phx::bind( [this](algorithm::MidPathConfig & S, T num)
|
||||
{
|
||||
S.same_point_tolerance = num;
|
||||
}, _val, _1 )]
|
||||
)
|
||||
>> -no_setting_) | no_setting_;
|
||||
|
||||
all_names_ = (no_case[same_point_tol_name] >> ':');
|
||||
|
||||
auto str_to_T = [this](T & num, std::string str)
|
||||
{
|
||||
num = bertini::NumTraits<T>::FromString(str);
|
||||
};
|
||||
|
||||
|
||||
same_point_tol_.name("same_point_tol_");
|
||||
same_point_tol_ = *(char_ - all_names_) >> (no_case[same_point_tol_name] >> ':')
|
||||
>> mpfr_rules.number_string_[phx::bind( str_to_T, _val, _1 )] >> ';';
|
||||
|
||||
|
||||
no_setting_.name("no_setting_");
|
||||
no_setting_ = *(char_ - all_names_);
|
||||
|
||||
no_decl_.name("no_decl_");
|
||||
no_decl_ = *(char_);
|
||||
|
||||
|
||||
|
||||
|
||||
using phx::val;
|
||||
using phx::construct;
|
||||
using namespace qi::labels;
|
||||
qi::on_error<qi::fail>
|
||||
( root_rule_ ,
|
||||
std::cout<<
|
||||
val("config parser could not complete parsing. Expecting ")<<
|
||||
_4<<
|
||||
val(" here: ")<<
|
||||
construct<std::string>(_3,_2)<<
|
||||
std::endl
|
||||
);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
qi::rule<Iterator, algorithm::MidPathConfig(), ascii::space_type > root_rule_;
|
||||
qi::rule<Iterator, T(), ascii::space_type > same_point_tol_;
|
||||
qi::rule<Iterator, ascii::space_type, std::string()> no_decl_, no_setting_, all_names_;
|
||||
rules::LongNum<Iterator> mpfr_rules;
|
||||
|
||||
}; //re: MidPath
|
||||
|
||||
|
||||
template<typename Iterator, typename Skipper>
|
||||
struct ConfigSettingParser<Iterator, algorithm::AutoRetrackConfig, Skipper> : qi::grammar<Iterator, algorithm::AutoRetrackConfig(), Skipper>
|
||||
{
|
||||
using T = double;
|
||||
|
||||
ConfigSettingParser() : ConfigSettingParser::base_type(root_rule_, "config::AutoRetrack")
|
||||
{
|
||||
namespace phx = boost::phoenix;
|
||||
using qi::_1;
|
||||
using qi::_2;
|
||||
using qi::_3;
|
||||
using qi::_4;
|
||||
using qi::_val;
|
||||
using qi::eps;
|
||||
using qi::lit;
|
||||
using qi::char_;
|
||||
using qi::omit;
|
||||
using boost::spirit::lexeme;
|
||||
using boost::spirit::as_string;
|
||||
using boost::spirit::ascii::no_case;
|
||||
|
||||
|
||||
|
||||
std::string decrease_factor_name = "retracktolfactor";
|
||||
|
||||
|
||||
root_rule_.name("config::AutoRetrack");
|
||||
|
||||
root_rule_ = ((decrease_factor[phx::bind( [this](algorithm::AutoRetrackConfig & S, T num)
|
||||
{
|
||||
S.midpath_decrease_tolerance_factor = num;
|
||||
}, _val, _1 )]
|
||||
)
|
||||
>> -no_setting_) | no_setting_;
|
||||
|
||||
all_names_ = (no_case[decrease_factor_name] >> ':');
|
||||
|
||||
auto str_to_T = [this](T & num, std::string str)
|
||||
{
|
||||
num = bertini::NumTraits<T>::FromString(str);
|
||||
};
|
||||
|
||||
|
||||
decrease_factor.name("decrease_factor");
|
||||
decrease_factor = *(char_ - all_names_) >> (no_case[decrease_factor_name] >> ':')
|
||||
>> mpfr_rules.number_string_[phx::bind( str_to_T, _val, _1 )] >> ';';
|
||||
|
||||
|
||||
no_setting_.name("no_setting_");
|
||||
no_setting_ = *(char_ - all_names_);
|
||||
|
||||
no_decl_.name("no_decl_");
|
||||
no_decl_ = *(char_);
|
||||
|
||||
|
||||
|
||||
|
||||
using phx::val;
|
||||
using phx::construct;
|
||||
using namespace qi::labels;
|
||||
qi::on_error<qi::fail>
|
||||
( root_rule_ ,
|
||||
std::cout<<
|
||||
val("config parser could not complete parsing. Expecting ")<<
|
||||
_4<<
|
||||
val(" here: ")<<
|
||||
construct<std::string>(_3,_2)<<
|
||||
std::endl
|
||||
);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
qi::rule<Iterator, algorithm::AutoRetrackConfig(), ascii::space_type > root_rule_;
|
||||
qi::rule<Iterator, T(), ascii::space_type > decrease_factor;
|
||||
qi::rule<Iterator, ascii::space_type, std::string()> no_decl_, no_setting_, all_names_;
|
||||
rules::LongNum<Iterator> mpfr_rules;
|
||||
|
||||
}; //re: AutoRetrack
|
||||
|
||||
|
||||
template<typename Iterator, typename Skipper>
|
||||
struct ConfigSettingParser<Iterator, algorithm::SharpeningConfig, Skipper> : qi::grammar<Iterator, algorithm::SharpeningConfig(), Skipper>
|
||||
{
|
||||
using T = double;
|
||||
|
||||
ConfigSettingParser() : ConfigSettingParser::base_type(root_rule_, "algorithm::config::Sharpening")
|
||||
{
|
||||
namespace phx = boost::phoenix;
|
||||
using qi::_1;
|
||||
using qi::_2;
|
||||
using qi::_3;
|
||||
using qi::_4;
|
||||
using qi::_val;
|
||||
using qi::eps;
|
||||
using qi::lit;
|
||||
using qi::char_;
|
||||
using qi::omit;
|
||||
using boost::spirit::lexeme;
|
||||
using boost::spirit::as_string;
|
||||
using boost::spirit::ascii::no_case;
|
||||
|
||||
|
||||
|
||||
std::string sharpen_digits_name = "sharpendigits";
|
||||
std::string func_res_tol_name = "functiontolerance";
|
||||
std::string ratio_tol_name = "ratiotolerance";
|
||||
|
||||
|
||||
root_rule_.name("config::Sharpening");
|
||||
|
||||
root_rule_ = ((sharpen_digits_[phx::bind( [this](algorithm::SharpeningConfig & S, unsigned num)
|
||||
{
|
||||
S.sharpendigits = num;
|
||||
}, _val, _1 )]
|
||||
^ func_res_tol_[phx::bind( [this](algorithm::SharpeningConfig & S, T num)
|
||||
{
|
||||
S.function_residual_tolerance = num;
|
||||
}, _val, _1 )]
|
||||
^ ratio_tol_[phx::bind( [this](algorithm::SharpeningConfig & S, T num)
|
||||
{
|
||||
S.ratio_tolerance = num;
|
||||
}, _val, _1 )]
|
||||
)
|
||||
>> -no_setting_) | no_setting_;
|
||||
|
||||
all_names_ = (no_case[sharpen_digits_name] >> ':') |
|
||||
(no_case[func_res_tol_name] >> ':') |
|
||||
(no_case[ratio_tol_name] >> ':')
|
||||
;
|
||||
|
||||
|
||||
auto str_to_T = [this](T & num, std::string str)
|
||||
{
|
||||
num = bertini::NumTraits<T>::FromString(str);
|
||||
};
|
||||
|
||||
|
||||
func_res_tol_.name("func_res_tol_");
|
||||
func_res_tol_ = *(char_ - all_names_) >> (no_case[func_res_tol_name] >> ':')
|
||||
>> mpfr_rules.number_string_[phx::bind( str_to_T, _val, _1 )] >> ';';
|
||||
|
||||
ratio_tol_.name("ratio_tol_");
|
||||
ratio_tol_ = *(char_ - all_names_) >> (no_case[ratio_tol_name] >> ':')
|
||||
>> mpfr_rules.number_string_[phx::bind( str_to_T, _val, _1 )] >> ';';
|
||||
|
||||
sharpen_digits_.name("sharpen_digits_");
|
||||
sharpen_digits_ = *(char_ - all_names_) >> (no_case[sharpen_digits_name] >> ':') >> qi::uint_[_val=_1] >> ';';
|
||||
|
||||
|
||||
|
||||
no_setting_.name("no_setting_");
|
||||
no_setting_ = *(char_ - all_names_);
|
||||
|
||||
no_decl_.name("no_decl_");
|
||||
no_decl_ = *(char_);
|
||||
|
||||
|
||||
|
||||
|
||||
using phx::val;
|
||||
using phx::construct;
|
||||
using namespace qi::labels;
|
||||
qi::on_error<qi::fail>
|
||||
( root_rule_ ,
|
||||
std::cout<<
|
||||
val("config parser could not complete parsing. Expecting ")<<
|
||||
_4<<
|
||||
val(" here: ")<<
|
||||
construct<std::string>(_3,_2)<<
|
||||
std::endl
|
||||
);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
qi::rule<Iterator, algorithm::SharpeningConfig(), ascii::space_type > root_rule_;
|
||||
|
||||
qi::rule<Iterator, T(), ascii::space_type > func_res_tol_, ratio_tol_;
|
||||
qi::rule<Iterator, unsigned int(), ascii::space_type > sharpen_digits_;
|
||||
|
||||
qi::rule<Iterator, ascii::space_type, std::string()> no_decl_, no_setting_, all_names_;
|
||||
rules::LongNum<Iterator> mpfr_rules;
|
||||
|
||||
|
||||
|
||||
}; //re: Sharpening
|
||||
|
||||
template<typename Iterator, typename Skipper>
|
||||
struct ConfigSettingParser<Iterator, algorithm::RegenerationConfig, Skipper> : qi::grammar<Iterator, algorithm::RegenerationConfig(), Skipper>
|
||||
{
|
||||
using T = double;
|
||||
|
||||
ConfigSettingParser() : ConfigSettingParser::base_type(root_rule_, "algorithm::config::Regeneration")
|
||||
{
|
||||
namespace phx = boost::phoenix;
|
||||
using qi::_1;
|
||||
using qi::_2;
|
||||
using qi::_3;
|
||||
using qi::_4;
|
||||
using qi::_val;
|
||||
using qi::eps;
|
||||
using qi::lit;
|
||||
using qi::char_;
|
||||
using qi::omit;
|
||||
using boost::spirit::lexeme;
|
||||
using boost::spirit::as_string;
|
||||
using boost::spirit::ascii::no_case;
|
||||
|
||||
|
||||
|
||||
std::string regen_remove_inf_name = "regenremoveinf";
|
||||
std::string slice_before_name = "slicetolbeforeeg";
|
||||
std::string slice_during_name = "slicetolduringeg";
|
||||
std::string slice_final_name = "slicefinaltol";
|
||||
std::string higher_dim_check_name = "regenhigherdimtest";
|
||||
std::string start_level_name = "regenstartlevel";
|
||||
|
||||
|
||||
root_rule_.name("config::Regeneration");
|
||||
|
||||
root_rule_ = ((regen_remove_inf_[phx::bind( [this](algorithm::RegenerationConfig & S, int num)
|
||||
{
|
||||
S.remove_infinite_endpoints = static_cast<bool>(num);
|
||||
}, _val, _1 )]
|
||||
^ higher_dim_check_[phx::bind( [this](algorithm::RegenerationConfig & S, int num)
|
||||
{
|
||||
S.higher_dimension_check = static_cast<bool>(num);
|
||||
}, _val, _1 )]
|
||||
^ start_level_[phx::bind( [this](algorithm::RegenerationConfig & S, int num)
|
||||
{
|
||||
S.start_level = num;
|
||||
}, _val, _1 )]
|
||||
^ slice_before_[phx::bind( [this](algorithm::RegenerationConfig & S, T num)
|
||||
{
|
||||
S.newton_before_endgame = num;
|
||||
}, _val, _1 )]
|
||||
^ slice_during_[phx::bind( [this](algorithm::RegenerationConfig & S, T num)
|
||||
{
|
||||
S.newton_during_endgame = num;
|
||||
}, _val, _1 )]
|
||||
^ slice_final_[phx::bind( [this](algorithm::RegenerationConfig & S, T num)
|
||||
{
|
||||
S.final_tolerance = num;
|
||||
}, _val, _1 )]
|
||||
)
|
||||
>> -no_setting_) | no_setting_;
|
||||
|
||||
all_names_ = (no_case[regen_remove_inf_name] >> ':') |
|
||||
(no_case[higher_dim_check_name] >> ':') |
|
||||
(no_case[start_level_name] >> ':') |
|
||||
(no_case[slice_before_name] >> ':') |
|
||||
(no_case[slice_during_name] >> ':') |
|
||||
(no_case[slice_final_name] >> ':')
|
||||
;
|
||||
|
||||
|
||||
auto str_to_T = [this](T & num, std::string str)
|
||||
{
|
||||
num = bertini::NumTraits<T>::FromString(str);
|
||||
};
|
||||
|
||||
|
||||
higher_dim_check_.name("higher_dim_check_");
|
||||
higher_dim_check_ = *(char_ - all_names_) >> (no_case[higher_dim_check_name] >> ':') >> qi::int_[_val=_1] >> ';';
|
||||
|
||||
start_level_.name("start_level_");
|
||||
start_level_ = *(char_ - all_names_) >> (no_case[start_level_name] >> ':') >> qi::int_[_val=_1] >> ';';
|
||||
|
||||
regen_remove_inf_.name("regen_remove_inf_");
|
||||
regen_remove_inf_ = *(char_ - all_names_) >> (no_case[regen_remove_inf_name] >> ':') >> qi::int_[_val=_1] >> ';';
|
||||
|
||||
|
||||
|
||||
slice_before_.name("slice_before_");
|
||||
slice_before_ = *(char_ - all_names_) >> (no_case[slice_before_name] >> ':')
|
||||
>> mpfr_rules.number_string_[phx::bind( str_to_T, _val, _1 )] >> ';';
|
||||
|
||||
slice_during_.name("slice_during_");
|
||||
slice_during_ = *(char_ - all_names_) >> (no_case[slice_during_name] >> ':')
|
||||
>> mpfr_rules.number_string_[phx::bind( str_to_T, _val, _1 )] >> ';';
|
||||
|
||||
slice_final_.name("slice_final_");
|
||||
slice_final_ = *(char_ - all_names_) >> (no_case[slice_final_name] >> ':')
|
||||
>> mpfr_rules.number_string_[phx::bind( str_to_T, _val, _1 )] >> ';';
|
||||
|
||||
|
||||
|
||||
no_setting_.name("no_setting_");
|
||||
no_setting_ = *(char_ - all_names_);
|
||||
|
||||
no_decl_.name("no_decl_");
|
||||
no_decl_ = *(char_);
|
||||
|
||||
|
||||
|
||||
|
||||
using phx::val;
|
||||
using phx::construct;
|
||||
using namespace qi::labels;
|
||||
qi::on_error<qi::fail>
|
||||
( root_rule_ ,
|
||||
std::cout<<
|
||||
val("config parser could not complete parsing. Expecting ")<<
|
||||
_4<<
|
||||
val(" here: ")<<
|
||||
construct<std::string>(_3,_2)<<
|
||||
std::endl
|
||||
);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
qi::rule<Iterator, algorithm::RegenerationConfig(), ascii::space_type > root_rule_;
|
||||
|
||||
qi::rule<Iterator, T(), ascii::space_type > slice_before_, slice_during_, slice_final_;
|
||||
qi::rule<Iterator, int(), ascii::space_type > regen_remove_inf_, start_level_, higher_dim_check_;
|
||||
|
||||
qi::rule<Iterator, ascii::space_type, std::string()> no_decl_, no_setting_, all_names_;
|
||||
rules::LongNum<Iterator> mpfr_rules;
|
||||
|
||||
|
||||
|
||||
}; //re: Regeneration
|
||||
|
||||
|
||||
template<typename Iterator, typename Skipper>
|
||||
struct ConfigSettingParser<Iterator, algorithm::PostProcessingConfig, Skipper> : qi::grammar<Iterator, algorithm::PostProcessingConfig(), Skipper>
|
||||
{
|
||||
using T = double;
|
||||
|
||||
ConfigSettingParser() : ConfigSettingParser::base_type(root_rule_, "algorithm::PostProcessingConfig")
|
||||
{
|
||||
namespace phx = boost::phoenix;
|
||||
using qi::_1;
|
||||
using qi::_2;
|
||||
using qi::_3;
|
||||
using qi::_4;
|
||||
using qi::_val;
|
||||
using qi::eps;
|
||||
using qi::lit;
|
||||
using qi::char_;
|
||||
using qi::omit;
|
||||
using boost::spirit::lexeme;
|
||||
using boost::spirit::as_string;
|
||||
using boost::spirit::ascii::no_case;
|
||||
|
||||
|
||||
|
||||
std::string real_thresh_name = "imagthreshold";
|
||||
std::string endpoint_finite_name = "endpointfinitethreshold";
|
||||
std::string same_point_name = "endpointsamethreshold";
|
||||
|
||||
|
||||
|
||||
root_rule_.name("config::PostProcessing");
|
||||
|
||||
root_rule_ = ((real_threshold_[phx::bind( [this](algorithm::PostProcessingConfig & S, T num)
|
||||
{
|
||||
S.real_threshold = num;
|
||||
}, _val, _1 )]
|
||||
^ endpoint_finite_[phx::bind( [this](algorithm::PostProcessingConfig & S, T num)
|
||||
{
|
||||
S.endpoint_finite_threshold = num;
|
||||
}, _val, _1 )]
|
||||
^ same_point_[phx::bind( [this](algorithm::PostProcessingConfig & S, T num)
|
||||
{
|
||||
S.same_point_tolerance = num;
|
||||
}, _val, _1 )]
|
||||
)
|
||||
>> -no_setting_) | no_setting_;
|
||||
|
||||
all_names_ = (no_case[real_thresh_name] >> ':') |
|
||||
(no_case[endpoint_finite_name] >> ':') |
|
||||
(no_case[same_point_name] >> ':')
|
||||
;
|
||||
|
||||
|
||||
auto str_to_T = [this](T & num, std::string str)
|
||||
{
|
||||
num = bertini::NumTraits<T>::FromString(str);
|
||||
};
|
||||
|
||||
real_threshold_.name("real_thresh_");
|
||||
real_threshold_ = *(char_ - all_names_) >> (no_case[real_thresh_name] >> ':')
|
||||
>> mpfr_rules.number_string_[phx::bind( str_to_T, _val, _1 )] >> ';';
|
||||
|
||||
endpoint_finite_.name("endpoint_finite_");
|
||||
endpoint_finite_ = *(char_ - all_names_) >> (no_case[endpoint_finite_name] >> ':')
|
||||
>> mpfr_rules.number_string_[phx::bind( str_to_T, _val, _1 )] >> ';';
|
||||
|
||||
same_point_.name("same_point_");
|
||||
same_point_ = *(char_ - all_names_) >> (no_case[same_point_name] >> ':')
|
||||
>> mpfr_rules.number_string_[phx::bind( str_to_T, _val, _1 )] >> ';';
|
||||
|
||||
|
||||
|
||||
no_setting_.name("no_setting_");
|
||||
no_setting_ = *(char_ - all_names_);
|
||||
|
||||
no_decl_.name("no_decl_");
|
||||
no_decl_ = *(char_);
|
||||
|
||||
|
||||
|
||||
|
||||
using phx::val;
|
||||
using phx::construct;
|
||||
using namespace qi::labels;
|
||||
qi::on_error<qi::fail>
|
||||
( root_rule_ ,
|
||||
std::cout<<
|
||||
val("config parser could not complete parsing. Expecting ")<<
|
||||
_4<<
|
||||
val(" here: ")<<
|
||||
construct<std::string>(_3,_2)<<
|
||||
std::endl
|
||||
);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
qi::rule<Iterator, algorithm::PostProcessingConfig(), ascii::space_type > root_rule_;
|
||||
|
||||
qi::rule<Iterator, T(), ascii::space_type > real_threshold_, endpoint_finite_, same_point_;
|
||||
|
||||
qi::rule<Iterator, ascii::space_type, std::string()> no_decl_, no_setting_, all_names_;
|
||||
rules::LongNum<Iterator> mpfr_rules;
|
||||
|
||||
|
||||
|
||||
}; //re: PostProcessing
|
||||
|
||||
|
||||
|
||||
template<typename Iterator, typename Skipper> //boost::spirit::unused_type
|
||||
struct ConfigSettingParser<Iterator, algorithm::classic::AlgoChoice, Skipper> : qi::grammar<Iterator, algorithm::classic::AlgoChoice(), Skipper>
|
||||
{
|
||||
using T = double;
|
||||
|
||||
ConfigSettingParser() : ConfigSettingParser::base_type(root_rule_, "config::classic::AlgoChoice")
|
||||
{
|
||||
namespace phx = boost::phoenix;
|
||||
using qi::_1;
|
||||
using qi::_2;
|
||||
using qi::_3;
|
||||
using qi::_4;
|
||||
using qi::_val;
|
||||
using qi::eps;
|
||||
using qi::lit;
|
||||
using qi::char_;
|
||||
using qi::omit;
|
||||
using boost::spirit::lexeme;
|
||||
using boost::spirit::as_string;
|
||||
using boost::spirit::ascii::no_case;
|
||||
|
||||
tracktype_.add("-4", algorithm::classic::AlgoChoice::EvalFunctions);
|
||||
tracktype_.add("-3", algorithm::classic::AlgoChoice::EvalFunctionJacobian);
|
||||
tracktype_.add("-2", algorithm::classic::AlgoChoice::NewtonIteration);
|
||||
tracktype_.add("-1", algorithm::classic::AlgoChoice::NewtonIterationCondNum);
|
||||
tracktype_.add("0", algorithm::classic::AlgoChoice::ZeroDim);
|
||||
tracktype_.add("1", algorithm::classic::AlgoChoice::NID);
|
||||
tracktype_.add("2", algorithm::classic::AlgoChoice::SampleComponent);
|
||||
tracktype_.add("3", algorithm::classic::AlgoChoice::MembershipTest);
|
||||
tracktype_.add("4", algorithm::classic::AlgoChoice::ExtractWitnessSet);
|
||||
tracktype_.add("5", algorithm::classic::AlgoChoice::WitnessSetProjection);
|
||||
tracktype_.add("6", algorithm::classic::AlgoChoice::IsosingularStab);
|
||||
|
||||
std::string setting_name = "tracktype";
|
||||
|
||||
|
||||
root_rule_.name("config::classic::AlgoChoice");
|
||||
|
||||
root_rule_ = config_name_[_val = _1] >> -no_setting_
|
||||
| no_setting_[_val = algorithm::classic::AlgoChoice::ZeroDim];
|
||||
|
||||
config_name_.name("tracktype_");
|
||||
config_name_ = *(char_ - (no_case[setting_name] >> ':')) >> (no_case[setting_name] >> ':') >> tracktype_[_val = _1] >> ';';
|
||||
|
||||
no_setting_.name("no_setting_");
|
||||
no_setting_ = *(char_ - no_case[setting_name]);
|
||||
|
||||
no_decl_.name("no_decl_");
|
||||
no_decl_ = *(char_);
|
||||
|
||||
|
||||
|
||||
|
||||
using phx::val;
|
||||
using phx::construct;
|
||||
using namespace qi::labels;
|
||||
qi::on_error<qi::fail>
|
||||
( root_rule_ ,
|
||||
std::cout<<
|
||||
val("config parser could not complete parsing. Expecting ")<<
|
||||
_4<<
|
||||
val(" here: ")<<
|
||||
construct<std::string>(_3,_2)<<
|
||||
std::endl
|
||||
);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
qi::rule<Iterator, algorithm::classic::AlgoChoice(), ascii::space_type > root_rule_, config_name_;
|
||||
qi::rule<Iterator, ascii::space_type, std::string()> no_decl_, no_setting_;
|
||||
|
||||
qi::symbols<char,algorithm::classic::AlgoChoice> tracktype_;
|
||||
|
||||
|
||||
}; //re: Meta
|
||||
|
||||
|
||||
|
||||
} // re: namespace classic
|
||||
|
||||
}// re: namespace parsing
|
||||
}// re: namespace bertini
|
||||
59
core/include/bertini2/io/parsing/settings_parsers/base.hpp
Normal file
59
core/include/bertini2/io/parsing/settings_parsers/base.hpp
Normal file
@@ -0,0 +1,59 @@
|
||||
//This file is part of Bertini 2.
|
||||
//
|
||||
//bertini2/io/parsing/settings_parsers/base.hpp is free software: you can redistribute it and/or modify
|
||||
//it under the terms of the GNU General Public License as published by
|
||||
//the Free Software Foundation, either version 3 of the License, or
|
||||
//(at your option) any later version.
|
||||
//
|
||||
//bertini2/io/parsing/settings_parsers/base.hpp is distributed in the hope that it will be useful,
|
||||
//but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
//GNU General Public License for more details.
|
||||
//
|
||||
//You should have received a copy of the GNU General Public License
|
||||
//along with bertini2/io/parsing/settings_parsers/base.hpp. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// Copyright(C) 2015 - 2017 by Bertini2 Development Team
|
||||
//
|
||||
// See <http://www.gnu.org/licenses/> for a copy of the license,
|
||||
// as well as COPYING. Bertini2 is provided with permitted
|
||||
// additional terms in the b2/licenses/ directory.
|
||||
|
||||
|
||||
/**
|
||||
\file bertini2/io/parsing/settings_parsers/base.hpp
|
||||
|
||||
\brief Provides the base type for config settings parsers
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
|
||||
#include "bertini2/io/parsing/qi_files.hpp"
|
||||
#include "bertini2/io/parsing/number_rules.hpp"
|
||||
|
||||
namespace bertini {
|
||||
namespace parsing {
|
||||
namespace classic {
|
||||
|
||||
namespace qi = ::boost::spirit::qi;
|
||||
namespace ascii = ::boost::spirit::ascii;
|
||||
|
||||
|
||||
/**
|
||||
Qi Parser object for parsing config settings This ensures we can provide backwards compatibility with Bertini Classic input files.
|
||||
|
||||
This is a base case template, which we specialize elsewhere
|
||||
*/
|
||||
template<typename Iterator, typename Structure, typename Skipper = ascii::space_type> //boost::spirit::unused_type
|
||||
struct ConfigSettingParser : qi::grammar<Iterator, Structure(), Skipper>
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
} // re: namespace classic
|
||||
|
||||
}// re: namespace parsing
|
||||
}// re: namespace bertini
|
||||
533
core/include/bertini2/io/parsing/settings_parsers/endgames.hpp
Normal file
533
core/include/bertini2/io/parsing/settings_parsers/endgames.hpp
Normal file
@@ -0,0 +1,533 @@
|
||||
//This file is part of Bertini 2.
|
||||
//
|
||||
//bertini2/io/parsing/settings_parsers/endgames.hpp is free software: you can redistribute it and/or modify
|
||||
//it under the terms of the GNU General Public License as published by
|
||||
//the Free Software Foundation, either version 3 of the License, or
|
||||
//(at your option) any later version.
|
||||
//
|
||||
//bertini2/io/parsing/settings_parsers/endgames.hpp is distributed in the hope that it will be useful,
|
||||
//but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
//GNU General Public License for more details.
|
||||
//
|
||||
//You should have received a copy of the GNU General Public License
|
||||
//along with bertini2/io/parsing/settings_parsers/endgames.hpp. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// Copyright(C) 2015 - 2017 by Bertini2 Development Team
|
||||
//
|
||||
// See <http://www.gnu.org/licenses/> for a copy of the license,
|
||||
// as well as COPYING. Bertini2 is provided with permitted
|
||||
// additional terms in the b2/licenses/ directory.
|
||||
|
||||
|
||||
/**
|
||||
\file bertini2/io/parsing/settings_parsers/endgames.hpp
|
||||
|
||||
\brief Provides the parsing rules for endgames-related settings in bertini2.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "bertini2/io/parsing/settings_parsers/base.hpp"
|
||||
#include "bertini2/endgames/config.hpp"
|
||||
|
||||
|
||||
namespace bertini {
|
||||
namespace parsing {
|
||||
namespace classic {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
*/
|
||||
template<typename Iterator, typename Skipper> //boost::spirit::unused_type
|
||||
struct ConfigSettingParser<Iterator, bertini::endgame::SecurityConfig, Skipper> : qi::grammar<Iterator, bertini::endgame::SecurityConfig(), Skipper>
|
||||
{
|
||||
using T = double;
|
||||
|
||||
ConfigSettingParser() : ConfigSettingParser::base_type(root_rule_, "SecurityConfig")
|
||||
{
|
||||
|
||||
namespace phx = boost::phoenix;
|
||||
using qi::_1;
|
||||
using qi::_2;
|
||||
using qi::_3;
|
||||
using qi::_4;
|
||||
using qi::_val;
|
||||
using qi::eps;
|
||||
using qi::lit;
|
||||
using qi::char_;
|
||||
using qi::omit;
|
||||
using boost::spirit::lexeme;
|
||||
using boost::spirit::as_string;
|
||||
using boost::spirit::ascii::no_case;
|
||||
|
||||
|
||||
|
||||
std::string level_name = "securitylevel";
|
||||
std::string maxnorm_name = "securitymaxnorm";
|
||||
|
||||
|
||||
root_rule_.name("config::Security");
|
||||
|
||||
root_rule_ = ((security_level_[phx::bind( [this](bertini::endgame::SecurityConfig & S, int l)
|
||||
{
|
||||
S.level = l;
|
||||
}, _val, _1 )]
|
||||
^ security_max_norm_[phx::bind( [this](bertini::endgame::SecurityConfig & S, T norm)
|
||||
{
|
||||
S.max_norm = norm;
|
||||
}, _val, _1 )])
|
||||
>> -no_setting_) | no_setting_;
|
||||
|
||||
all_names_ = (no_case[level_name] >> ':') | (no_case[maxnorm_name] >> ':');
|
||||
|
||||
security_level_.name("security_level_");
|
||||
security_level_ = *(char_ - all_names_) >> (no_case[level_name] >> ':') >> qi::int_[_val = _1] >> ';';
|
||||
|
||||
security_max_norm_.name("security_max_norm_");
|
||||
security_max_norm_ = *(char_ - all_names_) >> (no_case[maxnorm_name] >> ':')
|
||||
>> mpfr_rules.number_string_[phx::bind( [this](T & num, std::string str)
|
||||
{
|
||||
num = bertini::NumTraits<T>::FromString(str);
|
||||
}, _val, _1 )] >> ';';
|
||||
|
||||
no_setting_.name("no_setting_");
|
||||
no_setting_ = *(char_ - all_names_);
|
||||
|
||||
no_decl_.name("no_decl_");
|
||||
no_decl_ = *(char_);
|
||||
|
||||
|
||||
|
||||
|
||||
using phx::val;
|
||||
using phx::construct;
|
||||
using namespace qi::labels;
|
||||
qi::on_error<qi::fail>
|
||||
( root_rule_ ,
|
||||
std::cout<<
|
||||
val("config parser could not complete parsing. Expecting ")<<
|
||||
_4<<
|
||||
val(" here: ")<<
|
||||
construct<std::string>(_3,_2)<<
|
||||
std::endl
|
||||
);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
qi::rule<Iterator, bertini::endgame::SecurityConfig(), ascii::space_type > root_rule_;
|
||||
qi::rule<Iterator, int(), ascii::space_type > security_level_;
|
||||
qi::rule<Iterator, T(), ascii::space_type > security_max_norm_;
|
||||
qi::rule<Iterator, ascii::space_type, std::string()> no_decl_, no_setting_, all_names_;
|
||||
rules::LongNum<Iterator> mpfr_rules;
|
||||
|
||||
|
||||
|
||||
}; //re: SecurityParser
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
*/
|
||||
template<typename Iterator, typename Skipper> //boost::spirit::unused_type
|
||||
struct ConfigSettingParser<Iterator, bertini::endgame::EndgameConfig, Skipper> : qi::grammar<Iterator, bertini::endgame::EndgameConfig(), Skipper>
|
||||
{
|
||||
using T = double;
|
||||
using R = mpq_rational;
|
||||
|
||||
ConfigSettingParser() : ConfigSettingParser::base_type(root_rule_, "EndgameConfig")
|
||||
{
|
||||
namespace phx = boost::phoenix;
|
||||
using qi::_1;
|
||||
using qi::_2;
|
||||
using qi::_3;
|
||||
using qi::_4;
|
||||
using qi::_val;
|
||||
using qi::eps;
|
||||
using qi::lit;
|
||||
using qi::char_;
|
||||
using qi::omit;
|
||||
using boost::spirit::lexeme;
|
||||
using boost::spirit::as_string;
|
||||
using boost::spirit::ascii::no_case;
|
||||
|
||||
|
||||
|
||||
std::string samplefactor_name = "samplefactor";
|
||||
std::string numpoints_name = "numsamplepoints";
|
||||
std::string mintrack_name = "nbhdradius";
|
||||
|
||||
|
||||
root_rule_.name("config::Endgame");
|
||||
|
||||
root_rule_ = ((sample_factor_[phx::bind( [this](bertini::endgame::EndgameConfig & S, R num)
|
||||
{
|
||||
S.sample_factor = num;
|
||||
}, _val, _1 )]
|
||||
^ min_track_[phx::bind( [this](bertini::endgame::EndgameConfig & S, T num)
|
||||
{
|
||||
S.min_track_time = num;
|
||||
}, _val, _1 )]
|
||||
^ num_sample_[phx::bind( [this](bertini::endgame::EndgameConfig & S, unsigned num)
|
||||
{
|
||||
S.num_sample_points = num;
|
||||
}, _val, _1 )])
|
||||
|
||||
>> -no_setting_)
|
||||
| no_setting_;
|
||||
|
||||
|
||||
all_names_ = (no_case[samplefactor_name] >> ':') | (no_case[numpoints_name] >> ':')| (no_case[mintrack_name] >> ':');
|
||||
|
||||
sample_factor_.name("sample_factor_");
|
||||
sample_factor_ = *(char_ - all_names_) >> (no_case[samplefactor_name] >> ':')
|
||||
>> mpfr_rules.rational[phx::bind( [this](R & num, std::string str)
|
||||
{
|
||||
num = bertini::NumTraits<double>::FromString(str);
|
||||
}, _val, _1 )] >> ';';
|
||||
|
||||
min_track_.name("min_track_");
|
||||
min_track_ = *(char_ - all_names_) >> (no_case[mintrack_name] >> ':')
|
||||
>> mpfr_rules.number_string_[phx::bind( [this](T & num, std::string str)
|
||||
{
|
||||
num = bertini::NumTraits<T>::FromString(str);
|
||||
}, _val, _1 )] >> ';';
|
||||
|
||||
num_sample_.name("num_sample_");
|
||||
num_sample_ = *(char_ - all_names_) >> (no_case[numpoints_name] >> ':')
|
||||
>> qi::uint_[_val=_1] >> ';';
|
||||
|
||||
no_setting_.name("no_setting_");
|
||||
no_setting_ = *(char_ - all_names_);
|
||||
|
||||
no_decl_.name("no_decl_");
|
||||
no_decl_ = *(char_);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
using phx::val;
|
||||
using phx::construct;
|
||||
using namespace qi::labels;
|
||||
qi::on_error<qi::fail>
|
||||
( root_rule_ ,
|
||||
std::cout<<
|
||||
val("config parser could not complete parsing. Expecting ")<<
|
||||
_4<<
|
||||
val(" here: ")<<
|
||||
construct<std::string>(_3,_2)<<
|
||||
std::endl
|
||||
);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
qi::rule<Iterator, bertini::endgame::EndgameConfig(), ascii::space_type > root_rule_;
|
||||
qi::rule<Iterator, R(), ascii::space_type > sample_factor_;
|
||||
qi::rule<Iterator, T(), ascii::space_type > min_track_;
|
||||
qi::rule<Iterator, unsigned int(), ascii::space_type > num_sample_;
|
||||
qi::rule<Iterator, ascii::space_type, std::string()> no_decl_, no_setting_, all_names_;
|
||||
rules::LongNum<Iterator> mpfr_rules;
|
||||
}; //re: EndgameParser
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
*/
|
||||
template<typename Iterator, typename Skipper> //boost::spirit::unused_type
|
||||
struct ConfigSettingParser<Iterator, bertini::endgame::PowerSeriesConfig, Skipper> : qi::grammar<Iterator, bertini::endgame::PowerSeriesConfig(), Skipper>
|
||||
{
|
||||
using T = double;
|
||||
|
||||
ConfigSettingParser() : ConfigSettingParser::base_type(root_rule_, "bertini::endgame::PowerSeriesConfigType")
|
||||
{
|
||||
namespace phx = boost::phoenix;
|
||||
using qi::_1;
|
||||
using qi::_2;
|
||||
using qi::_3;
|
||||
using qi::_4;
|
||||
using qi::_val;
|
||||
using qi::eps;
|
||||
using qi::lit;
|
||||
using qi::char_;
|
||||
using qi::omit;
|
||||
using boost::spirit::lexeme;
|
||||
using boost::spirit::as_string;
|
||||
using boost::spirit::ascii::no_case;
|
||||
|
||||
|
||||
|
||||
std::string maxcycle_name = "maxcyclenum";
|
||||
|
||||
|
||||
root_rule_.name("bertini::endgame::PowerSeriesConfig");
|
||||
|
||||
root_rule_ = (max_cycle_[phx::bind( [this](bertini::endgame::PowerSeriesConfig & S, unsigned num)
|
||||
{
|
||||
S.max_cycle_number = num;
|
||||
}, _val, _1 )]
|
||||
|
||||
>> -no_setting_)
|
||||
| no_setting_;
|
||||
|
||||
|
||||
|
||||
all_names_ = eps >> (no_case[maxcycle_name] >> ':');
|
||||
|
||||
max_cycle_.name("max_cycle_");
|
||||
max_cycle_ = *(char_ - all_names_) >> (no_case[maxcycle_name] >> ':') >> qi::uint_[_val=_1] >> ';';
|
||||
|
||||
no_setting_.name("no_setting_");
|
||||
no_setting_ = *(char_ - all_names_);
|
||||
|
||||
no_decl_.name("no_decl_");
|
||||
no_decl_ = *(char_);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
using phx::val;
|
||||
using phx::construct;
|
||||
using namespace qi::labels;
|
||||
qi::on_error<qi::fail>
|
||||
( root_rule_ ,
|
||||
std::cout<<
|
||||
val("config parser could not complete parsing. Expecting ")<<
|
||||
_4<<
|
||||
val(" here: ")<<
|
||||
construct<std::string>(_3,_2)<<
|
||||
std::endl
|
||||
);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
qi::rule<Iterator, bertini::endgame::PowerSeriesConfig(), Skipper> root_rule_;
|
||||
qi::rule<Iterator, unsigned int(), ascii::space_type > max_cycle_;
|
||||
qi::rule<Iterator, ascii::space_type, std::string()> no_decl_, no_setting_, all_names_;
|
||||
}; //re: PowerSeriesParser
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
*/
|
||||
template<typename Iterator, typename Skipper> //boost::spirit::unused_type
|
||||
struct ConfigSettingParser<Iterator, bertini::endgame::CauchyConfig, Skipper> : qi::grammar<Iterator, bertini::endgame::CauchyConfig(), Skipper>
|
||||
{
|
||||
using T = double;
|
||||
|
||||
ConfigSettingParser() : ConfigSettingParser::base_type(root_rule_, "bertini::endgame::CauchyConfig")
|
||||
{
|
||||
namespace phx = boost::phoenix;
|
||||
using qi::_1;
|
||||
using qi::_2;
|
||||
using qi::_3;
|
||||
using qi::_4;
|
||||
using qi::_val;
|
||||
using qi::eps;
|
||||
using qi::lit;
|
||||
using qi::char_;
|
||||
using qi::omit;
|
||||
using boost::spirit::lexeme;
|
||||
using boost::spirit::as_string;
|
||||
using boost::spirit::ascii::no_case;
|
||||
|
||||
|
||||
|
||||
std::string cyclecutoff_name = "cycletimecutoff";
|
||||
std::string ratiocutoff_name = "ratiotimecutoff";
|
||||
|
||||
|
||||
root_rule_.name("config::Cauchy");
|
||||
|
||||
root_rule_ = ((cycle_cutoff_[phx::bind( [this](bertini::endgame::CauchyConfig & S, T num)
|
||||
{
|
||||
S.cycle_cutoff_time = num;
|
||||
}, _val, _1 )]
|
||||
^ ratio_cutoff_[phx::bind( [this](bertini::endgame::CauchyConfig & S, T num)
|
||||
{
|
||||
S.ratio_cutoff_time = num;
|
||||
}, _val, _1 )])
|
||||
>> -no_setting_) | no_setting_;
|
||||
|
||||
all_names_ = (no_case[cyclecutoff_name] >> ':') | (no_case[ratiocutoff_name] >> ':');
|
||||
|
||||
cycle_cutoff_.name("cycle_cutoff_");
|
||||
cycle_cutoff_ = *(char_ - all_names_) >> (no_case[cyclecutoff_name] >> ':')
|
||||
>> mpfr_rules.number_string_[phx::bind( [this](T & num, std::string str)
|
||||
{
|
||||
num = bertini::NumTraits<T>::FromString(str);
|
||||
}, _val, _1 )] >> ';';
|
||||
|
||||
ratio_cutoff_.name("ratio_cutoff_");
|
||||
ratio_cutoff_ = *(char_ - all_names_) >> (no_case[ratiocutoff_name] >> ':')
|
||||
>> mpfr_rules.number_string_[phx::bind( [this](T & num, std::string str)
|
||||
{
|
||||
num = bertini::NumTraits<T>::FromString(str);
|
||||
}, _val, _1 )] >> ';';
|
||||
|
||||
no_setting_.name("no_setting_");
|
||||
no_setting_ = *(char_ - all_names_);
|
||||
|
||||
no_decl_.name("no_decl_");
|
||||
no_decl_ = *(char_);
|
||||
|
||||
|
||||
|
||||
|
||||
using phx::val;
|
||||
using phx::construct;
|
||||
using namespace qi::labels;
|
||||
qi::on_error<qi::fail>
|
||||
( root_rule_ ,
|
||||
std::cout<<
|
||||
val("config parser could not complete parsing. Expecting ")<<
|
||||
_4<<
|
||||
val(" here: ")<<
|
||||
construct<std::string>(_3,_2)<<
|
||||
std::endl
|
||||
);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
qi::rule<Iterator, bertini::endgame::CauchyConfig(), ascii::space_type > root_rule_;
|
||||
qi::rule<Iterator, T(), ascii::space_type > cycle_cutoff_, ratio_cutoff_;
|
||||
qi::rule<Iterator, ascii::space_type, std::string()> no_decl_, no_setting_, all_names_;
|
||||
rules::LongNum<Iterator> mpfr_rules;
|
||||
|
||||
|
||||
|
||||
}; //re: CauchyParser
|
||||
|
||||
|
||||
|
||||
template<typename Iterator, typename Skipper> //boost::spirit::unused_type
|
||||
struct ConfigSettingParser<Iterator, bertini::endgame::TrackBackConfig, Skipper> : qi::grammar<Iterator, bertini::endgame::TrackBackConfig(), Skipper>
|
||||
{
|
||||
using T = double;
|
||||
|
||||
ConfigSettingParser() : ConfigSettingParser::base_type(root_rule_, "bertini::endgame::TrackBackConfig")
|
||||
{
|
||||
namespace phx = boost::phoenix;
|
||||
using qi::_1;
|
||||
using qi::_2;
|
||||
using qi::_3;
|
||||
using qi::_4;
|
||||
using qi::_val;
|
||||
using qi::eps;
|
||||
using qi::lit;
|
||||
using qi::char_;
|
||||
using qi::omit;
|
||||
using boost::spirit::lexeme;
|
||||
using boost::spirit::as_string;
|
||||
using boost::spirit::ascii::no_case;
|
||||
|
||||
|
||||
|
||||
std::string min_cycle_name = "mincycletrackback";
|
||||
std::string junk_removal_name = "junkremovaltrackback";
|
||||
std::string maxdepth_name = "maxldtdepth";
|
||||
|
||||
root_rule_.name("bertini::endgame::TrackBackConfig");
|
||||
|
||||
root_rule_ = root_rule_ = ((min_cycle_[phx::bind( [this](bertini::endgame::TrackBackConfig & S, unsigned num)
|
||||
{
|
||||
S.minimum_cycle = num;
|
||||
}, _val, _1 )]
|
||||
^ junk_removal_[phx::bind( [this](bertini::endgame::TrackBackConfig & S, int num)
|
||||
{
|
||||
S.junk_removal_test = static_cast<bool>(num);
|
||||
}, _val, _1 )]
|
||||
^ max_depth_[phx::bind( [this](bertini::endgame::TrackBackConfig & S, unsigned num)
|
||||
{
|
||||
S.max_depth_LDT = num;
|
||||
}, _val, _1 )]
|
||||
)
|
||||
>> -no_setting_) | no_setting_;
|
||||
|
||||
|
||||
|
||||
all_names_ = eps >> (no_case[min_cycle_name] >> ':') |
|
||||
(no_case[junk_removal_name] >> ':') |
|
||||
(no_case[maxdepth_name] >> ':');
|
||||
|
||||
min_cycle_.name("min_cycle_");
|
||||
min_cycle_ = *(char_ - all_names_) >> (no_case[min_cycle_name] >> ':') >> qi::uint_[_val=_1] >> ';';
|
||||
|
||||
junk_removal_.name("junk_removal_");
|
||||
junk_removal_ = *(char_ - all_names_) >> (no_case[junk_removal_name] >> ':') >> qi::int_[_val=_1] >> ';';
|
||||
|
||||
max_depth_.name("max_depth_");
|
||||
max_depth_ = *(char_ - all_names_) >> (no_case[maxdepth_name] >> ':') >> qi::uint_[_val=_1] >> ';';
|
||||
|
||||
no_setting_.name("no_setting_");
|
||||
no_setting_ = *(char_ - all_names_);
|
||||
|
||||
no_decl_.name("no_decl_");
|
||||
no_decl_ = *(char_);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
using phx::val;
|
||||
using phx::construct;
|
||||
using namespace qi::labels;
|
||||
qi::on_error<qi::fail>
|
||||
( root_rule_ ,
|
||||
std::cout<<
|
||||
val("config parser could not complete parsing. Expecting ")<<
|
||||
_4<<
|
||||
val(" here: ")<<
|
||||
construct<std::string>(_3,_2)<<
|
||||
std::endl
|
||||
);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
qi::rule<Iterator, bertini::endgame::TrackBackConfig(), Skipper> root_rule_;
|
||||
qi::rule<Iterator, unsigned int(), ascii::space_type > min_cycle_, max_depth_;
|
||||
qi::rule<Iterator, int(), ascii::space_type > junk_removal_;
|
||||
qi::rule<Iterator, ascii::space_type, std::string()> no_decl_, no_setting_, all_names_;
|
||||
}; //re: TrackBackParser
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
} // re: namespace classic
|
||||
|
||||
}// re: namespace parsing
|
||||
}// re: namespace bertini
|
||||
705
core/include/bertini2/io/parsing/settings_parsers/tracking.hpp
Normal file
705
core/include/bertini2/io/parsing/settings_parsers/tracking.hpp
Normal file
@@ -0,0 +1,705 @@
|
||||
//This file is part of Bertini 2.
|
||||
//
|
||||
//bertini2/io/parsing/settings_parsers/tracking.hpp is free software: you can redistribute it and/or modify
|
||||
//it under the terms of the GNU General Public License as published by
|
||||
//the Free Software Foundation, either version 3 of the License, or
|
||||
//(at your option) any later version.
|
||||
//
|
||||
//bertini2/io/parsing/settings_parsers/tracking.hpp is distributed in the hope that it will be useful,
|
||||
//but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
//GNU General Public License for more details.
|
||||
//
|
||||
//You should have received a copy of the GNU General Public License
|
||||
//along with bertini2/io/parsing/settings_parsers/tracking.hpp. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// Copyright(C) 2015 - 2017 by Bertini2 Development Team
|
||||
//
|
||||
// See <http://www.gnu.org/licenses/> for a copy of the license,
|
||||
// as well as COPYING. Bertini2 is provided with permitted
|
||||
// additional terms in the b2/licenses/ directory.
|
||||
|
||||
|
||||
/**
|
||||
\file bertini2/io/parsing/settings_parsers/tracking.hpp
|
||||
|
||||
\brief Provides the parsing rules for tracking-related settings in bertini2.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "bertini2/io/parsing/settings_parsers/base.hpp"
|
||||
#include "bertini2/trackers/config.hpp"
|
||||
|
||||
|
||||
namespace bertini {
|
||||
namespace parsing {
|
||||
namespace classic {
|
||||
|
||||
|
||||
namespace {
|
||||
using namespace bertini::tracking;
|
||||
}
|
||||
/**
|
||||
Qi Parser object for parsing config settings This ensures we can provide backwards compatibility with Bertini Classic input files.
|
||||
|
||||
To use this parser, construct an object of its type, then use it to parse.
|
||||
|
||||
\code
|
||||
ConfigT conf
|
||||
std::string str = "tracktype: 1; tracktolbeforeeg: 1e-8; \n";
|
||||
|
||||
std::string::const_iterator iter = str.begin();
|
||||
std::string::const_iterator end = str.end();
|
||||
|
||||
|
||||
bertini::ConfigSettingParser<std::string::const_iterator, ConfigT> S;
|
||||
|
||||
|
||||
bool s = phrase_parse(iter, end, S,boost::spirit::ascii::space, conf);
|
||||
|
||||
\endcode
|
||||
|
||||
\brief Qi Parser object for parsing config file to determine settings.
|
||||
|
||||
*/
|
||||
template<typename Iterator, typename Skipper> //boost::spirit::unused_type
|
||||
struct ConfigSettingParser<Iterator, PrecisionType, Skipper> : qi::grammar<Iterator, PrecisionType(), Skipper>
|
||||
{
|
||||
|
||||
ConfigSettingParser() : ConfigSettingParser::base_type(root_rule_, "PrecisionType")
|
||||
{
|
||||
namespace phx = boost::phoenix;
|
||||
using qi::_1;
|
||||
using qi::_2;
|
||||
using qi::_3;
|
||||
using qi::_4;
|
||||
using qi::_val;
|
||||
using qi::eps;
|
||||
using qi::lit;
|
||||
using qi::char_;
|
||||
using qi::omit;
|
||||
using boost::spirit::lexeme;
|
||||
using boost::spirit::as_string;
|
||||
using boost::spirit::ascii::no_case;
|
||||
|
||||
precisiontype_.add("0", PrecisionType::Fixed);
|
||||
precisiontype_.add("1", PrecisionType::Adaptive);
|
||||
precisiontype_.add("2", PrecisionType::Adaptive);
|
||||
|
||||
|
||||
|
||||
|
||||
root_rule_.name("config::PrecisionType");
|
||||
|
||||
root_rule_ = (config_name_[_val = _1] >> -no_setting_) | no_setting_[_val = PrecisionType::Adaptive];
|
||||
|
||||
config_name_.name("precisiontype_");
|
||||
config_name_ = *(char_ - (no_case["mptype"]>>':')) >> (no_case["mptype"] >> ':') >> precisiontype_[_val = _1] >> ';';
|
||||
|
||||
no_setting_.name("no_setting_");
|
||||
no_setting_ = *(char_ - no_case["mptype:"]);
|
||||
|
||||
no_decl_.name("no_decl_");
|
||||
no_decl_ = *(char_);
|
||||
|
||||
|
||||
|
||||
|
||||
using phx::val;
|
||||
using phx::construct;
|
||||
using namespace qi::labels;
|
||||
qi::on_error<qi::fail>
|
||||
( root_rule_ ,
|
||||
std::cout<<
|
||||
val("config parser could not complete parsing. Expecting ")<<
|
||||
_4<<
|
||||
val(" here: ")<<
|
||||
construct<std::string>(_3,_2)<<
|
||||
std::endl
|
||||
);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
qi::rule<Iterator, PrecisionType(), ascii::space_type > root_rule_, config_name_;
|
||||
qi::rule<Iterator, ascii::space_type, std::string()> no_decl_, no_setting_;
|
||||
|
||||
qi::symbols<char,PrecisionType> precisiontype_;
|
||||
|
||||
|
||||
}; //re: PrecisionTypeParser
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
*/
|
||||
template<typename Iterator, typename Skipper> //boost::spirit::unused_type
|
||||
struct ConfigSettingParser<Iterator, Predictor, Skipper> : qi::grammar<Iterator, Predictor(), Skipper>
|
||||
{
|
||||
|
||||
ConfigSettingParser() : ConfigSettingParser::base_type(root_rule_, "config::PredictorType")
|
||||
{
|
||||
namespace phx = boost::phoenix;
|
||||
using qi::_1;
|
||||
using qi::_2;
|
||||
using qi::_3;
|
||||
using qi::_4;
|
||||
using qi::_val;
|
||||
using qi::eps;
|
||||
using qi::lit;
|
||||
using qi::char_;
|
||||
using qi::omit;
|
||||
using boost::spirit::lexeme;
|
||||
using boost::spirit::as_string;
|
||||
using boost::spirit::ascii::no_case;
|
||||
|
||||
predictor_.add("-1", Predictor::Constant);
|
||||
predictor_.add("0", Predictor::Euler);
|
||||
predictor_.add("1", Predictor::Heun);
|
||||
predictor_.add("2", Predictor::RK4);
|
||||
predictor_.add("3", Predictor::Heun);
|
||||
predictor_.add("4", Predictor::RKNorsett34);
|
||||
predictor_.add("5", Predictor::RKF45);
|
||||
predictor_.add("6", Predictor::RKCashKarp45);
|
||||
predictor_.add("7", Predictor::RKDormandPrince56);
|
||||
predictor_.add("8", Predictor::RKVerner67);
|
||||
|
||||
|
||||
std::string setting_name = "odepredictor";
|
||||
|
||||
|
||||
root_rule_.name("Predictor");
|
||||
|
||||
root_rule_ = (config_name_[_val = _1] >> -no_setting_) | no_setting_[_val = Predictor::RKF45];
|
||||
|
||||
config_name_.name("predictor_");
|
||||
config_name_ = *(char_ - (no_case[setting_name] >> ':')) >> (no_case[setting_name] >> ':') >> predictor_[_val = _1] >> ';';
|
||||
|
||||
no_setting_.name("no_setting_");
|
||||
no_setting_ = *(char_ - no_case[setting_name]);
|
||||
|
||||
no_decl_.name("no_decl_");
|
||||
no_decl_ = *(char_);
|
||||
|
||||
|
||||
|
||||
|
||||
using phx::val;
|
||||
using phx::construct;
|
||||
using namespace qi::labels;
|
||||
qi::on_error<qi::fail>
|
||||
( root_rule_ ,
|
||||
std::cout<<
|
||||
val("config parser could not complete parsing. Expecting ")<<
|
||||
_4<<
|
||||
val(" here: ")<<
|
||||
construct<std::string>(_3,_2)<<
|
||||
std::endl
|
||||
);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
qi::rule<Iterator, Predictor(), ascii::space_type > root_rule_, config_name_;
|
||||
qi::rule<Iterator, ascii::space_type, std::string()> no_decl_, no_setting_;
|
||||
|
||||
qi::symbols<char,Predictor> predictor_;
|
||||
|
||||
|
||||
}; //re: PredictorTypeParser
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
*/
|
||||
template<typename Iterator, typename Skipper> //boost::spirit::unused_type
|
||||
struct ConfigSettingParser<Iterator, SteppingConfig, Skipper> : qi::grammar<Iterator, SteppingConfig(), Skipper>
|
||||
{
|
||||
|
||||
private:
|
||||
using T = double;
|
||||
using R = mpq_rational;
|
||||
|
||||
public:
|
||||
|
||||
ConfigSettingParser() : ConfigSettingParser::base_type(root_rule_, "config::SteppingType")
|
||||
{
|
||||
|
||||
namespace phx = boost::phoenix;
|
||||
using qi::_1;
|
||||
using qi::_2;
|
||||
using qi::_3;
|
||||
using qi::_4;
|
||||
using qi::_val;
|
||||
using qi::eps;
|
||||
using qi::lit;
|
||||
using qi::char_;
|
||||
using qi::omit;
|
||||
using boost::spirit::lexeme;
|
||||
using boost::spirit::as_string;
|
||||
using boost::spirit::ascii::no_case;
|
||||
|
||||
|
||||
|
||||
std::string maxstep_name = "maxstepsize";
|
||||
std::string stepsuccess_name = "stepsuccessfactor";
|
||||
std::string stepfail_name = "stepfailfactor";
|
||||
std::string stepsincrease_name = "stepsforincrease";
|
||||
std::string maxnumsteps_name = "maxnumbersteps";
|
||||
|
||||
|
||||
root_rule_.name("SteppingConfig");
|
||||
|
||||
root_rule_ = ((max_step_size_[phx::bind( [this](SteppingConfig & S, T num)
|
||||
{
|
||||
S.max_step_size = num;
|
||||
}, _val, _1 )]
|
||||
^ stepsize_success_[phx::bind( [this](SteppingConfig & S, R num)
|
||||
{
|
||||
S.step_size_success_factor = num;
|
||||
}, _val, _1 )]
|
||||
^ stepsize_fail_[phx::bind( [this](SteppingConfig & S, R num)
|
||||
{
|
||||
S.step_size_fail_factor = num;
|
||||
}, _val, _1 )]
|
||||
^ steps_increase_[phx::bind( [this](SteppingConfig & S, unsigned num)
|
||||
{
|
||||
S.consecutive_successful_steps_before_stepsize_increase = num;
|
||||
}, _val, _1 )]
|
||||
^ max_num_steps_[phx::bind( [this](SteppingConfig & S, unsigned num)
|
||||
{
|
||||
S.max_num_steps = num;
|
||||
}, _val, _1 )])
|
||||
|
||||
>> -no_setting_)
|
||||
| no_setting_;
|
||||
|
||||
|
||||
all_names_ = (no_case[maxstep_name] >> ':') | (no_case[stepsuccess_name] >> ':')|
|
||||
(no_case[stepfail_name] >> ':')| (no_case[stepsincrease_name] >> ':') | (no_case[maxnumsteps_name] >> ':');
|
||||
|
||||
max_step_size_.name("max_step_size_");
|
||||
max_step_size_ = *(char_ - all_names_) >> (no_case[maxstep_name] >> ':')
|
||||
>> mpfr_rules.rational[phx::bind( [this](T & num, std::string const& str)
|
||||
{
|
||||
num = bertini::NumTraits<T>::FromString(str);
|
||||
}, _val, _1 )] >> ';';
|
||||
|
||||
stepsize_success_.name("stepsize_success_");
|
||||
stepsize_success_ = *(char_ - all_names_) >> (no_case[stepsuccess_name] >> ':')
|
||||
>> mpfr_rules.rational[phx::bind( [this](R & num, std::string const& str)
|
||||
{
|
||||
num = bertini::NumTraits<double>::FromString(str);
|
||||
}, _val, _1 )] >> ';';
|
||||
|
||||
stepsize_fail_.name("stepsize_fail_");
|
||||
stepsize_fail_ = *(char_ - all_names_) >> (no_case[stepfail_name] >> ':')
|
||||
>> mpfr_rules.rational[phx::bind( [this](R & num, std::string const& str)
|
||||
{
|
||||
num = bertini::NumTraits<double>::FromString(str);
|
||||
}, _val, _1 )] >> ';';
|
||||
|
||||
steps_increase_.name("steps_increase_");
|
||||
steps_increase_ = *(char_ - all_names_) >> (no_case[stepsincrease_name] >> ':') >> qi::uint_[_val=_1] >> ';';
|
||||
|
||||
max_num_steps_.name("max_num_steps_");
|
||||
max_num_steps_ = *(char_ - all_names_) >> (no_case[maxnumsteps_name] >> ':') >> qi::uint_[_val=_1] >> ';';
|
||||
|
||||
no_setting_.name("no_setting_");
|
||||
no_setting_ = *(char_ - all_names_);
|
||||
|
||||
no_decl_.name("no_decl_");
|
||||
no_decl_ = *(char_);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
using phx::val;
|
||||
using phx::construct;
|
||||
using namespace qi::labels;
|
||||
qi::on_error<qi::fail>
|
||||
( root_rule_ ,
|
||||
std::cout<<
|
||||
val("config parser could not complete parsing. Expecting ")<<
|
||||
_4<<
|
||||
val(" here: ")<<
|
||||
construct<std::string>(_3,_2)<<
|
||||
std::endl
|
||||
);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
qi::rule<Iterator, SteppingConfig(), ascii::space_type > root_rule_;
|
||||
qi::rule<Iterator, T(), ascii::space_type > max_step_size_;
|
||||
qi::rule<Iterator, R(), ascii::space_type > stepsize_success_, stepsize_fail_;
|
||||
qi::rule<Iterator, unsigned int(), ascii::space_type > steps_increase_, max_num_steps_;
|
||||
qi::rule<Iterator, ascii::space_type, std::string()> no_decl_, no_setting_, all_names_;
|
||||
rules::LongNum<Iterator> mpfr_rules;
|
||||
|
||||
|
||||
|
||||
}; //re: SteppingParser
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
*/
|
||||
template<typename Iterator, typename Skipper> //boost::spirit::unused_type
|
||||
struct ConfigSettingParser<Iterator, NewtonConfig, Skipper> : qi::grammar<Iterator, NewtonConfig(), Skipper>
|
||||
{
|
||||
|
||||
ConfigSettingParser() : ConfigSettingParser::base_type(root_rule_, "config::NewtonType")
|
||||
{
|
||||
namespace phx = boost::phoenix;
|
||||
using qi::_1;
|
||||
using qi::_2;
|
||||
using qi::_3;
|
||||
using qi::_4;
|
||||
using qi::_val;
|
||||
using qi::eps;
|
||||
using qi::lit;
|
||||
using qi::char_;
|
||||
using qi::omit;
|
||||
using boost::spirit::lexeme;
|
||||
using boost::spirit::as_string;
|
||||
using boost::spirit::ascii::no_case;
|
||||
|
||||
|
||||
|
||||
std::string maxits_name = "maxnewtonits";
|
||||
|
||||
|
||||
root_rule_.name("NewtonConfig");
|
||||
|
||||
root_rule_ = (max_its_[phx::bind( [this](NewtonConfig & S, unsigned num)
|
||||
{
|
||||
S.max_num_newton_iterations = num;
|
||||
}, _val, _1 )]
|
||||
|
||||
>> -no_setting_)
|
||||
| no_setting_;
|
||||
|
||||
|
||||
|
||||
all_names_ = eps >> (no_case[maxits_name] >> ':');
|
||||
|
||||
max_its_.name("max_its_");
|
||||
max_its_ = *(char_ - no_case[maxits_name]) >> (no_case[maxits_name] >> ':') >> qi::uint_[_val=_1] >> ';';
|
||||
|
||||
no_setting_.name("no_setting_");
|
||||
no_setting_ = *(char_ - all_names_);
|
||||
|
||||
no_decl_.name("no_decl_");
|
||||
no_decl_ = *(char_);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
using phx::val;
|
||||
using phx::construct;
|
||||
using namespace qi::labels;
|
||||
qi::on_error<qi::fail>
|
||||
( root_rule_ ,
|
||||
std::cout<<
|
||||
val("config parser could not complete parsing. Expecting ")<<
|
||||
_4<<
|
||||
val(" here: ")<<
|
||||
construct<std::string>(_3,_2)<<
|
||||
std::endl
|
||||
);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
qi::rule<Iterator, NewtonConfig(), Skipper> root_rule_;
|
||||
qi::rule<Iterator, unsigned int(), ascii::space_type > max_its_;
|
||||
qi::rule<Iterator, ascii::space_type, std::string()> no_decl_, no_setting_, all_names_;
|
||||
}; //re: NewtonParser
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
As of this writing, there are no meaningful settings in FixedPrecisionConfig,
|
||||
so this parser is ... empty
|
||||
*/
|
||||
template<typename Iterator, typename Skipper>
|
||||
struct ConfigSettingParser<Iterator, FixedPrecisionConfig, Skipper> : qi::grammar<Iterator, FixedPrecisionConfig(), Skipper>
|
||||
{
|
||||
|
||||
ConfigSettingParser() : ConfigSettingParser::base_type(root_rule_, "config::FixedPrecision")
|
||||
{
|
||||
namespace phx = boost::phoenix;
|
||||
using qi::_1;
|
||||
using qi::_2;
|
||||
using qi::_3;
|
||||
using qi::_4;
|
||||
using qi::_val;
|
||||
using qi::eps;
|
||||
using qi::lit;
|
||||
using qi::char_;
|
||||
using qi::omit;
|
||||
using boost::spirit::lexeme;
|
||||
using boost::spirit::as_string;
|
||||
using boost::spirit::ascii::no_case;
|
||||
|
||||
|
||||
|
||||
root_rule_.name("config::FixedPrecision");
|
||||
root_rule_ = eps[_val = FixedPrecisionConfig()] >> omit[*(char_)];
|
||||
|
||||
|
||||
|
||||
using phx::val;
|
||||
using phx::construct;
|
||||
using namespace qi::labels;
|
||||
qi::on_error<qi::fail>
|
||||
( root_rule_ ,
|
||||
std::cout<<
|
||||
val("config parser could not complete parsing. Expecting ")<<
|
||||
_4<<
|
||||
val(" here: ")<<
|
||||
construct<std::string>(_3,_2)<<
|
||||
std::endl
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
qi::rule<Iterator, FixedPrecisionConfig(), ascii::space_type > root_rule_;
|
||||
}; //re: FixedPrecisionConfig Parser
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
using AdaptiveMultiplePrecisionConfig = AdaptiveMultiplePrecisionConfig;
|
||||
template<typename Iterator, typename Skipper>
|
||||
struct ConfigSettingParser<Iterator, AdaptiveMultiplePrecisionConfig, Skipper> : qi::grammar<Iterator, AdaptiveMultiplePrecisionConfig(), Skipper>
|
||||
{
|
||||
|
||||
ConfigSettingParser() : ConfigSettingParser::base_type(root_rule_, "AdaptiveMultiplePrecisionConfig")
|
||||
{
|
||||
using T = double;
|
||||
|
||||
namespace phx = boost::phoenix;
|
||||
using qi::_1;
|
||||
using qi::_2;
|
||||
using qi::_3;
|
||||
using qi::_4;
|
||||
using qi::_val;
|
||||
using qi::eps;
|
||||
using qi::lit;
|
||||
using qi::char_;
|
||||
using qi::omit;
|
||||
using boost::spirit::lexeme;
|
||||
using boost::spirit::as_string;
|
||||
using boost::spirit::ascii::no_case;
|
||||
|
||||
|
||||
|
||||
std::string coefficient_bound_name = "coefficientbound";
|
||||
std::string degree_bound_name = "degreebound";
|
||||
std::string lin_solve_error_bnd_name = "epsilon";
|
||||
std::string jac_eval_err_bnd_name = "phi";
|
||||
std::string func_eval_err_bnd_name = "psi";
|
||||
std::string safety_one_name = "ampsafetydigits1";
|
||||
std::string safety_two_name = "ampsafetydigits2";
|
||||
std::string max_prec_name = "ampmaxprec";
|
||||
std::string consec_steps_prec_dec_name = "maxstepsprecisiondecrease";
|
||||
std::string max_num_prec_decs_name = "maxnumprecdecreases";
|
||||
|
||||
root_rule_.name("config::AMP");
|
||||
|
||||
root_rule_ = ((coefficient_bound_[phx::bind( [this](AdaptiveMultiplePrecisionConfig & S, T num)
|
||||
{
|
||||
S.coefficient_bound = num;
|
||||
}, _val, _1 )]
|
||||
^ degree_bound_[phx::bind( [this](AdaptiveMultiplePrecisionConfig & S, T num)
|
||||
{
|
||||
S.degree_bound = num;
|
||||
}, _val, _1 )]
|
||||
^ lin_solve_error_bnd_[phx::bind( [this](AdaptiveMultiplePrecisionConfig & S, T num)
|
||||
{
|
||||
S.epsilon = num;
|
||||
}, _val, _1 )]
|
||||
^ jac_eval_err_bnd_[phx::bind( [this](AdaptiveMultiplePrecisionConfig & S, T num)
|
||||
{
|
||||
S.Phi = num;
|
||||
}, _val, _1 )]
|
||||
^ func_eval_err_bnd_[phx::bind( [this](AdaptiveMultiplePrecisionConfig & S, T num)
|
||||
{
|
||||
S.Psi = num;
|
||||
}, _val, _1 )]
|
||||
^ safety_one_[phx::bind( [this](AdaptiveMultiplePrecisionConfig & S, int num)
|
||||
{
|
||||
S.safety_digits_1 = num;
|
||||
}, _val, _1 )]
|
||||
^ safety_two_[phx::bind( [this](AdaptiveMultiplePrecisionConfig & S, int num)
|
||||
{
|
||||
S.safety_digits_2 = num;
|
||||
}, _val, _1 )]
|
||||
^ max_prec_[phx::bind( [this](AdaptiveMultiplePrecisionConfig & S, unsigned num)
|
||||
{
|
||||
S.maximum_precision = num;
|
||||
}, _val, _1 )]
|
||||
^ consec_steps_prec_dec_[phx::bind( [this](AdaptiveMultiplePrecisionConfig & S, unsigned num)
|
||||
{
|
||||
S.consecutive_successful_steps_before_precision_decrease = num;
|
||||
}, _val, _1 )]
|
||||
^ max_num_prec_decs_[phx::bind( [this](AdaptiveMultiplePrecisionConfig & S, unsigned num)
|
||||
{
|
||||
S.max_num_precision_decreases = num;
|
||||
}, _val, _1 )]
|
||||
)
|
||||
>> -no_setting_) | no_setting_;
|
||||
|
||||
all_names_ = (no_case[coefficient_bound_name] >> ':') |
|
||||
(no_case[degree_bound_name] >> ':') |
|
||||
(no_case[lin_solve_error_bnd_name] >> ':') |
|
||||
(no_case[jac_eval_err_bnd_name] >> ':') |
|
||||
(no_case[func_eval_err_bnd_name] >> ':') |
|
||||
(no_case[safety_one_name] >> ':') |
|
||||
(no_case[safety_two_name] >> ':') |
|
||||
(no_case[max_prec_name] >> ':') |
|
||||
(no_case[consec_steps_prec_dec_name] >> ':') |
|
||||
(no_case[max_num_prec_decs_name] >> ':')
|
||||
;
|
||||
|
||||
|
||||
auto str_to_T = [this](T & num, std::string const& str)
|
||||
{
|
||||
// std::cout << str << std::endl;
|
||||
num = bertini::NumTraits<T>::FromString(str);
|
||||
};
|
||||
|
||||
|
||||
degree_bound_.name("degree_bound_");
|
||||
degree_bound_ = *(char_ - all_names_) >> (no_case[degree_bound_name] >> ':')
|
||||
>> mpfr_rules.number_string_[phx::bind( str_to_T, _val, _1 )] >> ';';
|
||||
|
||||
coefficient_bound_.name("coefficient_bound_");
|
||||
coefficient_bound_ = *(char_ - all_names_) >> (no_case[coefficient_bound_name] >> ':')
|
||||
>> mpfr_rules.number_string_[phx::bind( str_to_T, _val, _1 )] >> ';';
|
||||
|
||||
lin_solve_error_bnd_.name("lin_solve_error_bnd_");
|
||||
lin_solve_error_bnd_ = *(char_ - all_names_) >> (no_case[lin_solve_error_bnd_name] >> ':')
|
||||
>> mpfr_rules.number_string_[phx::bind( str_to_T, _val, _1 )] >> ';';
|
||||
|
||||
jac_eval_err_bnd_.name("jac_eval_err_bnd_");
|
||||
jac_eval_err_bnd_ = *(char_ - all_names_) >> (no_case[jac_eval_err_bnd_name] >> ':')
|
||||
>> mpfr_rules.number_string_[phx::bind( str_to_T, _val, _1 )] >> ';';
|
||||
|
||||
func_eval_err_bnd_.name("func_eval_err_bnd_");
|
||||
func_eval_err_bnd_ = *(char_ - all_names_) >> (no_case[func_eval_err_bnd_name] >> ':')
|
||||
>> mpfr_rules.number_string_[phx::bind( str_to_T, _val, _1 )] >> ';';
|
||||
|
||||
safety_one_.name("safety_one_");
|
||||
safety_one_ = *(char_ - all_names_) >> (no_case[safety_one_name] >> ':') >> qi::int_[_val=_1] >> ';';
|
||||
|
||||
safety_two_.name("safety_two_");
|
||||
safety_two_ = *(char_ - all_names_) >> (no_case[safety_two_name] >> ':') >> qi::int_[_val=_1] >> ';';
|
||||
|
||||
max_prec_.name("max_prec_");
|
||||
max_prec_ = *(char_ - all_names_) >> (no_case[max_prec_name] >> ':') >> qi::uint_[_val=_1] >> ';';
|
||||
|
||||
consec_steps_prec_dec_.name("consec_steps_prec_dec_");
|
||||
consec_steps_prec_dec_ = *(char_ - all_names_) >> (no_case[consec_steps_prec_dec_name] >> ':') >> qi::uint_[_val=_1] >> ';';
|
||||
|
||||
max_num_prec_decs_.name("max_num_prec_decs_");
|
||||
max_num_prec_decs_ = *(char_ - all_names_) >> (no_case[max_num_prec_decs_name] >> ':') >> qi::uint_[_val=_1] >> ';';
|
||||
|
||||
|
||||
no_setting_.name("no_setting_");
|
||||
no_setting_ = *(char_ - all_names_);
|
||||
|
||||
no_decl_.name("no_decl_");
|
||||
no_decl_ = *(char_);
|
||||
|
||||
|
||||
|
||||
|
||||
using phx::val;
|
||||
using phx::construct;
|
||||
using namespace qi::labels;
|
||||
qi::on_error<qi::fail>
|
||||
( root_rule_ ,
|
||||
std::cout<<
|
||||
val("config parser could not complete parsing. Expecting ")<<
|
||||
_4<<
|
||||
val(" here: ")<<
|
||||
construct<std::string>(_3,_2)<<
|
||||
std::endl
|
||||
);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
qi::rule<Iterator, AdaptiveMultiplePrecisionConfig(), ascii::space_type > root_rule_;
|
||||
|
||||
qi::rule<Iterator, double(), ascii::space_type > degree_bound_, coefficient_bound_, lin_solve_error_bnd_, jac_eval_err_bnd_, func_eval_err_bnd_;
|
||||
qi::rule<Iterator, int(), ascii::space_type > safety_one_, safety_two_;
|
||||
qi::rule<Iterator, unsigned int(), ascii::space_type > max_prec_, consec_steps_prec_dec_, max_num_prec_decs_;
|
||||
|
||||
qi::rule<Iterator, ascii::space_type, std::string()> no_decl_, no_setting_, all_names_;
|
||||
rules::LongNum<Iterator> mpfr_rules;
|
||||
|
||||
|
||||
|
||||
}; //re: AMPParser
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
} // re: namespace classic
|
||||
|
||||
}// re: namespace parsing
|
||||
}// re: namespace bertini
|
||||
32
core/include/bertini2/io/parsing/settings_rules.hpp
Normal file
32
core/include/bertini2/io/parsing/settings_rules.hpp
Normal file
@@ -0,0 +1,32 @@
|
||||
//This file is part of Bertini 2.
|
||||
//
|
||||
//bertini2/io/parsers.hpp is free software: you can redistribute it and/or modify
|
||||
//it under the terms of the GNU General Public License as published by
|
||||
//the Free Software Foundation, either version 3 of the License, or
|
||||
//(at your option) any later version.
|
||||
//
|
||||
//bertini2/io/parsing/settings_parsers.hpp is distributed in the hope that it will be useful,
|
||||
//but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
//GNU General Public License for more details.
|
||||
//
|
||||
//You should have received a copy of the GNU General Public License
|
||||
//along with bertini2/io/parsing/settings_parsers.hpp. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// Copyright(C) 2015 - 2017 by Bertini2 Development Team
|
||||
//
|
||||
// See <http://www.gnu.org/licenses/> for a copy of the license,
|
||||
// as well as COPYING. Bertini2 is provided with permitted
|
||||
// additional terms in the b2/licenses/ directory.
|
||||
|
||||
|
||||
/**
|
||||
\file bertini2/io/parsing/settings_parsers.hpp
|
||||
|
||||
\brief Useful Qi rules for parsing settings
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
96
core/include/bertini2/io/parsing/system_parsers.hpp
Normal file
96
core/include/bertini2/io/parsing/system_parsers.hpp
Normal file
@@ -0,0 +1,96 @@
|
||||
//This file is part of Bertini 2.
|
||||
//
|
||||
//bertini2/io/parsers.hpp is free software: you can redistribute it and/or modify
|
||||
//it under the terms of the GNU General Public License as published by
|
||||
//the Free Software Foundation, either version 3 of the License, or
|
||||
//(at your option) any later version.
|
||||
//
|
||||
//bertini2/io/parsing/system_parsers.hpp is distributed in the hope that it will be useful,
|
||||
//but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
//GNU General Public License for more details.
|
||||
//
|
||||
//You should have received a copy of the GNU General Public License
|
||||
//along with bertini2/io/parsing/system_parsers.hpp. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// Copyright(C) 2015 - 2017 by Bertini2 Development Team
|
||||
//
|
||||
// See <http://www.gnu.org/licenses/> for a copy of the license,
|
||||
// as well as COPYING. Bertini2 is provided with permitted
|
||||
// additional terms in the b2/licenses/ directory.
|
||||
|
||||
|
||||
/**
|
||||
\file bertini2/io/parsing/system_parsers.hpp
|
||||
|
||||
\brief Provides the parsers for systems in bertini2.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
|
||||
#include "bertini2/io/parsing/system_rules.hpp"
|
||||
|
||||
|
||||
|
||||
namespace bertini {
|
||||
namespace parsing {
|
||||
|
||||
namespace classic {
|
||||
|
||||
|
||||
|
||||
template <typename Iterator>
|
||||
static bool parse(Iterator first, Iterator last, System& sys)
|
||||
{
|
||||
using boost::spirit::qi::double_;
|
||||
using boost::spirit::qi::_1;
|
||||
using boost::spirit::qi::phrase_parse;
|
||||
using boost::spirit::ascii::space;
|
||||
using boost::phoenix::ref;
|
||||
|
||||
SystemParser<Iterator> S;
|
||||
|
||||
System s{};
|
||||
bool r = phrase_parse(first, last,
|
||||
S,
|
||||
space,
|
||||
s);
|
||||
|
||||
if (!r || first != last) // fail if we did not get a full match
|
||||
return false;
|
||||
|
||||
sys = s;
|
||||
return r;
|
||||
}
|
||||
|
||||
} // re: namespace classic
|
||||
|
||||
}// re: namespace parsing
|
||||
|
||||
inline
|
||||
System::System(std::string const& input)
|
||||
{
|
||||
System sys;
|
||||
|
||||
parsing::classic::SystemParser<std::string::const_iterator> S;
|
||||
|
||||
std::string::const_iterator iter = input.begin();
|
||||
std::string::const_iterator end = input.end();
|
||||
|
||||
bool s = phrase_parse(iter, end, S,boost::spirit::ascii::space, sys);
|
||||
|
||||
if (!s || iter!=end)
|
||||
{
|
||||
throw std::runtime_error("unable to correctly parse string in construction of system");
|
||||
}
|
||||
|
||||
using std::swap;
|
||||
swap(sys,*this);
|
||||
}
|
||||
|
||||
}// re: namespace bertini
|
||||
|
||||
|
||||
379
core/include/bertini2/io/parsing/system_rules.hpp
Normal file
379
core/include/bertini2/io/parsing/system_rules.hpp
Normal file
@@ -0,0 +1,379 @@
|
||||
//This file is part of Bertini 2.
|
||||
//
|
||||
//bertini2/io/parsers.hpp is free software: you can redistribute it and/or modify
|
||||
//it under the terms of the GNU General Public License as published by
|
||||
//the Free Software Foundation, either version 3 of the License, or
|
||||
//(at your option) any later version.
|
||||
//
|
||||
//bertini2/io/parsing/system_rules.hpp is distributed in the hope that it will be useful,
|
||||
//but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
//GNU General Public License for more details.
|
||||
//
|
||||
//You should have received a copy of the GNU General Public License
|
||||
//along with bertini2/io/parsing/system_rules.hpp. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// Copyright(C) 2015 - 2017 by Bertini2 Development Team
|
||||
//
|
||||
// See <http://www.gnu.org/licenses/> for a copy of the license,
|
||||
// as well as COPYING. Bertini2 is provided with permitted
|
||||
// additional terms in the b2/licenses/ directory.
|
||||
|
||||
|
||||
/**
|
||||
\file bertini2/io/parsing/system_rules.hpp
|
||||
|
||||
\brief Provides the parsing rules for systems in bertini2.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
|
||||
#include "bertini2/io/parsing/qi_files.hpp"
|
||||
#include "bertini2/system/system.hpp"
|
||||
#include "bertini2/io/parsing/function_rules.hpp"
|
||||
|
||||
|
||||
|
||||
namespace bertini {
|
||||
namespace parsing {
|
||||
namespace classic {
|
||||
// a few local using statements to reduce typing etc.
|
||||
using Function = node::Function;
|
||||
using Variable = node::Variable;
|
||||
using Node = node::Node;
|
||||
|
||||
|
||||
using Fn = std::shared_ptr<Function>;
|
||||
using Var = std::shared_ptr<Variable>;
|
||||
using Nd = std::shared_ptr<Node>;
|
||||
|
||||
/**
|
||||
Qi Parser object for parsing text into the System class. This ensures we can provide backwards compatibility with Bertini Classic input files.
|
||||
|
||||
To use this parser, construct an object of its type, then use it to parse.
|
||||
|
||||
\code
|
||||
System sys;
|
||||
std::string str = "variable_group x, y, z; \nfunction f1, f2;\n f1 = x*y*z;\n f2 = x+y+z;\n";
|
||||
|
||||
std::string::const_iterator iter = str.begin();
|
||||
std::string::const_iterator end = str.end();
|
||||
|
||||
|
||||
bertini::SystemParser<std::string::const_iterator> S;
|
||||
|
||||
|
||||
bool s = phrase_parse(iter, end, S,boost::spirit::ascii::space, sys);
|
||||
|
||||
\endcode
|
||||
|
||||
\brief Qi Parser object for parsing text into the System class.
|
||||
|
||||
This parser could not have been written without the help of SO user sehe.
|
||||
*/
|
||||
template<typename Iterator, typename Skipper = ascii::space_type>
|
||||
struct SystemParser : qi::grammar<Iterator, System(), Skipper>
|
||||
{
|
||||
|
||||
|
||||
SystemParser() : function_parser_(&encountered_symbols_),
|
||||
/*initialize here with address of encountered_symbols*/
|
||||
SystemParser::base_type(root_rule_)
|
||||
{
|
||||
namespace phx = boost::phoenix;
|
||||
using qi::_1;
|
||||
using qi::_2;
|
||||
using qi::_3;
|
||||
using qi::_4;
|
||||
using qi::_val;
|
||||
using qi::eps;
|
||||
using qi::lit;
|
||||
using boost::spirit::lexeme;
|
||||
|
||||
|
||||
declarative_symbols_.add("variable_group",0);
|
||||
declarative_symbols_.add("hom_variable_group",1);
|
||||
declarative_symbols_.add("variable",2);
|
||||
declarative_symbols_.add("function",3);
|
||||
declarative_symbols_.add("constant",4);
|
||||
declarative_symbols_.add("parameter",5);
|
||||
declarative_symbols_.add("implicit_parameter",6);
|
||||
declarative_symbols_.add("pathvariable",7);
|
||||
declarative_symbols_.add("random",8);
|
||||
declarative_symbols_.add("random_real",9);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
special_numbers_.add("pi", node::Pi());
|
||||
special_numbers_.add("Pi", special_numbers_.at("pi"));
|
||||
|
||||
special_numbers_.add("e", node::E());
|
||||
special_numbers_.add("E", special_numbers_.at("e"));
|
||||
|
||||
|
||||
special_numbers_.add("i", node::I());
|
||||
special_numbers_.add("I", special_numbers_.at("i"));
|
||||
|
||||
|
||||
|
||||
encountered_symbols_.add("pi", special_numbers_.at("pi"));
|
||||
encountered_symbols_.add("Pi", special_numbers_.at("pi"));
|
||||
|
||||
encountered_symbols_.add("e", special_numbers_.at("e"));
|
||||
encountered_symbols_.add("E", special_numbers_.at("e"));
|
||||
|
||||
|
||||
encountered_symbols_.add("i", special_numbers_.at("i"));
|
||||
encountered_symbols_.add("I", special_numbers_.at("i"));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//TODO refine this so that counts are enforced at parse time?
|
||||
root_rule_.name("system_parsing");
|
||||
root_rule_ =
|
||||
*(
|
||||
variable_group_ [phx::bind(&System::AddVariableGroup, _val, _1)]
|
||||
|
|
||||
hom_variable_group_ [phx::bind(&System::AddHomVariableGroup, _val, _1)]
|
||||
|
|
||||
variables_ [phx::bind(&System::AddUngroupedVariables, _val, _1)]
|
||||
|
|
||||
functions_ [phx::bind(&System::AddFunctions, _val, _1)]
|
||||
|
|
||||
constants_ [phx::bind(&System::AddConstants, _val, _1)]
|
||||
|
|
||||
parameters_ [phx::bind(&System::AddParameters, _val, _1)]
|
||||
|
|
||||
implicit_parameters_ [phx::bind(&System::AddImplicitParameters, _val, _1)]
|
||||
|
|
||||
path_variable_ [phx::bind(&System::AddPathVariable, _val, _1)]
|
||||
|
|
||||
subfunction_ [phx::bind(&System::AddSubfunction, _val, _1)]
|
||||
|
|
||||
definition_
|
||||
)
|
||||
;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
variables_.name("variables_"); hom_variable_group_.name("hom_variable_group_"); variable_group_.name("variable_group_"); implicit_parameters_.name("implicit_parameters_");
|
||||
|
||||
|
||||
variables_ = "variable" > genericvargp_ > ';';
|
||||
hom_variable_group_ = "hom_variable_group" > genericvargp_ > ';';
|
||||
variable_group_ = "variable_group" > genericvargp_ > ';';
|
||||
implicit_parameters_ = "implicit_parameter" > genericvargp_ > ';';
|
||||
|
||||
|
||||
|
||||
path_variable_.name("path_variable_");
|
||||
path_variable_ = "pathvariable" > new_variable_ > ';';
|
||||
|
||||
|
||||
|
||||
genericvargp_.name("genericvargp_");
|
||||
genericvargp_ = new_variable_ % ',';
|
||||
|
||||
new_variable_.name("new_variable_");
|
||||
new_variable_ = unencountered_symbol_ [boost::phoenix::bind( [this](Var & V, std::string str)
|
||||
{
|
||||
MakeAndAddVariable(V,str);
|
||||
}, _val, _1 )];
|
||||
|
||||
|
||||
|
||||
functions_.name("functions_"); constants_.name("constants_"); parameters_.name("parameters_");
|
||||
|
||||
functions_ = "function" > genericfuncgp_ > ';';
|
||||
constants_ = "constant" > genericfuncgp_ > ';';
|
||||
parameters_ = "parameter" > genericfuncgp_ > ';';
|
||||
|
||||
|
||||
genericfuncgp_.name("genericfuncgp_");
|
||||
genericfuncgp_ = new_function_ % ',';
|
||||
|
||||
|
||||
new_function_.name("new_function_");
|
||||
new_function_ = unencountered_symbol_ [boost::phoenix::bind( [this](Fn & F, std::string str)
|
||||
{
|
||||
MakeAndAddFunction(F,str);
|
||||
}, _val, _1 )];//[_val = make_shared_<Function>() (_1)]
|
||||
|
||||
|
||||
|
||||
|
||||
// this rule gets a string.
|
||||
unencountered_symbol_.name("unencountered_symbol_");
|
||||
unencountered_symbol_ = valid_variable_name_ - lexeme[( declarative_symbols_ | encountered_symbols_ )];
|
||||
// i am unsure about the use of lexeme in the above rule (unencountered_symbol).
|
||||
|
||||
|
||||
|
||||
|
||||
// get a string which fits the naming rules.
|
||||
valid_variable_name_.name("valid_variable_name_");
|
||||
valid_variable_name_ = +qi::alpha >> *(qi::alnum | qi::char_("[]_") );
|
||||
|
||||
|
||||
|
||||
|
||||
definition_.name("definition_");
|
||||
definition_ = (encountered_functions_ > '=' > function_parser_ > ';') [phx::bind( [](const Fn & F, const Nd & N)
|
||||
{
|
||||
F->SetRoot(N);
|
||||
},_1, _2)] ;
|
||||
|
||||
|
||||
using qi::_a;
|
||||
using qi::omit;
|
||||
subfunction_.name("subfunction");
|
||||
subfunction_ = new_function_ [_a = _1] > '=' >
|
||||
function_parser_ [_val = _a, phx::bind( [](Fn & F, const Nd & N)
|
||||
{
|
||||
F->SetRoot(N);
|
||||
},_a, _1)]
|
||||
// omit close
|
||||
> ';';
|
||||
|
||||
|
||||
// debug(root_rule_);
|
||||
//
|
||||
//
|
||||
//
|
||||
// debug(functions_);
|
||||
// debug(constants_);
|
||||
// debug(parameters_);
|
||||
//
|
||||
// debug(genericfuncgp_);
|
||||
// debug(new_function_);
|
||||
//
|
||||
//
|
||||
//
|
||||
// debug(definition_);
|
||||
//
|
||||
// debug(subfunction_);
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// debug(variables_);
|
||||
// debug(hom_variable_group_);
|
||||
// debug(variable_group_);
|
||||
// debug(implicit_parameters_);
|
||||
// debug(path_variable_);
|
||||
//
|
||||
// debug(new_variable_);
|
||||
// debug(genericvargp_); debug(variable_group_);
|
||||
//
|
||||
// debug(unencountered_symbol_);
|
||||
//
|
||||
// debug(valid_variable_name_);
|
||||
|
||||
|
||||
|
||||
|
||||
// BOOST_SPIRIT_DEBUG_NODES( (unencountered_symbol_) (new_variable_) (genericvargp_))
|
||||
|
||||
using phx::val;
|
||||
using phx::construct;
|
||||
using namespace qi::labels;
|
||||
qi::on_error<qi::fail>
|
||||
( root_rule_ ,
|
||||
std::cout<<
|
||||
val("System parser could not complete parsing. Expecting ")<<
|
||||
_4<<
|
||||
val(" here: ")<<
|
||||
construct<std::string>(_3,_2)<<
|
||||
std::endl
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// rule declarations. these are member variables for the parser.
|
||||
qi::rule<Iterator, System(), Skipper > root_rule_;
|
||||
|
||||
|
||||
qi::rule<Iterator, VariableGroup(), Skipper > variable_group_, hom_variable_group_, variables_, implicit_parameters_;
|
||||
qi::rule<Iterator, VariableGroup(), Skipper > genericvargp_;
|
||||
|
||||
qi::rule<Iterator, Var(), Skipper> path_variable_;
|
||||
qi::rule<Iterator, Var()> new_variable_;
|
||||
|
||||
|
||||
|
||||
|
||||
qi::rule<Iterator, std::vector<Fn>(), Skipper > functions_, constants_, parameters_;
|
||||
qi::rule<Iterator, std::vector<Fn>(), Skipper > genericfuncgp_;
|
||||
qi::rule<Iterator, Fn(), Skipper, qi::locals<Fn> > subfunction_;
|
||||
|
||||
qi::rule<Iterator, Fn()> new_function_;
|
||||
|
||||
|
||||
qi::rule<Iterator, std::string()> unencountered_symbol_;
|
||||
|
||||
|
||||
// the rule which determines valid variable names
|
||||
qi::rule<Iterator, std::string()> valid_variable_name_;
|
||||
|
||||
qi::rule<Iterator, Skipper, qi::unused_type> definition_;
|
||||
|
||||
// symbol declarations
|
||||
qi::symbols<char,Nd> encountered_symbols_;
|
||||
qi::symbols<char,int> declarative_symbols_;
|
||||
qi::symbols<char,Fn> encountered_functions_;
|
||||
qi::symbols<char,Nd> special_numbers_;
|
||||
|
||||
FunctionParser<Iterator> function_parser_;
|
||||
|
||||
/**
|
||||
To accompany the rule for making new functions when you encounter a new symbol.
|
||||
Simultaneously makes a new function, and adds it to the set of symbols.
|
||||
*/
|
||||
void MakeAndAddFunction(Fn & F, std::string str)
|
||||
{
|
||||
F = Function::Make(str);
|
||||
encountered_symbols_.add(str, F);
|
||||
encountered_functions_.add(str,F);
|
||||
}
|
||||
|
||||
/**
|
||||
To accompany the rule for making new variables when you encounter a new symbol.
|
||||
Simultaneously makes a new variable, and adds it to the set of symbols.
|
||||
*/
|
||||
void MakeAndAddVariable(Var & V, std::string str)
|
||||
{
|
||||
V = Variable::Make(str);
|
||||
encountered_symbols_.add(str, V);
|
||||
}
|
||||
|
||||
|
||||
void SetRootNode(Fn & F, const Nd & N)
|
||||
{
|
||||
F->SetRoot(N);
|
||||
}
|
||||
};
|
||||
|
||||
} // re: namespace classic
|
||||
|
||||
} //re: namespace parsing
|
||||
|
||||
|
||||
|
||||
|
||||
} // re: namespace bertini
|
||||
Reference in New Issue
Block a user