Skip to main content
gamedev.net
🔒 Locked

Parse error issue

Started by choffstein 19 replies 2.6k views
Original Post
choffstein
choffstein
I am getting a parse error, but I can't figure out why. I have a static class defined as such: ConcreteFactory.h

/*
 *  ConcreteFactory.h
 *  Symphony Engine
 *
 *  Created by Corey Hoffstein on 8/31/05.
 *  Copyright 2005 Corey Hoffstein. All rights reserved.
 *
 */

#ifndef __CONCRETEFACTORY_H__
#define __CONCRETEFACTORY_H__

//#include "precompiled.h"

#include "Logger.h"
#include "AudioCore.h"
#include "InputManager.h"
#include "ResourceCore.h"
#include "ObjectFactory.h"

namespace Symphony
{
	class ConcreteFactory
	{
		private:
			static Logger *l;
			static AudioCore *ac;
			static InputManager *im;
			static ResourceCore *rc;
			static ObjectFactory *of;

		public:
			ConcreteFactory()
			{
			}
			~ConcreteFactory()
			{
			}
			
			static inline void createFactory()
			{
				l = new Logger();
				ac = new AudioCore();
				im = new InputManager();
				rc = new ResourceCore();
				of = new ObjectFactory();
			}
			
			static inline void destroyFactory()
			{
				//delete our audio core, input manager, and resource core
				if(ac) delete ac;
				if(im) delete im;
				if(rc) delete rc;
				
				//delete the object factory
				if(of) delete of;
				
				//close our logger
				if(l) delete l;
			}
			
			static inline Logger *getLogger()
			{
				return l;
			}
			static inline AudioCore *getAudioCore()
			{
				return ac;
			}
			static inline InputManager *getInputManager()
			{
				return im;
			}
			static inline ResourceCore *getResourceCore()
			{
				return rc;
			}
			static inline ObjectFactory *getObjectFactory()
			{
				return of;
			}
	};	
}
#endif

ConcreteFactory.cpp

/*
 *  ConcreteFactory.cpp
 *  Symphony Engine
 *
 *  Created by Corey Hoffstein on 8/31/05.
 *  Copyright 2005 Corey Hoffstein. All rights reserved.
 *
 */

#include "ConcreteFactory.h"

using namespace Symphony;

Logger *ConcreteFactory::l = NULL;
AudioCore *ConcreteFactory::ac = NULL;
InputManager *ConreteFactory::im = NULL;
ResourceCore *ConreteFactory::rc = NULL;
ObjectFactory *ConreteFactory::of = NULL;

Everything seems fine to me -- maybe not? Anyway, so I try to use it like this:

#include "ConcreteFactory.h"

...
ptr = ConcreteFactory::getObjectFactory()->createInstance(name, ptr);

