Generating data structures by analyzing text files

I wrote a parser for the game that I am writing to make it easier for myself to change various aspects of the game (for example, character / stage / collision data). For example, I may have a character class as follows:

class Character { public: int x, y; // Character location Character* teammate; } 

I configured my parser to read from a data structure file with syntax similar to C ++

 Character Sidekick { X = 12 Y = 0 } Character AwesomeDude { X = 10 Y = 50 Teammate = Sidekick } 

This will create two data structures and put them in the <std::string, Character*> map, where the key string is the name I gave it (in this case Sidekick and AwesomeDude). When my parser sees a pointer to a class, such as a pointer to a command, it is smart enough to look on the map to get a pointer to this data structure. The problem is that I cannot declare a Sidekick AwesomeDude teammate because he has not yet been placed in the character map.

I am trying to find a better way to solve this problem in order to be able to bind data structures to objects that have not yet been added to the map. The two simplest solutions that I can think of are either (a) adding the ability to send data structure declarations or (b) reading the analyzer file twice once to fill the map with pointers to empty data structures, and go through the second time them.

The problem with (a) is that I can also decide which constructor should call the class, and if I redirect the declaration, I have to have the constructor separate from the rest of the data, which can be confusing.The problem with (b) is that I might want to declare Sidekick and AwesomeDude in my files. I have to get my parser to take a list of files to read, and not just one at a time (this is not so bad, I think, although sometimes I may need a list of files to read from a file). (b) also has the disadvantage that it cannot use the data structures declared later in the constructor itself, but I don't think this is a huge deal.

Which way sounds like the best approach? Is there a third option that I have not thought about? There seems to be some kind of smart solution for this with links or pointer bindings or something else ...: - I suppose this is somewhat subjective, based on what functions I want to give myself, but any input is welcome.

+7
c ++ parsing
source share
6 answers

When you first meet the link, just save it as a link. You can then put the symbol, link, or something else into the list of "links that you need to resolve later."

When the file is executed, launch those that have links and enable them.

+13
source share

Well, you asked for the third option. You do not need to use XML, but if you follow the following structure, it would be very simple to use a SAX parser to create your data structure.

In any case, instead of referring to a teammate, each character refers to the team (the blue team in this case). This will cancel the round reference issue. Just make sure you list the commands before the characters.

 <team>Blue</team> <character> <name>Sidekick</name> <X>12</X> <Y>0</Y> <teamref>Blue</teamref> </character> <character> <name>Sidekick</name> <X>10</X> <Y>50</Y> <teamref>Blue</teamref> </character> 
+5
source share

Personally, I would go with b). Separation of the code into Parser and Validator classes working in the same data structure. Parser will read and analyze the file, filling in the data structure and storing any references to objects as their text names, leaving the real pointer null in your structure at the moment.

When you are done uploading files, use the Validator class to check and resolve any links by filling in the "real" pointers. You need to think about how to structure your data in order to make these searches enjoyable and quick.

+2
source share

I’ll say for sure that I’m going to write. Just keep a list or something with unresolved links.

And do not forget to throw an error if there are unresolved links after reading the file = P

+1
source share

Instead of saving a symbol object on the map, save the proxy for the symbol. The proxy server will contain a pointer to the actual symbol object when loading the object. Type Character :: teammate will be changed to this type of proxy. When you read a link that is not already on the map, you create a proxy server and use a proxy server. When you download a symbol on which you already have an empty proxy on the map, fill it with a new loaded symbol. You can also add a counter to keep track of how many empty proxy servers you have on the map so you know when all the link symbols have been loaded.

Another layer of indirection .... it always makes programming easier and slower.

0
source share

One option is to cancel the obligation. The map is responsible for filling out the link

 template<T> class SymbolMap // I never could rememeber C++ template syntax { ... /// fill in target with thing name /// if no name yet, add it to the list of thing that will be name void Set(T& target, std::string name); /// define name as target /// go back and fill in anything that needs to be name void Define(T target, std::string name); /// make sure everything is resolved ~SymbolMap() } 

which won't interact well with meaning / moving semantics, but I suspect there won't be that much.

0
source share

All Articles