Skip to content

Instantly share code, notes, and snippets.

@ghaskins
Created October 2, 2015 02:29
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 ghaskins/c492171f5b2a8197bf48 to your computer and use it in GitHub Desktop.
Save ghaskins/c492171f5b2a8197bf48 to your computer and use it in GitHub Desktop.
// 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