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;