/////////////////////////////////////////////////////////////////////////////// // // Date : 04/03/06 // Filename : string_parser.cpp // Description : 'Unmangledname' Function Protype String parser // application in specific to Windows (as of now). // What i mean by that is it can only parse INPUT string // is from a data structure in a Win32 DLL as // presented below. Also look at the spaces... // // Usage : // INPUT STRING: "unsiged long const * __cdecl Func1_(int,unsigned char const *)" // OUTPUT: (in vector) // 0 : 'unsiged long const * ' // 1 : '__cdecl' // 2 : 'Func1_' // 3 : 'int' // 4 : 'unsigned char const *' // // NOTE: actual running application may differ with OUTPUT, its bec. i modified // this one... but it works the same... // // Email me : kerbym@driftmark.com /////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #include #include #include #include //#include #include /////////////////////////////////////////////////////////////////////////////// using namespace std; using namespace boost::spirit; /////////////////////////////////////////////////////////////////////////////// struct FunctionSpec { // simple variable spec enum eVarType { VAR_VOID, VAR_BOOL, VAR_INT, VAR_FLOAT, VAR_STRING, VAR_USER,VAR_UNKNOWN, }; // possible calling conventions enum eCallType { CALL_CDECL, CALL_STDCALL, CALL_THISCALL, CALL_THISCALLVARARG, }; typedef std::vector ParamVec; vector params; // temporary parameters vector, since we cant fill vector with enum yet... std::string m_Name; // Function name DWORD m_dwAddress; // Function address eVarType m_ReturnType; // Return Type ParamVec m_ParamTypes; // Parameter type(s) eCallType m_CallType; // Call Type vector v; // another temporary vector to hold strings }; typedef std::vector FunctionVec; FunctionVec g_Functions; // the global set of specifications for exported functions typedef std::map map_vartype; typedef std::map map_caltype; class list_actor { public: list_actor (FunctionSpec &spec_) : spec(spec_) {} template void operator() (ActionIterT const &first, ActionIterT const &last) const { cout << "list_actor operator()...\n"; std::string s(first, last-first); spec.v.push_back(s); } private: typedef list_actor self_t; FunctionSpec &spec; map_vartype m_map_var; // Variable Types Map map_caltype m_map_cal; // Call Types Map // Dictionary // Not yet working.... void fill_maps( int i1 ) { cout << "filling maps...\n"; m_map_var.insert(make_pair(FunctionSpec::VAR_BOOL, "bool")); } // This will be for assigning tags to FunctionSpec's enum members // using the string we get from operator()..., not yet working void check() { string s; map_vartype::iterator it; for ( it = m_map_var.begin() ; it != m_map_var.end() ; ++it ){ //s = it->first; //cout << "s = " << it->second << "\n"; } } }; void foo( int i1 ) { cout << "BOOST! " << i1 << "\n"; } /////////////////////////////////// // // Function prototype parser (working) // ////////////////////////////////// bool x_parser4(char const* str, FunctionSpec& spec) { int i1 = 5; (boost::bind(&foo, _1))(i1); vector v; // Grammar rules rule<> rettype, datatype, calltype, params, group, function; rule<> top; // Begin Grammar top = rettype >> calltype >> *space_p >> function >> group; group = '(' >> params >> ')'; calltype = lexeme_d[ (str_p("__")) >> *(alnum_p)][push_back_a(spec.v) ]; rettype = lexeme_d[ (alpha_p) >> *(alnum_p | space_p | ch_p('*')) ][list_actor(spec)]; datatype = lexeme_d[ (alpha_p) >> *(alnum_p | space_p | ch_p('*')) ][push_back_a(spec.params)]; function = lexeme_d[ (alpha_p | ch_p('_')) >> *(alnum_p | ch_p('_')) ][assign_a(spec.m_Name)]; params = *( datatype % ch_p(',') ); parse_info<> r = parse(str, ( top )); return true; } //////////////////////////////////////////////////////////////////////////// // // Main program // //////////////////////////////////////////////////////////////////////////// int main() { cout << "-------------------------\n"; cout << " Parser by Kerby \n"; cout << "-------------------------\n"; cout << "Ex. type: void __cdecl MyFunc(int,int)\n"; string str; while (getline(cin, str)) { if (str.empty() || str[0] == 'q' || str[0] == 'Q') break; FunctionSpec spec; x_parser4(str.c_str(), spec); cout << "NAME = '" << spec.m_Name << "'\n"; for (vector::size_type i = 0; i < spec.v.size(); ++i) cout << i << ": " << "'" << spec.v[i] << "'" << endl; for (vector::size_type i = 0; i < spec.params.size(); ++i) cout << i << ": " << "'" << spec.params[i] << "'" << endl; } cout << "Bye... :-) \n\n"; return 0; }