Spirit grammar definition

Hi, I have a problem with a spirit parser. My grammar/skipgrammer and its definition are working, but only on the first spirit::parse() call. My function around parse() looks like this. void function() { string str; file.open(); file >> str; file.close(); vector<string> library; vector<Group> groups; MyGrammar g( library, groups ); MySkipGrammar s(); boost::spirit::parse( str, g, s ); // library and groups are now filled properly setLibrary( library ); setGroups( groups ); } This works fine, as long as i call function() only one time. The second time i call the function ( even if the parse data(str) is the same ), the parse() function failes with a memory error ( access to 0xcccccccc ( MSVCs default debug value ) ) I have tried to debug it and found the following. It seems that in the second call, the inner class(definition) of MyGrammer is still referencing the old data. And the first access in one rule actor to library or groups failes with memory access to 0xcccccccc. And even if a create MyGrammar on the heap ( MyGrammar* g = new... ) it seems that the inner definition class is not created the second time. I have set breakpoints to a self created actor, and the actor is only created once on the first function call. Every other function() call other than the first does not create the actors, so they are still hold the old object references. Any ideas where the error could be? And why are the actors only created once? P.S.: I`m using MSVC.net 2003

"Nico Massi" <desertswat@gmx.de> wrote in message news:opsbebwvw8yic797@swat...
Hi,
I have a problem with a spirit parser. My grammar/skipgrammer and its definition are working, but only on the first spirit::parse() call.
My function around parse() looks like this.
void function() { string str; file.open(); file >> str; file.close(); vector<string> library; vector<Group> groups;
MyGrammar g( library, groups ); MySkipGrammar s(); boost::spirit::parse( str, g, s );
// library and groups are now filled properly setLibrary( library ); setGroups( groups ); }
This works fine, as long as i call function() only one time. The second time i call the function ( even if the parse data(str) is the same ), the parse() function failes with a memory error ( access to 0xcccccccc ( MSVCs default debug value ) )
I have tried to debug it and found the following. It seems that in the second call, the inner class(definition) of MyGrammer is still referencing the old data. And the first access in one rule actor to library or groups failes with memory access to 0xcccccccc.
Without seeing MyGrammar and MySkipGrammar your not likely to get much help. Post a stripped down to the minimally complete/compilable code sample. Also you might want to post on the spirit mailing lists. Jeff F

Ok here is a slightly simplified version of MyGrammar ( MySkipGrammer is simply space_p | comment_p( ';' ) ). But it also generates the same error. The first run works as expected and the second run seems to still hold old references. class MyGrammar : public boost::spirit::grammar<MyGrammar> { public: std::vector<Group>& vGroups; std::vector<std::string>& vLibraries; MyGrammar( std::vector<std::string>& rvLibraries, std::vector<Group>& rvGroups ) : vGroups(rvGroups), vLibraries(rvLibraries) { } template <typename ScannerT> struct definition { // rule deklarations here Group kCurrentGroup; std::vector<Group> vTmpGroups; std::list<Group> vFullGroups; std::vector<std::string vLibs; definition( const MyGrammar& rkSelf ) { startRule = (*group)[ copy_a( rkSelf.vGroups, vFullGroups ) ][ copy_a( rkSelf.vLibraries, vLibs ) ]; group = groupID[ assign_a( kCurrentGroup.id, id ) ] >> ch_p( '{' ) >> groupDefinition >> *( eps_p(as_lower_d[str_p("group")])[ push_back_a( vTmpGroups, kCurrentGroup ) ] >> group[ my_assign_a( kCurrentGroup, vTmpGroups ) ][ pop_back_a( vTmpGroups ) ] ) >> ch_p( '}' )[ push_front_a( vFullGroups, kCurrentGroup ) ]; groupID = as_lower_d[ str_p( "group" ) ] >> confix_p( '(', uid[ assign_uid( id ) ], ')' ); groupDefinition = name[ assign_a( kCurrentGroup.name, strName ) ] >> description[ assign_a( kCurrentGroup.description, desc ) ]; name = as_lower_d[ str_p( "name" ) ] >> ch_p( '=' ) >> identifier[ assign_a( strName ) ]; description = as_lower_d[ str_p( "description" ) ] >> ch_p( '=' ) >> confix_p( '"', (*anychar_p)[ assign_a( desc ) ], '"' ); library = as_lower_d[ str_p( "library" ) ] >> ch_p( '=' ) >> identifier[ assign_a( lib ) ][ push_back_unique_a( vLibs ) ]; identifier = lexeme_d [* ( range_p( 'a', 'z' ) | range_p( 'A', 'Z' ) | ch_p('_') ) ]; uid = lexeme_d [ repeat_p(8)[ range_p( 'A', 'F') | range_p( '0', '9' ) ] >> ch_p( '-' ) >> repeat_p(4)[ range_p( 'A', 'F') | range_p( '0', '9' ) ] >> ch_p( '-' ) >> repeat_p(4)[ range_p( 'a', 'f') | range_p( '0', '9' ) ] >> ch_p( '-' ) >> repeat_p(4)[ range_p( 'A', 'F') | range_p( '0', '9' ) ] >> ch_p( '-' ) >> repeat_p(12)[ range_p( 'A', 'F') | range_p( '0', '9' )] ]; } const rule<ScannerT>& start() const { return startRule; } } }

Hi, First of all, the Spirit list is the proper forum. Please post Spirit related questions there: Spirit-general mailing list Spirit-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spirit-general Nico Massi wrote:
Ok here is a slightly simplified version of MyGrammar ( MySkipGrammer is simply space_p | comment_p( ';' ) ). But it also generates the same error. The first run works as expected and the second run seems to still hold old references.
[...] Did you #define BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE ? If not, then you've probably hit a bug. Let's discuss this in Spirit's list. Cheers, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net
participants (3)
-
Jeff Flinn
-
Joel de Guzman
-
Nico Massi