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 ];
79 KEYWORD keywords[] = { { "INCLUDE", INC_STATE, 0 },
80 { "MODEL", MOD_STATE, 0 },
81 { "INTEGRATOR", INT_STATE, 0 },
82 { "JACOBIAN", PRM_STATE, JACOBIAN },
83 { "HESSIAN", PRM_STATE, HESSIAN },
84 { "STOICMAT", PRM_STATE, STOICMAT },
85 { "STOCHASTIC", PRM_STATE, STOCHASTIC },
86 { "DOUBLE", PRM_STATE, DOUBLE },
87 { "REORDER", PRM_STATE, REORDER },
88 { "MEX", PRM_STATE, MEX },
89 { "DUMMYINDEX", PRM_STATE, DUMMYINDEX},
90 { "EQNTAGS", PRM_STATE, EQNTAGS},
91 { "FUNCTION", PRM_STATE, FUNCTION },
92 { "ATOMS", ATM_STATE, ATOMDECL },
93 { "CHECK", ATM_STATE, CHECK },
94 { "CHECKALL", INITIAL, CHECKALL },
95 { "DEFVAR", DSP_STATE, DEFVAR },
96 { "DEFRAD", DSP_STATE, DEFRAD },
97 { "DEFFIX", DSP_STATE, DEFFIX },
98 { "SETVAR", SSP_STATE, SETVAR },
99 { "SETRAD", SSP_STATE, SETRAD },
100 { "SETFIX", SSP_STATE, SETFIX },
101 { "INITVALUES", INI_STATE, INITVALUES },
102 { "EQUATIONS", EQN_STATE, EQUATIONS },
103 { "LUMP", LMP_STATE, LUMP },
104 { "LOOKAT", LKT_STATE, LOOKAT },
105 { "LOOKATALL", INITIAL, LOOKATALL },
106 { "TRANSPORT", TPT_STATE, TRANSPORT },
107 { "TRANSPORTALL", INITIAL, TRANSPORTALL },
108 { "INITIALIZE", PRM_STATE, INITIALIZE },
109 { "XGRID", PRM_STATE, XGRID },
110 { "YGRID", PRM_STATE, YGRID },
111 { "ZGRID", PRM_STATE, ZGRID },
112 { "MONITOR", MNI_STATE, MONITOR },
113 { "WRITE_ATM", INITIAL, WRITE_ATM },
114 { "WRITE_SPC", INITIAL, WRITE_SPC },
115 { "WRITE_MAT", INITIAL, WRITE_MAT },
116 { "WRITE_OPT", INITIAL, WRITE_OPT },
117 { "USE", PRM_STATE, USE },
118 { "LANGUAGE", PRM_STATE, LANGUAGE },
119 { "INLINE", INL_STATE, INLINE },
120 { "ENDINLINE", INITIAL, ENDINLINE },
121 { "INTFILE", PRM_STATE, INTFILE },
122 { "DRIVER", PRM_STATE, DRIVER },
123 { "RUN", PRM_STATE, RUN },
124 { "USES", USE_STATE, USES },
125 { "SPARSEDATA", PRM_STATE, SPARSEDATA },
126 { "WRFCONFORM", INITIAL, WRFCONFORM },
130 int CheckKeyword( char *cmd );
132 #define RETURN( x ) \
134 if ( yyerrflag == 0) { \
135 strcpy( crtToken, nextToken ); \
136 crtTokType = nextTokType; \
137 crtLine = crt_line_no; \
138 strcpy( crtFile, crt_filename ); \
140 strcpy( nextToken, yytext); \
156 IDSPC {LIT}[a-zA-Z_0-9]*
162 FLOAT {REAL}([eE]{NRS})?
163 UFLOAT {UREAL}([eE]{NRS})?
170 \{ { oldstate = (yy_start - 1) / 2;
173 \/\/ { oldstate = (yy_start - 1) / 2;
178 <COMMENT>\} { BEGIN oldstate;
182 <COMMENT2>{CR} { crt_line_no++;
185 {CR} { crt_line_no++;
187 <CMD_STATE>{STRING} { idx = CheckKeyword( yytext );
192 BEGIN keywords[idx].next;
193 if ( keywords[idx].cmd ) {
194 crt_section = keywords[idx].cmd;
195 RETURN( keywords[idx].cmd );
198 <INC_STATE>{STRING} { Include( IncName(yytext) );
201 <MOD_STATE>{STRING} { Include( ModelName(yytext) );
204 <INT_STATE>{STRING} { Include( IntegName(yytext) );
207 <PRM_STATE>{STRING} { strcpy( yylval.str, yytext );
211 <CR_IGNORE>{STRING} { ScanError("Extra parameter on command line '%s'", yytext);
213 <ATM_STATE>{IDSPC} { strcpy( yylval.str, yytext );
216 <ATM_STATE>; { RETURN( yytext[0] );
218 <DSP_STATE>{IDSPC} { strcpy( yylval.str, yytext );
221 <DSP_STATE>{NR} { strcpy( yylval.str, yytext );
224 <DSP_STATE>[=] { RETURN( SPCEQUAL );
226 <DSP_STATE>[+] { RETURN( SPCPLUS );
228 <DSP_STATE>; { RETURN( yytext[0] );
230 <DSP_STATE>[^;#] { ScanError("Invalid character '%c' in species definition", yytext[0] );
232 <SSP_STATE>{IDSPC} { strcpy( yylval.str, yytext );
235 <SSP_STATE>; { RETURN( yytext[0] );
237 <INI_STATE>{IDSPC} { strcpy( yylval.str, yytext );
240 <INI_STATE>[=] { RETURN( INIEQUAL );
242 <INI_STATE>; { RETURN( yytext[0] );
244 <INI_STATE>{FLOAT} { strcpy( yylval.str, yytext );
247 <INI_STATE>[^=;#] { ScanError("Invalid character '%c' in initial values", yytext[0] );
249 <EQN_STATE>{IDSPC} { strcpy( yylval.str, yytext );
252 <EQN_STATE>[=] { RETURN( EQNEQUAL );
254 <EQN_STATE>{UFLOAT} { strcpy( yylval.str, yytext );
257 <EQN_STATE>[:] { BEGIN RATE_STATE;
261 <EQN_STATE>[+-] { strcpy( yylval.str, yytext );
264 <EQN_STATE>[<] { BEGIN EQNTAG_STATE;
267 <EQNTAG_STATE>{TAG} { strcpy( yylval.str, yytext );
270 <EQNTAG_STATE>[>] { BEGIN EQN_STATE;
271 RETURN( EQNGREATER );
273 <RATE_STATE>{STRING} { strcpy( yylval.str, yytext );
276 <RATE_STATE>; { BEGIN EQN_STATE;
279 <LMP_STATE>{IDSPC} { strcpy( yylval.str, yytext );
282 <LMP_STATE>[+] { RETURN( LMPPLUS );
284 <LMP_STATE>[:] { RETURN( LMPCOLON );
286 <LMP_STATE>; { RETURN( yytext[0] );
288 <LMP_STATE>[^;#] { ScanError("Invalid character '%c' in species definition", yytext[0] );
290 <LKT_STATE>{IDSPC} { strcpy( yylval.str, yytext );
293 <LKT_STATE>; { RETURN( yytext[0] );
295 <TPT_STATE>{IDSPC} { strcpy( yylval.str, yytext );
298 <TPT_STATE>; { RETURN( yytext[0] );
300 <USE_STATE>{STRING} { strcpy( yylval.str, yytext );
303 <USE_STATE>; { RETURN( yytext[0] );
305 <MNI_STATE>{IDSPC} { strcpy( yylval.str, yytext );
308 <MNI_STATE>; { RETURN( yytext[0] );
310 <INL_STATE>{STRING} { strcpy( yylval.str, yytext );
314 <INL_CODE>#[^ \t\n]* { if ( EqNoCase( yytext+1, "ENDINLINE" ) ){
319 strcpy( yylval.str, yytext );
323 <INL_CODE>\n { crt_line_no++;
324 strcpy( yylval.str,yytext );
327 <INL_CODE>[^#\n]* { strcpy( yylval.str,yytext );
330 <<EOF>> { if ( ! EndInclude() ) {
336 void Include ( char * name )
339 YY_BUFFER_STATE newb;
341 if ( yy_buf_level == MAX_INCLUDE ) {
342 printf("\nInclude nested too deep. Include %s ignored", name);
346 yy_buffers[ yy_buf_level ] = yy_current_buffer;
347 yy_line_no[ yy_buf_level ] = crt_line_no;
348 yy_filename[ yy_buf_level ] = crt_filename;
353 crt_filename = malloc( 1 + strlen( name ) );
354 strcpy( crt_filename, name );
357 f = fopen( name, "r" );
359 FatalError(3,"%s: Can't read file", name );
361 newb = yy_create_buffer(f, YY_BUF_SIZE);
362 yy_switch_to_buffer( newb );
367 YY_BUFFER_STATE oldb;
370 if ( yy_buf_level > 0 ) {
371 oldb = yy_current_buffer;
374 yy_switch_to_buffer( yy_buffers[yy_buf_level] );
375 crt_line_no = yy_line_no[ yy_buf_level ];
376 crt_filename = yy_filename[ yy_buf_level ];
377 yy_delete_buffer( oldb );
384 int EqNoCase( char *s1, char *s2 )
387 if ( toupper(*s1++) != toupper(*s2++) ) return 0;
392 int CheckKeyword( char *cmd )
398 if( keywords[i].name == 0 ) {
399 ScanError( "'%s': Unknown command (ignored)", cmd);
402 if( EqNoCase( cmd, keywords[i].name ) ) {