configparser.y 4.54 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

%pure-parser
%error-verbose
%locations

%parse-param {yyscan_t * scanner}
%lex-param {yyscan_t * scanner}
%parse-param {ParserParams * param}

// Note lower versions might also work
%require "2.3"

%name-prefix="cfgp_"
%defines

%{


#include <assert.h>
20
#include "src/modelconfig/configglue.h"
21 22 23 24 25 26 27 28 29 30

#if defined __GNUC__
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wunused-function"
#elif defined __SUNPRO_CC
#pragma disable_warn
#elif defined _MSC_VER
#pragma warning(push, 1)
#endif

31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55

%}

%code requires {
  
  #ifndef YY_TYPEDEF_YY_SCANNER_T
  #define YY_TYPEDEF_YY_SCANNER_T
  typedef void* yyscan_t;
  #endif
   
}
    

%union {
        struct
        {
            char string_buf [512];
            unsigned int curstringpos;
        };

}

%{
#include "src/modelconfig/configlex.h"

56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
int cfgp_error (YYLTYPE * loc, yyscan_t * scanner, ParserParams * p, 
                        const char * msg)
{
   if (loc)
   {
     return cfgp_parser_error (p, msg, loc->first_line, 
     loc->first_column, loc->last_line, loc->last_column);
   }
   else
   {
     return cfgp_parser_error (p, msg, 0,0,0,0);
   }
}

%}

72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
%start configfile
%token <string_buf> LITERAL_STRING
%token OPENSECTION
%token CLOSESECTION
%token <string_buf> IDENTIFIER
%token EQUAL_TOKEN
%token SEMICOLUMN
%token KOMMA
%token LOPEN
%token LCLOSE


%initial-action {
   param->stacktop = 0;
   param->sectionstack[0] = 0;
   param->parser_error_code = 0;
   param->parser_error_string = 0;
}

91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117


%%

initdummy: /* empty */ {
                /* used to initialize vars */
                param->stacktop = 0;
          } 

configfile: initdummy sectioncontents ;

sectioncontents: sectioncontents entry | ;

entry: key | subsection;


key: singlekey | multikey  ;
  
singlekey: IDENTIFIER EQUAL_TOKEN LITERAL_STRING SEMICOLUMN {
                const char * key = & $<string_buf>1 [0];
                const char * value = & $<string_buf>3 [0];
                cf_createKey (param->configfile,
                      param->sectionstack[param->stacktop], key, &value, 1);
         }

multikeynonzero: KOMMA LITERAL_STRING {
                   param->keyvals[param->count++] = strdup ($<string_buf>2);
Jonathan Jenkins's avatar
Jonathan Jenkins committed
118
                   assert (param->count < param->maxsize); 
119 120 121 122 123 124 125
               }

multikeyentry : multikeynonzero multikeyentry | ;

multikeyinit : /* empty */ {
             param->maxsize = 1000;
             param->count = 0;
126
             param->keyvals = (char**) malloc (sizeof(char*)*param->maxsize);
127 128 129 130
             }

multikeystart : LITERAL_STRING  { 
                param->keyvals[param->count++] = strdup ($<string_buf>1);
Jonathan Jenkins's avatar
Jonathan Jenkins committed
131
                assert (param->count < param->maxsize); 
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
             }

/* this can probably be simplified */
multikeybody: multikeystart multikeyentry | ; 
          
multikey: IDENTIFIER EQUAL_TOKEN LOPEN multikeyinit multikeybody LCLOSE
        SEMICOLUMN {
                unsigned int i;
               /* when this is reduced we have all the keys */
               const char * key = & $<string_buf>1 [0];
                const char ** value = (const char **) param->keyvals;
                cf_createKey (param->configfile,
                      param->sectionstack[param->stacktop], key, value,
                      param->count);

                /* can free strings */
                for (i=0; i<param->count; ++i)
                {
                        free (param->keyvals[i]);
                }
                free (param->keyvals);
                param->keyvals = 0;
            }

opt_semicolumn: SEMICOLUMN | ;

subsection_openaction: IDENTIFIER OPENSECTION
                     {
                         SectionHandle newsection;
Jonathan Jenkins's avatar
Jonathan Jenkins committed
161
                         assert(param->stacktop < sizeof(param->sectionstack)/sizeof(param->sectionstack[0]));
162 163 164 165 166 167 168 169 170 171 172 173
                         
                         cf_createSection (param->configfile,
                         param->sectionstack[param->stacktop], $1,
                         &newsection);

                         /*cf_openSection (param->configfile,
                             param->sectionstack[param->stacktop], $1, &newsection); */
                         param->sectionstack[++param->stacktop] = newsection;
                     }; 

subsection_closeaction: CLOSESECTION opt_semicolumn
                      {
Jonathan Jenkins's avatar
Jonathan Jenkins committed
174
                          assert (param->stacktop > 0);
175 176 177 178 179 180 181 182 183 184
                          SectionHandle old = param->sectionstack[param->stacktop--];
                          cf_closeSection (param->configfile, old);
                      };

subsection: subsection_openaction sectioncontents subsection_closeaction ;


%%