Sign in to follow this  
choffstein

Parse error issue

Recommended Posts

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.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
You didn't say on which line (and in which file) the parse error occurred.
If it was on one of the lines:

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

it may be because NULL is not defined. Replace all NULLs with 0 (zero). Alternatively you can include the header where NULL is defined (don't know which one), but using zero instead is recommended for C++ code (0 is a valid value for a pointer of any type).

If this didn't help you, please post the filename and line number where the error occurred.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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;
}

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
Error is in:
ObjectFactory *of = ConcreteFactory::getObjectFactory();
.
Ill see what I can do about preprocessor output (I'm new to xcode...)

Thanks.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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...

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this