%{ /************************************************************************* * * (c) Copyright 1992,1993,1994 by G & A Technical Software, Inc., * 28 Research Drive, Hampton, Virginia, 23666. * * All Rights Reserved. No part of this software or publication may be * reproduced, stored in a retrieval system, or transmitted, in any form * or by any means, electronic, mechanical, photocopying, recording, or * otherwise without the prior written permission of G & A Technical * Software, Inc. * ************************************************************************* * * Filename: s3_parser.y * * Purpose: Defines the grammar for parsing the syntax of the EMT, PCT, * PDT, and control files * * Author: John Burton * * Date: 5/31/94 * ************************************************************************* * * Modification History: * * $Log: s3_parser.y,v $ * Revision 2.1 1994/07/08 17:52:24 jcburt * Updated typedefs, defines and function protypes to allow recursive * parsing of pct files. Enabled use of sub-PDT files and scoping of * datasets. Datasets used in a pct must be defined either in the * associated pdt file or the pdt file associated with the direct * ancestors of the current pct file. * * DataSet functions and subroutines now have an additional parameter * passed to them, indicating the number of parameters passed in the * dataset list, i.e. was: function(DataSet **dl) * now: function(int nargs, DataSet **dl) * Parameters passed to the dataset routines from the PCT level are all * still contained in the dataset list, nargs is during the function or * subroutine call from s3_exec_enode * * Revision 2.0.0.1 1994/06/28 18:48:27 jcburt * S3 Version 2.0 Initial Source * * ************************************************************************* * * Revision Control Information: */ static char rcsid[] = "$Id: s3_parser.y,v 2.1 1994/07/08 17:52:24 jcburt Exp $"; static char rcsrev[] = "$Revision: 2.1 $"; /************************************************************************* * * Include Files * *************************************************************************/ #include "s3_defines.h" #include "s3_typedefs.h" #include "s3_externals.h" #include "s3_globals.h" #include "s3_parser_globals.h" /************************************************************************* * * Global Variables * *************************************************************************/ static int check_symbol = TRUE; static int cs; %} %pure_parser %union { int ival; float rval; complex cval; char *cstr; Con_list cdat; Val_list data; File_list *flst; ST_entry *symp; ST_entry **syml; } %token POW %token EOPDT EOPCT EOS CR %token START_EMT START_PDT START_PCT START_CON %token SYMBOL %token IVALUE PN EN CT SC GP DS PR OB LB EXOL EXOI %token RVALUE %token CVALUE %token CHRSTR SLABEL PATHNAME %left '-' '+' %left '*' '/' '%' %right POW %nonassoc UMINUS %type value_list val_list ilist svalue_list %type value simple_value simple_val %type repeat_value %type expr %type fname eol_list %type dimension parameter %type sym_list CON_symbol_list symbol_list dim_list dimension_list %type parameter_list param_list dataset_list %type fname_list %% Combined_parser: Parse_EMT_File | Parse_CON_File | Parse_PDT_File | Parse_PCT_File ; Parse_EMT_File: START_EMT EMT_file ; Parse_CON_File: START_CON CON_file ; Parse_PDT_File: START_PDT PDT_file ; Parse_PCT_File: START_PCT PCT_file ; EMT_file: EMT_stmtlist { /* s3_setup_shared_library(); */ } ; EMT_stmtlist: EMT_stmt | EMT_stmtlist EMT_stmt ; EMT_stmt: EOS | PN ':' SYMBOL ':' fname EOS { s3_setup_pnode($3,$5); } | PR ':' EN ':' symbol_list EOS { s3_setup_enode($3,$5,nsymbols); } | OB ':' fname_list EOS { s3_add_objects_to_list($3); } | LB ':' fname_list EOS { s3_add_libs_to_list($3); } ; CON_file: CON_stmtlist ; CON_stmtlist: CON_stmt | CON_stmtlist CON_stmt ; CON_stmt: EOS | CON_symbol_list {datatype = $1[0]->ds.type;} val_list EOS { s3_initialize_dataset($1,$3); } ; CON_symbol_list: SYMBOL { ST_entry *symp; symp = (Global_Control_File) ? s3_global_get_symbol($1) : s3_get_symbol($1); if(symp == NULL) s3_parse_warning("Symbol %s is undefined",$1); nsymbols = 1; $$ = (ST_entry **)xrealloc(NULL,nsymbols*sizeof(ST_entry *)); $$[0] = symp; } | symbol_list ',' SYMBOL { ST_entry *symp; symp = (Global_Control_File) ? s3_global_get_symbol($3) : s3_get_symbol($3); if(symp == NULL) s3_parse_warning("Symbol %s is undefined",$3); nsymbols++; $$ = (ST_entry **)xrealloc($1,nsymbols*sizeof(ST_entry *)); $$[nsymbols-1] = symp; } ; PDT_file: PDT_stmtlist ; PDT_stmtlist: PDT_stmt | PDT_stmtlist PDT_stmt ; PDT_stmt: EOS | CT ':' SYMBOL '=' expr EOS { ST_entry *symp; if((symp = s3_add_symbol($3)) == NULL) s3_parse_warning("Symbol %s previously defined",$3); symp->co.value = $5.ivalue; symp->co.type = CONST; symp->co.description = strsave($5.list); s3_dprint("CONST: %s -> %x\n",$3,symp->co.type); pdt_info->const_list = s3_add_to_list(pdt_info->const_list,&(symp),&(pdt_info->nconst),1); xfree($5.list); } | SC ':' dataset_list EOS { check_symbol = TRUE; s3_dprint("STATIC: %s \n",$3[0]->co.name); pdt_info->static_list = s3_add_to_list(pdt_info->static_list,$3,&(pdt_info->nstatic),nsymbols); } | GP ':' SYMBOL ':' dataset_list EOS { ST_entry *symp; if((symp = s3_add_symbol($3)) == NULL) s3_parse_warning("Symbol %s previously defined",$3); symp->ss.type = GROUP; symp->gr.NDS = nsymbols; symp->gr.dslist = $5; check_symbol = TRUE; s3_dprint("GROUP: %s \n",symp->co.name); pdt_info->group_list = s3_add_to_list(pdt_info->group_list,&(symp),&(pdt_info->ngroup),1); } | DS {datatype = $1;} sym_list dim_list val_list EOS { s3_create_dataset($1,$3,$4,$5); s3_dprint("DATASET: %s -> type = %x \n",$3[0]->co.name,$1); switch($1) { case BYTE: pdt_info->byte_list = s3_add_to_list(pdt_info->byte_list,$3,&(pdt_info->nbyte),nsymbols); break; case CHAR: pdt_info->char_list = s3_add_to_list(pdt_info->char_list,$3,&(pdt_info->nchar),nsymbols); break; case STRING: pdt_info->string_list = s3_add_to_list(pdt_info->string_list,$3,&(pdt_info->nstring),nsymbols); break; case INT: pdt_info->int_list = s3_add_to_list(pdt_info->int_list,$3,&(pdt_info->nint),nsymbols); break; case REAL: pdt_info->real_list = s3_add_to_list(pdt_info->real_list,$3,&(pdt_info->nreal),nsymbols); break; case DREAL: pdt_info->dreal_list = s3_add_to_list(pdt_info->dreal_list,$3,&(pdt_info->ndreal),nsymbols); break; case COMP: pdt_info->comp_list = s3_add_to_list(pdt_info->comp_list,$3,&(pdt_info->ncomp),nsymbols); break; case DCOMP: pdt_info->dcomp_list = s3_add_to_list(pdt_info->dcomp_list,$3,&(pdt_info->ndcomp),nsymbols); break; } } ; sym_list: symbol_list { s3_parse_warning("syntax error - missing :"); } | ':' symbol_list { $$ = $2; } ; symbol_list: SYMBOL { ST_entry *symp; if(check_symbol == TRUE) { if((symp = s3_add_symbol($1)) == NULL) s3_parse_warning("Symbol %s previously defined",$1); } else { if((symp = s3_get_symbol($1)) == NULL) yyerror("Symbol %s is undefined",$1); } nsymbols = 1; $$ = (ST_entry **)xrealloc(NULL,nsymbols*sizeof(ST_entry *)); $$[0] = symp; } | symbol_list ',' SYMBOL { ST_entry *symp; if(check_symbol == TRUE) { if((symp = s3_add_symbol($3)) == NULL) s3_parse_warning("Symbol %s previously defined",$3); } else { if((symp = s3_get_symbol($3)) == NULL) s3_parse_warning("Symbol %s is undefined",$3); } nsymbols++; $$ = (ST_entry **)xrealloc($1,nsymbols*sizeof(ST_entry *)); $$[nsymbols-1] = symp; } ; dataset_list: SYMBOL { ST_entry *symp; if((symp = s3_get_symbol($1)) == NULL) s3_parse_warning("Symbol %s is undefined",$1); nsymbols = 1; $$ = (ST_entry **)xrealloc(NULL,nsymbols*sizeof(ST_entry *)); $$[0] = symp; } | dataset_list ',' SYMBOL { ST_entry *symp; if((symp = s3_get_symbol($3)) == NULL) s3_parse_warning("Symbol %s is undefined",$3); nsymbols++; $$ = (ST_entry **)xrealloc($1,nsymbols*sizeof(ST_entry *)); $$[nsymbols-1] = symp; } ; dim_list: { ndims = 0; $$ = NULL; } | ':' dimension_list { $$ = $2; } ; dimension_list: {s3_parse_warning("syntax error - No dataset dimensions found");} | dimension { ndims = 1; $$ = (ST_entry **)xrealloc(NULL,ndims*sizeof(ST_entry *)); $$[0] = $1; } | dimension_list ',' dimension { ndims++; $$ = (ST_entry **)xrealloc($1,ndims*sizeof(ST_entry *)); $$[ndims-1] = $3; } ; dimension: SYMBOL { ST_entry *symp; if((symp = s3_get_symbol($1)) == NULL) s3_parse_warning("Symbol %s is undefined",$1); if(symp->ss.type == CONST) $$ = symp; else s3_parse_warning("%s is not a constant\n",$1); } | IVALUE { char tmp[32]; sprintf(tmp,"%d",$1); $$ = s3_lookup_symbol(tmp); $$->co.type = CONST; $$->co.value = $1; } | RVALUE { s3_parse_warning("REAL value not allowed in dimension statment");} ; val_list: { $$.nvals = 0; $$.dat.by = NULL; } | '=' {nvalues = 0;} ilist { $$ = $3; } ; ilist: value { $$ = $1; } | CHRSTR { $$.dat.ch_arr = (char **)xcalloc(1,sizeof(char *)); $$.dat.ch_arr[0] = strsave($1); $$.nvals = 1; $$.size = sizeof(char); } | '{' value_list '}' { $$ = $2; } | '{' svalue_list '}' { $$ = $2; } ; value_list: value { $$ = $1; } | value_list ',' value { byte *tmp; int nbytes,nbytes1,nbytes3; $$.nvals = $1.nvals + $3.nvals; $$.size = $1.size; nbytes = $$.size * $$.nvals; nbytes1 = $1.size * $1.nvals; nbytes3 = $3.size * $3.nvals; $$.dat.by = (byte *)xrealloc($1.dat.by,nbytes); tmp = $$.dat.by + nbytes1; tmp = (byte *)memcpy(tmp,$3.dat.by,nbytes3); xfree($3.dat.by); } ; value: simple_value { $$.nvals = $1.nvals; $$.size = $1.size; $$.dat.by = (byte *)xrealloc(NULL,$$.nvals*$$.size); $$.dat.by = (byte *)memcpy($$.dat.by,&($1.val.by),$1.size); } | repeat_value '*' simple_value { byte *tmp; int i; nvalues += $1; $$.nvals = $1 * $3.nvals; $$.size = $3.size; $$.dat.by = (byte *)xrealloc(NULL,$$.nvals*$$.size); tmp = $$.dat.by; for(i=0;i<$1;i++,tmp+=$$.size) tmp = (byte *)memcpy(tmp,&($3.val.by),$$.size); } ; repeat_value: SYMBOL { ST_entry *symp; if((symp = s3_get_symbol($1)) == NULL) s3_parse_warning("Symbol %s is undefined",$1); if(symp->ss.type == CONST) $$ = symp->co.value; else s3_parse_warning("%s is not a constant\n",$1); } | IVALUE { $$ = $1; } ; simple_value: simple_val { $$ = $1; } | '-' simple_val { $$ = $2; switch(datatype) { case BYTE: $$.val.by = - $$.val.by; break; case INT: $$.val.in = - $$.val.in; break; case REAL: $$.val.fl = - $$.val.fl; break; case DREAL: $$.val.db = - $$.val.db; break; case COMP: $$.val.co.r = - $$.val.co.r; $$.val.co.i = - $$.val.co.i; break; case DCOMP: $$.val.dc.r = - $$.val.dc.r; $$.val.dc.i = - $$.val.dc.i; break; default: s3_parse_error("Cannot Initialize - Undefined data type"); break; } } ; simple_val: SYMBOL { ST_entry *symp; if((symp = s3_get_symbol($1)) == NULL) s3_parse_warning("Symbol %s is undefined",$1); if(symp->ss.type == CONST) { switch(datatype) { case INT: $$.size = sizeof(int); $$.val.in = symp->co.value; break; case BYTE: $$.size = sizeof(int); if(symp->co.value > 255) { $$.val.by = 0; s3_parse_warning("Constant value %d is too large for type BYTE",symp->co.value); } else $$.val.by = symp->co.value; break; case REAL: case DREAL: case COMP: case DCOMP: s3_parse_warning("Type mismatch between dataset and constant value %s",symp->co.name); break; default: s3_parse_error("Cannot Initialize - Undefined data type"); break; } } else s3_parse_warning("%s is not a constant\n",symp->ss.name); $$.nvals = 1; } | IVALUE { switch(datatype) { case INT: $$.size = sizeof(int); $$.val.in = $1; break; case BYTE: $$.size = sizeof(byte); if($1 > 255) { $$.val.by = 0; s3_parse_warning("Constant value %d is too large for type BYTE",$1); } else $$.val.by = $1; break; case REAL: case DREAL: case COMP: case DCOMP: s3_parse_error("Type mismatch between dataset and initialization value %d",$1); break; default: s3_parse_error("Cannot Initialize - Undefined data type"); break; } $$.nvals = 1; } | RVALUE { switch(datatype) { case REAL: $$.size = sizeof(float); $$.val.fl = $1; break; case DREAL: $$.size = sizeof(double); $$.val.db = $1; break; case BYTE: case INT: case COMP: case DCOMP: s3_parse_error("Type mismatch between dataset and initialization value"); break; default: s3_parse_error("Cannot Initialize - Undefined data type"); break; } $$.nvals = 1; } | CVALUE { switch(datatype) { case COMP: $$.size = sizeof(complex); $$.val.co.r = $1.r; $$.val.co.i = $1.i; break; case DCOMP: $$.size = sizeof(dbl_complex); $$.val.dc.r = $1.r; $$.val.dc.i = $1.i; break; case BYTE: case INT: case REAL: case DREAL: s3_parse_warning("Type mismatch between dataset and initialization value"); break; default: s3_parse_error("Cannot Initialize - Undefined data type"); break; } $$.nvals = 1; } ; svalue_list: CHRSTR { $$.dat.ch_arr = (char **)xrealloc(NULL,sizeof(char *)); $$.dat.ch_arr[0] = strsave($1); $$.nvals = 1; $$.size = sizeof(char); } | svalue_list ',' CHRSTR { $$.nvals = $1.nvals + 1; $$.dat.ch_arr = (char **)xrealloc($1.dat.ch_arr,$$.nvals*sizeof(char *)); $$.dat.ch_arr[$1.nvals] = strsave($3); } ; expr: expr '+' expr { $$.ivalue = $1.ivalue + $3.ivalue; $$.list = strsave2(strsave2($1.list,"+"),$3.list); xfree($1.list); xfree($3.list); } | expr '-' expr { $$.ivalue = $1.ivalue - $3.ivalue; $$.list = strsave2(strsave2($1.list,"-"),$3.list); xfree($1.list); xfree($3.list); } | expr '*' expr { $$.ivalue = $1.ivalue * $3.ivalue; $$.list = strsave2(strsave2($1.list,"*"),$3.list); xfree($1.list); xfree($3.list); } | expr '/' expr { if($3.ivalue == 0) s3_parse_warning("divide by zero"); else { $$.ivalue = $1.ivalue / $3.ivalue; $$.list = strsave2(strsave2($1.list,"/"),$3.list); xfree($1.list); xfree($3.list); } } | expr '%' expr { $$.ivalue = $1.ivalue % $3.ivalue; $$.list = strsave2(strsave2($1.list,"%"),$3.list); xfree($1.list); xfree($3.list); } | expr POW expr { int i, tmp; tmp = 1; for(i=0;i<$3.ivalue;i++) tmp = tmp * $1.ivalue; $$.ivalue = tmp; $$.list = strsave2(strsave2($1.list,"**"),$3.list); xfree($1.list); xfree($3.list); } | '-' expr %prec UMINUS { $$.ivalue = -$2.ivalue; $$.list = strsave2("-",$2.list); xfree($2.list); } | '(' expr ')' { $$.ivalue = $2.ivalue; $$.list = strsave2(strsave2("(",$2.list),")"); xfree($2.list); } | IVALUE { char tmp[32]; sprintf(tmp,"%d",$1); $$.ivalue = $1; $$.list = strsave(tmp); } | SYMBOL { ST_entry *symp; if((symp = s3_get_symbol($1)) == NULL) s3_parse_warning("Symbol %s is undefined",$1); if(symp->ss.type == CONST) { $$.ivalue = symp->co.value; $$.list = strsave(symp->co.name); } else s3_parse_warning("%s is not a constant\n",$1); } ; PCT_file: PCT_init PCT_stmtlist { ST_entry **elist; int i; if((verbose)||(debug)) { fprintf(fperr,"PCT => %s \n",current_pct->pn.name); fprintf(fperr," Description => %s\n",current_pct->pn.description); fprintf(fperr," EOL => %s\n",current_pct->pn.EOL); fprintf(fperr," EOI => %d\n",current_pct->pn.EOI); fprintf(fperr," filename => %s\n",current_pct->pn.filename); fprintf(fperr," elkey => %s\n",current_pct->pn.elkey); fprintf(fperr," NE => %d\n",current_pct->pn.NE); elist = current_pct->pn.elist; for(i=0;ipn.NE;i++) { fprintf(fperr," Entry %d => %s\n",i,elist[i]->ss.name); } } } ; PCT_init: { current_pnode = (Pnode *)current_pct; current_pct->pn.NE = 0; s3_dprint("PCT => %s\n",current_pct->pn.name); } PCT_stmtlist: PCT_stmt | PCT_stmtlist PCT_stmt ; PCT_stmt: EOS | EXOL '=' eol_list EOS { current_pct->pn.EOL = strsave($3); s3_dprint("EOL = %s\n",$3); } | EXOI '=' IVALUE EOS { current_pct->pn.EOI = $3; } | SLABEL ':' SYMBOL param_list EOS { ST_entry *tmp,*symp; s3_add_elkey($1); s3_dprint("yyparse: PCT_stmt: SYMBOL = %s, nparams = %d",$3,nparams); if((symp = s3_get_symbol($3)) == NULL) s3_parse_warning("Symbol %s is undefined",$3); if(symp->ss.type == PNODE) { tmp = s3_initialize_pnode(symp,$4,nparams); s3_add_to_elist(tmp); s3_parse_sub_pct(tmp); } else { tmp = s3_initialize_enode(symp,$4,nparams); s3_add_to_elist(tmp); } } ; eol_list: SYMBOL { $$ = strsave($1); } | eol_list ',' SYMBOL { $$ = stringcat($1,$3); } ; fname_list: fname { $$ = s3_add_file(NULL,$1); } | fname_list ',' fname { $$ = s3_add_file($1,$3); } ; fname: SYMBOL { $$ = $1; } | PATHNAME { $$ = $1; } ; param_list: { $$ = NULL; nparams = 0;} | ':' { $$ = NULL; nparams = 0; s3_parse_warning("Parameter list expected, no parameters will be passed"); } | ':' parameter_list { $$ = $2; } ; parameter_list: parameter { $$ = s3_make_parameter_list(NULL,$1); } | parameter_list ',' parameter { $$ = s3_make_parameter_list($1,$3); } ; parameter : SYMBOL { ST_entry *entry,*symp; if((symp = s3_get_symbol($1)) == NULL) s3_parse_warning("Symbol %s is undefined",$1); s3_dprint("yyparse: parameter: symbol %s has type %x",symp->ss.name,symp->ss.type); switch(symp->ss.type) { case CONST: entry = s3_make_temp_dataset(symp->ss.name,INT,0,NULL); entry->ds.d.in[0] = symp->co.value; $$ = entry; break; case BYTE: case CHAR: case STRING: case INT: case REAL: case DREAL: case COMP: case DCOMP: case GROUP: $$ = symp; break; default: s3_parse_error("Symbol %s has invalid type = %x",symp->ss.name,symp->ss.type); break; } } | IVALUE { ST_entry *entry; char buff[20]; sprintf(buff,"%d",$1); entry = s3_make_temp_dataset(buff,INT,0,NULL); entry->ds.d.in[0] = $1; $$ = entry; } | RVALUE { ST_entry *entry; char buff[20]; sprintf(buff,"%f",$1); entry = s3_make_temp_dataset(buff,REAL,0,NULL); entry->ds.d.fl[0] = $1; $$ = entry; } | CHRSTR { ST_entry *entry; int len; len = strlen($1) + 1; s3_dprint("yyparse: parameter = CHRSTR = %s",$1); s3_dprint(" strlen = %d",len); entry = s3_make_temp_dataset(NULL,CHAR,1,&len); entry->ds.d.ch = strcpy(entry->ds.d.ch,$1); $$ = entry; } ; %%