1 | /****************************************************************************** |
---|
2 | |
---|
3 | KPP - The Kinetic PreProcessor |
---|
4 | Builds simulation code for chemical kinetic systems |
---|
5 | |
---|
6 | Copyright (C) -2020 996 Valeriu Damian and Adrian Sandu |
---|
7 | Copyright (C) -2020 005 Adrian Sandu |
---|
8 | |
---|
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. |
---|
13 | |
---|
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. |
---|
18 | |
---|
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. |
---|
23 | |
---|
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 |
---|
29 | |
---|
30 | ******************************************************************************/ |
---|
31 | |
---|
32 | /****************************************************************************** |
---|
33 | bug fixes for upgrading from yacc to bison implemented by Rolf Sander, |
---|
34 | following suggestions from Jason Lander <jason@env.leeds.ac.uk> |
---|
35 | ******************************************************************************/ |
---|
36 | |
---|
37 | %s CMD_STATE INC_STATE MOD_STATE INT_STATE |
---|
38 | %s PRM_STATE DSP_STATE SSP_STATE INI_STATE EQN_STATE EQNTAG_STATE |
---|
39 | %s RATE_STATE LMP_STATE CR_IGNORE SC_IGNORE ATM_STATE LKT_STATE INL_STATE |
---|
40 | %s MNI_STATE TPT_STATE USE_STATE |
---|
41 | %s COMMENT COMMENT2 EQN_ID |
---|
42 | %x INL_CODE |
---|
43 | |
---|
44 | %{ |
---|
45 | #include <string.h> /* strcpy, strlen */ |
---|
46 | #include "gdata.h" |
---|
47 | #include "scan.h" |
---|
48 | #include "y.tab.h" |
---|
49 | |
---|
50 | void Include ( char * filename ); |
---|
51 | int EndInclude(); |
---|
52 | |
---|
53 | int crt_line_no = 1; |
---|
54 | char *crt_filename; |
---|
55 | |
---|
56 | #define MAX_INCLUDE 10 |
---|
57 | |
---|
58 | YY_BUFFER_STATE yy_buffers[ MAX_INCLUDE ]; |
---|
59 | int yy_line_no[ MAX_INCLUDE ]; |
---|
60 | char *yy_filename[ MAX_INCLUDE ]; |
---|
61 | int yy_buf_level = 0; |
---|
62 | |
---|
63 | char crtToken[100]; |
---|
64 | char nextToken[100]; |
---|
65 | int crtTokType; |
---|
66 | int nextTokType; |
---|
67 | int crtLine; |
---|
68 | char crtFile[100]; |
---|
69 | char crt_rate[100]; |
---|
70 | |
---|
71 | int oldnErr = 0; |
---|
72 | |
---|
73 | int idx; |
---|
74 | int oldstate; |
---|
75 | extern int yyerrflag; |
---|
76 | |
---|
77 | typedef struct { |
---|
78 | char *name; |
---|
79 | int next; |
---|
80 | int cmd; |
---|
81 | } KEYWORD; |
---|
82 | |
---|
83 | KEYWORD keywords[]; |
---|
84 | |
---|
85 | int CheckKeyword( char *cmd ); |
---|
86 | |
---|
87 | #define RETURN( x ) \ |
---|
88 | if(1) { \ |
---|
89 | if ( yyerrflag == 0) { \ |
---|
90 | strcpy( crtToken, nextToken ); \ |
---|
91 | crtTokType = nextTokType; \ |
---|
92 | crtLine = crt_line_no; \ |
---|
93 | strcpy( crtFile, crt_filename ); \ |
---|
94 | } \ |
---|
95 | strcpy( nextToken, yytext); \ |
---|
96 | nextTokType = x; \ |
---|
97 | return (x); \ |
---|
98 | } |
---|
99 | %} |
---|
100 | |
---|
101 | |
---|
102 | BT [ \t] |
---|
103 | SPACE [ \t] |
---|
104 | CR [\n] |
---|
105 | TAG [a-zA-Z_0-9]+ |
---|
106 | STRING [^ \t\n{}#;]+ |
---|
107 | |
---|
108 | LIT [a-zA-Z_] |
---|
109 | CIF [0-9] |
---|
110 | |
---|
111 | IDSPC {LIT}[a-zA-Z_0-9]* |
---|
112 | |
---|
113 | NR {CIF}* |
---|
114 | NRS [+-]?{CIF}+ |
---|
115 | REAL {NRS}?"."?{NR} |
---|
116 | UREAL {NR}?"."?{NR} |
---|
117 | FLOAT {REAL}([eE]{NRS})? |
---|
118 | UFLOAT {UREAL}([eE]{NRS})? |
---|
119 | |
---|
120 | %% |
---|
121 | {SPACE}+ { |
---|
122 | } |
---|
123 | # { BEGIN CMD_STATE; |
---|
124 | } |
---|
125 | \{ { oldstate = (yy_start - 1) / 2; |
---|
126 | BEGIN COMMENT; |
---|
127 | } |
---|
128 | \/\/ { oldstate = (yy_start - 1) / 2; |
---|
129 | BEGIN COMMENT2; |
---|
130 | } |
---|
131 | <COMMENT>[^\}\n]* { |
---|
132 | } |
---|
133 | <COMMENT>\} { BEGIN oldstate; |
---|
134 | } |
---|
135 | <COMMENT2>[^\n]* { |
---|
136 | } |
---|
137 | <COMMENT2>{CR} { crt_line_no++; |
---|
138 | BEGIN oldstate; |
---|
139 | } |
---|
140 | {CR} { crt_line_no++; |
---|
141 | } |
---|
142 | <CMD_STATE>{STRING} { idx = CheckKeyword( yytext ); |
---|
143 | if ( idx < 0 ) { |
---|
144 | BEGIN CR_IGNORE; |
---|
145 | break; |
---|
146 | } |
---|
147 | BEGIN keywords[idx].next; |
---|
148 | if ( keywords[idx].cmd ) { |
---|
149 | crt_section = keywords[idx].cmd; |
---|
150 | RETURN( keywords[idx].cmd ); |
---|
151 | } |
---|
152 | } |
---|
153 | <INC_STATE>{STRING} { Include( IncName(yytext) ); |
---|
154 | BEGIN CR_IGNORE; |
---|
155 | } |
---|
156 | <MOD_STATE>{STRING} { Include( ModelName(yytext) ); |
---|
157 | BEGIN CR_IGNORE; |
---|
158 | } |
---|
159 | <INT_STATE>{STRING} { Include( IntegName(yytext) ); |
---|
160 | BEGIN CR_IGNORE; |
---|
161 | } |
---|
162 | <PRM_STATE>{STRING} { strcpy( yylval.str, yytext ); |
---|
163 | BEGIN CR_IGNORE; |
---|
164 | RETURN( PARAMETER ); |
---|
165 | } |
---|
166 | <CR_IGNORE>{STRING} { ScanError("Extra parameter on command line '%s'", yytext); |
---|
167 | } |
---|
168 | <ATM_STATE>{IDSPC} { strcpy( yylval.str, yytext ); |
---|
169 | RETURN( ATOMID ); |
---|
170 | } |
---|
171 | <ATM_STATE>; { RETURN( yytext[0] ); |
---|
172 | } |
---|
173 | <DSP_STATE>{IDSPC} { strcpy( yylval.str, yytext ); |
---|
174 | RETURN( SPCSPC ); |
---|
175 | } |
---|
176 | <DSP_STATE>{NR} { strcpy( yylval.str, yytext ); |
---|
177 | RETURN( SPCNR ); |
---|
178 | } |
---|
179 | <DSP_STATE>[=] { RETURN( SPCEQUAL ); |
---|
180 | } |
---|
181 | <DSP_STATE>[+] { RETURN( SPCPLUS ); |
---|
182 | } |
---|
183 | <DSP_STATE>; { RETURN( yytext[0] ); |
---|
184 | } |
---|
185 | <DSP_STATE>[^;#] { ScanError("Invalid character '%c' in species definition", yytext[0] ); |
---|
186 | } |
---|
187 | <SSP_STATE>{IDSPC} { strcpy( yylval.str, yytext ); |
---|
188 | RETURN( SSPID ); |
---|
189 | } |
---|
190 | <SSP_STATE>; { RETURN( yytext[0] ); |
---|
191 | } |
---|
192 | <INI_STATE>{IDSPC} { strcpy( yylval.str, yytext ); |
---|
193 | RETURN( INISPC ); |
---|
194 | } |
---|
195 | <INI_STATE>[=] { RETURN( INIEQUAL ); |
---|
196 | } |
---|
197 | <INI_STATE>; { RETURN( yytext[0] ); |
---|
198 | } |
---|
199 | <INI_STATE>{FLOAT} { strcpy( yylval.str, yytext ); |
---|
200 | RETURN( INIVALUE ); |
---|
201 | } |
---|
202 | <INI_STATE>[^=;#] { ScanError("Invalid character '%c' in initial values", yytext[0] ); |
---|
203 | } |
---|
204 | <EQN_STATE>{IDSPC} { strcpy( yylval.str, yytext ); |
---|
205 | RETURN( EQNSPC ); |
---|
206 | } |
---|
207 | <EQN_STATE>[=] { RETURN( EQNEQUAL ); |
---|
208 | } |
---|
209 | <EQN_STATE>{UFLOAT} { strcpy( yylval.str, yytext ); |
---|
210 | RETURN( EQNCOEF ); |
---|
211 | } |
---|
212 | <EQN_STATE>[:] { BEGIN RATE_STATE; |
---|
213 | *crt_rate = 0; |
---|
214 | RETURN( EQNCOLON ); |
---|
215 | } |
---|
216 | <EQN_STATE>[+-] { strcpy( yylval.str, yytext ); |
---|
217 | RETURN( EQNSIGN ); |
---|
218 | } |
---|
219 | <EQN_STATE>[<] { BEGIN EQNTAG_STATE; |
---|
220 | RETURN( EQNLESS ); |
---|
221 | } |
---|
222 | <EQNTAG_STATE>{TAG} { strcpy( yylval.str, yytext ); |
---|
223 | RETURN( EQNTAG ); |
---|
224 | } |
---|
225 | <EQNTAG_STATE>[>] { BEGIN EQN_STATE; |
---|
226 | RETURN( EQNGREATER ); |
---|
227 | } |
---|
228 | <RATE_STATE>{STRING} { strcpy( yylval.str, yytext ); |
---|
229 | RETURN( RATE ); |
---|
230 | } |
---|
231 | <RATE_STATE>; { BEGIN EQN_STATE; |
---|
232 | RETURN( yytext[0] ); |
---|
233 | } |
---|
234 | <LMP_STATE>{IDSPC} { strcpy( yylval.str, yytext ); |
---|
235 | RETURN( LMPSPC ); |
---|
236 | } |
---|
237 | <LMP_STATE>[+] { RETURN( LMPPLUS ); |
---|
238 | } |
---|
239 | <LMP_STATE>[:] { RETURN( LMPCOLON ); |
---|
240 | } |
---|
241 | <LMP_STATE>; { RETURN( yytext[0] ); |
---|
242 | } |
---|
243 | <LMP_STATE>[^;#] { ScanError("Invalid character '%c' in species definition", yytext[0] ); |
---|
244 | } |
---|
245 | <LKT_STATE>{IDSPC} { strcpy( yylval.str, yytext ); |
---|
246 | RETURN( LKTID ); |
---|
247 | } |
---|
248 | <LKT_STATE>; { RETURN( yytext[0] ); |
---|
249 | } |
---|
250 | <TPT_STATE>{IDSPC} { strcpy( yylval.str, yytext ); |
---|
251 | RETURN( TPTID ); |
---|
252 | } |
---|
253 | <TPT_STATE>; { RETURN( yytext[0] ); |
---|
254 | } |
---|
255 | <USE_STATE>{STRING} { strcpy( yylval.str, yytext ); |
---|
256 | RETURN( USEID ); |
---|
257 | } |
---|
258 | <USE_STATE>; { RETURN( yytext[0] ); |
---|
259 | } |
---|
260 | <MNI_STATE>{IDSPC} { strcpy( yylval.str, yytext ); |
---|
261 | RETURN( MNIID ); |
---|
262 | } |
---|
263 | <MNI_STATE>; { RETURN( yytext[0] ); |
---|
264 | } |
---|
265 | <INL_STATE>{STRING} { strcpy( yylval.str, yytext ); |
---|
266 | BEGIN INL_CODE; |
---|
267 | RETURN( INLCTX ); |
---|
268 | } |
---|
269 | <INL_CODE>#[^ \t\n]* { if ( EqNoCase( yytext+1, "ENDINLINE" ) ){ |
---|
270 | BEGIN INITIAL; |
---|
271 | RETURN( ENDINLINE ); |
---|
272 | } |
---|
273 | else { |
---|
274 | strcpy( yylval.str, yytext ); |
---|
275 | RETURN( INCODE ); |
---|
276 | } |
---|
277 | } |
---|
278 | <INL_CODE>\n { crt_line_no++; |
---|
279 | strcpy( yylval.str,yytext ); |
---|
280 | RETURN( INCODE ); |
---|
281 | } |
---|
282 | <INL_CODE>[^#\n]* { strcpy( yylval.str,yytext ); |
---|
283 | RETURN( INCODE ); |
---|
284 | } |
---|
285 | <<EOF>> { if ( ! EndInclude() ) { |
---|
286 | RETURN( INITIAL ); |
---|
287 | } |
---|
288 | } |
---|
289 | %% |
---|
290 | |
---|
291 | KEYWORD keywords[] = { { "INCLUDE", INC_STATE, 0 }, |
---|
292 | { "MODEL", MOD_STATE, 0 }, |
---|
293 | { "INTEGRATOR", INT_STATE, 0 }, |
---|
294 | { "JACOBIAN", PRM_STATE, JACOBIAN }, |
---|
295 | { "HESSIAN", PRM_STATE, HESSIAN }, |
---|
296 | { "DECLARE", PRM_STATE, DECLARE }, |
---|
297 | { "STOICMAT", PRM_STATE, STOICMAT }, |
---|
298 | { "STOCHASTIC", PRM_STATE, STOCHASTIC }, |
---|
299 | { "DOUBLE", PRM_STATE, DOUBLE }, |
---|
300 | { "REORDER", PRM_STATE, REORDER }, |
---|
301 | { "MEX", PRM_STATE, MEX }, |
---|
302 | { "DUMMYINDEX", PRM_STATE, DUMMYINDEX}, |
---|
303 | { "EQNTAGS", PRM_STATE, EQNTAGS}, |
---|
304 | { "FUNCTION", PRM_STATE, FUNCTION }, |
---|
305 | { "ATOMS", ATM_STATE, ATOMDECL }, |
---|
306 | { "CHECK", ATM_STATE, CHECK }, |
---|
307 | { "CHECKALL", INITIAL, CHECKALL }, |
---|
308 | { "DEFVAR", DSP_STATE, DEFVAR }, |
---|
309 | { "DEFRAD", DSP_STATE, DEFVAR }, |
---|
310 | { "DEFFIX", DSP_STATE, DEFFIX }, |
---|
311 | { "SETVAR", SSP_STATE, SETVAR }, |
---|
312 | { "SETRAD", SSP_STATE, SETVAR }, |
---|
313 | { "SETFIX", SSP_STATE, SETFIX }, |
---|
314 | { "INITVALUES", INI_STATE, INITVALUES }, |
---|
315 | { "EQUATIONS", EQN_STATE, EQUATIONS }, |
---|
316 | { "LUMP", LMP_STATE, LUMP }, |
---|
317 | { "LOOKAT", LKT_STATE, LOOKAT }, |
---|
318 | { "LOOKATALL", INITIAL, LOOKATALL }, |
---|
319 | { "TRANSPORT", TPT_STATE, TRANSPORT }, |
---|
320 | { "TRANSPORTALL", INITIAL, TRANSPORTALL }, |
---|
321 | { "INITIALIZE", PRM_STATE, INITIALIZE }, |
---|
322 | { "XGRID", PRM_STATE, XGRID }, |
---|
323 | { "YGRID", PRM_STATE, YGRID }, |
---|
324 | { "ZGRID", PRM_STATE, ZGRID }, |
---|
325 | { "MONITOR", MNI_STATE, MONITOR }, |
---|
326 | { "WRITE_ATM", INITIAL, WRITE_ATM }, |
---|
327 | { "WRITE_SPC", INITIAL, WRITE_SPC }, |
---|
328 | { "WRITE_MAT", INITIAL, WRITE_MAT }, |
---|
329 | { "WRITE_OPT", INITIAL, WRITE_OPT }, |
---|
330 | { "USE", PRM_STATE, USE }, |
---|
331 | { "LANGUAGE", PRM_STATE, LANGUAGE }, |
---|
332 | { "INLINE", INL_STATE, INLINE }, |
---|
333 | { "ENDINLINE", INITIAL, ENDINLINE }, |
---|
334 | { "INTFILE", PRM_STATE, INTFILE }, |
---|
335 | { "DRIVER", PRM_STATE, DRIVER }, |
---|
336 | { "RUN", PRM_STATE, RUN }, |
---|
337 | { "USES", USE_STATE, USES }, |
---|
338 | { "SPARSEDATA", PRM_STATE, SPARSEDATA }, |
---|
339 | { 0, 0, 0 } |
---|
340 | }; |
---|
341 | |
---|
342 | void Include ( char * name ) |
---|
343 | { |
---|
344 | FILE *f; |
---|
345 | YY_BUFFER_STATE newb; |
---|
346 | |
---|
347 | if ( yy_buf_level == MAX_INCLUDE ) { |
---|
348 | printf("\nInclude nested too deep. Include %s ignored", name); |
---|
349 | return; |
---|
350 | } |
---|
351 | |
---|
352 | yy_buffers[ yy_buf_level ] = YY_CURRENT_BUFFER; |
---|
353 | yy_line_no[ yy_buf_level ] = crt_line_no; |
---|
354 | yy_filename[ yy_buf_level ] = crt_filename; |
---|
355 | yy_buf_level++; |
---|
356 | |
---|
357 | crt_line_no = 1; |
---|
358 | |
---|
359 | crt_filename = malloc( 1 + strlen( name ) ); |
---|
360 | strcpy( crt_filename, name ); |
---|
361 | |
---|
362 | |
---|
363 | f = fopen( name, "r" ); |
---|
364 | if( f == 0 ) |
---|
365 | FatalError(3,"%s: Can't read file", name ); |
---|
366 | |
---|
367 | newb = yy_create_buffer(f, YY_BUF_SIZE); |
---|
368 | yy_switch_to_buffer( newb ); |
---|
369 | } |
---|
370 | |
---|
371 | int EndInclude() |
---|
372 | { |
---|
373 | YY_BUFFER_STATE oldb; |
---|
374 | char * oldn; |
---|
375 | |
---|
376 | if ( yy_buf_level > 0 ) { |
---|
377 | oldb = YY_CURRENT_BUFFER; |
---|
378 | oldn = crt_filename; |
---|
379 | yy_buf_level--; |
---|
380 | yy_switch_to_buffer( yy_buffers[yy_buf_level] ); |
---|
381 | crt_line_no = yy_line_no[ yy_buf_level ]; |
---|
382 | crt_filename = yy_filename[ yy_buf_level ]; |
---|
383 | yy_delete_buffer( oldb ); |
---|
384 | free( oldn ); |
---|
385 | return 1; |
---|
386 | } |
---|
387 | return 0; |
---|
388 | } |
---|
389 | |
---|
390 | int EqNoCase( char *s1, char *s2 ) |
---|
391 | { |
---|
392 | while( *s1 ) { |
---|
393 | if ( toupper(*s1++) != toupper(*s2++) ) return 0; |
---|
394 | } |
---|
395 | return *s1 == *s2; |
---|
396 | } |
---|
397 | |
---|
398 | int CheckKeyword( char *cmd ) |
---|
399 | { |
---|
400 | int i; |
---|
401 | |
---|
402 | i = 0; |
---|
403 | while( 1 ) { |
---|
404 | if( keywords[i].name == 0 ) { |
---|
405 | ScanError( "'%s': Unknown command (ignored)", cmd); |
---|
406 | return -1; |
---|
407 | } |
---|
408 | if( EqNoCase( cmd, keywords[i].name ) ) { |
---|
409 | return i; |
---|
410 | } |
---|
411 | i++; |
---|
412 | } |
---|
413 | } |
---|
414 | |
---|