--- 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 <filename> *)
- * directive...
- */
-/*
- NOTE: already defined in iec_bison.h
-extern const char *current_filename;
-*/
+ * apropriately whenever it comes across an (*#include <filename> *) 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) */
<body_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 <source_code>) 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;