%{ /************************************************************************* * * (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_lexer.l * * Purpose: Provides the lexical analyser front-end to the S3 grammar parser * s3_parser.y * * Author: John Burton * * Date: 5/31/94 * ************************************************************************* * * Modification History: * * $Log: s3_lexer.l,v $ * Revision 2.1 1994/07/08 17:52:22 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:26 jcburt * S3 Version 2.0 Initial Source * * ************************************************************************* * * Revision Control Information: */ static char rcsid[] = "$Id: s3_lexer.l,v 2.1 1994/07/08 17:52:22 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.tab.h" #include #include "s3_lexer_globals.h" /************************************************************************* * * Defines and Macros * *************************************************************************/ #define MAX_QUEUE 64 #define YY_USER_INIT if(first_pass)\ {\ first_pass = 0;\ switch(parser_start_type) \ { \ case PARSE_CON: \ BEGIN CON; \ return START_CON; \ break; \ case PARSE_EMT: \ BEGIN EMT; \ return START_EMT; \ break; \ case PARSE_PDT: \ BEGIN PDT; \ return START_PDT; \ break; \ case PARSE_PCT: \ BEGIN PCT; \ return START_PCT; \ break; \ }\ } #undef YY_DECL #define YY_DECL int yylex (YYSTYPE *lvalp) /************************************************************************* * * Global Variables and Function Prototypes * *************************************************************************/ extern int yyparse(); typedef struct stack_entry{ ST_entry *entry; YY_BUFFER_STATE state; int tokenpos; int lineno; struct stack_entry *previous; } Stack_Entry; typedef struct { Stack_Entry *top; } Stack_Type; Stack_Type state_stack = {NULL}; ST_entry *state_queue[MAX_QUEUE]; int queue_ptr = 0; int queue_end = 0; static int first_pass = 1; typedef struct { char *name; int ptype; int type; } S3_stmt_type; S3_stmt_type PDT_type[] = { "BYTE", DS, BYTE, "CHAR", DS, CHAR, "STRING", DS, STRING, "INT", DS, INT, "REAL", DS, REAL, "DREAL", DS, DREAL, "COMP", DS, COMP, "DCOMP", DS, DCOMP, "CONST", CT, CONST, "STATIC", SC, STATIC, "GROUP", GP, GROUP }; S3_stmt_type EMT_type[] = { "SPCT", PN, PNODE, "PROC", PR, PROC, "OBJS", OB, OBJS, "LIBS", LB, LIBS }; S3_stmt_type PCT_type[] = { "PN", PN, PNODE, "CF", EN, CFUNC, "CS", EN, CSUBR, "DF", EN, DFUNC, "DS", EN, DSUBR, "FF", EN, FFUNC, "FS", EN, FSUBR, "EOL", EXOL, EXOL, "EOI", EXOI, EXOI }; %} %s PDT PCT EMT CON intvalue (-?[0-9]+) realvalue (-?(([0-9]+)|([0-9]*\.[0-9]+)([eE][-+]?[0-9]+)?)) %% ^[\t ]*[a-zA-Z]+[\t ]*/: { int ndtypes = sizeof(EMT_type) / sizeof(S3_stmt_type); int i,j,len; char *tmp; Tokenpos += yyleng; tmp = strsave(yytext); len = strlen(tmp); for(i=0,j=0;iival = EMT_type[i].type; return (EMT_type[i].ptype); } "**" { Tokenpos += yyleng; return POW;} ^[\t ]*[a-zA-Z]+[\t ]*/: { int ndtypes = sizeof(PDT_type) / sizeof(S3_stmt_type); int i,j,len; char *tmp; Tokenpos += yyleng; tmp = strsave(yytext); len = strlen(tmp); for(i=0,j=0;iival = PDT_type[i].type; return (PDT_type[i].ptype); } [Pp][Nn] { int ndtypes = sizeof(PCT_type) / sizeof(S3_stmt_type); int i,len; char *tmp; Tokenpos += yyleng; lvalp->ival = PNODE; return (PN); } [Ee][Oo][LlIi] {int ndtypes = sizeof(PCT_type) / sizeof(S3_stmt_type); int i,len; char *tmp; Tokenpos += yyleng; tmp = strsave(yytext); len = strlen(tmp); for(i=0;iival = PCT_type[i].type; return (PCT_type[i].ptype); } [CcDdFf][FfSs] { int ndtypes = sizeof(PCT_type) / sizeof(S3_stmt_type); int i,len; char *tmp; Tokenpos += yyleng; tmp = strsave(yytext); len = strlen(tmp); for(i=0;iival = PCT_type[i].type; if((lvalp->ival == FSUBR)||(lvalp->ival == FFUNC)) CaseSensitive = FALSE; else CaseSensitive = TRUE; return (PCT_type[i].ptype); } ^[\t ]*[a-zA-Z][\t ]*/: { Tokenpos += yyleng; lvalp->cstr = strsave(yytext); return SLABEL; } {intvalue} { Tokenpos += yyleng; lvalp->ival = atoi(yytext); return IVALUE; } {realvalue} { Tokenpos += yyleng; lvalp->rval = atof(yytext); return RVALUE; } "("{realvalue}","{realvalue}")" { Tokenpos += yyleng; scanf(yytext,"(%f,%f)",&(lvalp->cval.r),&(lvalp->cval.i)); return CVALUE; } \"[^"\n]*\" { Tokenpos += yyleng; lvalp->cstr = strsave(yytext+1); lvalp->cstr[strlen(lvalp->cstr)-1] = '\0'; return CHRSTR; } \"[^"\n]*$ { Tokenpos += yyleng; yyerror("Unterminated string - %s",yytext); lvalp->cstr = strsave(yytext+1); lvalp->cstr[strlen(lvalp->cstr)-1] = '\0'; return CHRSTR; } \'[^'\n]*\' { Tokenpos += yyleng; lvalp->cstr = strsave(yytext+1); lvalp->cstr[strlen(lvalp->cstr)-1] = '\0'; return CHRSTR; } \'[^'\n]*$ { Tokenpos += yyleng; yyerror("Unterminated string - %s",yytext); lvalp->cstr = strsave(yytext+1); lvalp->cstr[strlen(lvalp->cstr)-1] = '\0'; return CHRSTR; } [ \t]+ {Tokenpos += yyleng;} /* ignore white space */ [ \f\t]+\n { Tokenpos += yyleng; Lineno++; } [_A-Za-z][_A-Za-z0-9]* { /* return symbol pointer */ Tokenpos += yyleng; lvalp->cstr = strsave(yytext); return SYMBOL; } [-_A-Za-z/"."][-_A-Za-z0-9/"."]* { /* File pathname */ Tokenpos += yyleng; lvalp->cstr = strsave(yytext); return PATHNAME; } "!".* { Tokenpos += yyleng; } ";".* { Tokenpos += yyleng; return EOS; } \\.* { Tokenpos += yyleng; } \n.* { Tokenpos = 0; if (Linebuf != NULL) xfree(Linebuf); Lineno++; Linebuf = strsave(yytext); yyless(1); } . { Tokenpos += yyleng; return yytext[0];} <> { CaseSensitive = TRUE; BEGIN PDT; yyterminate(); } <> { BEGIN PCT; yyterminate(); } <> { BEGIN PCT; yyterminate(); } %% /************************************************************************* * * Module: s3_push_stack_entry * * Description: Adds a pct file to the parsing stack. * * Syntax: s3_push_stack_entry(stack_entry *entry) * * Inputs: *entry: Pointer to the stack entry * * Outputs: Adds entry to the global variable state_stack * * Returns: * * Modules Called: * *************************************************************************/ void s3_push_stack_entry(Stack_Entry *entry) { entry->previous = state_stack.top; state_stack.top = entry; } /************************************************************************* * * Module: s3_pop_stack_entry * * Description: Removes a pct file from the parsing stack. * * Syntax: s3_pop_stack_entry() * * Inputs: * * Outputs: Removes entry from the global variable state_stack * * Returns: The stack entry at the top of the stack * * Modules Called: * *************************************************************************/ Stack_Entry *s3_pop_stack_entry() { Stack_Entry *tmp; tmp = state_stack.top; state_stack.top = tmp->previous; return tmp; } /************************************************************************* * * Module: s3_parse_warning * * Description: Displays a parser warning message to stderr giving the * line number and text of the offending line. Warnings * are not fatal and parsing continues. Increments the * global variable parse_warning_count. * * Syntax: s3_parse_warning(va_list) * * Inputs: va_list: A variable argument list typically containing * a format string and various data to be displayed * (similar to a printf statement) * * Outputs: Displays error message on stderr. * * Returns: * * Modules Called: * *************************************************************************/ /* VARARGS */ void s3_parse_warning(va_alist) va_dcl { va_list ap; char *fmt,*tmp; int type; va_start(ap); fmt = va_arg(ap, char *); fprintf(fperr,"\n%s: Line number %d: ", currentfilename,Lineno); vfprintf(fperr,fmt, ap); fprintf(fperr,"\n%s\n",Linebuf); fprintf(fperr,"%*s\n",1+Tokenpos,"^"); fprintf(fperr,"\n"); va_end(ap); parse_warning_count++; } /************************************************************************* * * Module: s3_parse_error * * Description: Displays a parser error message to stderr giving the * line number and text of the offending line. Errors * are fatal and parsing halts. * * Syntax: s3_parse_error(va_list) * * Inputs: va_list: A variable argument list typically containing * a format string and various data to be displayed * (similar to a printf statement) * * Outputs: Displays error message on stderr. * * Returns: * * Modules Called: * *************************************************************************/ void s3_parse_error(va_alist) va_dcl { va_list ap; char *fmt,*tmp; int type; va_start(ap); sprintf(tmp,"this is a test...testing...testing...\n"); fmt = va_arg(ap, char *); fprintf(fperr,"\n%s: Line number %d: ", currentfilename,Lineno); vfprintf(fperr,fmt, ap); fprintf(fperr,"\n%s\n",Linebuf); fprintf(fperr,"%*s\n",1+Tokenpos,"^"); fprintf(fperr, "\n"); va_end(ap); exit(1); } /************************************************************************* * * Module: s3_parse_control_file * * Description: Parses and S3 control file to initialize datasets. * * Syntax: s3_parse_control_file(char *filename) * * Inputs: *filename: character string containing the name of * control file to be parsed. * * Outputs: * * Returns: Number of parser warnings encountered * * Modules Called: * *************************************************************************/ int s3_parse_control_file(char *filename) { int i; if((yyin = fopen(filename,"r")) == NULL) s3_error(SYS,"Cannot open control file %s",filename); parser_start_type = PARSE_CON; if(currentfilename != NULL) xfree(currentfilename); currentfilename = strsave(filename); Lineno = 1; Tokenpos = 0; first_pass = 1; yy_init = 1; yyparse(); return (parse_warning_count); } /************************************************************************* * * Module: s3_parse_emt_file * * Description: Initiates parsing of an EMT (executable module definition) * file. * * Syntax: s3_parse_emt_file(char *filename) * * Inputs: *filename: character string containing the name of the * EMT file to be parsed. * * Outputs: * * Returns: Number of parser warnings encountered * * Modules Called: * *************************************************************************/ EMT_struct *s3_parse_emt_file(char *filename) { emt_info = (EMT_struct *)xmalloc(sizeof(EMT_struct)); emt_info = (EMT_struct *)memset(emt_info,0,sizeof(EMT_struct)); if((yyin = fopen(filename,"r")) == NULL) s3_error(SYS,"Cannot open EMT file %s",filename); parser_start_type = PARSE_EMT; if(currentfilename != NULL) xfree(currentfilename); currentfilename = strsave(filename); Lineno = 1; Tokenpos = 0; first_pass = 1; yy_init = 1; yyparse(); if(parse_warning_count > 0) return NULL; else return emt_info; } /************************************************************************* * * Module: s3_parse_pdt_file * * Description: Initiates the parsing of a PDT (parameter definition * table) file . * * Syntax: s3_parse_pdt_file(char *filename) * * Inputs: *filename: A character string containing the name of * the PDT file to be parsed. * * Outputs: * * Returns: A pointer to the pdt_info data structure * * Modules Called: * *************************************************************************/ PDT_struct *s3_parse_pdt_file(char *filename) { pdt_info = (PDT_struct *)xmalloc(sizeof(PDT_struct)); pdt_info = (PDT_struct *)memset(pdt_info,0,sizeof(PDT_struct)); if((yyin = fopen(filename,"r")) == NULL) s3_error(SYS,"Cannot open PDT file %s",filename); parser_start_type = PARSE_PDT; if(currentfilename != NULL) xfree(currentfilename); currentfilename = strsave(filename); Lineno = 1; Tokenpos = 0; first_pass = 1; yy_init = 1; yyparse(); if(parse_warning_count > 0) return NULL; else return pdt_info; } /************************************************************************* * * Module: s3_parse_pct_file * * Description: Initiates parsing of a PCT (process control table) * file. * * Syntax: s3_parse_pct_file(char *filename) * * Inputs: *filename: A character string containing the name of * the PCT file to be parsed. * * Outputs: * * Returns: A pointer to the pct_info data structure. * * Modules Called: * *************************************************************************/ PCT_struct *s3_parse_pct_file(char *filename,int Static) { ST_entry *entry; char *basename,*ptr; pct_info = (PCT_struct *)xmalloc(sizeof(PCT_struct)); pct_info = (PCT_struct *)memset(pct_info,0,sizeof(PCT_struct)); pct_info->pct_list = (ST_entry **)xrealloc(NULL,sizeof(ST_entry *)); basename = strsave(filename); ptr = strstr(basename,".pct"); *ptr = '\0'; if(!Static) s3_setup_pnode(basename,filename); entry = s3_get_symbol(basename); entry->pn.parsed = TRUE; current_pct = entry; main_pnode = (Pnode *)current_pct; pct_info->main_pct = entry; pct_info->pct_list[0] = entry; pct_info->npct = 1; parser_start_type = PARSE_PCT; Lineno = 1; Tokenpos = 0; first_pass = 1; yy_init = 1; queue_ptr = 0; if(currentfilename != NULL) xfree(currentfilename); currentfilename = strsave(entry->pn.filename); if((yyin = fopen(currentfilename,"r")) == NULL) s3_error(SYS,"Cannot open PCT file %s",currentfilename); yyrestart(yyin); yyparse(); if(parse_warning_count > 0) return NULL; else return pct_info; } /************************************************************************* * * Module: s3_parse_sub_pdt_file * * Description: Initiates the parsing of a PDT (parameter definition * table) file . * * Syntax: s3_parse_sub_pdt_file(char *filename) * * Inputs: *filename: A character string containing the name of * the PDT file to be parsed. * * Outputs: * * Returns: A pointer to the pdt_info data structure * * Modules Called: * *************************************************************************/ void s3_parse_sub_pdt_file(char *filename) { if((yyin = fopen(filename,"r")) != NULL) { parser_start_type = PARSE_PDT; if(currentfilename != NULL) xfree(currentfilename); currentfilename = strsave(filename); Lineno = 1; Tokenpos = 0; first_pass = 1; yy_init = 1; parser_start_type = PARSE_PDT; yy_switch_to_buffer(yy_create_buffer(yyin,YY_BUF_SIZE)); yyparse(); yy_delete_buffer(YY_CURRENT_BUFFER); } } /************************************************************************* * * Module: s3_parse_sub_pct_file * * Description: Initiates parsing of a PCT (process control table) * file. * * Syntax: s3_parse_pct_file(char *filename) * * Inputs: *filename: A character string containing the name of * the PCT file to be parsed. * * Outputs: * * Returns: A pointer to the pct_info data structure. * * Modules Called: * *************************************************************************/ void s3_parse_sub_pct(ST_entry *entry) { char *pdtname,*ptr; Stack_Entry *st; ST_entry **table; if (!entry->pn.parsed) { st = (Stack_Entry *)xmalloc(sizeof(Stack_Entry)); st->entry = current_pct; st->state = YY_CURRENT_BUFFER; st->lineno = Lineno; st->tokenpos = Tokenpos; s3_push_stack_entry(st); table = s3_create_symbol_table(); s3_push_symbol_table(table); entry->pn.symbol_table = table; entry->pn.parsed = TRUE; pct_info->pct_list = (ST_entry **)xrealloc(pct_info->pct_list, (pct_info->npct+1)*sizeof(ST_entry *)); pct_info->pct_list[pct_info->npct] = entry; pct_info->npct++; pdtname = strsave2(entry->pn.name,".pdt"); s3_parse_sub_pdt_file(pdtname); if(currentfilename != NULL) xfree(currentfilename); currentfilename = strsave(entry->pn.filename); if((yyin = fopen(currentfilename,"r")) == NULL) s3_error(SYS,"Cannot open PCT file %s",currentfilename); yy_switch_to_buffer(yy_create_buffer(yyin,YY_BUF_SIZE)); current_pct = entry; Lineno = 1; Tokenpos = 0; first_pass = 1; yy_init = 1; parser_start_type = PARSE_PCT; yyparse(); s3_pop_symbol_table(); st = s3_pop_stack_entry(); yy_delete_buffer(YY_CURRENT_BUFFER); yy_switch_to_buffer(st->state); current_pct = st->entry; Lineno = st->lineno; Tokenpos = st->tokenpos; xfree(st); } } int yywrap() { return 1; }