[2696] | 1 | /****************************************************************************** |
---|
| 2 | |
---|
| 3 | KPP - The Kinetic PreProcessor |
---|
| 4 | Builds simulation code for chemical kinetic systems |
---|
| 5 | |
---|
[4481] | 6 | Copyright (C) -2020 996 Valeriu Damian and Adrian Sandu |
---|
| 7 | Copyright (C) -2020 005 Adrian Sandu |
---|
[2696] | 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 | |
---|