enter code here
#include <QtCore/QCoreApplication>
#include <boost/tuple/tuple.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <iostream>
#include <string>
#include <list>
#include <map>
#define CODE_CPP_KEYWORD_ENUM "enum"
namespace haha
{
struct CPPCodeEnum
{
::std::string enumName;
::std::map<::std::string,int> enumMembers;
};
}
namespace haha
{
namespace fusion = boost::fusion;
namespace phoenix = boost::phoenix;
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
template <typename Iterator>
struct CPPCodeEnumGrammar
: qi::grammar<Iterator,CPPCodeEnum(),ascii::space_type >
{
CPPCodeEnumGrammar()
: CPPCodeEnumGrammar::base_type(mRuleEntrence)
{
using qi::_val;
using qi::_1;
using qi::_2;
using qi::lit;
using qi::lexeme;
using qi::space;
using ascii::char_;
using ascii::string;
mRuleCPPValueName %= lexeme[+(qi::alpha|char_('_'))>>*(qi::alpha|char_('_')|qi::digit) ];
mRuleMemberValue =(mRuleCPPValueName>>qi::omit[char_("=")]>>qi::int_)
[
phoenix::bind(&::std::pair<::std::string,int>::first, _val)=_1,
phoenix::bind(&::std::pair<::std::string,int>::second, _val)=_2,
phoenix::ref(mTempValue)=_2+1
];
mRuleMemberDefaultValue = mRuleCPPValueName
[
phoenix::bind(&::std::pair<::std::string,int>::first, _val)=_1,
phoenix::bind(&::std::pair<::std::string,int>::second, _val)=phoenix::ref(mTempValue),
phoenix::ref(mTempValue)++
];
mRuleEntrence =
lexeme[lit(CODE_CPP_KEYWORD_ENUM)[phoenix::ref(mTempValue)=0]>>+space]>>
*mRuleCPPValueName[phoenix::bind(&CPPCodeEnum::enumName, _val)= _1]>>
char_("{")>>
*(((mRuleMemberValue[phoenix::insert(phoenix::bind(&CPPCodeEnum::enumMembers, _val), _1)])|
mRuleMemberDefaultValue[phoenix::insert(phoenix::bind(&CPPCodeEnum::enumMembers, _val), _1)])
%',')>>
-char_(",")>>
char_("}");
}
int mTempValue;
qi::rule<Iterator,::std::pair<::std::string,int>(),ascii::space_type> mRuleMemberValue;
qi::rule<Iterator,::std::pair<::std::string,int>(),ascii::space_type> mRuleMemberDefaultValue;
qi::rule<Iterator, std::string(),ascii::space_type> mRuleCPPValueName;
qi::rule<Iterator, CPPCodeEnum(),ascii::space_type> mRuleEntrence;
};
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
::std::string teststr="enum _0_my_e_name_1233 {m1,m2,m3 ,m4 =5 ,m5 =90,m6}";
using boost::spirit::ascii::space;
std::string::const_iterator iter = teststr.begin();
std::string::const_iterator end = teststr.end();
haha::CPPCodeEnumGrammar<std::string::const_iterator> myCPPCodeEnumGrammar;
haha::CPPCodeEnum data;
bool r = phrase_parse(iter, end, myCPPCodeEnumGrammar, space, data);
return a.exec();
}
I finally reached! (^_^) This is truly a C ++ parser and is fully compliant with the C ++ standard. He is able to parse code like this "enum _0_my_e_name_1233 {m1, m2, m3, m4 = 5, m5 = 90, m6}."