And this is the error: error: parse error before `;' token Thoughts about this? Thanks.
choffstein
choffstein
Whoops, sorry about that. On this line:

ptr = ConcreteFactory::getObjectFactory()->createInstance(name, ptr);

It was used before in a singleton instance, like this: ObjectFactory::getInstance()->, so I know that the issue is with the new ConcreteFactory.

Thanks.
Enigma
Enigma
I assume the error occured on the line posted in the third sourcecode box. Did you bring the name ConcreteFactory into scope using a using declaration?

Enigma
antareus
antareus
using namespace Symphony;Logger *ConcreteFactory::l = NULL;AudioCore *ConcreteFactory::ac = NULL;InputManager *ConreteFactory::im = NULL;ResourceCore *ConreteFactory::rc = NULL;ObjectFactory *ConreteFactory::of = NULL;

Don't do this. Using directives merely import the requested symbols into the current scope. They don't actually place things in there. Try this instead:
namespace Symphony{Logger *ConcreteFactory::l = NULL;AudioCore *ConcreteFactory::ac = NULL;InputManager *ConreteFactory::im = NULL;ResourceCore *ConreteFactory::rc = NULL;ObjectFactory *ConreteFactory::of = NULL;}
--God has paid us the intolerable compliment of loving us, in the deepest, most tragic, most inexorable sense.- C.S. Lewis
choffstein
choffstein
The code it is within is within the Symphony namespace as well. What I mean by that is that code is from within a class, which is also within the Symphony namespace -- as such:
#include "ConcreteFactory.h"namespace Symphony{    class SomeClass    {        private:             ....        public:             inline void someFunction()             {                  ...                  ptr = ConcreteFactory::getObjectFactory()->createInstance(name, ptr);             }    };}



Thanks for the thoughts so far.


EDIT: antareus -- unfortunately, no effect.
Enigma
Enigma
I don't see any logic errors in what you've posted so far (barring the issue antareus pointed out - good spot). Can you try breaking the function down into:
ObjectFactory *of = ConcreteFactory::getObjectFactory();
ptr = of->createInstance(name, ptr);

to narrow down where the error is.

The only other thing I can think to suggest without seeing more code is to examine the preprocessor output to check that your inclusion guards haven't been accidentally duplicated in another file or tromped on by a compiler-defined symbol (since it's technically a name reserved for the implementation).

Enigma
choffstein
choffstein
Error is in:
ObjectFactory *of = ConcreteFactory::getObjectFactory();
.
Ill see what I can do about preprocessor output (I'm new to xcode...)

Thanks.
choffstein
choffstein
I hate bumping, but I am really stuck here.....*bump*
Enigma
Enigma
How big is the source? Can you post a zip or cut it down to a small enough test case?

Enigma
choffstein
choffstein
The source is wayyy too big to zip and post to make it helpful. I tried to cut it down as small as possible. Here is some more source from the same file that is getting the error:
inline ObjectFactorySmartPtr(string iClassName, bool create=true){	if(create)	{		ptr = ConcreteFactory::getObjectFactory()->createInstance( iClassName.c_str(), ptr);		//cout << "Constructing (string): " << ptr->Type() << "(" << ptr->getID() << ") with current references of " << ptr->GetReferences() << " after creation" << endl;	}	else	{		ptr = NULL;	}        className = iClassname;}


The error is on the "ptr =" line.

I am also getting another error, though I figure it is unrelated, perhaps it isn't. Here is what it says:
Audio.h:82: error: invalid operands of types const char[34]' and const char*' to binary operator<<'
Audio.h:82: error:
DEBUG_LOG' undeclared (first use this function)


On this line:
DEBUG_LOG(Logger::ERROR, "Could not find audio sound file: " << fileName);

The file includes "precompiled.h", which includes "LoggerInterface.h", which has this source:
/* *  LoggerInterface.h *  Symphony Engine * *  Created by Corey Hoffstein on 8/31/05. *  Copyright 2005 Corey Hoffstein. All rights reserved. * */#include "ConcreteFactory.h"using namespace Symphony;//OMG, THE MACRO HACKERY BURNS MY EYES!  WHYYYYYYYYYYYYYY?#define LOG(type, a)  (*ConcreteFactory::getLogger())  << "<TR><TD>" << Logger::timeStamp() << "</TD><TD>" << __PRETTY_FUNCTION__ << "</TD>"; 								if(type == Logger::INFO) 										(*ConcreteFactory::getLogger()) << "<TD bgcolor=\"#FFFFFF\">"; 								else if(type == Logger::WARNING)										(*ConcreteFactory::getLogger()) << "<TD bgcolor=\"#FFFF00\">"; 								else if(type == Logger::ERROR) 										(*ConcreteFactory::getLogger()) << "<TD bgcolor=\"#FF0000\">"; 								(*ConcreteFactory::getLogger()) <<  __FILE__ << ": " << __LINE__ << " -- " << a << "</TD></TR>"#ifdef DEBUG	#define DEBUG_LOG(type, a)  (*ConcreteFactory::getLogger())  << "<TR><TD>" << Logger::timeStamp() << "</TD><TD>" << __PRETTY_FUNCTION__ << "</TD>"; 								if(type == Logger::INFO) 										(*ConcreteFactory::getLogger()) << "<TD bgcolor=\"#FFFFFF\">"; 								else if(type == Logger::WARNING)										(*ConcreteFactory::getLogger()) << "<TD bgcolor=\"#FFFF00\">"; 								else if(type == Logger::ERROR) 										(*ConcreteFactory::getLogger()) << "<TD bgcolor=\"#FF0000\">"; 								(*ConcreteFactory::getLogger()) << __FILE__ << ": " << __LINE__ << " -- " << a << "</TD></TR>"#else	#define DEBUG_LOG(type, a)#endif


Any ideas? Thanks for the help so far.
Enigma
Enigma
Is ObjectFactorySmartPtr defined within the class definition (i.e.:
class ObjectFactorySmartPtr{	public:		inline ObjectFactorySmartPtr(string iClassName, bool create=true)		{			// code		}}
)
Is ptr definitely a valid symbol, i.e. you haven't forgotten to declare it as a class member or misspelt it?

I'm afraid without being able to compile some source myself and try things this is going to be a very slow process. As to you second error - can you post the declarations for ObjectFactory's operator<<(s)?

Enigma
choffstein
choffstein
Ptr is definitely defined. Everything worked before I tried using the concrete factory and used singleton's instead. Here is what the Logger class looks like:
/* *  Logger.h *  Symphony Engine * *  Created by Corey Hoffstein on 6/15/05. *  Copyright 2005 Corey Hoffstein. All rights reserved. * */#ifndef __LOGGER_H__#define __LOGGER_H__#include "precompiled.h"#include "ConcreteFactory.h"#define BUILD_VERSION "VERSION: " << VERSION << " -- DATE: " << __DATE__ << " -- TIME: "<< __TIME__namespace Symphony{	class Logger	{		private:			ofstream outFile;					public:			enum LOG_TYPE			{				INFO = 0,				WARNING,				ERROR			};						Logger();			Logger(string fileName);			~Logger();						void openLog(std::string fileName);			void closeLog();						static string timeStamp();						template <class T>			ofstream & operator << (T obj)			{				outFile << obj;				return outFile;			}	};}#endif


It worked as well before the concrete factory was used...

Thanks so far guys
Enigma
Enigma
Hmm. Time to get the big guns out. Can you add a random string to the beginning of your ConcreteFactory class name (i.e. djkohjtConcreteFactory) and the same with your inclusion guard for the header and implementation files (i.e.
#ifndef djkohjt__CONCRETEFACTORY_H__
#define djkohjt__CONCRETEFACTORY_H__
)
Then double check that you've renamed in all applicable places. That should rule out name conflicts.

Enigma
choffstein
choffstein
I did, renamed everything that was ConcreteFactory to djkohjtConcreteFactory. Same errors.
Enigma
Enigma
Just a thought, can you try changing ptr = ConcreteFactory::getObjectFactory()->createInstance( iClassName.c_str(), ptr); to ptr = Symphony::ConcreteFactory::getObjectFactory()->createInstance( iClassName.c_str(), ptr); (after renaming ConcreteFactory back). If your compiler complains that Symphony isn't a member of Symphony then all well and good, otherwise you probably have an improperly nested namespace somewhere.

Enigma
choffstein
choffstein
Yep: error: no class template named ConcreteFactory' in Symphony'. Everything really does seem fine. This is so freaking weird.

Thanks for all the help so far man.
Enigma
Enigma
You don't have any using declarations in any of your header files do you? And can you double check your namespace scoping and spelling. Another test would be to see what happens if you add a second minimal class defintion for ConcreteFactory (i.e. just define a static member function named getObjectFactory which takes and returns void) just before the definition of ObjectFactorySmartPtr.

Enigma
choffstein
choffstein
I tried two things. The first was a private class in ObjectFactorySmartPointer with a static member function:
static inline void getObjectFactory(){ return; }

The compiler stopped complaining about parsing errors, but started complaining about not ignoring void. So that means that somewhere along the line, for some reason, my compiler isn't recognizing the actual ConcreteFactory class, which is weird.

Another thing I tried was adding another static member function by the same name in ConcreteFactory that took and returned void -- I only recieved one error about not being able to overload the functions -- which definitely makes me think that in ObjectFactorySmartPtr, it cannot find ConcreteFactory.

So I checked my name spaces -- everything seems fine. I made a slight change to one of my files:
LoggerInterface.h
/* *  LoggerInterface.h *  Symphony Engine * *  Created by Corey Hoffstein on 8/31/05. *  Copyright 2005 Corey Hoffstein. All rights reserved. * */#ifndef __LOGGERINTERFACE_H__#define __LOGGERINTERFACE_H__#include "ConcreteFactory.h"namespace Symphony{	//OMG, THE MACRO HACKERY BURNS MY EYES!  WHYYYYYYYYYYYYYY?	#define LOG(type, a)  (*ConcreteFactory::getLogger())  << "<TR><TD>" << Logger::timeStamp() << "</TD><TD>" << __PRETTY_FUNCTION__ << "</TD>"; 									if(type == Logger::INFO) 											(*ConcreteFactory::getLogger()) << "<TD bgcolor=\"#FFFFFF\">"; 									else if(type == Logger::WARNING)											(*ConcreteFactory::getLogger()) << "<TD bgcolor=\"#FFFF00\">"; 									else if(type == Logger::ERROR) 											(*ConcreteFactory::getLogger()) << "<TD bgcolor=\"#FF0000\">"; 									(*ConcreteFactory::getLogger()) <<  __FILE__ << ": " << __LINE__ << " -- " << a << "</TD></TR>"	#ifdef DEBUG		#define DEBUG_LOG(type, a)  (*ConcreteFactory::getLogger())  << "<TR><TD>" << Logger::timeStamp() << "</TD><TD>" << __PRETTY_FUNCTION__ << "</TD>"; 									if(type == Logger::INFO) 											(*ConcreteFactory::getLogger()) << "<TD bgcolor=\"#FFFFFF\">"; 									else if(type == Logger::WARNING)											(*ConcreteFactory::getLogger()) << "<TD bgcolor=\"#FFFF00\">"; 									else if(type == Logger::ERROR) 											(*ConcreteFactory::getLogger()) << "<TD bgcolor=\"#FF0000\">"; 									(*ConcreteFactory::getLogger()) << __FILE__ << ": " << __LINE__ << " -- " << a << "</TD></TR>"	#else		#define DEBUG_LOG(type, a)	#endif}#endif


Basically added inclusion guards and put it under the symphony namespace. No changes...
choffstein
choffstein
Okay, I think the error is with circular includes. This is what I mean:

I include precompiled.h, which includes Logger.h, which includes LoggerInterface.h, which includes ConcreteFactory.h which includes Logger.h, trying to use the Logger class. Well, since the inclusion guard is already set off, it skips Logger.h, tries to use the logging class, but since the #includes haven't unwound yet, it hasn't been defined -- so there is no way to use it.

Anyone know a way I can get around this? Thanks.
Enigma
Enigma
Ah yes, that could well be the problem. Why don't you break your ConcreteFactory::createFactory and ConcreteFactory::destroyFactory implementations out into ConcreteFactory.cpp file. They're dealing with dynamic memory and will be called infrequently, so there's really no need to try and inline them anyway. That would allow you to just forward declare the various classes in ConcreteFactory.h and hopefully break the circular includes.

Enigma

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.