# HG changeset patch # User Mario de Sousa # Date 1354031345 0 # Node ID f1fc4aa6f0e35421a2c5a1ea0b2a254dedd62746 # Parent 634f476cb60f04ba6d351959aae90691c6207be4 Code cleanup: move tracking functions to flex. diff -r 634f476cb60f -r f1fc4aa6f0e3 stage1_2/iec_bison.yy --- a/stage1_2/iec_bison.yy Tue Nov 27 14:49:08 2012 +0000 +++ b/stage1_2/iec_bison.yy Tue Nov 27 15:49:05 2012 +0000 @@ -7971,11 +7971,6 @@ #include #include "../util/symtable.hh" -/* variables defined in code generated by flex... */ -extern FILE *yyin; -extern int yylineno; -extern tracking_t* current_tracking; - @@ -8102,7 +8097,6 @@ } //fprintf(stderr, "error %d: %s\n", yynerrs /* a global variable */, additional_error_msg); print_include_stack(); - //fprintf(stderr, "%s(%d-%d): %s\n", current_filename, first_line, last_line, current_error_msg); } @@ -8253,36 +8247,11 @@ bool full_token_loc_ /* error messages specify full token location */ ) { - FILE *in_file = NULL, *lib_file = NULL; char *libfilename = NULL; - - if((in_file = fopen(filename, "r")) == NULL) { - char *errmsg = strdup2("Error opening main file ", filename); - perror(errmsg); - free(errmsg); - return -1; - } if (includedir != NULL) { INCLUDE_DIRECTORIES[0] = includedir; } - if ((libfilename = strdup3(INCLUDE_DIRECTORIES[0], "/", LIBFILE)) == NULL) { - fprintf (stderr, "Out of memory. Bailing out!\n"); - return -1; - } - - if((lib_file = fopen(libfilename, "r")) == NULL) { - char *errmsg = strdup2("Error opening library file ", libfilename); - perror(errmsg); - free(errmsg); - } - - if (lib_file == NULL) { - /* we give up... */ - free(libfilename); - fclose(in_file); - return -1; - } /* first parse the standard library file... */ /* Do not debug the standard library, even if debug flag is set! */ @@ -8291,12 +8260,23 @@ yydebug = 1; #endif */ - yyin = lib_file; + + if ((libfilename = strdup3(INCLUDE_DIRECTORIES[0], "/", LIBFILE)) == NULL) { + fprintf (stderr, "Out of memory. Bailing out!\n"); + return -1; + } + + if(parse_file(libfilename) < 0) { + char *errmsg = strdup2("Error opening library file ", libfilename); + perror(errmsg); + free(errmsg); + /* we give up... */ + return -1; + } + allow_function_overloading = true; allow_extensible_function_parameters = true; full_token_loc = full_token_loc_; - current_filename = libfilename; - current_tracking = GetNewTracking(yyin); if (yyparse() != 0) ERROR; @@ -8305,7 +8285,6 @@ ERROR; } free(libfilename); - fclose(lib_file); /* if by any chance the library is not complete, we * now add the missing reserved keywords to the list!!! @@ -8320,17 +8299,21 @@ #if YYDEBUG yydebug = 1; #endif - yyin = in_file; + + if(parse_file(filename) < 0) { + char *errmsg = strdup2("Error opening main file ", filename); + perror(errmsg); + free(errmsg); + return -1; + } + allow_function_overloading = false; allow_extensible_function_parameters = false; full_token_loc = full_token_loc_; - current_filename = filename; - current_tracking = GetNewTracking(yyin); - {int res; - if ((res = yyparse()) != 0) { - fprintf (stderr, "\nParsing failed because of too many consecutive syntax errors. Bailing out!\n"); - exit(EXIT_FAILURE); - } + + if (yyparse() != 0) { + fprintf (stderr, "\nParsing failed because of too many consecutive syntax errors. Bailing out!\n"); + exit(EXIT_FAILURE); } if (yynerrs > 0) { @@ -8341,7 +8324,6 @@ if (tree_root_ref != NULL) *tree_root_ref = tree_root; - fclose(in_file); return 0; } diff -r 634f476cb60f -r f1fc4aa6f0e3 stage1_2/iec_flex.ll --- a/stage1_2/iec_flex.ll Tue Nov 27 14:49:08 2012 +0000 +++ b/stage1_2/iec_flex.ll Tue Nov 27 15:49:05 2012 +0000 @@ -144,15 +144,11 @@ extern YYSTYPE yylval; /* The name of the file currently being parsed... - * This variable is declared and read from the code generated by bison! * Note that flex accesses and updates this global variable - * apropriately whenever it comes across an (*#include *) - * directive... - */ -/* - NOTE: already defined in iec_bison.h -extern const char *current_filename; -*/ + * apropriately whenever it comes across an (*#include *) directive... + */ +const char *current_filename = NULL; + /* We will not be using unput() in our flex code... */ @@ -249,6 +245,8 @@ void unput_and_mark(const char c); void include_file(const char *include_filename); + +int GetNextChar(char *b, int maxBuffer); %} @@ -466,12 +464,22 @@ #define MAX_INCLUDE_DEPTH 16 typedef struct { + int eof; + int lineNumber; + int currentChar; + int lineLength; + int currentTokenStart; + char *buffer; + FILE *in_file; + } tracking_t; + +typedef struct { YY_BUFFER_STATE buffer_state; - tracking_t* env; + tracking_t *env; const char *filename; } include_stack_t; -tracking_t* current_tracking; +tracking_t *current_tracking = NULL; include_stack_t include_stack[MAX_INCLUDE_DEPTH]; int include_stack_ptr = 0; @@ -483,7 +491,6 @@ "/usr/lib/iec", NULL /* must end with NULL!! */ }; - %} @@ -885,6 +892,7 @@ * parser is called once again with a new file. * (In fact, we currently do just that!) */ + fclose(yyin); free(current_tracking); if (include_stack_ptr == 0) { /* yyterminate() terminates the scanner and returns a 0 to the @@ -984,20 +992,20 @@ /* body_state -> (il_state | st_state) */ { {st_whitespace_no_pragma} /* Eat any whitespace */ -{qualified_identifier}{st_whitespace}":=" unput_text(0); BEGIN(st_state); -{direct_variable_standard}{st_whitespace}":=" unput_text(0); BEGIN(st_state); +{qualified_identifier}{st_whitespace}":=" unput_text(0); BEGIN(st_state); +{direct_variable_standard}{st_whitespace}":=" unput_text(0); BEGIN(st_state); {qualified_identifier}"[" unput_text(0); BEGIN(st_state); -RETURN unput_text(0); BEGIN(st_state); -IF unput_text(0); BEGIN(st_state); +RETURN unput_text(0); BEGIN(st_state); +IF unput_text(0); BEGIN(st_state); CASE unput_text(0); BEGIN(st_state); -FOR unput_text(0); BEGIN(st_state); +FOR unput_text(0); BEGIN(st_state); WHILE unput_text(0); BEGIN(st_state); -REPEAT unput_text(0); BEGIN(st_state); +REPEAT unput_text(0); BEGIN(st_state); EXIT unput_text(0); BEGIN(st_state); /* ':=' occurs only in transitions, and not Function or FB bodies! */ -:= unput_text(0); BEGIN(st_state); +:= unput_text(0); BEGIN(st_state); /* Hopefully, the above rules (along with the last one), * used to distinguish ST from IL, are @@ -1649,6 +1657,60 @@ %% +/*************************/ +/* Tracking Functions... */ +/*************************/ + +#define MAX_BUFFER_LENGTH 1000 + +tracking_t *GetNewTracking(FILE* in_file) { + tracking_t* new_env = new tracking_t; + new_env->eof = 0; + new_env->lineNumber = 0; + new_env->currentChar = 0; + new_env->lineLength = 0; + new_env->currentTokenStart = 0; + new_env->buffer = (char*)malloc(MAX_BUFFER_LENGTH); + new_env->in_file = in_file; + return new_env; +} + + +/* GetNextChar: reads a character from input */ +int GetNextChar(char *b, int maxBuffer) { + char *p; + + if ( current_tracking->eof ) + return 0; + + while ( current_tracking->currentChar >= current_tracking->lineLength ) { + current_tracking->currentChar = 0; + current_tracking->currentTokenStart = 1; + current_tracking->eof = false; + + p = fgets(current_tracking->buffer, MAX_BUFFER_LENGTH, current_tracking->in_file); + if ( p == NULL ) { + if ( ferror(current_tracking->in_file) ) + return 0; + current_tracking->eof = true; + return 0; + } + + current_tracking->lineNumber++; + current_tracking->lineLength = strlen(current_tracking->buffer); + } + + b[0] = current_tracking->buffer[current_tracking->currentChar]; + if (b[0] == ' ' || b[0] == '\t') + current_tracking->currentTokenStart++; + current_tracking->currentChar++; + + return b[0]==0?0:1; +} + + + + /***********************************/ /* Utility function definitions... */ /***********************************/ @@ -1691,7 +1753,7 @@ /* insert the code (in ) into the source code we are parsing. * This is done by creating an artificial file with that new source code, and then 'including' the file */ -void include_string(const char *source_code) { +void include_string_(const char *source_code) { FILE *tmp_file = tmpfile(); if(tmp_file == NULL) { @@ -1790,6 +1852,37 @@ +/*******************************/ +/* Public Interface for Bison. */ +/*******************************/ + +/* The following functions will be called from inside bison code! */ + +void include_string(const char *source_code) {include_string_(source_code);} + + +/* Tell flex which file to parse. This function will not imediately start parsing the file. + * To parse the file, you then need to call yyparse() + * + * Returns -1 on error opening the file (and a valid errno), or 0 on success. + */ +int parse_file(const char *filename) { + FILE *filehandle = NULL; + + if((filehandle = fopen(filename, "r")) == NULL) + return -1; + + yyin = filehandle; + current_filename = strdup(filename); + current_tracking = GetNewTracking(yyin); + return 0; +} + + + + + + /*************************************/ /* Include a main() function to test */ /* the token parsing by flex.... */ @@ -1801,7 +1894,6 @@ yystype yylval; YYLTYPE yylloc; -const char *current_filename; diff -r 634f476cb60f -r f1fc4aa6f0e3 stage1_2/stage1_2.cc --- a/stage1_2/stage1_2.cc Tue Nov 27 14:49:08 2012 +0000 +++ b/stage1_2/stage1_2.cc Tue Nov 27 15:49:05 2012 +0000 @@ -51,18 +51,6 @@ -/**************************************/ -/* The name of the file being parsed. */ -/**************************************/ -/* The name of the file currently being parsed... - * Note that flex accesses and updates this global variable - * apropriately whenever it comes across an (*#include *) - * directive... - * ... and bison will use it when producing error messages. - * Note that bison also sets this variable correctly to the first - * file being parsed. - */ -const char *current_filename = NULL; /******************************************************/ @@ -220,59 +208,7 @@ return strcat(strcat(strcpy(res, a), b), c); /* safe, actually */ } -/*************************/ -/* Tracking Functions... */ -/*************************/ - -extern tracking_t* current_tracking; - -/*-------------------------------------------------------------------- - * GetNextChar - * - * reads a character from input for flex - *------------------------------------------------------------------*/ -int GetNextChar(char *b, int maxBuffer) { - char *p; - - if ( current_tracking->eof ) - return 0; - - while ( current_tracking->currentChar >= current_tracking->lineLength ) { - current_tracking->currentChar = 0; - current_tracking->currentTokenStart = 1; - current_tracking->eof = false; - - p = fgets(current_tracking->buffer, MAX_BUFFER_LENGTH, current_tracking->in_file); - if ( p == NULL ) { - if ( ferror(current_tracking->in_file) ) - return 0; - current_tracking->eof = true; - return 0; - } - - current_tracking->lineNumber++; - current_tracking->lineLength = strlen(current_tracking->buffer); - } - - b[0] = current_tracking->buffer[current_tracking->currentChar]; - if (b[0] == ' ' || b[0] == '\t') - current_tracking->currentTokenStart++; - current_tracking->currentChar++; - - return b[0]==0?0:1; -} - -tracking_t* GetNewTracking(FILE* in_file) { - tracking_t* new_env = new tracking_t; - new_env->eof = 0; - new_env->lineNumber = 0; - new_env->currentChar = 0; - new_env->lineLength = 0; - new_env->currentTokenStart = 0; - new_env->buffer = (char*)malloc(MAX_BUFFER_LENGTH); - new_env->in_file = in_file; - return new_env; -} + /***********************************************************************/ /***********************************************************************/ diff -r 634f476cb60f -r f1fc4aa6f0e3 stage1_2/stage1_2_priv.hh --- a/stage1_2/stage1_2_priv.hh Tue Nov 27 14:49:08 2012 +0000 +++ b/stage1_2/stage1_2_priv.hh Tue Nov 27 15:49:05 2012 +0000 @@ -118,34 +118,20 @@ */ void include_string(const char *source_code); -/**************************************/ -/* The name of the file being parsed. */ -/**************************************/ -/* The name of the file currently being parsed... - * Note that flex accesses and updates this global variable - * apropriately whenever it comes across an (*#include *) - * directive... - * ... and bison will use it when producing error messages. - * Note that bison also sets this variable correctly to the first - * file being parsed. - */ -extern const char *current_filename; - - -#define MAX_BUFFER_LENGTH 1000 - -typedef struct { - int eof; - int lineNumber; - int currentChar; - int lineLength; - int currentTokenStart; - char* buffer; - FILE *in_file; - } tracking_t; - -int GetNextChar(char *b, int maxBuffer); -tracking_t* GetNewTracking(FILE* in_file); + +/**********************************/ +/* Tell flex which file to parse. */ +/**********************************/ +/* This is a service that flex provides to bison... */ +/* Tell flex which file to parse. This function will not imediately start parsing the file. + * To parse the file, you then need to call yyparse() + * + * Returns -1 on error opening the file (and a valid errno), or 0 on success. + */ +int parse_file(const char *filename); + + + /****************************************************/ /* Controlling the entry to the body_state in flex. */