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
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.
25 Computer Science Department
26 Virginia Polytechnic Institute and State University
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
46 void Include ( char * filename );
52 #define MAX_INCLUDE 10
54 YY_BUFFER_STATE yy_buffers[ MAX_INCLUDE ];
55 int yy_line_no[ MAX_INCLUDE ];
56 char *yy_filename[ MAX_INCLUDE ];
83 #define EQNTAG_STATE 10
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 },
155 int CheckKeyword( char *cmd );
157 #define RETURN( x ) \
159 if ( yyerrflag == 0) { \
160 strcpy( crtToken, nextToken ); \
161 crtTokType = nextTokType; \
162 crtLine = crt_line_no; \
163 strcpy( crtFile, crt_filename ); \
165 strcpy( nextToken, yytext); \
181 IDSPC {LIT}[a-zA-Z_0-9]*
187 FLOAT {REAL}([eE]{NRS})?
188 UFLOAT {UREAL}([eE]{NRS})?
195 \{ { oldstate = (yy_start - 1) / 2;
198 \/\/ { oldstate = (yy_start - 1) / 2;
203 <COMMENT>\} { BEGIN oldstate;
207 <COMMENT2>{CR} { crt_line_no++;
210 {CR} { crt_line_no++;
212 <CMD_STATE>{STRING} { idx = CheckKeyword( yytext );
217 BEGIN keywords[idx].next;
218 if ( keywords[idx].cmd ) {
219 crt_section = keywords[idx].cmd;
220 RETURN( keywords[idx].cmd );
223 <INC_STATE>{STRING} { Include( IncName(yytext) );
226 <MOD_STATE>{STRING} { Include( ModelName(yytext) );
229 <INT_STATE>{STRING} { Include( IntegName(yytext) );
232 <PRM_STATE>{STRING} { strcpy( yylval.str, yytext );
236 <CR_IGNORE>{STRING} { ScanError("Extra parameter on command line '%s'", yytext);
238 <ATM_STATE>{IDSPC} { strcpy( yylval.str, yytext );
241 <ATM_STATE>; { RETURN( yytext[0] );
243 <DSP_STATE>{IDSPC} { strcpy( yylval.str, yytext );
246 <DSP_STATE>{NR} { strcpy( yylval.str, yytext );
249 <DSP_STATE>[=] { RETURN( SPCEQUAL );
251 <DSP_STATE>[+] { RETURN( SPCPLUS );
253 <DSP_STATE>; { RETURN( yytext[0] );
255 <DSP_STATE>[^;#] { ScanError("Invalid character '%c' in species definition", yytext[0] );
257 <SSP_STATE>{IDSPC} { strcpy( yylval.str, yytext );
260 <SSP_STATE>; { RETURN( yytext[0] );
262 <INI_STATE>{IDSPC} { strcpy( yylval.str, yytext );
265 <INI_STATE>[=] { RETURN( INIEQUAL );
267 <INI_STATE>; { RETURN( yytext[0] );
269 <INI_STATE>{FLOAT} { strcpy( yylval.str, yytext );
272 <INI_STATE>[^=;#] { ScanError("Invalid character '%c' in initial values", yytext[0] );
274 <EQN_STATE>{IDSPC} { strcpy( yylval.str, yytext );
277 <EQN_STATE>[=] { RETURN( EQNEQUAL );
279 <EQN_STATE>{UFLOAT} { strcpy( yylval.str, yytext );
282 <EQN_STATE>[:] { BEGIN RATE_STATE;
286 <EQN_STATE>[+-] { strcpy( yylval.str, yytext );
289 <EQN_STATE>[<] { BEGIN EQNTAG_STATE;
292 <EQNTAG_STATE>{TAG} { strcpy( yylval.str, yytext );
295 <EQNTAG_STATE>[>] { BEGIN EQN_STATE;
296 RETURN( EQNGREATER );
298 <RATE_STATE>{STRING} { strcpy( yylval.str, yytext );
301 <RATE_STATE>; { BEGIN EQN_STATE;
304 <LMP_STATE>{IDSPC} { strcpy( yylval.str, yytext );
307 <LMP_STATE>[+] { RETURN( LMPPLUS );
309 <LMP_STATE>[:] { RETURN( LMPCOLON );
311 <LMP_STATE>; { RETURN( yytext[0] );
313 <LMP_STATE>[^;#] { ScanError("Invalid character '%c' in species definition", yytext[0] );
315 <LKT_STATE>{IDSPC} { strcpy( yylval.str, yytext );
318 <LKT_STATE>; { RETURN( yytext[0] );
320 <TPT_STATE>{IDSPC} { strcpy( yylval.str, yytext );
323 <TPT_STATE>; { RETURN( yytext[0] );
325 <USE_STATE>{STRING} { strcpy( yylval.str, yytext );
328 <USE_STATE>; { RETURN( yytext[0] );
330 <MNI_STATE>{IDSPC} { strcpy( yylval.str, yytext );
333 <MNI_STATE>; { RETURN( yytext[0] );
335 <INL_STATE>{STRING} { strcpy( yylval.str, yytext );
339 <INL_CODE>#[^ \t\n]* { if ( EqNoCase( yytext+1, "ENDINLINE" ) ){
344 strcpy( yylval.str, yytext );
348 <INL_CODE>\n { crt_line_no++;
349 strcpy( yylval.str,yytext );
352 <INL_CODE>[^#\n]* { strcpy( yylval.str,yytext );
355 <<EOF>> { if ( ! EndInclude() ) {
361 void Include ( char * name )
364 YY_BUFFER_STATE newb;
366 if ( yy_buf_level == MAX_INCLUDE ) {
367 printf("\nInclude nested too deep. Include %s ignored", name);
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;
378 crt_filename = malloc( 1 + strlen( name ) );
379 strcpy( crt_filename, name );
382 f = fopen( name, "r" );
384 FatalError(3,"%s: Can't read file", name );
386 newb = yy_create_buffer(f, YY_BUF_SIZE);
387 yy_switch_to_buffer( newb );
392 YY_BUFFER_STATE oldb;
395 if ( yy_buf_level > 0 ) {
396 oldb = YY_CURRENT_BUFFER;
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 );
409 int EqNoCase( char *s1, char *s2 )
412 if ( toupper(*s1++) != toupper(*s2++) ) return 0;
417 int CheckKeyword( char *cmd )
423 if( keywords[i].name == 0 ) {
424 ScanError( "'%s': Unknown command (ignored)", cmd);
427 if( EqNoCase( cmd, keywords[i].name ) ) {