Page principale | Liste alphabétique | Liste des classes | Liste des fichiers | Membres de classe | Membres de fichier | Pages associées

Parser.h

Aller à la documentation de ce fichier.
00001 /*! \file Parser.h
00002     \brief Parser.
00003 
00004     Parser à pseudo langage programmable.
00005 
00006     \author     aerith (http://aerith.fr)
00007     \version    1.0
00008     \date       20/05/2008
00009 */
00010 
00011 #ifndef INCLUDE_RSRC_PARSER
00012 #define INCLUDE_RSRC_PARSER
00013 
00014 #include    "../Surcouche/SurcoucheModule.h"
00015 #include    "../Tools/Tools.h"
00016 #include    "../Error/Error.h"
00017 #include    "ParserRule.h"
00018 #include    <vector>
00019 #include    <string>
00020 
00021 using namespace std;
00022 
00023 
00024 #define     PARSER_BUFFER       10240
00025 #define     PARSER_LABEL        32
00026 #define     PARSER_TOK          '$'
00027 
00028 //! Information sur une règle.
00029 /*! Information sur une règle.
00030 */
00031 class ParserRule
00032 {
00033 public  :
00034     ROUTINE                 function;           /*!< Nom de la routine à éxécutée.                      */
00035     string                  syntax;             /*!< Syntax de la requette.                             */
00036 
00037     /*! Initialise avec des paramétres par defaut.
00038         \param pFunction routine à appeler
00039         \param pSyntax syntax de la règle
00040     */
00041     ParserRule(ROUTINE pFunction, const char *pSyntax)
00042     {
00043         function = pFunction;
00044         syntax = pSyntax;
00045     };
00046 };
00047 
00048 //! Parser.
00049 /*! Parser à pseudo langage programmable.
00050 */
00051 template <class T> class Parser
00052 {
00053 private :
00054     vector<ParserRule *>    rules;          /*!< Chaque lignes est une règle.                       */
00055     T                       *obj;           /*!< Classe ou structure à passer aux routines.         */
00056     char                    none[1];        /*!< Valeur d'un get non trouvé.                        */
00057 
00058 public  :
00059     /*! Initialise avec des paramétres par defaut.
00060         \param pObj class ou structure à passer au routine
00061     */
00062     Parser(T *pObj)
00063     {
00064         obj = pObj;
00065         *none   = '\0';
00066     };
00067 
00068     /*! Libère la mémoire proprement
00069     */
00070     ~Parser()
00071     {
00072         unsigned int    i;
00073 
00074         for(i = 0; i < rules.size(); i ++)
00075             delete rules[i];
00076         rules.clear();
00077     };
00078 
00079     //! Ajoute une règle.
00080     /*! Ajoute une règle avec une syntax et une routine lier.
00081         \param pFunction routine a lier.
00082         \param pSyntax syntax de la règle.
00083     */
00084     void    AddRule(ROUTINE pFunction, const char *pSyntax, ...)
00085     {
00086         char        temp[PARSER_BUFFER];
00087         va_list     args;
00088 
00089         va_start(args, pSyntax);
00090         vsprintf(temp, pSyntax, args);
00091         va_end(args);
00092 
00093         rules.push_back(new ParserRule(pFunction, temp));
00094     };
00095 
00096     //! Supprime une règle.
00097     /*! Supprime la règle à la position \a iPos.
00098         \param iPos position de la règle.
00099     */
00100     void    DelRule(unsigned int iPos)
00101     {
00102         if(iPos < rules.size())
00103             rules.erase(rules.begin() + iPos);
00104     };
00105 
00106     //! Retourne la syntax de la règle.
00107     /*! Retourne la syntax de la règle \a iPos.
00108         \param iPos Position de la règle.
00109         \return pointeur sur la syntax de la règle.
00110     */
00111     inline const char   *GetSyntax(unsigned int iPos)
00112     {
00113         if(iPos < rules.size())
00114             return rules[iPos]->syntax.data();
00115 
00116         return none;
00117     };
00118 
00119     //! Retourne le nombre de règles.
00120     /*! Retourne le nombre de règles du parser.
00121         \return nombre de requette du parser.
00122     */
00123     inline unsigned int     GetNbRule()
00124     {
00125         return rules.size();
00126     };
00127 
00128     //! Parse un buffer.
00129     /*! Parse un buffer ligne à ligne, recherche et éxécute les routines.
00130         \param pBuffer buffer à parser.
00131     */
00132     void    ParseLine(const char *pBuffer)
00133     {
00134         char            out[PARSER_BUFFER];
00135         const char      *b = pBuffer;
00136         char            *o = out;
00137         TRY
00138 
00139         while(*b)
00140         {
00141             if((*b != '\n') && (*b != '\r'))
00142             {
00143                 *o++ = *b;
00144             }
00145             else if(out != o)
00146             {
00147                 *o = '\0';
00148                 Parse(out);
00149                 o = out;
00150             }
00151 
00152             b++;
00153         }
00154 
00155         CATCH
00156     };
00157 
00158     //! Parse un buffer.
00159     /*! Parse le buffer en un seul block, recherche et éxécute une routine.
00160         \param pBuffer buffer à parser.
00161     */
00162     void    Parse(const char *pBuffer)
00163     {
00164         unsigned int            i = 0;
00165         const char              *pSyntax = NULL;
00166         char                    end = '\0';
00167         char                    buffer[PARSER_BUFFER];
00168         char                    temp[PARSER_BUFFER];
00169         char                    label[PARSER_LABEL];
00170         char                    *pBuf = NULL;
00171         char                    *pTemp = NULL;
00172         char                    *pLabel = NULL;
00173         ParserRuleParameter<T>  *parameter = NULL;
00174         TRY
00175 
00176         strncpy(buffer, pBuffer, PARSER_BUFFER);
00177 
00178         for(i = 0; i < rules.size(); i++)
00179         {
00180             pBuf = buffer;
00181             pSyntax = rules[i]->syntax.c_str();
00182             parameter = new ParserRuleParameter<T>(obj);
00183 
00184             do
00185             {
00186                 if(*pSyntax == PARSER_TOK) //si c'est un paramètre
00187                 {
00188                     pLabel = label;
00189                     pTemp = temp;
00190 
00191                     pSyntax++; //passe le PARSER_TOK
00192                     while(IsAlphaNumCar(*pSyntax))
00193                         *pLabel++ = *pSyntax++; //copie le nom du paramètre
00194                     *pLabel = '\0';
00195 
00196                     end = *pSyntax; //carractère où s'arrète le paramètre
00197 
00198                     while((*pBuf != '\0') && (*pBuf != end))
00199                     {
00200                         *pTemp = *pBuf; //copie la valeur du paramètre
00201                         pTemp++;
00202                         pBuf++;
00203                     }
00204                     *pTemp = '\0';
00205                     pBuf++; //pour être différent de Tok
00206 
00207                     parameter->Add(label, temp);
00208                 }
00209                 else //si c'est un carractère non utile
00210                 {
00211                     if(*pSyntax == *pBuf)
00212                         pBuf++;
00213                     else //si la requette ne correspond pas au mask
00214                         break;
00215                 }
00216 
00217                 if(*pSyntax != '\0')
00218                     pSyntax++;
00219             }
00220             while(*pBuf && *pSyntax);
00221 
00222             if((*pSyntax == '\0') && (*pBuf == '\0'))
00223                 rules[i]->function((PARAMETRE)parameter);
00224 
00225             delete parameter;
00226         }
00227 
00228         CATCH
00229     };
00230 };
00231 
00232 #endif

Généré le Thu Jun 12 09:12:30 2008 pour A.I.F. par  doxygen 1.3.9.1