Created
October 2, 2015 02:29
-
-
Save ghaskins/c492171f5b2a8197bf48 to your computer and use it in GitHub Desktop.
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
// compile with: g++ -g -O0 -std=c++11 -o spirittest main.cc | |
#include <iostream> | |
#include <list> | |
#include <stack> | |
#include <vector> | |
#include <boost/spirit/include/qi.hpp> | |
#include <boost/spirit/include/qi_string.hpp> | |
#include <boost/spirit/include/qi_uint.hpp> | |
#include <boost/spirit/include/qi_action.hpp> | |
#include <boost/spirit/include/support_istream_iterator.hpp> | |
#include <boost/fusion/include/adapt_struct.hpp> | |
#include <boost/fusion/include/adapt_adt.hpp> | |
#include <boost/fusion/adapted/adt/adapt_adt.hpp> | |
namespace qi = boost::spirit::qi; | |
namespace ascii = boost::spirit::ascii; | |
//************************************************************* | |
// Define the basic abstract syntax tree | |
//************************************************************* | |
namespace Ast | |
{ | |
class Foo | |
{ | |
public: | |
unsigned one() const { return m_one; } | |
void set_one(const unsigned &v) { m_one = v; } | |
unsigned two() const { return m_two; } | |
void set_two(const unsigned &v) { m_two = v; } | |
private: | |
unsigned m_one; | |
unsigned m_two; | |
}; | |
typedef std::vector<Foo> Foos; | |
}; | |
BOOST_FUSION_ADAPT_ADT( | |
Ast::Foo, | |
(unsigned, const unsigned, obj.one(), obj.set_one(val)) | |
(unsigned, const unsigned, obj.two(), obj.set_two(val)) | |
) | |
template <typename Iterator> | |
struct foo_grammar : qi::grammar<Iterator, Ast::Foos()> | |
{ | |
foo_grammar() : foo_grammar::base_type(foos) | |
{ | |
using qi::lit; | |
using qi::eol; | |
using qi::uint_; | |
foo = uint_ >> lit(',') >> uint_ >> eol; | |
foos = +(foo); | |
foo.name("foo"); | |
foos.name("foos"); | |
#if 0 | |
debug(foo); | |
debug(foos); | |
#endif | |
} | |
qi::rule<Iterator, Ast::Foo()> foo; | |
qi::rule<Iterator, Ast::Foos()> foos; | |
}; | |
Ast::Foos | |
Parse(std::istream &is) | |
{ | |
typedef boost::spirit::istream_iterator iterator_type; | |
typedef foo_grammar<iterator_type> foo_grammar; | |
is.unsetf(std::ios::skipws); | |
foo_grammar grammar; | |
iterator_type begin(is); | |
iterator_type end; | |
Ast::Foos result; | |
bool r = parse(begin, end, grammar, result); | |
if (!r) { | |
std::ostringstream os; | |
os << "Error: invalid order stream"; | |
throw std::runtime_error(os.str()); | |
} | |
return result; | |
} | |
int main() | |
{ | |
std::stringstream input; | |
input << "1,2" << std::endl | |
<< "3,4" << std::endl; | |
Ast::Foos foos(Parse(input)); | |
for (auto foo : foos) | |
std::cout << foo.one() << "," << foo.two() << std::endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment