This is a do-nothing lexer&parser -- it returns the string read. I would like to have this extended to be able to deal with a C++-like include statement. I can imagine how to do this -- but I would like to know if there is some easier or already available way. If I would have to do this, I would implement my own iterator (to be passed to the lexer). This iterator would contain
- an index into a string (potentially using -1 to indicate end() iterator)
- a pointer to this string
The lexer on encountering some include statement would insert the file into the string at the current position overwriting the include statement. How would you do this?
Here is my do-nothing lexer/parser:
#include <boost/phoenix.hpp>
#include <boost/bind.hpp>
#include <boost/fusion/adapted/struct.hpp>
#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/qi.hpp>
#include <algorithm>
#include <iostream>
#include <string>
#include <utility>
#include <vector>
namespace lex = boost::spirit::lex;
namespace qi = boost::spirit::qi;
namespace phoenix = boost::phoenix;
template<typename Lexer>
class lexer:public lex::lexer<Lexer>
{ public:
typedef lex::token_def<char> char_token_type;
char_token_type m_sChar;
//lex::token_def<lex::omit> m_sInclude;
lexer(void)
: m_sChar(".")//,
//m_sInclude("^#include \"[^\"]*\"")
{ this->self += m_sChar;
}
};
template<typename Iterator>
class grammar : public qi::grammar<Iterator, std::string()>
{ public:
qi::rule<Iterator, std::string()> m_sStart;
template<typename Tokens>
explicit grammar(Tokens const& tokens)
: grammar::base_type(m_sStart)
{ m_sStart %= *tokens.m_sChar >> qi::eoi;
}
};
int main(int, char**)
{
typedef lex::lexertl::token<std::string::const_iterator, boost::mpl::vector<char> > token_type;
typedef lexer<lex::lexertl::actor_lexer<token_type> > expression_lexer_type;
typedef expression_lexer_type::iterator_type expression_lexer_iterator_type;
typedef grammar<expression_lexer_iterator_type> expression_grammar_type;
expression_lexer_type lexer;
expression_grammar_type grammar(lexer);
const std::string s_ac = "this is a test\n\
#include \"test.dat\"\n\
";
std::string s;
auto pBegin = std::begin(s_ac);
lex::tokenize_and_parse(pBegin, std::end(s_ac), lexer, grammar, s);
}