Skip to content

Instantly share code, notes, and snippets.

@AHaliq
Created April 30, 2021 12:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AHaliq/84fddf671d669315ec47a21b2b94d4ae to your computer and use it in GitHub Desktop.
Save AHaliq/84fddf671d669315ec47a21b2b94d4ae to your computer and use it in GitHub Desktop.
error: too many arguments to function
/******************************************************************************
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;
}
/******************************************************************************
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