Merge remote-tracking branch 'origin/release-v4.6.1'
[WRF.git] / chem / KPP / kpp / kpp-2.1 / src.org / scan.l
blob9634940041fec26c6620dfcf3535c669482555ee
1 /******************************************************************************
3   KPP - The Kinetic PreProcessor
4         Builds simulation code for chemical kinetic systems
6   Copyright (C) 1995-1996 Valeriu Damian and Adrian Sandu
7   Copyright (C) 1997-2005 Adrian Sandu
9   KPP is free software; you can redistribute it and/or modify it under the
10   terms of the GNU General Public License as published by the Free Software
11   Foundation (http://www.gnu.org/copyleft/gpl.html); either version 2 of the
12   License, or (at your option) any later version.
14   KPP is distributed in the hope that it will be useful, but WITHOUT ANY
15   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16   FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
17   details.
19   You should have received a copy of the GNU General Public License along
20   with this program; if not, consult http://www.gnu.org/copyleft/gpl.html or
21   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22   Boston, MA  02111-1307,  USA.
24   Adrian Sandu
25   Computer Science Department
26   Virginia Polytechnic Institute and State University
27   Blacksburg, VA 24060
28   E-mail: sandu@cs.vt.edu
30 ******************************************************************************/
34 %s CMD_STATE INC_STATE MOD_STATE INT_STATE 
35 %s PRM_STATE DSP_STATE SSP_STATE INI_STATE EQN_STATE EQNTAG_STATE 
36 %s RATE_STATE LMP_STATE CR_IGNORE SC_IGNORE ATM_STATE LKT_STATE INL_STATE 
37 %s MNI_STATE TPT_STATE USE_STATE
38 %s COMMENT COMMENT2 EQN_ID
39 %x INL_CODE
42   #include "gdata.h" 
43   #include "scan.h" 
44   #include "y.tab.h"
46   void Include ( char * filename );
47   int EndInclude();
49   int crt_line_no = 1;
50   char *crt_filename;
52   #define MAX_INCLUDE 10
53   
54   YY_BUFFER_STATE yy_buffers[ MAX_INCLUDE ];
55   int yy_line_no[ MAX_INCLUDE ];
56   char *yy_filename[ MAX_INCLUDE ];
57   int yy_buf_level = 0;
58   
59   char crtToken[100];
60   char nextToken[100];
61   int crtTokType;
62   int nextTokType;
63   int crtLine;
64   char crtFile[100];
65   char crt_rate[100];
67   int oldnErr = 0;
69   int idx;
70   int oldstate;
71   extern int yyerrflag;
73 #define INITIAL 0
74 #define CMD_STATE 1
75 #define INC_STATE 2
76 #define MOD_STATE 3
77 #define INT_STATE 4
78 #define PRM_STATE 5
79 #define DSP_STATE 6
80 #define SSP_STATE 7
81 #define INI_STATE 8
82 #define EQN_STATE 9
83 #define EQNTAG_STATE 10
84 #define RATE_STATE 11
85 #define LMP_STATE 12
86 #define CR_IGNORE 13
87 #define SC_IGNORE 14
88 #define ATM_STATE 15
89 #define LKT_STATE 16
90 #define INL_STATE 17
91 #define MNI_STATE 18
92 #define TPT_STATE 19
93 #define USE_STATE 20
94 #define COMMENT 21
95 #define COMMENT2 22
96 #define EQN_ID 23
97 #define INL_CODE 24
99   typedef struct {
100                    char *name;
101                    int next;
102                    int cmd; 
103                  } KEYWORD;
105   KEYWORD keywords[] = { { "INCLUDE",    INC_STATE, 0 },
106                          { "MODEL",      MOD_STATE, 0 },
107                          { "INTEGRATOR", INT_STATE, 0 },
108                          { "JACOBIAN",   PRM_STATE, JACOBIAN }, 
109                          { "HESSIAN",    PRM_STATE, HESSIAN }, 
110                          { "STOICMAT",   PRM_STATE, STOICMAT }, 
111                          { "STOCHASTIC", PRM_STATE, STOCHASTIC }, 
112                          { "DOUBLE",     PRM_STATE, DOUBLE }, 
113                          { "REORDER",    PRM_STATE, REORDER }, 
114                          { "MEX",        PRM_STATE, MEX }, 
115                          { "DUMMYINDEX", PRM_STATE, DUMMYINDEX}, 
116                          { "EQNTAGS",    PRM_STATE, EQNTAGS}, 
117                          { "FUNCTION",   PRM_STATE, FUNCTION }, 
118                          { "ATOMS",      ATM_STATE, ATOMDECL },   
119                          { "CHECK",      ATM_STATE, CHECK },
120                          { "CHECKALL",   INITIAL,   CHECKALL },
121                          { "DEFVAR",     DSP_STATE, DEFVAR }, 
122                          { "DEFRAD",     DSP_STATE, DEFRAD }, 
123                          { "DEFFIX",     DSP_STATE, DEFFIX }, 
124                          { "SETVAR",     SSP_STATE, SETVAR }, 
125                          { "SETRAD",     SSP_STATE, SETRAD }, 
126                          { "SETFIX",     SSP_STATE, SETFIX }, 
127                          { "INITVALUES", INI_STATE, INITVALUES }, 
128                          { "EQUATIONS",  EQN_STATE, EQUATIONS }, 
129                          { "LUMP",       LMP_STATE, LUMP }, 
130                          { "LOOKAT",     LKT_STATE, LOOKAT },
131                          { "LOOKATALL",  INITIAL,   LOOKATALL },
132                          { "TRANSPORT",  TPT_STATE, TRANSPORT },
133                          { "TRANSPORTALL", INITIAL,   TRANSPORTALL },
134                          { "INITIALIZE", PRM_STATE, INITIALIZE },
135                          { "XGRID",      PRM_STATE, XGRID },
136                          { "YGRID",      PRM_STATE, YGRID },
137                          { "ZGRID",      PRM_STATE, ZGRID },
138                          { "MONITOR",    MNI_STATE, MONITOR },
139                          { "WRITE_ATM",  INITIAL,   WRITE_ATM },
140                          { "WRITE_SPC",  INITIAL,   WRITE_SPC },
141                          { "WRITE_MAT",  INITIAL,   WRITE_MAT },
142                          { "WRITE_OPT",  INITIAL,   WRITE_OPT },
143                          { "USE",        PRM_STATE, USE },
144                          { "LANGUAGE",   PRM_STATE, LANGUAGE },
145                          { "INLINE",     INL_STATE, INLINE },
146                          { "ENDINLINE",  INITIAL,   ENDINLINE },
147                          { "INTFILE",    PRM_STATE, INTFILE },
148                          { "DRIVER",     PRM_STATE, DRIVER },
149                          { "RUN",        PRM_STATE, RUN },
150                          { "USES",       USE_STATE, USES },
151                          { "SPARSEDATA", PRM_STATE, SPARSEDATA },
152                          { 0, 0, 0 } 
153                        };
155   int CheckKeyword( char *cmd );
157 #define RETURN( x ) \
158         if(1) { \
159           if ( yyerrflag == 0) { \
160             strcpy( crtToken, nextToken ); \
161             crtTokType = nextTokType; \
162             crtLine = crt_line_no; \
163             strcpy( crtFile, crt_filename ); \
164           } \
165           strcpy( nextToken, yytext); \
166           nextTokType = x; \
167           return (x); \
168         }
172 BT      [ \t]
173 SPACE   [ \t]
174 CR      [\n] 
175 TAG     [a-zA-Z_0-9]+
176 STRING  [^ \t\n{}#;]+
178 LIT     [a-zA-Z_]
179 CIF     [0-9]
181 IDSPC   {LIT}[a-zA-Z_0-9]*
183 NR      {CIF}*
184 NRS     [+-]?{CIF}+
185 REAL    {NRS}?"."?{NR}
186 UREAL   {NR}?"."?{NR}
187 FLOAT   {REAL}([eE]{NRS})?
188 UFLOAT  {UREAL}([eE]{NRS})?
191 {SPACE}+                {
192                         }  
193 #                       { BEGIN CMD_STATE; 
194                         }
195 \{                      { oldstate = (yy_start - 1) / 2;
196                           BEGIN COMMENT;
197                         }
198 \/\/                    { oldstate = (yy_start - 1) / 2;
199                           BEGIN COMMENT2;
200                         }
201 <COMMENT>[^\}\n]*       {
202                         } 
203 <COMMENT>\}             { BEGIN oldstate;
204                         }    
205 <COMMENT2>[^\n]*        {
206                         } 
207 <COMMENT2>{CR}          { crt_line_no++; 
208                           BEGIN oldstate;
209                         }    
210 {CR}                    { crt_line_no++; 
211                         }
212 <CMD_STATE>{STRING}     { idx = CheckKeyword( yytext );
213                           if ( idx < 0 ) { 
214                             BEGIN CR_IGNORE;
215                             break; 
216                           } 
217                           BEGIN keywords[idx].next;
218                           if ( keywords[idx].cmd ) {
219                             crt_section = keywords[idx].cmd;
220                             RETURN( keywords[idx].cmd );
221                           }
222                         } 
223 <INC_STATE>{STRING}     { Include( IncName(yytext) );
224                           BEGIN CR_IGNORE;
225                         } 
226 <MOD_STATE>{STRING}     { Include( ModelName(yytext) );
227                           BEGIN CR_IGNORE;
228                         } 
229 <INT_STATE>{STRING}     { Include( IntegName(yytext) );
230                           BEGIN CR_IGNORE;
231                         } 
232 <PRM_STATE>{STRING}     { strcpy( yylval.str, yytext );
233                           BEGIN CR_IGNORE;                         
234                           RETURN( PARAMETER ); 
235                         }
236 <CR_IGNORE>{STRING}     { ScanError("Extra parameter on command line '%s'", yytext);
237                         }
238 <ATM_STATE>{IDSPC}      { strcpy( yylval.str, yytext );
239                           RETURN( ATOMID );
240                         }
241 <ATM_STATE>;            { RETURN( yytext[0] );
242                         } 
243 <DSP_STATE>{IDSPC}      { strcpy( yylval.str, yytext );
244                           RETURN( SPCSPC );
245                         }
246 <DSP_STATE>{NR}         { strcpy( yylval.str, yytext );
247                           RETURN( SPCNR );
248                         }
249 <DSP_STATE>[=]          { RETURN( SPCEQUAL );
250                         } 
251 <DSP_STATE>[+]          { RETURN( SPCPLUS );
252                         } 
253 <DSP_STATE>;            { RETURN( yytext[0] );
254                         } 
255 <DSP_STATE>[^;#]        { ScanError("Invalid character '%c' in species definition", yytext[0] );
256                         }
257 <SSP_STATE>{IDSPC}      { strcpy( yylval.str, yytext );
258                           RETURN( SSPID );
259                         }
260 <SSP_STATE>;            { RETURN( yytext[0] );
261                         } 
262 <INI_STATE>{IDSPC}      { strcpy( yylval.str, yytext );
263                           RETURN( INISPC ); 
264                         } 
265 <INI_STATE>[=]          { RETURN( INIEQUAL );
266                         } 
267 <INI_STATE>;            { RETURN( yytext[0] );
268                         } 
269 <INI_STATE>{FLOAT}      { strcpy( yylval.str, yytext );
270                           RETURN( INIVALUE ); 
271                         } 
272 <INI_STATE>[^=;#]       { ScanError("Invalid character '%c' in initial values", yytext[0] );
273                         }
274 <EQN_STATE>{IDSPC}      { strcpy( yylval.str, yytext );
275                           RETURN( EQNSPC );
276                         } 
277 <EQN_STATE>[=]          { RETURN( EQNEQUAL );
278                         } 
279 <EQN_STATE>{UFLOAT}     { strcpy( yylval.str, yytext );
280                           RETURN( EQNCOEF ); 
281                         } 
282 <EQN_STATE>[:]          { BEGIN RATE_STATE;
283                           *crt_rate = 0;
284                           RETURN( EQNCOLON );
285                         } 
286 <EQN_STATE>[+-]         { strcpy( yylval.str, yytext );
287                           RETURN( EQNSIGN );
288                         } 
289 <EQN_STATE>[<]          { BEGIN EQNTAG_STATE;
290                           RETURN( EQNLESS );
291                         }
292 <EQNTAG_STATE>{TAG}     { strcpy( yylval.str, yytext );
293                           RETURN( EQNTAG );
294                         } 
295 <EQNTAG_STATE>[>]       { BEGIN EQN_STATE;
296                           RETURN( EQNGREATER );
297                         }    
298 <RATE_STATE>{STRING}    { strcpy( yylval.str, yytext );
299                           RETURN( RATE );
300                         } 
301 <RATE_STATE>;           { BEGIN EQN_STATE;
302                           RETURN( yytext[0] );
303                         } 
304 <LMP_STATE>{IDSPC}      { strcpy( yylval.str, yytext );
305                           RETURN( LMPSPC );
306                         }
307 <LMP_STATE>[+]          { RETURN( LMPPLUS );
308                         } 
309 <LMP_STATE>[:]          { RETURN( LMPCOLON );
310                         } 
311 <LMP_STATE>;            { RETURN( yytext[0] );
312                         } 
313 <LMP_STATE>[^;#]        { ScanError("Invalid character '%c' in species definition", yytext[0] );
314                         }
315 <LKT_STATE>{IDSPC}      { strcpy( yylval.str, yytext );
316                           RETURN( LKTID );
317                         }
318 <LKT_STATE>;            { RETURN( yytext[0] );
319                         } 
320 <TPT_STATE>{IDSPC}      { strcpy( yylval.str, yytext );
321                           RETURN( TPTID );
322                         }
323 <TPT_STATE>;            { RETURN( yytext[0] );
324                         } 
325 <USE_STATE>{STRING}     { strcpy( yylval.str, yytext );
326                           RETURN( USEID );
327                         }
328 <USE_STATE>;            { RETURN( yytext[0] );
329                         } 
330 <MNI_STATE>{IDSPC}      { strcpy( yylval.str, yytext );
331                           RETURN( MNIID );
332                         }
333 <MNI_STATE>;            { RETURN( yytext[0] );
334                         } 
335 <INL_STATE>{STRING}     { strcpy( yylval.str, yytext );
336                           BEGIN INL_CODE;
337                           RETURN( INLCTX );
338                         }
339 <INL_CODE>#[^ \t\n]*    { if ( EqNoCase( yytext+1, "ENDINLINE" ) ){
340                             BEGIN INITIAL;
341                             RETURN( ENDINLINE );
342                           }
343                           else {
344                             strcpy( yylval.str, yytext );
345                             RETURN( INCODE );
346                           }
347                         }
348 <INL_CODE>\n            { crt_line_no++;
349                           strcpy( yylval.str,yytext );
350                           RETURN( INCODE );
351                         }
352 <INL_CODE>[^#\n]*       { strcpy( yylval.str,yytext );
353                           RETURN( INCODE );
354                         }
355 <<EOF>>                 { if ( ! EndInclude() ) {
356                             RETURN( INITIAL );
357                           }
358                         }  
361 void Include ( char * name )
363 FILE *f;
364 YY_BUFFER_STATE newb;
366   if ( yy_buf_level == MAX_INCLUDE ) {
367     printf("\nInclude nested too deep. Include %s ignored", name);
368     return;
369   }
371   yy_buffers[ yy_buf_level ]  = YY_CURRENT_BUFFER;
372   yy_line_no[ yy_buf_level ]  = crt_line_no;
373   yy_filename[ yy_buf_level ] = crt_filename;
374   yy_buf_level++;
375   
376   crt_line_no = 1;  
378   crt_filename = malloc( 1 + strlen( name ) );
379   strcpy( crt_filename, name ); 
382   f = fopen( name, "r" );
383   if( f == 0 )
384     FatalError(3,"%s: Can't read file", name );
386   newb = yy_create_buffer(f, YY_BUF_SIZE);
387   yy_switch_to_buffer( newb );
390 int EndInclude()
392 YY_BUFFER_STATE oldb;
393 char * oldn;
395   if ( yy_buf_level > 0 ) {
396     oldb = YY_CURRENT_BUFFER;
397     oldn = crt_filename; 
398     yy_buf_level--;
399     yy_switch_to_buffer( yy_buffers[yy_buf_level] );
400     crt_line_no = yy_line_no[ yy_buf_level ];
401     crt_filename = yy_filename[ yy_buf_level ]; 
402     yy_delete_buffer( oldb ); 
403     free( oldn );
404     return 1;
405   } 
406   return 0;
409 int EqNoCase( char *s1, char *s2 )
411   while( *s1 ) {
412     if ( toupper(*s1++) != toupper(*s2++) ) return 0;
413   }
414   return *s1 == *s2;
417 int CheckKeyword( char *cmd )
419 int i;
421   i = 0;
422   while( 1 ) {
423     if( keywords[i].name == 0 ) {
424       ScanError( "'%s': Unknown command (ignored)", cmd);
425       return -1;
426     }
427     if( EqNoCase( cmd, keywords[i].name ) ) {
428       return i;
429     }
430     i++;
431   }