< index < 7. File parser < 7.6 Using the default parser listener | ===================================== 7.7 Parser listener - additional information ===================================== |

In many cases, the parser can be used in its default minimalist form, in which it can parse a single struct of any given type in a text file. This is useful, for instance, in case of configuration files, where there's only one instance of the struct containing the necessary variables. However, consider a case when there are many instances of the same kind of struct. This is the case I'll be addressing in this short tuto.
First of all, it's important to know what the listener actually does. Unlike the default parser, it will not store the parsed variable values internally. After parsing a file with several instances of the same kind of struct, the extracted data will vanish. However, the listener offers the possibility of telling it what to do with te extracted data so it does not get lost. In order to be able to store the information safely, it's recommended to previously create a data structure that will be able to hold all the extracted data. Something like this is a fine way of dealing with it:

    C++: class myData {
             public:
             char name[32];
             var 1
             var 2
             ...
             var n
             static TCODList <myData *> list;
             static myData * get (const char * name);
         };
    C:   struct my_data {
             char name[32];
             var 1
             var 2
             ...
             var n
         }
         TCOD_list_t my_data_list = TCOD_list_new();
         my_data * my_data_get (const char * name);

The above class/struct contain all the variables that are defined inside the configuration file. The extracted values will be copied to those fields. Additionally, there's a char array that will contain the extracted struct's name and that will be used for identification purposes;
The list that's declared in the above examples will store pointers to all the instances of the data structure, each containing data extracted from one instance of the struct in the text file. Additionally, there's a getter that will do the dirty job for us upon seeking the correct bit of data: it will automatically traverse the list and compare the provided string with each list element's name. This way, if we have a generic data structure, say, "Creature", and a set of names for its instances, say, "goblin", "orc" and "kobold", accessing the correct set of variables will require calling:

    C++: myData::get("myName");
    C:   my_data_get("my_name");

I'll leave the actual implementation of the above functions to the individual developers, as this is not key to understanding the parser listener.
So, now that we have the data structure sorted out, let's begin our work with the actual listener. We will need to tell the listener exactly what to do when certain events are encountered. As a general rule, this will break down into:

- creating an instance of the data structure, assigning it its name and pushing it on the list,
- assigning it correct values based on their names.

So, to make the parser run, create and build it according to what's been laid out in chapter 7.3: Running the parser. You have to remember these basic rules:

- The parser listener has no thoughts of its own and does only what it's instructed to. You have tell it how to decide what to do based on what's encountered in the configuration file.
- The variable names are retrieved in the form of strings, so you'll need to call strcmp a lot in order to determine what the retrieved value is.
- Each time you add a new field to the config file, make sure you let the listener know about it.
- The parser won't know what to do when something's wrong. Tell it where to display the errors.