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 },
129 int CheckKeyword( char *cmd );
131 #define RETURN( x ) \
133 if ( yyerrflag == 0) { \
134 strcpy( crtToken, nextToken ); \
135 crtTokType = nextTokType; \
136 crtLine = crt_line_no; \
137 strcpy( crtFile, crt_filename ); \
139 strcpy( nextToken, yytext); \
155 IDSPC {LIT}[a-zA-Z_0-9]*
161 FLOAT {REAL}([eE]{NRS})?
162 UFLOAT {UREAL}([eE]{NRS})?
169 \{ { oldstate = (yy_start - 1) / 2;
172 \/\/ { oldstate = (yy_start - 1) / 2;
177 <COMMENT>\} { BEGIN oldstate;
181 <COMMENT2>{CR} { crt_line_no++;
184 {CR} { crt_line_no++;
186 <CMD_STATE>{STRING} { idx = CheckKeyword( yytext );
191 BEGIN keywords[idx].next;
192 if ( keywords[idx].cmd ) {
193 crt_section = keywords[idx].cmd;
194 RETURN( keywords[idx].cmd );
197 <INC_STATE>{STRING} { Include( IncName(yytext) );
200 <MOD_STATE>{STRING} { Include( ModelName(yytext) );
203 <INT_STATE>{STRING} { Include( IntegName(yytext) );
206 <PRM_STATE>{STRING} { strcpy( yylval.str, yytext );
210 <CR_IGNORE>{STRING} { ScanError("Extra parameter on command line '%s'", yytext);
212 <ATM_STATE>{IDSPC} { strcpy( yylval.str, yytext );
215 <ATM_STATE>; { RETURN( yytext[0] );
217 <DSP_STATE>{IDSPC} { strcpy( yylval.str, yytext );
220 <DSP_STATE>{NR} { strcpy( yylval.str, yytext );
223 <DSP_STATE>[=] { RETURN( SPCEQUAL );
225 <DSP_STATE>[+] { RETURN( SPCPLUS );
227 <DSP_STATE>; { RETURN( yytext[0] );
229 <DSP_STATE>[^;#] { ScanError("Invalid character '%c' in species definition", yytext[0] );
231 <SSP_STATE>{IDSPC} { strcpy( yylval.str, yytext );
234 <SSP_STATE>; { RETURN( yytext[0] );
236 <INI_STATE>{IDSPC} { strcpy( yylval.str, yytext );
239 <INI_STATE>[=] { RETURN( INIEQUAL );
241 <INI_STATE>; { RETURN( yytext[0] );
243 <INI_STATE>{FLOAT} { strcpy( yylval.str, yytext );
246 <INI_STATE>[^=;#] { ScanError("Invalid character '%c' in initial values", yytext[0] );
248 <EQN_STATE>{IDSPC} { strcpy( yylval.str, yytext );
251 <EQN_STATE>[=] { RETURN( EQNEQUAL );
253 <EQN_STATE>{UFLOAT} { strcpy( yylval.str, yytext );
256 <EQN_STATE>[:] { BEGIN RATE_STATE;
260 <EQN_STATE>[+-] { strcpy( yylval.str, yytext );
263 <EQN_STATE>[<] { BEGIN EQNTAG_STATE;
266 <EQNTAG_STATE>{TAG} { strcpy( yylval.str, yytext );
269 <EQNTAG_STATE>[>] { BEGIN EQN_STATE;
270 RETURN( EQNGREATER );
272 <RATE_STATE>{STRING} { strcpy( yylval.str, yytext );
275 <RATE_STATE>; { BEGIN EQN_STATE;
278 <LMP_STATE>{IDSPC} { strcpy( yylval.str, yytext );
281 <LMP_STATE>[+] { RETURN( LMPPLUS );
283 <LMP_STATE>[:] { RETURN( LMPCOLON );
285 <LMP_STATE>; { RETURN( yytext[0] );
287 <LMP_STATE>[^;#] { ScanError("Invalid character '%c' in species definition", yytext[0] );
289 <LKT_STATE>{IDSPC} { strcpy( yylval.str, yytext );
292 <LKT_STATE>; { RETURN( yytext[0] );
294 <TPT_STATE>{IDSPC} { strcpy( yylval.str, yytext );
297 <TPT_STATE>; { RETURN( yytext[0] );
299 <USE_STATE>{STRING} { strcpy( yylval.str, yytext );
302 <USE_STATE>; { RETURN( yytext[0] );
304 <MNI_STATE>{IDSPC} { strcpy( yylval.str, yytext );
307 <MNI_STATE>; { RETURN( yytext[0] );
309 <INL_STATE>{STRING} { strcpy( yylval.str, yytext );
313 <INL_CODE>#[^ \t\n]* { if ( EqNoCase( yytext+1, "ENDINLINE" ) ){
318 strcpy( yylval.str, yytext );
322 <INL_CODE>\n { crt_line_no++;
323 strcpy( yylval.str,yytext );
326 <INL_CODE>[^#\n]* { strcpy( yylval.str,yytext );
329 <<EOF>> { if ( ! EndInclude() ) {
335 void Include ( char * name )
338 YY_BUFFER_STATE newb;
340 if ( yy_buf_level == MAX_INCLUDE ) {
341 printf("\nInclude nested too deep. Include %s ignored", name);
345 yy_buffers[ yy_buf_level ] = yy_current_buffer;
346 yy_line_no[ yy_buf_level ] = crt_line_no;
347 yy_filename[ yy_buf_level ] = crt_filename;
352 crt_filename = malloc( 1 + strlen( name ) );
353 strcpy( crt_filename, name );
356 f = fopen( name, "r" );
358 FatalError(3,"%s: Can't read file", name );
360 newb = yy_create_buffer(f, YY_BUF_SIZE);
361 yy_switch_to_buffer( newb );
366 YY_BUFFER_STATE oldb;
369 if ( yy_buf_level > 0 ) {
370 oldb = yy_current_buffer;
373 yy_switch_to_buffer( yy_buffers[yy_buf_level] );
374 crt_line_no = yy_line_no[ yy_buf_level ];
375 crt_filename = yy_filename[ yy_buf_level ];
376 yy_delete_buffer( oldb );
383 int EqNoCase( char *s1, char *s2 )
386 if ( toupper(*s1++) != toupper(*s2++) ) return 0;
391 int CheckKeyword( char *cmd )
397 if( keywords[i].name == 0 ) {
398 ScanError( "'%s': Unknown command (ignored)", cmd);
401 if( EqNoCase( cmd, keywords[i].name ) ) {