Created
April 30, 2021 12:15
-
-
Save AHaliq/84fddf671d669315ec47a21b2b94d4ae to your computer and use it in GitHub Desktop.
error: too many arguments to function
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/****************************************************************************** | |
Online C++ Compiler. | |
Code, Compile, Run and Debug C++ program online. | |
Write your code in this editor and press "Run" button to compile and execute it. | |
*******************************************************************************/ | |
#include <iostream> | |
#include <string> | |
#include <istream> | |
#include <functional> | |
#include <memory> | |
#include <vector> | |
#include <string> | |
// parser state classes | |
/////////////////////////////////////////////////////////////////////////////// | |
namespace parser::state { | |
const std::string STATE_NOT_FAILED_LABEL = "<not failed>"; //!< label when state not in failure state | |
struct empty {}; //!< empty struct for default user data in state | |
/*! State object virtual class */ | |
template <typename X = empty> | |
class State { | |
protected: | |
int i; //!< index to currently to be consumed character | |
private: | |
bool failed; //!< flag to determine failure | |
int fail_uuid; //!< uuid of failing parser | |
public: | |
X data; //!< user data | |
/*! | |
* Construct state with pointer to source string | |
*/ | |
State() : i(0), failed(false) {} | |
/*! | |
* Advance the currently consumed character (must be implemented by inheriting class) | |
* @return consumed character | |
*/ | |
virtual const char adv() { | |
throw std::vector<State<X>>(); | |
} | |
/*! | |
* Set state to failure with accompanying label | |
* @param label failure label | |
*/ | |
void fail(const int id) { | |
if(!failed) { | |
failed = true; | |
fail_uuid = id; | |
} | |
} | |
/*! | |
* Get failure flag | |
* @return flag | |
*/ | |
const bool has_failed() { return failed; } | |
/*! | |
* Get failure parser uuid | |
* @return failure id | |
*/ | |
const int get_fail() { return failed ? fail_uuid : -1; } | |
}; | |
/*! State using std::string as source */ | |
template <typename X = empty> | |
class StateString : public State<X> { | |
private: | |
std::string *src; //!< pointer to source string to be parsed | |
public: | |
StateString(std::string *_src) : State<X>(), src(_src) {} | |
const char adv() override { | |
if (this->i >= src->size()) throw std::vector<State<X>>(); | |
return src->at(this->i++); | |
} | |
}; | |
/*! State using std::istream as source */ | |
template <typename X = empty> | |
class StateIStream : public State<X> { | |
private: | |
std::istream *src; //!< pointer to input stream used to parse | |
public: | |
StateIStream(std::istream *_src) : State<X>(), src(_src) {} | |
const char adv() override { | |
char c; | |
if (this->i != src->tellg()) src->seekg(this->i); | |
*src >> c; | |
if (c == 0) throw std::vector<State<X>>(); | |
this->i++; | |
return c; | |
} | |
}; | |
} | |
// parser class | |
/////////////////////////////////////////////////////////////////////////////// | |
namespace parser { | |
using namespace parser::state; | |
enum parser_type { USER, SEQ, ALT, MAP, MANY, SOME }; //!< parser type values | |
const std::string label_str[] = { "seq", "alt", "map", "many", "some"}; //!< mapping parser type to string | |
/*! Class for parser metadata inclusive of unique id and children parser metadata */ | |
class ParserMetaData { | |
public: | |
const int uuid; | |
const std::string user_label; | |
const parser_type type; | |
const std::vector<ParserMetaData*> children; | |
ParserMetaData(std::string _label, std::vector<ParserMetaData*> _children = {}) : uuid(__COUNTER__), user_label(_label), type(USER), children(_children) {} | |
ParserMetaData(parser_type _type, std::vector<ParserMetaData*> _children = {}) : uuid(__COUNTER__), type(_type), children(_children) {} | |
}; | |
/*! Parser base class */ | |
template <typename T, typename X = empty> | |
class Parser { | |
private: | |
const std::function<T(State<X> &)> f; //!< core function | |
public: | |
const ParserMetaData metadata; //!< metadata object | |
/*! Constructor for user labelled type parser */ | |
Parser(const std::string _label, std::function<T(State<X>&)> _f, std::vector<ParserMetaData*> _children = {}) : f(_f), metadata(ParserMetaData(_label, _children)) {} | |
/*! Construtor for library standard type parser */ | |
Parser(const parser_type _type, std::function<T(State<X>&)> _f, std::vector<ParserMetaData*> _children = {}): f(_f), metadata(ParserMetaData(_type, _children)) {} | |
/*! Perform the parse given a state */ | |
T parse(State<X> &s) { | |
State<X> _s = s; | |
try { | |
return f(s); | |
} catch (std::vector<State<X>> &e) { | |
_s.fail(metadata.uuid); | |
e.push_back(_s); | |
throw e; | |
} | |
} | |
/*! Method chain to generate sequential parser from current parser */ | |
template <typename U, typename V> | |
std::shared_ptr<Parser<V,X>> seq(const std::shared_ptr<Parser<U,X>> second, const std::function<V(T,U)> g) { | |
return std::make_shared<Parser<V,X>>(SEQ, [this,second,g](State<X> &s) -> V { | |
return g(this->parse(s), second->parse(s)); | |
}, { &this->metadata, &second->metadata }); | |
} | |
}; | |
} | |
using State = parser::state::State<>; | |
int main() | |
{ | |
std::cout<<"Hello World"; | |
parser::Parser<char> p1("test1", [](State &s) -> char { return 'k'; }); | |
std::shared_ptr<parser::Parser<char>> p2 = std::make_shared<parser::Parser<char>>("test2", [](State &s) -> char { return 'o'; }); | |
State s; | |
std::cout << p1.seq<char, std::string>(p2, [](char a, char b) { return std::string(1,a) + std::string(1,b); })->parse(s); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/****************************************************************************** | |
Online C++ Compiler. | |
Code, Compile, Run and Debug C++ program online. | |
Write your code in this editor and press "Run" button to compile and execute it. | |
*******************************************************************************/ | |
#include <iostream> | |
#include <functional> | |
#include <memory> | |
using namespace std; | |
struct empty {}; | |
template <typename X = empty> | |
class State { | |
private: | |
public: | |
X data; | |
State() {} | |
}; | |
template <typename T, typename X = empty> | |
class Parser { | |
private: | |
std::function<T(State<X>&)> f; | |
public : | |
Parser(std::function<T(State<X>&)> _f) : f(_f) {} | |
T parse(State<X> &s) { | |
return f(s); | |
} | |
template <typename U, typename V> | |
std::shared_ptr<Parser<V,X>> seq(const std::shared_ptr<Parser<U,X>> second, const std::function<V(T,U)> g) { | |
return std::make_shared<Parser<V,X>>([this,second,g](State<X> &s) -> V { | |
return g(this->parse(s), second->parse(s)); | |
}); | |
} | |
}; | |
int main() | |
{ | |
cout<<"Hello World\n"; | |
Parser<char> p1([](State<> &s) -> char { return 'o'; }); | |
std::shared_ptr<Parser<char>> p2 = std::make_shared<Parser<char>>([](State<> &s) { return 'k'; }); | |
State<> s; | |
cout << p1.seq<char, std::string>(p2, [](char a, char b) { return std::string(1,a) + std::string(1,b); })->parse(s); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment