unable to get a parser&lexer going with token types other than int, double or std::string

"Foelsche, Peter" <[email protected]>
Newsgroups gmane.comp.parsers.spirit.general
Message-ID <[email protected]>
Dear All,

Always when attempting to have my lexer return other types than std::string or int or double I'm getting compiler errors.
I was joking that potentially I need to serialize my objects into/from a std::string in order to use spirit.
See attached my code example.
At the top there is a typedef:

Typedef std::string token;

One can change this typedef to a boost::variant and immediately everything breaks.
I've been fighting with this for days now.
Thanks for any help.

Peter

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot

_______________________________________________
Spirit-general mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/spirit-general
spirit_error.cpp (text/plain, 14.2 KB)
// spirit_error.cpp : Defines the entry point for the console application.
//
#include <boost/intrusive_ptr.hpp>
#include <boost/smart_ptr/intrusive_ref_counter.hpp>
#include <boost/variant.hpp>
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/phoenix/object.hpp>
#include <boost/spirit/include/qi_char_class.hpp>
#include <boost/spirit/include/phoenix_bind.hpp>
#include <boost/mpl/index_of.hpp>
#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/mpl/bool.hpp>

namespace frank
{
typedef std::string TOKEN;
//typedef boost::variant<int, double, std::string> TOKEN;
//typedef double TOKEN;
}
namespace boost
{
namespace spirit
{
namespace traits
{
template<>
struct is_container<frank::TOKEN>:boost::mpl::false_
{
};
namespace detail
{
template<>
struct is_container_of_ranges<frank::TOKEN>:boost::mpl::false_
{
};
}
}
}
}
namespace lex = boost::spirit::lex;
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;


namespace frank
{
class ref_counter:public boost::intrusive_ref_counter<ref_counter>
{	public:
	virtual ~ref_counter(void)
	{
	}
	typedef boost::intrusive_ptr<const ref_counter> intrusivePtr;
	typedef std::vector<intrusivePtr> vectorOfPtr;
};
class symbol:public ref_counter
{	public:
	typedef boost::intrusive_ptr<const symbol> symbolPtr;
	typedef std::vector<symbolPtr> symbolVector;
	struct push_scope
	{	push_scope()
		{
		}
		~push_scope(void)
		{
		}
		typedef std::shared_ptr<push_scope> ptr;
	};
};
class nature:public symbol
{	public:
	enum enumAttribute
	{	eAbstol,
		eAccess,
		eDDT,
		eIDT,
		eUnits
	};
	struct empty
	{	bool operator<(const empty&) const
		{	return false;
		}
		friend std::ostream &operator<<(std::ostream &_r, const empty&)
		{	return _r;
		}
	};
	typedef boost::variant<empty, std::string> attributeValue;
	typedef std::pair<enumAttribute, attributeValue> attributeValuePair;
};
class discipline:public symbol
{	public:
	enum enumDomain
	{	eDiscrete,
		eContinuous
	};
	typedef std::pair<bool, boost::intrusive_ptr<const nature> > CPotentialAndNature;
	struct empty
	{	bool operator<(const empty&) const
		{	return false;
		}
		friend std::ostream &operator<<(std::ostream &_r, const empty&)
		{	return _r;
		}
	};
	typedef boost::variant<empty, CPotentialAndNature, enumDomain> property;
};

class type:public ref_counter
{	public:
	typedef boost::intrusive_ptr<const type> typePtr;
	static typePtr getReal(void);
	static typePtr getString(void);
	static typePtr getInteger(void);
};
struct myIterator:std::iterator<std::random_access_iterator_tag, char, std::ptrdiff_t, const char*, const char&>
{	std::string *m_p;
	std::size_t m_iPos;
	myIterator(void)
		:m_p(nullptr),
		m_iPos(~std::size_t(0))
	{
	}
	myIterator(std::string &_r, const bool _bEnd = false)
		:m_p(&_r),
		m_iPos(_bEnd ? ~std::size_t(0) : 0)
	{
	}
	myIterator(const myIterator &_r)
		:m_p(_r.m_p),
		m_iPos(_r.m_iPos)
	{
	}
	myIterator &operator=(const myIterator &_r)
	{	if (this != &_r)
		{	m_p = _r.m_p;
			m_iPos = _r.m_iPos;
		}
		return *this;
	}
	const char &operator*(void) const
	{	return m_p->at(m_iPos);
	}
	bool operator==(const myIterator &_r) const
	{	return m_p == _r.m_p && m_iPos == _r.m_iPos;
	}
	bool operator!=(const myIterator &_r) const
	{	return m_p != _r.m_p || m_iPos != _r.m_iPos;
	}
	myIterator &operator++(void)
	{	++m_iPos;
		if (m_iPos == m_p->size())
			m_iPos = ~std::size_t(0);
		return *this;
	}
	myIterator operator++(int)
	{	const myIterator s(*this);
		operator++();
		return s;
	}
	myIterator &operator--(void)
	{	--m_iPos;
		return *this;
	}
	myIterator operator--(int)
	{	const myIterator s(*this);
		operator--();
		return s;
	}
	bool operator<(const myIterator &_r) const
	{	if (m_p == _r.m_p)
			return m_iPos < _r.m_iPos;
		else
			return m_p < _r.m_p;
	}
	std::ptrdiff_t operator-(const myIterator &_r) const
	{	return m_iPos - _r.m_iPos;
	}
};
struct onInclude
{	auto operator()(myIterator &_rStart, myIterator &_rEnd) const
	{       // erase what has been matched (the include statement)
		_rStart.m_p->erase(_rStart.m_iPos, _rEnd.m_iPos - _rStart.m_iPos);
		// and insert the contents of the file
		_rStart.m_p->insert(_rStart.m_iPos, "abcd");
		_rEnd = _rStart;
		return lex::pass_flags::pass_ignore;
	}
};
template<typename LEXER>
class lexer:public lex::lexer<LEXER>
{	public:
	lex::token_def<TOKEN> m_sKW_real, m_sKW_integer, m_sKW_string;
	lex::token_def<> m_sLineComment, m_sCComment;
	lex::token_def<> m_sWS;
	lex::token_def<> m_sSemicolon, m_sEqual, m_sColon, m_sInclude, m_sCharOP, m_sCharCP,
		m_sComma;
	lex::token_def<TOKEN> m_sIdentifier, m_sString;
	lex::token_def<TOKEN> m_sReal;
	lex::token_def<TOKEN> m_sInteger;
	lex::token_def<> m_sKW_units, m_sKW_access, m_sKW_idt_nature, m_sKW_ddt_nature, m_sKW_abstol,
		m_sKW_nature, m_sKW_endnature, m_sKW_continuous, m_sKW_discrete,
		m_sKW_potential, m_sKW_flow, m_sKW_domain, m_sKW_discipline, m_sKW_enddiscipline, m_sKW_module,
		m_sKW_endmodule, m_sKW_parameter;
	lexer(void)
		:m_sWS("[ \\t\\n\\r]+"),
		m_sKW_parameter("\"parameter\""),
		m_sKW_real("\"real\""),
		m_sKW_integer("\"integer\""),
		m_sKW_string("\"string\""),
		m_sLineComment("\\/\\/[^\\n]*"),
		m_sCComment("\\/\\*"
			"("
				"[^*]"
					"|" "[\\n]"
					"|" "([*][^/])"
			")*"
			"\\*\\/"),
		m_sSemicolon("\";\""),
		m_sEqual("\"=\""),
		m_sColon("\":\""),
		m_sCharOP("\"(\""), 
		m_sCharCP("\")\""),
		m_sComma("\",\""),
		m_sIdentifier("[a-zA-Z_]+[a-zA-Z0-9_]*"),
		m_sString("[\\\"]"
			//"("
			//	"(\\[\"])"
			//	"|"
				//"[^\"]"
			//")*"
			"[^\\\"]*"
			"[\\\"]"),
		m_sKW_units("\"units\""),
		m_sKW_access("\"access\""),
		m_sKW_idt_nature("\"idt_nature\""),
		m_sKW_ddt_nature("\"ddt_nature\""),
		m_sKW_abstol("\"abstol\""),
		m_sKW_nature("\"nature\""),
		m_sKW_endnature("\"endnature\""),
		m_sKW_continuous("\"continuous\""),
		m_sKW_discrete("\"discrete\""),
		m_sKW_domain("\"domain\""),
		m_sKW_discipline("\"discipline\""),
		m_sKW_enddiscipline("\"enddiscipline\""),
		m_sKW_potential("\"potential\""),
		m_sKW_flow("\"flow\""),
//realnumber      ({uint}{exponent})|((({uint}\.{uint})|(\.{uint})){exponent}?)
//exponent        [Ee][+-]?{uint}
//uint            [0-9][_0-9]*

