stage1_2/iec.y
changeset 15 0b472e25eb16
parent 13 77174ccc5471
child 17 38754701ac41
equal deleted inserted replaced
14:d926ee71f228 15:0b472e25eb16
    75 
    75 
    76 /* file with declaration of absyntax classes... */
    76 /* file with declaration of absyntax classes... */
    77 #include "../absyntax/absyntax.hh"
    77 #include "../absyntax/absyntax.hh"
    78 
    78 
    79 /* file with declaration of token constants. Generated by bison! */
    79 /* file with declaration of token constants. Generated by bison! */
    80 #include "iec.y.hh"
    80 // #include "iec.y.hh"
    81 
    81 
    82 /* file with the declarations of symbol tables... */
    82 #include "stage1_2_priv.hh"
    83 #include "../util/symtable.hh"
       
    84 
    83 
    85 
    84 
    86 /* an ugly hack!!
    85 /* an ugly hack!!
    87  * We will probably not need it when we decide
    86  * We will probably not need it when we decide
    88  *  to cut down the abstract syntax down to size.
    87  *  to cut down the abstract syntax down to size.
   108 #define ERROR error_exit(__FILE__,__LINE__)
   107 #define ERROR error_exit(__FILE__,__LINE__)
   109 /* function defined in main.cc */
   108 /* function defined in main.cc */
   110 extern void error_exit(const char *file_name, int line_no);
   109 extern void error_exit(const char *file_name, int line_no);
   111 
   110 
   112 
   111 
   113 /*********************************/
       
   114 /* The global symbol tables...   */
       
   115 /*********************************/
       
   116 /* NOTE: declared static because they are not accessed
       
   117  *       directly by the lexical parser (flex), but rather
       
   118  *       through the function get_identifier_token()
       
   119  */
       
   120 /* A symbol table to store all the library elements */
       
   121 /* e.g.: <function_name , function_decl>
       
   122  *       <fb_name , fb_decl>
       
   123  *       <type_name , type_decl>
       
   124  *       <program_name , program_decl>
       
   125  *       <configuration_name , configuration_decl>
       
   126  */
       
   127 static symtable_c<int, BOGUS_TOKEN_ID> library_element_symtable;
       
   128 
       
   129 /* A symbol table to store the declared variables of
       
   130  * the function currently being parsed...
       
   131  */
       
   132 static symtable_c<int, BOGUS_TOKEN_ID> variable_name_symtable;
       
   133 
       
   134 
   112 
   135 /*************************/
   113 /*************************/
   136 /* global variables...   */
   114 /* global variables...   */
   137 /*************************/
   115 /*************************/
   138 static symbol_c *tree_root = NULL;
   116 /* NOTE: For some strange reason bison ver 2.3 is including these declarations
   139 
   117  *       in the iec.y.hh file, which is in turn included by flex.
   140 /* The name of the file currently being parsed...
   118  *       We cannot therefore define any variables over here, but merely declare 
   141  * Note that flex accesses and updates this global variable
   119  *       their existance (otherwise we get errors when linking the code, since we
   142  * apropriately whenever it comes across an (*#include <filename> *)
   120  *       would get a new variable defined each time iec.y.hh is included!).
   143  * directive...
   121  *       Even though the variables are declared 'extern' over here, they will in
   144  */
   122  *       fact be defined towards the end of this same file (i.e. in the prologue)
   145 const char *current_filename = NULL;
   123  */
   146 
   124 
   147 /* A global flag used to tell the parser if overloaded funtions should be allowed.
   125 /* A global flag used to tell the parser if overloaded funtions should be allowed.
   148  * The IEC 61131-3 standard allows overloaded funtions in the standard library,
   126  * The IEC 61131-3 standard allows overloaded funtions in the standard library,
   149  * but disallows them in user code...
   127  * but disallows them in user code...
   150  */
   128  */
   151 bool allow_function_overloading = false;
   129 extern bool allow_function_overloading;
       
   130 
       
   131 /* A pointer to the root of the parsing tree that will be generated 
       
   132  * by bison.
       
   133  */
       
   134 extern symbol_c *tree_root;
       
   135 
   152 
   136 
   153 
   137 
   154 /************************/
   138 /************************/
   155 /* forward declarations */
   139 /* forward declarations */
   156 /************************/
   140 /************************/
   160 symbol_c *il_operator_c_2_identifier_c(symbol_c *il_operator);
   144 symbol_c *il_operator_c_2_identifier_c(symbol_c *il_operator);
   161 
   145 
   162 /* print an error message */
   146 /* print an error message */
   163 void print_err_msg(const char *filename, int lineno, const char *additional_error_msg);
   147 void print_err_msg(const char *filename, int lineno, const char *additional_error_msg);
   164 
   148 
   165 
       
   166 /************************/
       
   167 /* forward declarations */
       
   168 /************************/
       
   169 /* The functions declared here are defined in iec.flex... */
       
   170 void print_include_stack(void);
       
   171 void cmd_goto_body_state(void);
       
   172 int  get_goto_body_state(void);
       
   173 void rst_goto_body_state(void);
       
   174 
       
   175 %}
   149 %}
       
   150 
   176 
   151 
   177 
   152 
   178 
   153 
   179 %glr-parser
   154 %glr-parser
   180 // %expect-rr 1
   155 // %expect-rr 1
   204 
   179 
   205 
   180 
   206 /*****************************/
   181 /*****************************/
   207 /* Prelimenary constructs... */
   182 /* Prelimenary constructs... */
   208 /*****************************/
   183 /*****************************/
   209 %type <leaf> start
       
   210 
       
   211 %type <leaf>	any_identifier
       
   212 
       
   213 %token <ID>	prev_declared_variable_name_token
       
   214 %token <ID>	prev_declared_fb_name_token
       
   215 %type <leaf>	prev_declared_variable_name
       
   216 %type <leaf>	prev_declared_fb_name
       
   217 
       
   218 %token  <ID>	prev_declared_simple_type_name_token
       
   219 %token  <ID>	prev_declared_subrange_type_name_token
       
   220 %token  <ID>	prev_declared_enumerated_type_name_token
       
   221 %token  <ID>	prev_declared_array_type_name_token
       
   222 %token  <ID>	prev_declared_structure_type_name_token
       
   223 %token  <ID>	prev_declared_string_type_name_token
       
   224 
       
   225 %type  <leaf>	prev_declared_simple_type_name
       
   226 %type  <leaf>	prev_declared_subrange_type_name
       
   227 %type  <leaf>	prev_declared_enumerated_type_name
       
   228 %type  <leaf>	prev_declared_array_type_name
       
   229 %type  <leaf>	prev_declared_structure_type_name
       
   230 %type  <leaf>	prev_declared_string_type_name
       
   231 
       
   232 %token <ID>	prev_declared_derived_function_name_token
       
   233 %token <ID>	prev_declared_derived_function_block_name_token
       
   234 %token <ID>	prev_declared_program_type_name_token
       
   235 %type  <leaf>	prev_declared_derived_function_name
       
   236 %type  <leaf>	prev_declared_derived_function_block_name
       
   237 %type  <leaf>	prev_declared_program_type_name
       
   238 
       
   239 
       
   240 /* A bogus token that, in principle, flex MUST NEVER generate */
   184 /* A bogus token that, in principle, flex MUST NEVER generate */
   241 /* USE 1:
   185 /* USE 1:
   242  * ======
   186  * ======
   243  * This token is currently also being used as the default
   187  * This token is currently also being used as the default
   244  * initialisation value of the token_id member in
   188  * initialisation value of the token_id member in
   252  * This means that bison cannot handle it without some
   196  * This means that bison cannot handle it without some
   253  * caoxing from ourselves. We will then need this token
   197  * caoxing from ourselves. We will then need this token
   254  * to do the coaxing...
   198  * to do the coaxing...
   255  */
   199  */
   256 %token BOGUS_TOKEN_ID
   200 %token BOGUS_TOKEN_ID
       
   201 
       
   202 
       
   203 
       
   204 %{
       
   205 /* The interface through which bison and flex interact. */
       
   206 /* May only be included after the definition of BOGUS_TOKEN_ID */
       
   207 #include "stage1_2_priv.hh"
       
   208 %}
       
   209 
       
   210 
       
   211 %type <leaf> start
       
   212 
       
   213 %type <leaf>	any_identifier
       
   214 
       
   215 %token <ID>	prev_declared_variable_name_token
       
   216 %token <ID>	prev_declared_fb_name_token
       
   217 %type <leaf>	prev_declared_variable_name
       
   218 %type <leaf>	prev_declared_fb_name
       
   219 
       
   220 %token  <ID>	prev_declared_simple_type_name_token
       
   221 %token  <ID>	prev_declared_subrange_type_name_token
       
   222 %token  <ID>	prev_declared_enumerated_type_name_token
       
   223 %token  <ID>	prev_declared_array_type_name_token
       
   224 %token  <ID>	prev_declared_structure_type_name_token
       
   225 %token  <ID>	prev_declared_string_type_name_token
       
   226 
       
   227 %type  <leaf>	prev_declared_simple_type_name
       
   228 %type  <leaf>	prev_declared_subrange_type_name
       
   229 %type  <leaf>	prev_declared_enumerated_type_name
       
   230 %type  <leaf>	prev_declared_array_type_name
       
   231 %type  <leaf>	prev_declared_structure_type_name
       
   232 %type  <leaf>	prev_declared_string_type_name
       
   233 
       
   234 %token <ID>	prev_declared_derived_function_name_token
       
   235 %token <ID>	prev_declared_derived_function_block_name_token
       
   236 %token <ID>	prev_declared_program_type_name_token
       
   237 %type  <leaf>	prev_declared_derived_function_name
       
   238 %type  <leaf>	prev_declared_derived_function_block_name
       
   239 %type  <leaf>	prev_declared_program_type_name
       
   240 
       
   241 
   257 
   242 
   258 
   243 
   259 /* The pragmas... */
   244 /* The pragmas... */
   260 %token <ID>	pragma_token
   245 %token <ID>	pragma_token
   261 %type <leaf>	pragma
   246 %type <leaf>	pragma
   486 
   471 
   487 %token WSTRING
   472 %token WSTRING
   488 %token STRING
   473 %token STRING
   489 %token BOOL
   474 %token BOOL
   490 
   475 
   491 %token TIME
   476 // %token TIME
   492 %token DATE
   477 // %token DATE
   493 %token DATE_AND_TIME
   478 // %token DATE_AND_TIME
   494 %token DT
   479 %token DT
   495 %token TIME_OF_DAY
   480 // %token TIME_OF_DAY
   496 %token TOD
   481 %token TOD
   497 
   482 
   498 
   483 
   499 /********************************/
   484 /********************************/
   500 /* B 1.3.2 - Generic data types */
   485 /* B 1.3.2 - Generic data types */
   781 %token <ID>	standard_function_block_name_token
   766 %token <ID>	standard_function_block_name_token
   782 
   767 
   783 %token FUNCTION_BLOCK
   768 %token FUNCTION_BLOCK
   784 %token END_FUNCTION_BLOCK
   769 %token END_FUNCTION_BLOCK
   785 %token VAR_TEMP
   770 %token VAR_TEMP
   786 %token END_VAR
   771 // %token END_VAR
   787 %token VAR
   772 %token VAR
   788 %token NON_RETAIN
   773 // %token NON_RETAIN
   789 %token END_VAR
   774 // %token END_VAR
   790 
   775 
   791 
   776 
   792 /**********************/
   777 /**********************/
   793 /* B 1.5.3 - Programs */
   778 /* B 1.5.3 - Programs */
   794 /**********************/
   779 /**********************/
   829 %type  <tmp_symbol> action_header
   814 %type  <tmp_symbol> action_header
   830 %type  <leaf>	action
   815 %type  <leaf>	action
   831 %type  <leaf>	transition_name
   816 %type  <leaf>	transition_name
   832 
   817 
   833 
   818 
   834 %token ASSIGN
   819 // %token ASSIGN
   835 %token ACTION
   820 %token ACTION
   836 %token END_ACTION
   821 %token END_ACTION
   837 
   822 
   838 %token TRANSITION
   823 %token TRANSITION
   839 %token END_TRANSITION
   824 %token END_TRANSITION
   940 %token RESOURCE
   925 %token RESOURCE
   941 %token ON
   926 %token ON
   942 %token END_RESOURCE
   927 %token END_RESOURCE
   943 %token VAR_CONFIG
   928 %token VAR_CONFIG
   944 %token VAR_ACCESS
   929 %token VAR_ACCESS
   945 %token END_VAR
   930 // %token END_VAR
   946 %token WITH
   931 %token WITH
   947 %token PROGRAM
   932 // %token PROGRAM
   948 %token RETAIN
   933 // %token RETAIN
   949 %token NON_RETAIN
   934 // %token NON_RETAIN
   950 %token PRIORITY
   935 // %token PRIORITY
   951 %token SINGLE
   936 %token SINGLE
   952 %token INTERVAL
   937 %token INTERVAL
   953 %token READ_WRITE
   938 %token READ_WRITE
   954 %token READ_ONLY
   939 %token READ_ONLY
   955 
   940 
  1123 // %type  <leaf>	unary_operator
  1108 // %type  <leaf>	unary_operator
  1124 %type  <leaf>	primary_expression
  1109 %type  <leaf>	primary_expression
  1125 /* intermediate helper symbol for primary_expression */
  1110 /* intermediate helper symbol for primary_expression */
  1126 %type  <leaf>	function_invocation
  1111 %type  <leaf>	function_invocation
  1127 
  1112 
  1128 %token AND
  1113 // %token AND
  1129 %token XOR
  1114 // %token XOR
  1130 %token OR
  1115 // %token OR
  1131 %token MOD
  1116 // %token MOD
  1132 %token NOT
  1117 // %token NOT
  1133 %token OPER_NE
  1118 %token OPER_NE
  1134 %token OPER_GE
  1119 %token OPER_GE
  1135 %token OPER_LE
  1120 %token OPER_LE
  1136 %token OPER_EXP
  1121 %token OPER_EXP
  1137 
  1122 
  1146 
  1131 
  1147 /*********************************/
  1132 /*********************************/
  1148 /* B 3.2.1 Assignment Statements */
  1133 /* B 3.2.1 Assignment Statements */
  1149 /*********************************/
  1134 /*********************************/
  1150 %type <leaf> assignment_statement
  1135 %type <leaf> assignment_statement
  1151 %token ASSIGN   /* ":=" */
  1136 // %token ASSIGN   /* ":=" */
  1152 
  1137 
  1153 
  1138 
  1154 /*****************************************/
  1139 /*****************************************/
  1155 /* B 3.2.2 Subprogram Control Statements */
  1140 /* B 3.2.2 Subprogram Control Statements */
  1156 /*****************************************/
  1141 /*****************************************/
  1159 %type <leaf>	fb_invocation
  1144 %type <leaf>	fb_invocation
  1160 %type <leaf>	param_assignment
  1145 %type <leaf>	param_assignment
  1161 /* helper symbol for fb_invocation */
  1146 /* helper symbol for fb_invocation */
  1162 %type <list> param_assignment_list
  1147 %type <list> param_assignment_list
  1163 
  1148 
  1164 %token ASSIGN
  1149 // %token ASSIGN
  1165 %token SENDTO   /* "=>" */
  1150 // %token SENDTO   /* "=>" */
  1166 %token RETURN
  1151 %token RETURN
  1167 
  1152 
  1168 
  1153 
  1169 /********************************/
  1154 /********************************/
  1170 /* B 3.2.3 Selection Statements */
  1155 /* B 3.2.3 Selection Statements */
  1187 %token ELSIF
  1172 %token ELSIF
  1188 %token ELSE
  1173 %token ELSE
  1189 %token END_IF
  1174 %token END_IF
  1190 
  1175 
  1191 %token CASE
  1176 %token CASE
  1192 %token OF
  1177 // %token OF
  1193 %token ELSE
  1178 // %token ELSE
  1194 %token END_CASE
  1179 %token END_CASE
  1195 
  1180 
  1196 
  1181 
  1197 
  1182 
  1198 /********************************/
  1183 /********************************/
  1206 %type <leaf>	exit_statement
  1191 %type <leaf>	exit_statement
  1207 /* Integrated directly into for_statement */
  1192 /* Integrated directly into for_statement */
  1208 // %type <leaf>	for_list
  1193 // %type <leaf>	for_list
  1209 
  1194 
  1210 %token FOR
  1195 %token FOR
  1211 %token ASSIGN
  1196 // %token ASSIGN
  1212 %token TO
  1197 // %token TO
  1213 %token BY
  1198 %token BY
  1214 %token DO
  1199 %token DO
  1215 %token END_FOR
  1200 %token END_FOR
  1216 
  1201 
  1217 %token WHILE
  1202 %token WHILE
  1218 %token DO
  1203 // %token DO
  1219 %token END_WHILE
  1204 %token END_WHILE
  1220 
  1205 
  1221 %token REPEAT
  1206 %token REPEAT
  1222 %token UNTIL
  1207 %token UNTIL
  1223 %token END_REPEAT
  1208 %token END_REPEAT
  5176 
  5161 
  5177 /* variables defined in code generated by flex... */
  5162 /* variables defined in code generated by flex... */
  5178 extern FILE *yyin;
  5163 extern FILE *yyin;
  5179 extern int yylineno;
  5164 extern int yylineno;
  5180 
  5165 
       
  5166 
       
  5167 
       
  5168 /* A global flag used to tell the parser if overloaded funtions should be allowed.
       
  5169  * The IEC 61131-3 standard allows overloaded funtions in the standard library,
       
  5170  * but disallows them in user code...
       
  5171  */
       
  5172 bool allow_function_overloading = false;
       
  5173 
       
  5174 /* A pointer to the root of the parsing tree that will be generated 
       
  5175  * by bison.
       
  5176  */
       
  5177 symbol_c *tree_root;
       
  5178 
       
  5179 
       
  5180 
  5181 /* The following function is called automatically by bison whenever it comes across
  5181 /* The following function is called automatically by bison whenever it comes across
  5182  * an error. Unfortunately it calls this function before executing the code that handles
  5182  * an error. Unfortunately it calls this function before executing the code that handles
  5183  * the error itself, so we cannot print out the correct line numbers of the error location
  5183  * the error itself, so we cannot print out the correct line numbers of the error location
  5184  * over here.
  5184  * over here.
  5185  * Our solution is to store the current error message in a global variable, and have all
  5185  * Our solution is to store the current error message in a global variable, and have all
  5196 
  5196 
  5197 void print_err_msg(const char *filename, int lineno, const char *additional_error_msg) {
  5197 void print_err_msg(const char *filename, int lineno, const char *additional_error_msg) {
  5198   fprintf(stderr, "error %d: %s\n", yynerrs, additional_error_msg);
  5198   fprintf(stderr, "error %d: %s\n", yynerrs, additional_error_msg);
  5199   print_include_stack();
  5199   print_include_stack();
  5200   fprintf(stderr, "%s:%d: %s\n", filename, lineno, current_error_msg);
  5200   fprintf(stderr, "%s:%d: %s\n", filename, lineno, current_error_msg);
  5201 }
       
  5202 
       
  5203 /* Function only called from within flex!
       
  5204  *
       
  5205  * search for a symbol in either of the two symbol tables
       
  5206  * declared above, and return the token id of the first
       
  5207  * symbol found.
       
  5208  * Searches first in the variables, and only if not found
       
  5209  * does it continue searching in the library elements
       
  5210  */
       
  5211 int get_identifier_token(const char *identifier_str) {
       
  5212 //  std::cout << "get_identifier_token(" << identifier_str << "): \n";
       
  5213   int token_id;
       
  5214 
       
  5215   if ((token_id = variable_name_symtable.find_value(identifier_str)) == variable_name_symtable.end_value())
       
  5216     if ((token_id = library_element_symtable.find_value(identifier_str)) == library_element_symtable.end_value())
       
  5217       return identifier_token;
       
  5218   return token_id;
       
  5219 }
  5201 }
  5220 
  5202 
  5221 
  5203 
  5222 
  5204 
  5223 /* convert between an il_operator to a function name */
  5205 /* convert between an il_operator to a function name */
  5299   if (name == NULL)
  5281   if (name == NULL)
  5300     ERROR;
  5282     ERROR;
  5301 
  5283 
  5302   free(il_operator);
  5284   free(il_operator);
  5303   return new identifier_c(strdup(name));
  5285   return new identifier_c(strdup(name));
  5304 }
       
  5305 
       
  5306 
       
  5307 
       
  5308 
       
  5309 /*
       
  5310  * Join two strings together. Allocate space with malloc(3).
       
  5311  */
       
  5312 static char *strdup2(const char *a, const char *b) {
       
  5313   char *res = (char *)malloc(strlen(a) + strlen(b) + 1);
       
  5314 
       
  5315   if (!res)
       
  5316     return NULL;
       
  5317   return strcat(strcpy(res, a), b);  /* safe, actually */
       
  5318 }
       
  5319 
       
  5320 /*
       
  5321  * Join three strings together. Allocate space with malloc(3).
       
  5322  */
       
  5323 static char *strdup3(const char *a, const char *b, const char *c) {
       
  5324   char *res = (char *)malloc(strlen(a) + strlen(b) + strlen(c) + 1);
       
  5325 
       
  5326   if (!res)
       
  5327     return NULL;
       
  5328   return strcat(strcat(strcpy(res, a), b), c);  /* safe, actually */
       
  5329 }
  5286 }
  5330 
  5287 
  5331 
  5288 
  5332 
  5289 
  5333 
  5290 
  5408 
  5365 
  5409 
  5366 
  5410 #define LIBFILE "ieclib.txt"
  5367 #define LIBFILE "ieclib.txt"
  5411 #define DEF_LIBFILENAME LIBDIRECTORY "/" LIBFILE
  5368 #define DEF_LIBFILENAME LIBDIRECTORY "/" LIBFILE
  5412 
  5369 
  5413 int stage1_2(const char *filename, const char *includedir, symbol_c **tree_root_ref) {
  5370 int stage1_2__(const char *filename, const char *includedir, symbol_c **tree_root_ref) {
  5414   FILE *in_file = NULL, *lib_file = NULL;
  5371   FILE *in_file = NULL, *lib_file = NULL;
  5415   char *libfilename = NULL;
  5372   char *libfilename = NULL;
  5416 
  5373 
  5417   if((in_file = fopen(filename, "r")) == NULL) {
  5374   if((in_file = fopen(filename, "r")) == NULL) {
  5418     char *errmsg = strdup2("Error opening main file ", filename);
  5375     char *errmsg = strdup2("Error opening main file ", filename);