		m_sReal("({uint}{exponent})"
			"|"
				"("
					"(({uint}[\\.]{uint})|([\\.]{uint})){exponent}?"
				")"
		),
		m_sInteger("{uint}"),
		m_sInclude("\"`include\""),
		m_sKW_module("\"module\""),
		m_sKW_endmodule("\"endmodule\"")
	{	this->self.add_pattern
			("uint", "[0-9]+")
			("exponent", "[eE][\\+\\-]?{uint}");
		this->self = m_sSemicolon
			| m_sEqual
			| m_sColon
			| m_sCharOP
			| m_sCharCP
			| m_sComma
			| m_sString
			| m_sKW_real
			| m_sKW_integer
			| m_sKW_string
			| m_sKW_parameter
			| m_sKW_units
			| m_sKW_access
			| m_sKW_idt_nature
			| m_sKW_ddt_nature
			| m_sKW_abstol
			| m_sKW_nature
			| m_sKW_endnature
			| m_sKW_continuous
			| m_sKW_discrete
			| m_sKW_domain
			| m_sKW_discipline
			| m_sKW_enddiscipline
			| m_sReal
			| m_sInteger
			| m_sKW_potential
			| m_sKW_flow
			| m_sKW_module
			| m_sKW_endmodule
			| m_sIdentifier
			| m_sInclude [ lex::_state = "INCLUDE" ]
			;
		this->self("INCLUDE") += m_sString [
			lex::_state = "INITIAL", lex::_pass = boost::phoenix::bind(onInclude(), lex::_start, lex::_end)
		];
		this->self("WS") = m_sWS
			| m_sLineComment
			| m_sCComment
			;
	}
};
template<typename Iterator, typename Lexer>
class natureParser:public qi::grammar<Iterator, TOKEN(void), qi::in_state_skipper<Lexer> >
{	qi::rule<Iterator, TOKEN(void), qi::in_state_skipper<Lexer> > m_sStart;
	qi::rule<Iterator, TOKEN(void), qi::in_state_skipper<Lexer> > m_sProperty;
	qi::rule<Iterator, TOKEN(), qi::in_state_skipper<Lexer> > m_sName;
	public:
	template<typename Tokens>
	natureParser(const Tokens &_rTokens)
		:natureParser::base_type(m_sStart)
	{	m_sProperty = ((_rTokens.m_sKW_units
				>> _rTokens.m_sEqual
				>> _rTokens.m_sString
				>> _rTokens.m_sSemicolon
				)[qi::_val = boost::phoenix::bind([](){return TOKEN();})]
			| (_rTokens.m_sKW_access
				>> _rTokens.m_sEqual
				>> _rTokens.m_sIdentifier
				>> _rTokens.m_sSemicolon
				)[qi::_val = boost::phoenix::bind([](){return TOKEN();})]
			| (_rTokens.m_sKW_idt_nature
				>> _rTokens.m_sEqual
				>> _rTokens.m_sIdentifier
				>> _rTokens.m_sSemicolon
				)[qi::_val = boost::phoenix::bind([](){return TOKEN();})]
			| (_rTokens.m_sKW_ddt_nature
				>> _rTokens.m_sEqual
				>> _rTokens.m_sIdentifier
				>> _rTokens.m_sSemicolon
				)[qi::_val = boost::phoenix::bind([](){return TOKEN();})]
			| (_rTokens.m_sKW_abstol
				>> _rTokens.m_sEqual
				>> _rTokens.m_sReal
				>> _rTokens.m_sSemicolon
				)
			[qi::_val = boost::phoenix::bind([](){return TOKEN();})]);
		m_sName = (_rTokens.m_sColon >> _rTokens.m_sIdentifier);
		m_sStart = (_rTokens.m_sKW_nature
			>> _rTokens.m_sIdentifier
			>> -m_sName
			>> _rTokens.m_sSemicolon
			>> *m_sProperty
			>> _rTokens.m_sKW_endnature
			)[qi::_val = boost::phoenix::bind([](){return TOKEN();})];
		m_sStart.name("start");
		m_sProperty.name("property");
	}
};
/*
// Conservative discipline
discipline electrical; 
  potential    Voltage;
  flow         Current;
enddiscipline
*/
// a parser for a discipline declaration
template<typename Iterator, typename Lexer>
class disciplineParser:public qi::grammar<Iterator, TOKEN(void), qi::in_state_skipper<Lexer> >
{	qi::rule<Iterator, TOKEN(void), qi::in_state_skipper<Lexer> > m_sStart;
	qi::rule<Iterator, TOKEN(), qi::in_state_skipper<Lexer> > m_sDomain;
	qi::rule<Iterator, TOKEN(void), qi::in_state_skipper<Lexer> > m_sProperty;
	public:
	template<typename Tokens>
	disciplineParser(const Tokens &_rTokens)
		:disciplineParser::base_type(m_sStart)
	{	m_sDomain = _rTokens.m_sKW_continuous
			| _rTokens.m_sKW_discrete
			;
		m_sProperty = (_rTokens.m_sKW_potential >> _rTokens.m_sIdentifier >> _rTokens.m_sSemicolon)[qi::_val = boost::phoenix::bind([](){return TOKEN();})]
			| (_rTokens.m_sKW_flow >> _rTokens.m_sIdentifier >> _rTokens.m_sSemicolon)[qi::_val = boost::phoenix::bind([](){return TOKEN();})]
			| (_rTokens.m_sKW_domain >> m_sDomain >> _rTokens.m_sSemicolon)[qi::_val = boost::phoenix::bind([](){return TOKEN();})]
			;
		m_sStart = (_rTokens.m_sKW_discipline
			>> _rTokens.m_sIdentifier
			>> _rTokens.m_sSemicolon
			>> *m_sProperty
			>> _rTokens.m_sKW_enddiscipline
		)[qi::_val = boost::phoenix::bind([](){	return TOKEN();})];
	}
};
template<typename Iterator, typename Lexer>
class moduleParser:public qi::grammar<Iterator, TOKEN(void), qi::in_state_skipper<Lexer> >
{	public:
	qi::rule<Iterator, TOKEN(void), qi::in_state_skipper<Lexer> > m_sStart;
	qi::rule<Iterator, TOKEN(void), qi::in_state_skipper<Lexer> > m_sModulePortList;
	qi::rule<Iterator, TOKEN(void), qi::in_state_skipper<Lexer> > m_sPortList;
	qi::rule<Iterator, TOKEN(void), qi::in_state_skipper<Lexer> > m_sPort;
	qi::rule<Iterator, TOKEN(void), qi::in_state_skipper<Lexer> > m_sModule;
	
	qi::rule<Iterator, TOKEN(void), qi::in_state_skipper<Lexer> > m_sModuleItemList;
	qi::rule<Iterator, TOKEN(void), qi::in_state_skipper<Lexer> > m_sParameter;
	qi::rule<Iterator, TOKEN(void), qi::in_state_skipper<Lexer> > m_sModuleItem;
	qi::rule<Iterator, TOKEN(void), qi::in_state_skipper<Lexer> > m_sType;
	
	template<typename Tokens>
	moduleParser(const Tokens &_rTokens)
		:moduleParser::base_type(m_sStart)
	{	m_sPort = _rTokens.m_sIdentifier[qi::_val = boost::phoenix::bind([](){	return TOKEN();})];
		m_sPortList = (m_sPort % _rTokens.m_sComma)[qi::_val = boost::phoenix::bind([](){return TOKEN();})];
		m_sModulePortList = _rTokens.m_sCharOP >> m_sPortList >> _rTokens.m_sCharCP;
		m_sModule = _rTokens.m_sKW_module[qi::_val = boost::phoenix::bind([](){	return TOKEN();})];
		m_sType = (_rTokens.m_sKW_real[qi::_val = boost::phoenix::bind([](const TOKEN &_r){return _r;}, qi::_1)]
			| _rTokens.m_sKW_integer[qi::_val = boost::phoenix::bind([](const TOKEN &_r){return _r;}, qi::_1)]
			| _rTokens.m_sKW_string[qi::_val = boost::phoenix::bind([](const TOKEN &_r){return _r;}, qi::_1)])[qi::_val = boost::phoenix::bind([](const TOKEN &_r){return _r;}, qi::_1)];
		m_sParameter = _rTokens.m_sKW_parameter
			>> m_sType
			>> _rTokens.m_sIdentifier
		;
		m_sModuleItem = m_sParameter;
		m_sModuleItemList = *m_sModuleItem[qi::_val = boost::phoenix::bind([](){return TOKEN();})];
		m_sStart = (m_sModule
				>> _rTokens.m_sIdentifier
				>> m_sModulePortList
				>> m_sModuleItemList
				>> _rTokens.m_sKW_endmodule)[qi::_val = boost::phoenix::bind([](){return TOKEN();})];
	}
};
template<typename Iterator, typename Lexer>
class fileParser:public qi::grammar<Iterator, TOKEN(void), qi::in_state_skipper<Lexer> >
{	public:
	disciplineParser<Iterator, Lexer> m_sDiscipline;
	natureParser<Iterator, Lexer> m_sNature;
	moduleParser<Iterator, Lexer> m_sModule;
	qi::rule<Iterator, TOKEN(void), qi::in_state_skipper<Lexer> > m_sStart;
	qi::rule<Iterator, TOKEN(void), qi::in_state_skipper<Lexer> > m_sItem;
	//public:
	template<typename Tokens>
	fileParser(const Tokens &_rTokens)
		:fileParser::base_type(m_sStart),
		m_sNature(_rTokens),
		m_sDiscipline(_rTokens),
		m_sModule(_rTokens)
	{	m_sItem = m_sDiscipline | m_sNature | m_sModule;
		m_sStart = *m_sItem[qi::_val = boost::phoenix::bind([](){return TOKEN();})];
	}
};
}
int main()
{	std::string sInput = "\
nature Current;\n\
  units        = \"A\";\n\
  access       = I;\n\
  idt_nature   = Charge;\n\
  abstol       = 1e-12;\n\
endnature\n\
\n\
// Charge in coulombs\n\
nature Charge;\n\
  units      = \"coul\";\n\
  access     = Q;\n\
  ddt_nature = Current;\n\
  abstol     = 1e-14;\n\
endnature\n\
\n\
// Potential in volts\n\
nature Voltage;\n\
  units      = \"V\";\n\
  access     = V;\n\
  idt_nature = Flux;\n\
  abstol     = 1e-6;\n\
endnature\n\
\n\
discipline electrical;\n\
  potential    Voltage;\n\
  flow         Current;\n\
enddiscipline\n\
";
	typedef lex::lexertl::token<
		frank::myIterator, 
		boost::mpl::vector<
			frank::TOKEN
		>,
		boost::mpl::true_
	> token_type;
	typedef lex::lexertl::actor_lexer<token_type> lexer_type;
	typedef frank::lexer<lexer_type>::iterator_type iterator_type;
	typedef frank::fileParser<iterator_type, frank::lexer<lexer_type>::lexer_def> grammar_type;

	frank::lexer<lexer_type> sLexer;
	grammar_type sParser(sLexer);
	frank::symbol::push_scope sPush;
	auto pStringBegin = frank::myIterator(sInput);
	auto pBegin(sLexer.begin(pStringBegin, frank::myIterator(sInput, true)));
	const auto b = qi::phrase_parse(pBegin, sLexer.end(), sParser, qi::in_state("WS")[sLexer.self]); 
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.