stage1_2/iec.y
changeset 0 fb772792efd1
child 1 5d893a68be6e
equal deleted inserted replaced
-1:000000000000 0:fb772792efd1
       
     1 /*
       
     2  * (c) 2003 Mario de Sousa
       
     3  *
       
     4  * Offered to the public under the terms of the GNU General Public License
       
     5  * as published by the Free Software Foundation; either version 2 of the
       
     6  * License, or (at your option) any later version.
       
     7  *
       
     8  * This program is distributed in the hope that it will be useful, but
       
     9  * WITHOUT ANY WARRANTY; without even the implied warranty of
       
    10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
       
    11  * Public License for more details.
       
    12  *
       
    13  * This code is made available on the understanding that it will not be
       
    14  * used in safety-critical situations without a full and competent review.
       
    15  */
       
    16 
       
    17 /*
       
    18  * An IEC 61131-3 IL and ST compiler.
       
    19  *
       
    20  * Based on the
       
    21  * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10)
       
    22  *
       
    23  */
       
    24 
       
    25 /*
       
    26  * Stage 2
       
    27  * =======
       
    28  *
       
    29  *  This file contains the syntax definition of the textual
       
    30  *  languages IL and ST. The syntax parser, comprising the
       
    31  *  2nd stage of the overall compiler, is generated by runing
       
    32  *  bison on this file.
       
    33  */
       
    34 
       
    35 
       
    36 
       
    37 
       
    38 /**********************************************************************/
       
    39 /**********************************************************************/
       
    40 /**********************************************************************/
       
    41 /**********************************************************************/
       
    42 /*******                                                        *******/
       
    43 /*******   The following syntax does not have any conflicts.    *******/
       
    44 /*******                                                        *******/
       
    45 /*******   P L E A S E    K E E P    I T    T H A T    W A Y !  *******/
       
    46 /*******   ===================================================  *******/
       
    47 /*******                                                        *******/
       
    48 /**********************************************************************/
       
    49 /**********************************************************************/
       
    50 /**********************************************************************/
       
    51 /**********************************************************************/
       
    52 
       
    53 
       
    54 
       
    55 
       
    56 %{
       
    57 #include <string.h>	/* required for strdup()  */
       
    58 
       
    59 
       
    60 /* declare the token parser generated by flex... */
       
    61 int yylex(void);
       
    62 
       
    63 /* declare the error handler defined at the end of this file */
       
    64 void yyerror (const char *error_msg);
       
    65 
       
    66 /* produce a more verbose parsing error message */
       
    67 #define YYERROR_VERBOSE
       
    68 
       
    69 /* Include debuging code.
       
    70  * Printing of debug info must then be activated by setting
       
    71  * the variable yydebug to 1.
       
    72  */
       
    73 #define YYDEBUG 0
       
    74 
       
    75 
       
    76 /* file with declaration of absyntax classes... */
       
    77 #include "../absyntax/absyntax.hh"
       
    78 
       
    79 /* file with declaration of token constants. Generated by bison! */
       
    80 #include "iec.y.hh"
       
    81 
       
    82 /* file with the declarations of symbol tables... */
       
    83 #include "../util/symtable.hh"
       
    84 
       
    85 
       
    86 /* an ugly hack!!
       
    87  * We will probably not need it when we decide
       
    88  *  to cut down the abstract syntax down to size.
       
    89  *  We keep it as it is until we get to write
       
    90  *  stages 3 and 4 of the compiler. Who knows,
       
    91  *  we might just find out that we really do need
       
    92  *  the abstract syntax tree to stay as it is
       
    93  *  afterall!
       
    94  */
       
    95 /* for each element <elem> in list_c * <list>
       
    96  * execute the code <code>
       
    97  */
       
    98 #define FOR_EACH_ELEMENT(elem, list, code) {		\
       
    99   symbol_c *elem;					\
       
   100   for(int i = 0; i < list->n; i++) {			\
       
   101     elem = list->elements[i];				\
       
   102     code;						\
       
   103   }							\
       
   104 }
       
   105 
       
   106 
       
   107 /* A macro for printing out internal parser errors... */
       
   108 #define ERROR error_exit(__FILE__,__LINE__)
       
   109 /* function defined in main.cc */
       
   110 extern void error_exit(const char *file_name, int line_no);
       
   111 
       
   112 
       
   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 
       
   135 /*************************/
       
   136 /* global variables...   */
       
   137 /*************************/
       
   138 static symbol_c *tree_root = NULL;
       
   139 
       
   140 /* The name of the file currently being parsed...
       
   141  * Note that flex accesses and updates this global variable
       
   142  * apropriately whenever it comes across an (*#include <filename> *)
       
   143  * directive...
       
   144  */
       
   145 const char *current_filename = NULL;
       
   146 
       
   147 /* 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,
       
   149  * but disallows them in user code...
       
   150  */
       
   151 bool allow_function_overloading = false;
       
   152 
       
   153 
       
   154 /************************/
       
   155 /* forward declarations */
       
   156 /************************/
       
   157 /* The functions declared here are defined at the end of this file... */
       
   158 
       
   159 /* Convert an il_operator_c into an identifier_c */
       
   160 symbol_c *il_operator_c_2_identifier_c(symbol_c *il_operator);
       
   161 
       
   162 /* print an error message */
       
   163 void print_err_msg(const char *filename, int lineno, const char *additional_error_msg);
       
   164 
       
   165 
       
   166 /************************/
       
   167 /* forward declarations */
       
   168 /************************/
       
   169 /* The functions declared here are defined in iec.flex... */
       
   170 void print_include_stack(void);
       
   171 
       
   172 
       
   173 %}
       
   174 
       
   175 
       
   176 
       
   177 %union {
       
   178     symbol_c 	*leaf;
       
   179     list_c	*list;
       
   180     char 	*ID;	/* token value */
       
   181     struct {
       
   182       symbol_c	*first;
       
   183       symbol_c	*second;
       
   184     } double_symbol; /* used by il_simple_operator_clash_il_operand */
       
   185 }
       
   186 
       
   187 
       
   188 
       
   189 
       
   190 
       
   191 
       
   192 /*****************************/
       
   193 /* Prelimenary constructs... */
       
   194 /*****************************/
       
   195 %type <leaf> start
       
   196 
       
   197 %type <leaf>	any_identifier
       
   198 
       
   199 %token <ID>	prev_declared_variable_name_token
       
   200 %token <ID>	prev_declared_fb_name_token
       
   201 %type <leaf>	prev_declared_variable_name
       
   202 %type <leaf>	prev_declared_fb_name
       
   203 
       
   204 %token  <ID>	prev_declared_simple_type_name_token
       
   205 %token  <ID>	prev_declared_subrange_type_name_token
       
   206 %token  <ID>	prev_declared_enumerated_type_name_token
       
   207 %token  <ID>	prev_declared_array_type_name_token
       
   208 %token  <ID>	prev_declared_structure_type_name_token
       
   209 %token  <ID>	prev_declared_string_type_name_token
       
   210 
       
   211 %type  <leaf>	prev_declared_simple_type_name
       
   212 %type  <leaf>	prev_declared_subrange_type_name
       
   213 %type  <leaf>	prev_declared_enumerated_type_name
       
   214 %type  <leaf>	prev_declared_array_type_name
       
   215 %type  <leaf>	prev_declared_structure_type_name
       
   216 %type  <leaf>	prev_declared_string_type_name
       
   217 
       
   218 %token <ID>	prev_declared_derived_function_name_token
       
   219 %token <ID>	prev_declared_derived_function_block_name_token
       
   220 %token <ID>	prev_declared_program_type_name_token
       
   221 %type  <leaf>	prev_declared_derived_function_name
       
   222 %type  <leaf>	prev_declared_derived_function_block_name
       
   223 %type  <leaf>	prev_declared_program_type_name
       
   224 
       
   225 
       
   226 /* A bogus token that, in principle, flex MUST NEVER generate */
       
   227 /* USE 1:
       
   228  * ======
       
   229  * This token is currently also being used as the default
       
   230  * initialisation value of the token_id member in
       
   231  * the symbol_c base class.
       
   232  *
       
   233  * USE 2
       
   234  * =====
       
   235  * This token may also be used in the future to remove
       
   236  * mysterious reduce/reduce conflicts due to the fact
       
   237  * that our grammar may not be LALR(1) but merely LR(1).
       
   238  * This means that bison cannot handle it without some
       
   239  * caoxing from ourselves. We will then need this token
       
   240  * to do the coaxing...
       
   241  */
       
   242 %token BOGUS_TOKEN_ID
       
   243 
       
   244 
       
   245 /* The pragmas... */
       
   246 %token <ID>	pragma_token
       
   247 %type <leaf>	pragma
       
   248 
       
   249 
       
   250 /* Where do these tokens belong ?? */
       
   251 /* TODO: get the syntax parser to handle these tokens... */
       
   252 %token	EN
       
   253 %token	ENO
       
   254 
       
   255 
       
   256 
       
   257 /***************************/
       
   258 /* B 0 - Programming Model */
       
   259 /***************************/
       
   260 %type <list>	library
       
   261 %type <leaf>	library_element_declaration
       
   262 
       
   263 
       
   264 /*******************************************/
       
   265 /* B 1.1 - Letters, digits and identifiers */
       
   266 /*******************************************/
       
   267 /* Done totally within flex...
       
   268   letter
       
   269   digit
       
   270   octal_digit
       
   271   hex_digit
       
   272 */
       
   273 %token <ID>	identifier_token
       
   274 %type  <leaf>	identifier
       
   275 
       
   276 
       
   277 /*********************/
       
   278 /* B 1.2 - Constants */
       
   279 /*********************/
       
   280 %type <leaf>	constant
       
   281 /* a helper symbol for expression */
       
   282 %type  <leaf> non_negative_constant
       
   283 
       
   284 
       
   285 /******************************/
       
   286 /* B 1.2.1 - Numeric Literals */
       
   287 /******************************/
       
   288 /* Done totally within flex...
       
   289   bit
       
   290 */
       
   291 %type  <leaf> numeric_literal
       
   292 /* helper symbol for non_negative_constant */
       
   293 %type  <leaf> non_negative_numeric_literal
       
   294 %type  <leaf> integer_literal
       
   295 %type  <leaf> signed_integer
       
   296 /* a helper symbol for non_negative_constant */
       
   297 %type  <leaf> non_negative_signed_integer
       
   298 %token <ID>   integer_token
       
   299 %type  <leaf> integer
       
   300 %token <ID>   binary_integer_token
       
   301 %type  <leaf> binary_integer
       
   302 %token <ID>   octal_integer_token
       
   303 %type  <leaf> octal_integer
       
   304 %token <ID>   hex_integer_token
       
   305 %type  <leaf> hex_integer
       
   306 %token <ID>   real_token
       
   307 %type  <leaf> real
       
   308 %type  <leaf> signed_real
       
   309 /* helper symbol for non_negative_real_literal */
       
   310 %type  <leaf> non_negative_signed_real
       
   311 %type  <leaf> real_literal
       
   312 /* helper symbol for non_negative_numeric_literal */
       
   313 %type  <leaf> non_negative_real_literal
       
   314 // %type  <leaf> exponent
       
   315 %type  <leaf> bit_string_literal
       
   316 %type  <leaf> boolean_literal
       
   317 
       
   318 %token FALSE
       
   319 %token TRUE
       
   320 
       
   321 
       
   322 /*******************************/
       
   323 /* B 1.2.2 - Character Strings */
       
   324 /*******************************/
       
   325 %token <ID>   single_byte_character_string_token
       
   326 %token <ID>   double_byte_character_string_token
       
   327 
       
   328 %type  <leaf> character_string
       
   329 %type  <leaf> single_byte_character_string
       
   330 %type  <leaf> double_byte_character_string
       
   331 
       
   332 
       
   333 /***************************/
       
   334 /* B 1.2.3 - Time Literals */
       
   335 /***************************/
       
   336 %type  <leaf> time_literal
       
   337 
       
   338 
       
   339 /************************/
       
   340 /* B 1.2.3.1 - Duration */
       
   341 /************************/
       
   342 %type  <leaf>	duration
       
   343 %type  <leaf>	interval
       
   344 %type  <leaf>	days
       
   345 %type  <leaf>	fixed_point
       
   346 %type  <leaf>	hours
       
   347 %type  <leaf>	minutes
       
   348 %type  <leaf>	seconds
       
   349 %type  <leaf>	milliseconds
       
   350 
       
   351 %type  <leaf>	integer_d
       
   352 %type  <leaf>	integer_h
       
   353 %type  <leaf>	integer_m
       
   354 %type  <leaf>	integer_s
       
   355 %type  <leaf>	integer_ms
       
   356 %type  <leaf>	fixed_point_d
       
   357 %type  <leaf>	fixed_point_h
       
   358 %type  <leaf>	fixed_point_m
       
   359 %type  <leaf>	fixed_point_s
       
   360 %type  <leaf>	fixed_point_ms
       
   361 
       
   362 %token <ID>	fixed_point_token
       
   363 %token <ID>	fixed_point_d_token
       
   364 %token <ID>	integer_d_token
       
   365 %token <ID>	fixed_point_h_token
       
   366 %token <ID>	integer_h_token
       
   367 %token <ID>	fixed_point_m_token
       
   368 %token <ID>	integer_m_token
       
   369 %token <ID>	fixed_point_s_token
       
   370 %token <ID>	integer_s_token
       
   371 %token <ID>	fixed_point_ms_token
       
   372 %token <ID>	integer_ms_token
       
   373 
       
   374 %token TIME
       
   375 %token T_SHARP
       
   376 
       
   377 
       
   378 /************************************/
       
   379 /* B 1.2.3.2 - Time of day and Date */
       
   380 /************************************/
       
   381 %type  <leaf>	time_of_day
       
   382 %type  <leaf>	daytime
       
   383 %type  <leaf>	day_hour
       
   384 %type  <leaf>	day_minute
       
   385 %type  <leaf>	day_second
       
   386 %type  <leaf>	date
       
   387 %type  <leaf>	date_literal
       
   388 %type  <leaf>	year
       
   389 %type  <leaf>	month
       
   390 %type  <leaf>	day
       
   391 %type  <leaf>	date_and_time
       
   392 
       
   393 %token TIME_OF_DAY
       
   394 %token DATE
       
   395 %token D_SHARP
       
   396 %token DATE_AND_TIME
       
   397 
       
   398 
       
   399 /**********************/
       
   400 /* B 1.3 - Data Types */
       
   401 /**********************/
       
   402 /* Strangely, the following symbol does seem to be required! */
       
   403 // %type  <leaf> data_type_name
       
   404 %type  <leaf> non_generic_type_name
       
   405 
       
   406 
       
   407 /***********************************/
       
   408 /* B 1.3.1 - Elementary Data Types */
       
   409 /***********************************/
       
   410 /* NOTES:
       
   411  *
       
   412  *    - To make the definition of bit_string_literal more
       
   413  *      concise, it is useful to use an extra non-terminal
       
   414  *      symbol (i.e. a grouping or construct) that groups the
       
   415  *      following elements (BYTE, WORD, DWORD, LWORD).
       
   416  *      Note that the definition of bit_string_type_name
       
   417  *      (according to the spec) includes the above elements
       
   418  *      and an extra BOOL.
       
   419  *      We could use an extra construct with the first four
       
   420  *      elements to be used solely in the definition of
       
   421  *      bit_string_literal, but with the objective of not
       
   422  *      having to replicate the actions (if we ever need
       
   423  *      to change them, they would need to be changed in both
       
   424  *      bit_string_type_name and the extra grouping), we
       
   425  *      have re-defined bit_string_type_name as only including
       
   426  *      the first four elements.
       
   427  *      In order to have our parser implement the specification
       
   428  *      correctly we have augmented every occurence of
       
   429  *      bit_string_type_name in other rules with the BOOL
       
   430  *      token. Since bit_string_type_name only appears in
       
   431  *      the rule for elementary_type_name, this does not
       
   432  *      seem to be a big concession to make!
       
   433  *
       
   434  *    - We have added a helper symbol to concentrate the
       
   435  *      instantiation of STRING and WSTRING into a single
       
   436  *      location (elementary_string_type_name).
       
   437  *      These two elements show up in several other rules,
       
   438  *      but we want to create the equivalent abstract syntax
       
   439  *      in a single location of this file, in order to make
       
   440  *      possible future changes easier to edit...
       
   441  */
       
   442 %type  <leaf>	elementary_type_name
       
   443 %type  <leaf>	numeric_type_name
       
   444 %type  <leaf>	integer_type_name
       
   445 %type  <leaf>	signed_integer_type_name
       
   446 %type  <leaf>	unsigned_integer_type_name
       
   447 %type  <leaf>	real_type_name
       
   448 %type  <leaf>	date_type_name
       
   449 %type  <leaf>	bit_string_type_name
       
   450 /* helper symbol to concentrate the instantiation
       
   451  * of STRING and WSTRING into a single location
       
   452  */
       
   453 %type  <leaf>	elementary_string_type_name
       
   454 
       
   455 %token BYTE
       
   456 %token WORD
       
   457 %token DWORD
       
   458 %token LWORD
       
   459 
       
   460 %token LREAL
       
   461 %token REAL
       
   462 
       
   463 %token SINT
       
   464 %token INT
       
   465 %token DINT
       
   466 %token LINT
       
   467 
       
   468 %token USINT
       
   469 %token UINT
       
   470 %token UDINT
       
   471 %token ULINT
       
   472 
       
   473 %token WSTRING
       
   474 %token STRING
       
   475 %token BOOL
       
   476 
       
   477 %token TIME
       
   478 %token DATE
       
   479 %token DATE_AND_TIME
       
   480 %token DT
       
   481 %token TIME_OF_DAY
       
   482 %token TOD
       
   483 
       
   484 
       
   485 /********************************/
       
   486 /* B 1.3.2 - Generic data types */
       
   487 /********************************/
       
   488 /* Strangely, the following symbol does seem to be required! */
       
   489 // %type  <leaf>	generic_type_name
       
   490 
       
   491 /* The following tokens do not seem to be used either
       
   492  * but we declare them so they become reserved words...
       
   493  */
       
   494 %token ANY
       
   495 %token ANY_DERIVED
       
   496 %token ANY_ELEMENTARY
       
   497 %token ANY_MAGNITUDE
       
   498 %token ANY_NUM
       
   499 %token ANY_REAL
       
   500 %token ANY_INT
       
   501 %token ANY_BIT
       
   502 %token ANY_STRING
       
   503 %token ANY_DATE
       
   504 
       
   505 
       
   506 /********************************/
       
   507 /* B 1.3.3 - Derived data types */
       
   508 /********************************/
       
   509 %type  <leaf>	derived_type_name
       
   510 %type  <leaf>	single_element_type_name
       
   511 // %type  <leaf>	simple_type_name
       
   512 // %type  <leaf>	subrange_type_name
       
   513 // %type  <leaf>	enumerated_type_name
       
   514 // %type  <leaf>	array_type_name
       
   515 // %type  <leaf>	structure_type_name
       
   516 
       
   517 %type  <leaf>	data_type_declaration
       
   518 /* helper symbol for data_type_declaration */
       
   519 %type  <list>	type_declaration_list
       
   520 %type  <leaf>	type_declaration
       
   521 %type  <leaf>	single_element_type_declaration
       
   522 
       
   523 %type  <leaf>	simple_type_declaration
       
   524 %type  <leaf>	simple_spec_init
       
   525 %type  <leaf>	simple_specification
       
   526 
       
   527 %type  <leaf>	subrange_type_declaration
       
   528 %type  <leaf>	subrange_spec_init
       
   529 %type  <leaf>	subrange_specification
       
   530 %type  <leaf>	subrange
       
   531 
       
   532 %type  <leaf>	enumerated_type_declaration
       
   533 %type  <leaf>	enumerated_spec_init
       
   534 %type  <leaf>	enumerated_specification
       
   535 /* helper symbol for enumerated_value */
       
   536 %type  <list>	enumerated_value_list
       
   537 %type  <leaf>	enumerated_value
       
   538 
       
   539 %type  <leaf>	array_type_declaration
       
   540 %type  <leaf>	array_spec_init
       
   541 %type  <leaf>	array_specification
       
   542 /* helper symbol for array_specification */
       
   543 %type  <list>	array_subrange_list
       
   544 %type  <leaf>	array_initialization
       
   545 /* helper symbol for array_initialization */
       
   546 %type  <list>	array_initial_elements_list
       
   547 %type  <leaf>	array_initial_elements
       
   548 %type  <leaf>	array_initial_element
       
   549 
       
   550 %type  <leaf>	structure_type_declaration
       
   551 %type  <leaf>	structure_specification
       
   552 %type  <leaf>	initialized_structure
       
   553 %type  <leaf>	structure_declaration
       
   554 /* helper symbol for structure_declaration */
       
   555 %type  <list>	structure_element_declaration_list
       
   556 %type  <leaf>	structure_element_declaration
       
   557 %type  <leaf>	structure_element_name
       
   558 %type  <leaf>	structure_initialization
       
   559 /* helper symbol for structure_initialization */
       
   560 %type  <list>	structure_element_initialization_list
       
   561 %type  <leaf>	structure_element_initialization
       
   562 
       
   563 //%type  <leaf>	string_type_name
       
   564 %type  <leaf>	string_type_declaration
       
   565 /* helper symbol for string_type_declaration */
       
   566 %type  <leaf>	string_type_declaration_size
       
   567 /* helper symbol for string_type_declaration */
       
   568 %type  <leaf>	string_type_declaration_init
       
   569 
       
   570 %token ASSIGN
       
   571 %token DOTDOT  /* ".." */
       
   572 %token TYPE
       
   573 %token END_TYPE
       
   574 %token ARRAY
       
   575 %token OF
       
   576 %token STRUCT
       
   577 %token END_STRUCT
       
   578 
       
   579 
       
   580 
       
   581 /*********************/
       
   582 /* B 1.4 - Variables */
       
   583 /*********************/
       
   584 %type  <leaf>	variable
       
   585 %type  <leaf>	symbolic_variable
       
   586 /* helper symbol for prog_cnxn */
       
   587 %type  <leaf>	any_symbolic_variable
       
   588 %type  <leaf>	variable_name
       
   589 
       
   590 
       
   591 
       
   592 
       
   593 /********************************************/
       
   594 /* B.1.4.1   Directly Represented Variables */
       
   595 /********************************************/
       
   596 /* Done totally within flex...
       
   597  location_prefix
       
   598  size_prefix
       
   599 */
       
   600 %token <ID>	direct_variable_token
       
   601 %type  <leaf>	direct_variable
       
   602 
       
   603 
       
   604 /*************************************/
       
   605 /* B.1.4.2   Multi-element Variables */
       
   606 /*************************************/
       
   607 %type  <leaf>	multi_element_variable
       
   608 /* helper symbol for any_symbolic_variable */
       
   609 %type  <leaf>	any_multi_element_variable
       
   610 %type  <leaf>	array_variable
       
   611 /* helper symbol for any_symbolic_variable */
       
   612 %type  <leaf>	any_array_variable
       
   613 %type  <leaf>	subscripted_variable
       
   614 /* helper symbol for any_symbolic_variable */
       
   615 %type  <leaf>	any_subscripted_variable
       
   616 %type  <list>	subscript_list
       
   617 %type  <leaf>	subscript
       
   618 %type  <leaf>	structured_variable
       
   619 /* helper symbol for any_symbolic_variable */
       
   620 %type  <leaf>	any_structured_variable
       
   621 %type  <leaf>	record_variable
       
   622 /* helper symbol for any_symbolic_variable */
       
   623 %type  <leaf>	any_record_variable
       
   624 %type  <leaf>	field_selector
       
   625 
       
   626 
       
   627 /******************************************/
       
   628 /* B 1.4.3 - Declaration & Initialisation */
       
   629 /******************************************/
       
   630 %type  <leaf>	input_declarations
       
   631 /* helper symbol for input_declarations */
       
   632 %type  <list>	input_declaration_list
       
   633 %type  <leaf>	input_declaration
       
   634 %type  <leaf>	edge_declaration
       
   635 %type  <leaf>	var_init_decl
       
   636 %type  <leaf>	var1_init_decl
       
   637 %type  <list>	var1_list
       
   638 %type  <leaf>	array_var_init_decl
       
   639 %type  <leaf>	structured_var_init_decl
       
   640 %type  <leaf>	fb_name_decl
       
   641 /* helper symbol for fb_name_decl */
       
   642 %type  <list>	fb_name_list_with_colon
       
   643 /* helper symbol for fb_name_list_with_colon */
       
   644 %type  <list>	var1_list_with_colon
       
   645 // %type  <list>	fb_name_list
       
   646 // %type  <leaf>	fb_name
       
   647 %type  <leaf>	output_declarations
       
   648 %type  <leaf>	input_output_declarations
       
   649 /* helper symbol for input_output_declarations */
       
   650 %type  <list>	var_declaration_list
       
   651 %type  <leaf>	var_declaration
       
   652 %type  <leaf>	temp_var_decl
       
   653 %type  <leaf>	var1_declaration
       
   654 %type  <leaf>	array_var_declaration
       
   655 %type  <leaf>	structured_var_declaration
       
   656 %type  <leaf>	var_declarations
       
   657 %type  <leaf>	retentive_var_declarations
       
   658 %type  <leaf>	located_var_declarations
       
   659 /* helper symbol for located_var_declarations */
       
   660 %type  <list>	located_var_decl_list
       
   661 %type  <leaf>	located_var_decl
       
   662 %type  <leaf>	external_var_declarations
       
   663 /* helper symbol for external_var_declarations */
       
   664 %type  <list>	external_declaration_list
       
   665 %type  <leaf>	external_declaration
       
   666 %type  <leaf>	global_var_name
       
   667 %type  <leaf>	global_var_declarations
       
   668 /* helper symbol for global_var_declarations */
       
   669 %type  <list>	global_var_decl_list
       
   670 %type  <leaf>	global_var_decl
       
   671 %type  <leaf>	global_var_spec
       
   672 %type  <leaf>	located_var_spec_init
       
   673 %type  <leaf>	location
       
   674 %type  <list>	global_var_list
       
   675 %type  <leaf>	string_var_declaration
       
   676 %type  <leaf>	single_byte_string_var_declaration
       
   677 %type  <leaf>	single_byte_string_spec
       
   678 %type  <leaf>	double_byte_string_var_declaration
       
   679 %type  <leaf>	double_byte_string_spec
       
   680 %type  <leaf>	incompl_located_var_declarations
       
   681 /* helper symbol for incompl_located_var_declarations */
       
   682 %type  <list>	incompl_located_var_decl_list
       
   683 %type  <leaf>	incompl_located_var_decl
       
   684 %type  <leaf>	incompl_location
       
   685 %type  <leaf>	var_spec
       
   686 /* helper symbol for var_spec */
       
   687 %type  <leaf>	string_spec
       
   688 /* intermediate helper symbol for:
       
   689  *  - non_retentive_var_decls
       
   690  *  - output_declarations
       
   691  */
       
   692 %type  <list>	var_init_decl_list
       
   693 
       
   694 %token  <ID>	incompl_location_token
       
   695 
       
   696 %token VAR_INPUT
       
   697 %token VAR_OUTPUT
       
   698 %token VAR_IN_OUT
       
   699 %token VAR_EXTERNAL
       
   700 %token VAR_GLOBAL
       
   701 %token END_VAR
       
   702 %token RETAIN
       
   703 %token NON_RETAIN
       
   704 %token R_EDGE
       
   705 %token F_EDGE
       
   706 %token AT
       
   707 
       
   708 
       
   709 /***********************/
       
   710 /* B 1.5.1 - Functions */
       
   711 /***********************/
       
   712 //%type  <leaf>	function_name
       
   713 /* helper symbol for IL language */
       
   714 %type  <leaf>	function_name_no_clashes
       
   715 %type  <leaf>	function_name_simpleop_clashes
       
   716 //%type  <leaf>	function_name_expression_clashes
       
   717 /* helper symbols for ST language */
       
   718 //%type  <leaf>	function_name_NOT_clashes
       
   719 %type  <leaf>	function_name_no_NOT_clashes
       
   720 
       
   721 //%type  <leaf>	standard_function_name
       
   722 /* helper symbols for IL language */
       
   723 %type  <leaf>	standard_function_name_no_clashes
       
   724 %type  <leaf>	standard_function_name_simpleop_clashes
       
   725 %type  <leaf>	standard_function_name_expression_clashes
       
   726 /* helper symbols for ST language */
       
   727 %type  <leaf>	standard_function_name_NOT_clashes
       
   728 %type  <leaf>	standard_function_name_no_NOT_clashes
       
   729 
       
   730 %type  <leaf>	derived_function_name
       
   731 %type  <leaf>	function_declaration
       
   732 /* helper symbol for function_declaration */
       
   733 %type  <leaf>	function_name_declaration
       
   734 %type  <leaf>	io_var_declarations
       
   735 %type  <leaf>	function_var_decls
       
   736 %type  <leaf>	function_body
       
   737 %type  <leaf>	var2_init_decl
       
   738 /* intermediate helper symbol for function_declaration */
       
   739 %type  <list>	io_OR_function_var_declarations_list
       
   740 /* intermediate helper symbol for function_var_decls */
       
   741 %type  <list>	var2_init_decl_list
       
   742 
       
   743 %token <ID>	standard_function_name_token
       
   744 
       
   745 %token FUNCTION
       
   746 %token END_FUNCTION
       
   747 %token CONSTANT
       
   748 
       
   749 
       
   750 /*****************************/
       
   751 /* B 1.5.2 - Function Blocks */
       
   752 /*****************************/
       
   753 %type  <leaf>	function_block_type_name
       
   754 %type  <leaf>	standard_function_block_name
       
   755 %type  <leaf>	derived_function_block_name
       
   756 %type  <leaf>	function_block_declaration
       
   757 %type  <leaf>	other_var_declarations
       
   758 %type  <leaf>	temp_var_decls
       
   759 %type  <leaf>	non_retentive_var_decls
       
   760 %type  <leaf>	function_block_body
       
   761 /* intermediate helper symbol for function_declaration */
       
   762 %type  <list>	io_OR_other_var_declarations_list
       
   763 /* intermediate helper symbol for temp_var_decls */
       
   764 %type  <list>	temp_var_decls_list
       
   765 
       
   766 %token <ID>	standard_function_block_name_token
       
   767 
       
   768 %token FUNCTION_BLOCK
       
   769 %token END_FUNCTION_BLOCK
       
   770 %token VAR_TEMP
       
   771 %token END_VAR
       
   772 %token VAR
       
   773 %token NON_RETAIN
       
   774 %token END_VAR
       
   775 
       
   776 
       
   777 /**********************/
       
   778 /* B 1.5.3 - Programs */
       
   779 /**********************/
       
   780 %type  <leaf>	program_type_name
       
   781 %type  <leaf>	program_declaration
       
   782 /* helper symbol for program_declaration */
       
   783 %type  <list>	program_var_declarations_list
       
   784 
       
   785 %token PROGRAM
       
   786 %token END_PROGRAM
       
   787 
       
   788 
       
   789 /********************************************/
       
   790 /* B 1.6 Sequential Function Chart elements */
       
   791 /********************************************/
       
   792 /* TODO */
       
   793 /*
       
   794 %type  <list>	sequential_function_chart
       
   795 %type  <leaf>	sfc_network
       
   796 %type  <leaf>	initial_step
       
   797 %type  <leaf>	step
       
   798 %type  <leaf>	action_association_list
       
   799 %type  <leaf>	step_name
       
   800 %type  <leaf>	action_association
       
   801 /* helper symbol for action_association *
       
   802 %type  <list>	indicator_name_list
       
   803 %type  <leaf>	action_name
       
   804 %type  <leaf>	action_qualifier
       
   805 %type  <leaf>	timed_qualifier
       
   806 %type  <leaf>	action_time
       
   807 %type  <leaf>	indicator_name
       
   808 %type  <leaf>	transition
       
   809 %type  <leaf>	steps
       
   810 %type  <list>	step_name_list
       
   811 %type  <leaf>	transition_condition
       
   812 %type  <leaf>	action
       
   813 */
       
   814 
       
   815 %token ASSIGN
       
   816 %token ACTION
       
   817 %token END_ACTION
       
   818 
       
   819 %token TRANSITION
       
   820 %token END_TRANSITION
       
   821 %token FROM
       
   822 %token TO
       
   823 %token PRIORITY
       
   824 
       
   825 %token INITIAL_STEP
       
   826 %token STEP
       
   827 %token END_STEP
       
   828 
       
   829 %token L
       
   830 %token D
       
   831 %token SD
       
   832 %token DS
       
   833 %token SL
       
   834 
       
   835 %token N
       
   836 %token P
       
   837 /* NOTE: the following two clash with the R and S IL operators.
       
   838  * It will have to be handled when we include parsing of SFC...
       
   839  */
       
   840 /*
       
   841 %token R
       
   842 %token S
       
   843 */
       
   844 
       
   845 
       
   846 /********************************/
       
   847 /* B 1.7 Configuration elements */
       
   848 /********************************/
       
   849 %type  <leaf>	configuration_name
       
   850 %type  <leaf>	resource_type_name
       
   851 %type  <leaf>	configuration_declaration
       
   852 // helper symbol for
       
   853 //  - configuration_declaration
       
   854 //  - resource_declaration
       
   855 //
       
   856 %type  <leaf>	optional_global_var_declarations
       
   857 // helper symbol for configuration_declaration
       
   858 %type  <leaf>	optional_access_declarations
       
   859 // helper symbol for configuration_declaration
       
   860 %type  <leaf>	optional_instance_specific_initializations
       
   861 // helper symbol for configuration_declaration
       
   862 %type  <list>	resource_declaration_list
       
   863 %type  <leaf>	resource_declaration
       
   864 %type  <leaf>	single_resource_declaration
       
   865 // helper symbol for single_resource_declaration
       
   866 %type  <list>	task_configuration_list
       
   867 // helper symbol for single_resource_declaration
       
   868 %type  <list>	program_configuration_list
       
   869 %type  <leaf>	resource_name
       
   870 // %type  <leaf>	access_declarations
       
   871 // helper symbol for access_declarations
       
   872 // %type  <leaf>	access_declaration_list
       
   873 // %type  <leaf>	access_declaration
       
   874 // %type  <leaf>	access_path
       
   875 // helper symbol for access_path
       
   876 %type  <list>	any_fb_name_list
       
   877 %type  <leaf>	global_var_reference
       
   878 // %type  <leaf>	access_name
       
   879 %type  <leaf>	program_output_reference
       
   880 %type  <leaf>	program_name
       
   881 // %type  <leaf>	direction
       
   882 %type  <leaf>	task_configuration
       
   883 %type  <leaf>	task_name
       
   884 %type  <leaf>	task_initialization
       
   885 %type  <leaf>	data_source
       
   886 %type  <leaf>	program_configuration
       
   887 // helper symbol for program_configuration
       
   888 %type  <leaf>	optional_task_name
       
   889 // helper symbol for program_configuration
       
   890 %type  <leaf>	optional_prog_conf_elements
       
   891 %type  <list>	prog_conf_elements
       
   892 %type  <leaf>	prog_conf_element
       
   893 %type  <leaf>	fb_task
       
   894 %type  <leaf>	prog_cnxn
       
   895 %type  <leaf>	prog_data_source
       
   896 %type  <leaf>	data_sink
       
   897 %type  <leaf>	instance_specific_initializations
       
   898 // helper symbol for instance_specific_initializations
       
   899 %type  <list>	instance_specific_init_list
       
   900 %type  <leaf>	instance_specific_init
       
   901 // helper symbol for instance_specific_init
       
   902 %type  <leaf>	fb_initialization
       
   903 
       
   904 %type  <leaf>	prev_declared_global_var_name
       
   905 %token  <ID>	prev_declared_global_var_name_token
       
   906 
       
   907 %type  <leaf>	prev_declared_program_name
       
   908 %token  <ID>	prev_declared_program_name_token
       
   909 
       
   910 %type  <leaf>	prev_declared_resource_name
       
   911 %token  <ID>	prev_declared_resource_name_token
       
   912 
       
   913 %token  <ID>	prev_declared_configuration_name_token
       
   914 
       
   915 // %type  <leaf>	prev_declared_task_name
       
   916 // %token  <ID>	prev_declared_task_name_token
       
   917 
       
   918 %token CONFIGURATION
       
   919 %token END_CONFIGURATION
       
   920 %token TASK
       
   921 %token RESOURCE
       
   922 %token ON
       
   923 %token END_RESOURCE
       
   924 %token VAR_CONFIG
       
   925 %token VAR_ACCESS
       
   926 %token END_VAR
       
   927 %token WITH
       
   928 %token PROGRAM
       
   929 %token RETAIN
       
   930 %token NON_RETAIN
       
   931 %token PRIORITY
       
   932 %token SINGLE
       
   933 %token INTERVAL
       
   934 %token READ_WRITE
       
   935 %token READ_ONLY
       
   936 
       
   937 
       
   938 /***********************************/
       
   939 /* B 2.1 Instructions and Operands */
       
   940 /***********************************/
       
   941 %type  <list>	instruction_list
       
   942 %type  <leaf>	il_instruction
       
   943 %type  <leaf>	il_incomplete_instruction
       
   944 %type  <leaf>	label
       
   945 %type  <leaf>	il_simple_operation
       
   946 // helper symbol for il_simple_operation
       
   947 %type <double_symbol> il_simple_operator_clash_il_operand
       
   948 %type  <leaf>	il_expression
       
   949 %type  <leaf>	il_jump_operation
       
   950 %type  <leaf>	il_fb_call
       
   951 %type  <leaf>	il_formal_funct_call
       
   952 // helper symbol for il_formal_funct_call
       
   953 %type  <leaf> il_expr_operator_clash_eol_list
       
   954 %type  <leaf>	il_operand
       
   955 %type  <list>	il_operand_list
       
   956 %type  <list>	simple_instr_list
       
   957 %type  <leaf>	il_simple_instruction
       
   958 %type  <list>	il_param_list
       
   959 %type  <list>	il_param_instruction_list
       
   960 %type  <leaf>	il_param_instruction
       
   961 %type  <leaf>	il_param_last_instruction
       
   962 %type  <leaf>	il_param_assignment
       
   963 %type  <leaf>	il_param_out_assignment
       
   964 
       
   965 %token EOL
       
   966 
       
   967 
       
   968 /*******************/
       
   969 /* B 2.2 Operators */
       
   970 /*******************/
       
   971 %token <ID>	sendto_identifier_token
       
   972 %type  <leaf>	sendto_identifier
       
   973 
       
   974 %type  <leaf>	LD_operator
       
   975 %type  <leaf>	LDN_operator
       
   976 %type  <leaf>	ST_operator
       
   977 %type  <leaf>	STN_operator
       
   978 %type  <leaf>	NOT_operator
       
   979 %type  <leaf>	S_operator
       
   980 %type  <leaf>	R_operator
       
   981 %type  <leaf>	S1_operator
       
   982 %type  <leaf>	R1_operator
       
   983 %type  <leaf>	CLK_operator
       
   984 %type  <leaf>	CU_operator
       
   985 %type  <leaf>	CD_operator
       
   986 %type  <leaf>	PV_operator
       
   987 %type  <leaf>	IN_operator
       
   988 %type  <leaf>	PT_operator
       
   989 %type  <leaf>	AND_operator
       
   990 %type  <leaf>	AND2_operator
       
   991 %type  <leaf>	OR_operator
       
   992 %type  <leaf>	XOR_operator
       
   993 %type  <leaf>	ANDN_operator
       
   994 %type  <leaf>	ANDN2_operator
       
   995 %type  <leaf>	ORN_operator
       
   996 %type  <leaf>	XORN_operator
       
   997 %type  <leaf>	ADD_operator
       
   998 %type  <leaf>	SUB_operator
       
   999 %type  <leaf>	MUL_operator
       
  1000 %type  <leaf>	DIV_operator
       
  1001 %type  <leaf>	MOD_operator
       
  1002 %type  <leaf>	GT_operator
       
  1003 %type  <leaf>	GE_operator
       
  1004 %type  <leaf>	EQ_operator
       
  1005 %type  <leaf>	LT_operator
       
  1006 %type  <leaf>	LE_operator
       
  1007 %type  <leaf>	NE_operator
       
  1008 %type  <leaf>	CAL_operator
       
  1009 %type  <leaf>	CALC_operator
       
  1010 %type  <leaf>	CALCN_operator
       
  1011 %type  <leaf>	RET_operator
       
  1012 %type  <leaf>	RETC_operator
       
  1013 %type  <leaf>	RETCN_operator
       
  1014 %type  <leaf>	JMP_operator
       
  1015 %type  <leaf>	JMPC_operator
       
  1016 %type  <leaf>	JMPCN_operator
       
  1017 
       
  1018 %type  <leaf>	il_simple_operator
       
  1019 %type  <leaf>	il_simple_operator_clash
       
  1020 %type  <leaf>	il_simple_operator_clash1
       
  1021 %type  <leaf>	il_simple_operator_clash2
       
  1022 %type  <leaf>	il_simple_operator_noclash
       
  1023 
       
  1024 //%type  <leaf>	il_expr_operator
       
  1025 %type  <leaf>	il_expr_operator_clash
       
  1026 %type  <leaf>	il_expr_operator_noclash
       
  1027 
       
  1028 %type  <leaf>	il_assign_operator
       
  1029 %type  <leaf>	il_assign_out_operator
       
  1030 %type  <leaf>	il_call_operator
       
  1031 %type  <leaf>	il_return_operator
       
  1032 %type  <leaf>	il_jump_operator
       
  1033 
       
  1034 
       
  1035 %token LD
       
  1036 %token LDN
       
  1037 %token ST
       
  1038 %token STN
       
  1039 %token NOT
       
  1040 %token S
       
  1041 %token R
       
  1042 %token S1
       
  1043 %token R1
       
  1044 %token CLK
       
  1045 %token CU
       
  1046 %token CD
       
  1047 %token PV
       
  1048 %token IN
       
  1049 %token PT
       
  1050 %token AND
       
  1051 %token AND2  /* character '&' in the source code*/
       
  1052 %token OR
       
  1053 %token XOR
       
  1054 %token ANDN
       
  1055 %token ANDN2 /* characters '&N' in the source code */
       
  1056 %token ORN
       
  1057 %token XORN
       
  1058 %token ADD
       
  1059 %token SUB
       
  1060 %token MUL
       
  1061 %token DIV
       
  1062 %token MOD
       
  1063 %token GT
       
  1064 %token GE
       
  1065 %token EQ
       
  1066 %token LT
       
  1067 %token LE
       
  1068 %token NE
       
  1069 %token CAL
       
  1070 %token CALC
       
  1071 %token CALCN
       
  1072 %token RET
       
  1073 %token RETC
       
  1074 %token RETCN
       
  1075 %token JMP
       
  1076 %token JMPC
       
  1077 %token JMPCN
       
  1078 
       
  1079 %token SENDTO   /* "=>" */
       
  1080 
       
  1081 
       
  1082 /***********************/
       
  1083 /* B 3.1 - Expressions */
       
  1084 /***********************/
       
  1085 /* NOTE:
       
  1086  *
       
  1087  *    - unary_operator, multiply_operator,
       
  1088  *      add_operator and comparison_operator
       
  1089  *      are not required. Their values are integrated
       
  1090  *      directly into other rules...
       
  1091  */
       
  1092 %type  <leaf>	expression
       
  1093 %type  <leaf>	xor_expression
       
  1094 %type  <leaf>	and_expression
       
  1095 %type  <leaf>	comparison
       
  1096 %type  <leaf>	equ_expression
       
  1097 // %type  <leaf>	comparison_operator
       
  1098 %type  <leaf>	add_expression
       
  1099 // %type  <leaf>	add_operator
       
  1100 %type  <leaf>	term
       
  1101 // %type  <leaf>	multiply_operator
       
  1102 %type  <leaf>	power_expression
       
  1103 %type  <leaf>	unary_expression
       
  1104 // %type  <leaf>	unary_operator
       
  1105 %type  <leaf>	primary_expression
       
  1106 /* intermediate helper symbol for primary_expression */
       
  1107 %type  <leaf>	function_invocation
       
  1108 
       
  1109 %token AND
       
  1110 %token XOR
       
  1111 %token OR
       
  1112 %token MOD
       
  1113 %token NOT
       
  1114 %token OPER_NE
       
  1115 %token OPER_GE
       
  1116 %token OPER_LE
       
  1117 %token OPER_EXP
       
  1118 
       
  1119 
       
  1120 /********************/
       
  1121 /* B 3.2 Statements */
       
  1122 /********************/
       
  1123 %type <list> statement_list
       
  1124 %type <leaf> statement
       
  1125 
       
  1126 
       
  1127 
       
  1128 /*********************************/
       
  1129 /* B 3.2.1 Assignment Statements */
       
  1130 /*********************************/
       
  1131 %type <leaf> assignment_statement
       
  1132 %token ASSIGN   /* ":=" */
       
  1133 
       
  1134 
       
  1135 /*****************************************/
       
  1136 /* B 3.2.2 Subprogram Control Statements */
       
  1137 /*****************************************/
       
  1138 %type <leaf>	subprogram_control_statement
       
  1139 %type <leaf>	return_statement
       
  1140 %type <leaf>	fb_invocation
       
  1141 %type <leaf>	param_assignment
       
  1142 /* helper symbol for fb_invocation */
       
  1143 %type <list> param_assignment_list
       
  1144 
       
  1145 %token ASSIGN
       
  1146 %token SENDTO   /* "=>" */
       
  1147 %token RETURN
       
  1148 
       
  1149 
       
  1150 /********************************/
       
  1151 /* B 3.2.3 Selection Statements */
       
  1152 /********************************/
       
  1153 %type <leaf>	selection_statement
       
  1154 %type <leaf>	if_statement
       
  1155 %type <leaf>	case_statement
       
  1156 %type <leaf>	case_element
       
  1157 %type <list>	case_list
       
  1158 %type <leaf>	case_list_element
       
  1159 /* helper symbol for if_statement */
       
  1160 %type <list>	elseif_statement_list
       
  1161 /* helper symbol for elseif_statement_list */
       
  1162 %type <leaf>	elseif_statement
       
  1163 /* helper symbol for case_statement */
       
  1164 %type <list>	case_element_list
       
  1165 
       
  1166 %token IF
       
  1167 %token THEN
       
  1168 %token ELSIF
       
  1169 %token ELSE
       
  1170 %token END_IF
       
  1171 
       
  1172 %token CASE
       
  1173 %token OF
       
  1174 %token ELSE
       
  1175 %token END_CASE
       
  1176 
       
  1177 
       
  1178 
       
  1179 /********************************/
       
  1180 /* B 3.2.4 Iteration Statements */
       
  1181 /********************************/
       
  1182 %type <leaf>	iteration_statement
       
  1183 %type <leaf>	for_statement
       
  1184 %type <leaf>	control_variable
       
  1185 %type <leaf>	while_statement
       
  1186 %type <leaf>	repeat_statement
       
  1187 %type <leaf>	exit_statement
       
  1188 /* Integrated directly into for_statement */
       
  1189 // %type <leaf>	for_list
       
  1190 
       
  1191 %token FOR
       
  1192 %token ASSIGN
       
  1193 %token TO
       
  1194 %token BY
       
  1195 %token DO
       
  1196 %token END_FOR
       
  1197 
       
  1198 %token WHILE
       
  1199 %token DO
       
  1200 %token END_WHILE
       
  1201 
       
  1202 %token REPEAT
       
  1203 %token UNTIL
       
  1204 %token END_REPEAT
       
  1205 
       
  1206 %token EXIT
       
  1207 
       
  1208 %%
       
  1209 
       
  1210 
       
  1211 
       
  1212 
       
  1213 /********************************************************/
       
  1214 /********************************************************/
       
  1215 /********************************************************/
       
  1216 /********************************************************/
       
  1217 /********************************************************/
       
  1218 /********************************************************/
       
  1219 /********************************************************/
       
  1220 /********************************************************/
       
  1221 /********************************************************/
       
  1222 /********************************************************/
       
  1223 /********************************************************/
       
  1224 /********************************************************/
       
  1225 /********************************************************/
       
  1226 /********************************************************/
       
  1227 /********************************************************/
       
  1228 /********************************************************/
       
  1229 /********************************************************/
       
  1230 /********************************************************/
       
  1231 /********************************************************/
       
  1232 /********************************************************/
       
  1233 /********************************************************/
       
  1234 /********************************************************/
       
  1235 /********************************************************/
       
  1236 /********************************************************/
       
  1237 /********************************************************/
       
  1238 /********************************************************/
       
  1239 /********************************************************/
       
  1240 /********************************************************/
       
  1241 /********************************************************/
       
  1242 /********************************************************/
       
  1243 /********************************************************/
       
  1244 /********************************************************/
       
  1245 /********************************************************/
       
  1246 /********************************************************/
       
  1247 /********************************************************/
       
  1248 /********************************************************/
       
  1249 /********************************************************/
       
  1250 /********************************************************/
       
  1251 /********************************************************/
       
  1252 /********************************************************/
       
  1253 /********************************************************/
       
  1254 /********************************************************/
       
  1255 /********************************************************/
       
  1256 /********************************************************/
       
  1257 /********************************************************/
       
  1258 
       
  1259 
       
  1260 
       
  1261 
       
  1262 
       
  1263 /*****************************/
       
  1264 /* Prelimenary constructs... */
       
  1265 /*****************************/
       
  1266 start:
       
  1267   library	{$$ = $1;}
       
  1268 ;
       
  1269 
       
  1270 /* the pragmas... */
       
  1271 pragma:
       
  1272   pragma_token	{$$ = new pragma_c($1);}
       
  1273 
       
  1274 
       
  1275 
       
  1276 /* NOTE:
       
  1277  *       short version:
       
  1278  *       identifier is used for previously undeclared identifiers
       
  1279  *       any_identifier is used when any identifier, previously
       
  1280  *       declared or not, is required in the syntax.
       
  1281  *
       
  1282  *       long version:
       
  1283  *       When flex comes across an identifier, it first
       
  1284  *       searches through the currently declared variables,
       
  1285  *       functions, types, etc... to determine if it has
       
  1286  *       been previously declared.
       
  1287  *       Only if the identifier has not yet been declared
       
  1288  *       will it return an identifier_token (later turned into
       
  1289  *       an identifier symbol by the bison generated syntax parser).
       
  1290  *
       
  1291  *       Some constructs in the syntax, such as when calling
       
  1292  *       a function 'F(var1 := 1; var2 := 2);', will accept _any_
       
  1293  *       identifier in 'var1', even if it has been previously
       
  1294  *       declared in the current scope, since var1 belongs to
       
  1295  *       another scope (the variables declared in function F).
       
  1296  *
       
  1297  *       For the above reason, we need to define the symbol
       
  1298  *       any_identifier. All the symbols that may become an
       
  1299  *       any_identifier are expected to be stored in the
       
  1300  *       abstract syntax as a identifier_c
       
  1301  */
       
  1302 /* NOTE:
       
  1303  *  Type names, function names, function block type names and
       
  1304  *  program type names are considerd keywords once they are defined,
       
  1305  *  so may no longer be used for variable names!
       
  1306  *  BUT the spec is confusing on this issue, as it is not clear when
       
  1307  *  a function name should be considered as defined. If it is to be
       
  1308  *  considered defined only from the location from where it is declared
       
  1309  *  and onwards, it means that before it is declared its name may be
       
  1310  *  used for variable names!
       
  1311  *  This means that we must allow names previously used for functions
       
  1312  *  (et. al.) to also constitue an any_identifier!
       
  1313  */
       
  1314 any_identifier:
       
  1315   identifier
       
  1316 | prev_declared_fb_name
       
  1317 | prev_declared_variable_name
       
  1318 /**/
       
  1319 | prev_declared_enumerated_type_name
       
  1320 | prev_declared_simple_type_name
       
  1321 | prev_declared_subrange_type_name
       
  1322 | prev_declared_array_type_name
       
  1323 | prev_declared_structure_type_name
       
  1324 | prev_declared_string_type_name
       
  1325 | prev_declared_derived_function_name
       
  1326 | prev_declared_derived_function_block_name
       
  1327 | prev_declared_program_type_name
       
  1328 /**/
       
  1329 | prev_declared_resource_name
       
  1330 | prev_declared_program_name
       
  1331 | prev_declared_global_var_name
       
  1332 ;
       
  1333 
       
  1334 
       
  1335 
       
  1336 
       
  1337 prev_declared_variable_name: prev_declared_variable_name_token {$$ = new identifier_c($1);};
       
  1338 prev_declared_fb_name: prev_declared_fb_name_token {$$ = new identifier_c($1);};
       
  1339 
       
  1340 prev_declared_simple_type_name: prev_declared_simple_type_name_token {$$ = new identifier_c($1);};
       
  1341 prev_declared_subrange_type_name: prev_declared_subrange_type_name_token {$$ = new identifier_c($1);};
       
  1342 prev_declared_enumerated_type_name: prev_declared_enumerated_type_name_token {$$ = new identifier_c($1);};
       
  1343 prev_declared_array_type_name: prev_declared_array_type_name_token {$$ = new identifier_c($1);};
       
  1344 prev_declared_structure_type_name: prev_declared_structure_type_name_token {$$ = new identifier_c($1);};
       
  1345 prev_declared_string_type_name: prev_declared_string_type_name_token {$$ = new identifier_c($1);};
       
  1346 
       
  1347 prev_declared_derived_function_name: prev_declared_derived_function_name_token {$$ = new identifier_c($1);};
       
  1348 prev_declared_derived_function_block_name: prev_declared_derived_function_block_name_token {$$ = new identifier_c($1);};
       
  1349 prev_declared_program_type_name: prev_declared_program_type_name_token {$$ = new identifier_c($1);};
       
  1350 
       
  1351 
       
  1352 
       
  1353 
       
  1354 
       
  1355 /***************************/
       
  1356 /* B 0 - Programming Model */
       
  1357 /***************************/
       
  1358 library:
       
  1359   /* empty */
       
  1360 	{if (tree_root == NULL)
       
  1361 	  tree_root = new library_c();
       
  1362 	 $$ = (list_c *)tree_root;
       
  1363 	}
       
  1364 | library library_element_declaration
       
  1365 	{$$ = $1; $$->add_element($2);}
       
  1366 | library error
       
  1367 	{$$ = NULL;
       
  1368 	 print_err_msg(current_filename, @2.last_line, "unknown error.");
       
  1369 	 /* yychar */
       
  1370 	 yyerrok;
       
  1371 	}
       
  1372 ;
       
  1373 
       
  1374 
       
  1375 library_element_declaration:
       
  1376   data_type_declaration
       
  1377 | function_declaration
       
  1378 | function_block_declaration
       
  1379 | program_declaration
       
  1380 | configuration_declaration
       
  1381 ;
       
  1382 
       
  1383 
       
  1384 
       
  1385 /*******************************************/
       
  1386 /* B 1.1 - Letters, digits and identifiers */
       
  1387 /*******************************************/
       
  1388 /* NOTE: the spec defines identifier as:
       
  1389  *         identifier ::= (letter|('_' (letter|digit))) {['_'] (letter|digit)}
       
  1390  *       In essence, any sequence of letters or digits, starting with a letter
       
  1391  *       or '_'.
       
  1392  *
       
  1393  *       On section 2.1.3 (pg 26) , the spec states
       
  1394  *       "The keywords listed in annex C shall not be used for any other purpose,
       
  1395  *         e.g., variable names or extensions as defined in 1.5.1."
       
  1396  *       (NOTE: the spec itself does not follow this rule, as it defines standard
       
  1397  *       functions with names identidal to keywords, e.g. 'MOD', 'NOT' !!. This is
       
  1398  *       another issue altogether, and is worked around somewhere else...)
       
  1399  *
       
  1400  *       This means that we must re-define indentifier so as to exclude
       
  1401  *       any keywords defined in annex C.
       
  1402  *
       
  1403  *       Note also that the list includes
       
  1404  *          - Data type names
       
  1405  *          - Function names
       
  1406  *          - Function Block names
       
  1407  *       This means that any named used for a function name, data type name
       
  1408  *       or function block name, essentially becomes a keyword, and may therefore
       
  1409  *       no longer be re-used for any other use! (see NOTE 2)
       
  1410  *
       
  1411  *       In our case, excluding the keywords is achieved in the lexical parser,
       
  1412  *       by two mechanisms:
       
  1413  *         (1) giving higher priority to the keywords (tokens) than to identifiers,
       
  1414  *             so when the lexical parser finds a keyword it will be parsed as a
       
  1415  *             token before being parsed as an identifier.
       
  1416  *         (2) when an identifier is found that is not a keyword, the lexical parser
       
  1417  *             then looks in the global symbol table, and will not return an identifier
       
  1418  *             if the name has been previously used as a data type name, function name,
       
  1419  *             or function block name! (In these cases it will return a
       
  1420  *             prev_declared_function_name_token, etc...).
       
  1421  *
       
  1422  *       Unfortunately, the language (especially IL) uses tokens that are
       
  1423  *       not defined as keywords in the spec (e.g. 'IN', 'R1', 'S1', 'PT', etc...)!
       
  1424  *       This means that it is valid to name a function 'IN', a variable 'PT', etc...
       
  1425  *       BUT, the lexical parser will interpret these names as tokens (keywords).
       
  1426  *       To allow these names to be used as function names, variable names, etc...,
       
  1427  *       I (Mario) have augmented the definition of identifier to also include the tokens
       
  1428  *       that are not explicitly defined as keywords in the spec!!
       
  1429  *
       
  1430  *
       
  1431  *
       
  1432  *
       
  1433  * NOTE 2:
       
  1434  *         I (Mario) find it strange that the writers of the spec really want
       
  1435  *         names previously used for function names, data type names or function
       
  1436  *         block names, to become full fledged keywords. I understand that they
       
  1437  *         do not want these names being used as variable names, but how about
       
  1438  *         enumeration values? How about structure element names?
       
  1439  *         If we interpret the spec literally, these would not be accepted,
       
  1440  *         which would probably burden the programmer quite a bit, in making sure
       
  1441  *         all these name don't clash!
       
  1442  *
       
  1443  *
       
  1444  *
       
  1445  * NOTE 3: The keywords, as specified in Annex C are...
       
  1446  *
       
  1447  *          - Data type names
       
  1448  *          - Function names
       
  1449  *          - Function Block names
       
  1450  *          - ACTION...END_ACTION
       
  1451  *          - ARRAY...OF
       
  1452  *          - AT
       
  1453  *          - CASE...OF...ELSE...END_CASE
       
  1454  *          - CONFIGURATION...END_CONFIGURATION
       
  1455  *          - CONSTANT
       
  1456  *          - EN, ENO
       
  1457  *          - EXIT
       
  1458  *          - FALSE
       
  1459  *          - F_EDGE
       
  1460  *          - FOR...TO...BY...DO...END_FOR
       
  1461  *          - FUNCTION...END_FUNCTION
       
  1462  *          - FUNCTION_BLOCK...END_FUNCTION_BLOCK
       
  1463  *          - IF...THEN...ELSIF...ELSE...END_IF
       
  1464  *          - INITIAL_STEP...END_STEP
       
  1465  *          - NOT, MOD, AND, XOR, OR
       
  1466  *          - PROGRAM...WITH...
       
  1467  *          - PROGRAM...END_PROGRAM
       
  1468  *          - R_EDGE
       
  1469  *          - READ_ONLY, READ_WRITE
       
  1470  *          - REPEAT...UNTIL...END_REPEAT
       
  1471  *          - RESOURCE...ON...END_RESOURCE
       
  1472  *          - RETAIN, NON_RETAIN
       
  1473  *          - RETURN
       
  1474  *          - STEP...END_STEP
       
  1475  *          - STRUCT...END_STRUCT
       
  1476  *          - TASK
       
  1477  *          - TRANSITION...FROM...TO...END_TRANSITION
       
  1478  *          - TRUE
       
  1479  *          - TYPE...END_TYPE
       
  1480  *          - VAR...END_VAR
       
  1481  *          - VAR_INPUT...END_VAR
       
  1482  *          - VAR_OUTPUT...END_VAR
       
  1483  *          - VAR_IN_OUT...END_VAR
       
  1484  *          - VAR_TEMP...END_VAR
       
  1485  *          - VAR_EXTERNAL...END_VAR
       
  1486  *          - VAR_ACCESS...END_VAR
       
  1487  *          - VAR_CONFIG...END_VAR
       
  1488  *          - VAR_GLOBAL...END_VAR
       
  1489  *          - WHILE...DO...END_WHILE
       
  1490  *          - WITH
       
  1491  */
       
  1492 
       
  1493 identifier:
       
  1494   identifier_token	{$$ = new identifier_c($1);}
       
  1495 /*  Make sure that all tokens (names) not defined as keywords are included here...
       
  1496  * I (Mario) have already done this, but if any changes are made to this file,
       
  1497  * this list MUST be kept consistent!!
       
  1498  */
       
  1499 /**/
       
  1500 | PRIORITY		{$$ = new identifier_c(strdup("PRIORITY"));}
       
  1501 | SINGLE		{$$ = new identifier_c(strdup("SINGLE"));}
       
  1502 | INTERVAL		{$$ = new identifier_c(strdup("INTERVAL"));}
       
  1503 /**/
       
  1504 | LD_operator		{$$ = il_operator_c_2_identifier_c($1);}
       
  1505 | LDN_operator		{$$ = il_operator_c_2_identifier_c($1);}
       
  1506 | ST_operator		{$$ = il_operator_c_2_identifier_c($1);}
       
  1507 | STN_operator		{$$ = il_operator_c_2_identifier_c($1);}
       
  1508 | S_operator		{$$ = il_operator_c_2_identifier_c($1);}
       
  1509 | R_operator		{$$ = il_operator_c_2_identifier_c($1);}
       
  1510 | S1_operator		{$$ = il_operator_c_2_identifier_c($1);}
       
  1511 | R1_operator		{$$ = il_operator_c_2_identifier_c($1);}
       
  1512 | CLK_operator		{$$ = il_operator_c_2_identifier_c($1);}
       
  1513 | CU_operator		{$$ = il_operator_c_2_identifier_c($1);}
       
  1514 | CD_operator		{$$ = il_operator_c_2_identifier_c($1);}
       
  1515 | PV_operator		{$$ = il_operator_c_2_identifier_c($1);}
       
  1516 | IN_operator		{$$ = il_operator_c_2_identifier_c($1);}
       
  1517 | PT_operator		{$$ = il_operator_c_2_identifier_c($1);}
       
  1518 | ANDN_operator		{$$ = il_operator_c_2_identifier_c($1);}
       
  1519 /* NOTE: ANDN2_operator corresponds to the string '&N' in the source code!
       
  1520  *       This is __not__ a valid name, so it is omitted from this list!!
       
  1521  *| ANDN2_operator		{$$ = il_operator_c_2_identifier_c($1);}
       
  1522  */
       
  1523 /* NOTE: 'AND' is a keyword, so should not appear on this list... */
       
  1524 | ORN_operator		{$$ = il_operator_c_2_identifier_c($1);}
       
  1525 | XORN_operator		{$$ = il_operator_c_2_identifier_c($1);}
       
  1526 | ADD_operator		{$$ = il_operator_c_2_identifier_c($1);}
       
  1527 | SUB_operator		{$$ = il_operator_c_2_identifier_c($1);}
       
  1528 | MUL_operator		{$$ = il_operator_c_2_identifier_c($1);}
       
  1529 | DIV_operator		{$$ = il_operator_c_2_identifier_c($1);}
       
  1530 | GT_operator		{$$ = il_operator_c_2_identifier_c($1);}
       
  1531 | GE_operator		{$$ = il_operator_c_2_identifier_c($1);}
       
  1532 | EQ_operator		{$$ = il_operator_c_2_identifier_c($1);}
       
  1533 | LT_operator		{$$ = il_operator_c_2_identifier_c($1);}
       
  1534 | LE_operator		{$$ = il_operator_c_2_identifier_c($1);}
       
  1535 | NE_operator		{$$ = il_operator_c_2_identifier_c($1);}
       
  1536 | CAL_operator		{$$ = il_operator_c_2_identifier_c($1);}
       
  1537 | CALC_operator		{$$ = il_operator_c_2_identifier_c($1);}
       
  1538 | CALCN_operator	{$$ = il_operator_c_2_identifier_c($1);}
       
  1539 | RET_operator		{$$ = il_operator_c_2_identifier_c($1);}
       
  1540 | RETC_operator		{$$ = il_operator_c_2_identifier_c($1);}
       
  1541 | RETCN_operator	{$$ = il_operator_c_2_identifier_c($1);}
       
  1542 | JMP_operator		{$$ = il_operator_c_2_identifier_c($1);}
       
  1543 | JMPC_operator		{$$ = il_operator_c_2_identifier_c($1);}
       
  1544 | JMPCN_operator	{$$ = il_operator_c_2_identifier_c($1);}
       
  1545 /**/
       
  1546 | L		{$$ = new identifier_c(strdup("L"));}
       
  1547 | D		{$$ = new identifier_c(strdup("D"));}
       
  1548 | SD		{$$ = new identifier_c(strdup("SD"));}
       
  1549 | DS		{$$ = new identifier_c(strdup("DS"));}
       
  1550 | SL		{$$ = new identifier_c(strdup("SL"));}
       
  1551 | N		{$$ = new identifier_c(strdup("N"));}
       
  1552 /* NOTE: the following two clash with the R and S IL operators.
       
  1553  * It will have to be handled when we include parsing of SFC...
       
  1554  */
       
  1555 /*
       
  1556 | R		{$$ = new identifier_c(strdup("R"));}
       
  1557 | S		{$$ = new identifier_c(strdup("S"));}
       
  1558 */
       
  1559 | P		{$$ = new identifier_c(strdup("P"));}
       
  1560 
       
  1561 ;
       
  1562 
       
  1563 /*********************/
       
  1564 /* B 1.2 - Constants */
       
  1565 /*********************/
       
  1566 constant:
       
  1567   numeric_literal
       
  1568 | character_string
       
  1569 | time_literal
       
  1570 | bit_string_literal
       
  1571 | boolean_literal
       
  1572 /* NOTE: in order to remove reduce/reduce conflicts,
       
  1573  * unsigned_integer, signed_integer, binary_integer, octal_integer
       
  1574  * and hex_integer have been integrated directly into
       
  1575  * the constants construct, instead of belonging to
       
  1576  * either the bit_string_literal or integer_literal
       
  1577  * construct.
       
  1578  */
       
  1579 /* NOTE: unsigned_integer, although used in some
       
  1580  * rules, is not defined in the spec!
       
  1581  * We therefore replaced unsigned_integer as integer
       
  1582  */
       
  1583 /*| integer {} */  /* i.e. an unsigned_integer */ /* NOTE: already included as a signed integer! */
       
  1584 | signed_integer
       
  1585 | binary_integer
       
  1586 | octal_integer
       
  1587 | hex_integer
       
  1588 ;
       
  1589 
       
  1590 /* a helper symbol for expression */
       
  1591 /* A constant without any preceding '-', but may
       
  1592  * include a preceding '+' !
       
  1593  */
       
  1594 non_negative_constant:
       
  1595   non_negative_numeric_literal
       
  1596 | character_string
       
  1597 | time_literal
       
  1598 | bit_string_literal
       
  1599 | boolean_literal
       
  1600 | non_negative_signed_integer
       
  1601 | binary_integer
       
  1602 | octal_integer
       
  1603 | hex_integer
       
  1604 ;
       
  1605 
       
  1606 
       
  1607 
       
  1608 /******************************/
       
  1609 /* B 1.2.1 - Numeric Literals */
       
  1610 /******************************/
       
  1611 /* NOTES:
       
  1612  *
       
  1613  *    - integer is parsed by flex, but signed_integer
       
  1614  *      is parsed by bison. Flex cannot parse a signed
       
  1615  *      integer correctly!  For example: '123+456'
       
  1616  *      would be parsed by flex as an {integer} {signed_integer}
       
  1617  *      instead of {integer} '+' {integer}
       
  1618  *
       
  1619  *    - Neither flex nor bison can parse a real_literal
       
  1620  *      completely (and correctly).
       
  1621  *      Note that we cannot use the definition of real in bison as
       
  1622  *      real: signed_integer '.' integer [exponent]
       
  1623  *      exponent: {'E'|'e'} ['+'|'-'] integer
       
  1624  *      because 123e45 would be parsed by flex as
       
  1625  *      integer (123) identifier (e45).
       
  1626  *      I.e., flex never hands over an 'e' directly to
       
  1627  *      bison, but rather interprets it as an identifier.
       
  1628  *      I guess we could jump through hoops and get it
       
  1629  *      working in bison, but the following alternative
       
  1630  *      seems more straight forward...
       
  1631  *
       
  1632  *      We therefore had to break up the definition of
       
  1633  *      real_literal in discrete parts:
       
  1634  *      real_literal: [real_type_name '#'] singned_real
       
  1635  *      signed_real: ['+'|'-'] real
       
  1636  *      Flex handles real, while bison handles signed_real
       
  1637  *      and real_literal.
       
  1638  *
       
  1639  *    - According to the spec, intger '.' integer
       
  1640  *      may be reduced to either a real or a fixed_point.
       
  1641  *      It is nevertheless possible to figure out from the
       
  1642  *      context which of the two rules should be used in
       
  1643  *      the reduction.
       
  1644  *      Unfortunately, due to the issue described above
       
  1645  *      regarding the exponent of a real, the syntax
       
  1646  *      integer '.' integer
       
  1647  *      must be parsed by flex as a single token (i.e.
       
  1648  *      fixed_point_token). This means we must add fixed_point
       
  1649  *      to the definition of real!
       
  1650  *
       
  1651  *    - The syntax also uses a construct
       
  1652  *        fixed_point: integer ['.' integer]
       
  1653  *      Notice that real is not defined based on fixed point,
       
  1654  *      but rather off integer thus:
       
  1655  *        real: integer '.' integer [exponent]
       
  1656  *      This means that a real may not be composed of a single
       
  1657  *      integer, unlike the construct fixed_point!
       
  1658  *      This also means that a
       
  1659  *        integer '.' integer
       
  1660  *      could be reduced to either a real or a fixed_point
       
  1661  *      construct. It is probably possible to decide by looking
       
  1662  *      at the context, BUT:
       
  1663  *       Unfortunatley, due to the reasons explained way above,
       
  1664  *      a real (with an exponent) has to be handled by flex as a
       
  1665  *      whole. This means that we cannot leave to bison (the syntax
       
  1666  *      parser) the decision of how to reduce an
       
  1667  *        integer '.' integer
       
  1668  *      (either to real or to fixed_point)
       
  1669  *      The decision on how to reduce it would need to be done by
       
  1670  *      ther lexical analyser (i.e. flex). But flex cannot do this
       
  1671  *      sort of thing.
       
  1672  *      The solution I (Mario) adopted is to have flex return
       
  1673  *      a real_token on (notice that exponent is no longer optional)
       
  1674  *        integer '.' integer exponent
       
  1675  *      and to return a fixed_point_token when it finds
       
  1676  *        integer '.' integer
       
  1677  *      We now redefine real and fixed_point to be
       
  1678  *        fixed_point: fixed_point_token | integer
       
  1679  *        real: real_token | fixed_point_token
       
  1680  */
       
  1681 real:
       
  1682   real_token		{$$ = new real_c($1);}
       
  1683 | fixed_point_token	{$$ = new real_c($1);}
       
  1684 ;
       
  1685 
       
  1686 integer:	integer_token		{$$ = new integer_c($1);};
       
  1687 binary_integer:	binary_integer_token	{$$ = new binary_integer_c($1);};
       
  1688 octal_integer:	octal_integer_token	{$$ = new octal_integer_c($1);};
       
  1689 hex_integer:	hex_integer_token	{$$ = new hex_integer_c($1);};
       
  1690 
       
  1691 numeric_literal:
       
  1692   integer_literal
       
  1693 | real_literal
       
  1694 ;
       
  1695 
       
  1696 /* helper symbol for non_negative_constant */
       
  1697 non_negative_numeric_literal:
       
  1698   integer_literal
       
  1699 | non_negative_real_literal
       
  1700 ;
       
  1701 
       
  1702 
       
  1703 integer_literal:
       
  1704   integer_type_name '#' signed_integer
       
  1705 	{$$ = new integer_literal_c($1, $3);}
       
  1706 | integer_type_name '#' binary_integer
       
  1707 	{$$ = new integer_literal_c($1, $3);}
       
  1708 | integer_type_name '#' octal_integer
       
  1709 	{$$ = new integer_literal_c($1, $3);}
       
  1710 | integer_type_name '#' hex_integer
       
  1711 	{$$ = new integer_literal_c($1, $3);}
       
  1712 /* NOTE: see note in the definition of constant for reason
       
  1713  * why signed_integer, binary_integer, octal_integer
       
  1714  * and hex_integer are missing here!
       
  1715  */
       
  1716 ;
       
  1717 
       
  1718 signed_integer:
       
  1719   integer
       
  1720 | '+' integer   {$$ = $2;}
       
  1721 | '-' integer	{$$ = new neg_expression_c($2);}
       
  1722 ;
       
  1723 
       
  1724 /* a helper symbol for non_negative_constant */
       
  1725 /* A integer without any preceding '-', but may
       
  1726  * include a preceding '+' !
       
  1727  */
       
  1728 non_negative_signed_integer:
       
  1729   integer
       
  1730 | '+' integer   {$$ = $2;}
       
  1731 ;
       
  1732 
       
  1733 
       
  1734 real_literal:
       
  1735   signed_real
       
  1736 | real_type_name '#' signed_real
       
  1737 	{$$ = new real_literal_c($1, $3);}
       
  1738 ;
       
  1739 
       
  1740 /* helper symbol for non_negative_numeric_literal */
       
  1741 non_negative_real_literal:
       
  1742   non_negative_signed_real
       
  1743 | real_type_name '#' signed_real
       
  1744 	{$$ = new real_literal_c($1, $3);}
       
  1745 ;
       
  1746 
       
  1747 signed_real:
       
  1748   real
       
  1749 | '+' real	{$$ = $2;}
       
  1750 | '-' real	{$$ = new neg_expression_c($2);}
       
  1751 ;
       
  1752 
       
  1753 /* helper symbol for non_negative_real_literal */
       
  1754 non_negative_signed_real:
       
  1755   real
       
  1756 | '+' real	{$$ = $2;}
       
  1757 ;
       
  1758 
       
  1759 
       
  1760 bit_string_literal:
       
  1761   bit_string_type_name '#' integer  /* i.e. unsigned_integer */
       
  1762 	{$$ = new bit_string_literal_c($1, $3);}
       
  1763 | bit_string_type_name '#' binary_integer
       
  1764 	{$$ = new bit_string_literal_c($1, $3);}
       
  1765 | bit_string_type_name '#' octal_integer
       
  1766 	{$$ = new bit_string_literal_c($1, $3);}
       
  1767 | bit_string_type_name '#' hex_integer
       
  1768 	{$$ = new bit_string_literal_c($1, $3);}
       
  1769 /* NOTE: see note in the definition of constant for reason
       
  1770  * why unsigned_integer, binary_integer, octal_integer
       
  1771  * and hex_integer are missing here!
       
  1772  */
       
  1773 /* NOTE: see note under the B 1.2.1 section of token
       
  1774  * and grouping type definition for reason why the use of
       
  1775  * bit_string_type_name, although seemingly incorrect, is
       
  1776  * really correct here!
       
  1777  */
       
  1778 ;
       
  1779 
       
  1780 
       
  1781 boolean_literal:
       
  1782   TRUE	{$$ = new boolean_literal_c(new bool_type_name_c(),
       
  1783   				    new boolean_true_c());}
       
  1784 | FALSE	{$$ = new boolean_literal_c(new bool_type_name_c(),
       
  1785 				    new boolean_false_c());}
       
  1786 /*
       
  1787 |	BOOL '#' '1' {}
       
  1788 |	BOOL '#' '0' {}
       
  1789 */
       
  1790 /* NOTE: the rules
       
  1791  * BOOL '#' '1'
       
  1792  * and
       
  1793  * BOOL '#' '0'
       
  1794  * do not work as expected...
       
  1795  * Consider that we are using 'BOOL' and '#' as tokens
       
  1796  * that flex hands over to bison (yacc). Because flex would
       
  1797  * then parse the single '1' or '0' as an integer,
       
  1798  * the rule in bison would have to be
       
  1799  * BOOL '#' integer, followed by verifying of the
       
  1800  * integer has the correct value!
       
  1801  *
       
  1802  * We therefore have flex return TRUE whenever it
       
  1803  * comes across 'TRUE' or 'BOOL#1', and FALSE whenever
       
  1804  * it comes across 'FALSE' or 'BOOL#0'.
       
  1805  * Note that this means that flex will parse "BOOL#01"
       
  1806  * as FALSE followed by an integer ('1').
       
  1807  * Bison should detect this as an error, so we should
       
  1808  * be OK.
       
  1809  *
       
  1810  * Another option would be to change the rules to accept
       
  1811  * BOOL '#' integer
       
  1812  * but then check whether the integer has a correct
       
  1813  * value! At the moment I feel that the first option
       
  1814  * is more straight forward.
       
  1815  */
       
  1816 ;
       
  1817 
       
  1818 
       
  1819 
       
  1820 /*******************************/
       
  1821 /* B 1.2.2 - Character Strings */
       
  1822 /*******************************/
       
  1823 /* Transform the tokens given us by flex into leafs */
       
  1824 single_byte_character_string:	single_byte_character_string_token
       
  1825 	{$$ = new single_byte_character_string_c($1);};
       
  1826 
       
  1827 double_byte_character_string:	double_byte_character_string_token
       
  1828 	{$$ = new double_byte_character_string_c($1);};
       
  1829 
       
  1830 
       
  1831 character_string:
       
  1832   single_byte_character_string
       
  1833 | double_byte_character_string
       
  1834 ;
       
  1835 
       
  1836 
       
  1837 
       
  1838 
       
  1839 
       
  1840 /***************************/
       
  1841 /* B 1.2.3 - Time Literals */
       
  1842 /***************************/
       
  1843 time_literal:
       
  1844   time_of_day
       
  1845 | date
       
  1846 | date_and_time
       
  1847 | duration
       
  1848 ;
       
  1849 
       
  1850 
       
  1851 /************************/
       
  1852 /* B 1.2.3.1 - Duration */
       
  1853 /************************/
       
  1854 duration:
       
  1855 /*  (T | TIME) '#' ['-'] interval */
       
  1856 /* NOTE: since TIME is also a data type, it is a keyword
       
  1857  *       and may therefore be handled by a token.
       
  1858  *
       
  1859  *       Unfortunately T is not a data type, and therefore
       
  1860  *       not a keyword. This means that we may have variables named T!
       
  1861  *       Flex cannot return the token TIME when it comes across a single T!
       
  1862  *
       
  1863  *       We therefore have flex returning the token T_SHARP
       
  1864  *       when it comes across 'T#'
       
  1865  */
       
  1866   TIME '#' interval
       
  1867 	{$$ = new duration_c(NULL, $3);}
       
  1868 | TIME '#' '-' interval
       
  1869 	{$$ = new duration_c(new neg_time_c(), $4);}
       
  1870 | T_SHARP interval
       
  1871 	{$$ = new duration_c(NULL, $2);}
       
  1872 | T_SHARP '-' interval
       
  1873 	{$$ = new duration_c(new neg_time_c(), $3);}
       
  1874 ;
       
  1875 
       
  1876 
       
  1877 interval:
       
  1878   days
       
  1879 | hours
       
  1880 | minutes
       
  1881 | seconds
       
  1882 | milliseconds
       
  1883 ;
       
  1884 
       
  1885 integer_d:  integer_d_token  {$$ = new integer_c($1);};
       
  1886 integer_h:  integer_h_token  {$$ = new integer_c($1);};
       
  1887 integer_m:  integer_m_token  {$$ = new integer_c($1);};
       
  1888 integer_s:  integer_s_token  {$$ = new integer_c($1);};
       
  1889 integer_ms: integer_ms_token {$$ = new integer_c($1);};
       
  1890 
       
  1891 fixed_point_d:
       
  1892   fixed_point_d_token
       
  1893 	{$$ = new fixed_point_c($1);}
       
  1894 | integer_d
       
  1895 ;
       
  1896 
       
  1897 fixed_point_h:
       
  1898   fixed_point_h_token
       
  1899 	{$$ = new fixed_point_c($1);}
       
  1900 | integer_h
       
  1901 ;
       
  1902 
       
  1903 fixed_point_m:
       
  1904   fixed_point_m_token
       
  1905 	{$$ = new fixed_point_c($1);}
       
  1906 | integer_m
       
  1907 ;
       
  1908 
       
  1909 fixed_point_s:
       
  1910   fixed_point_s_token
       
  1911 	{$$ = new fixed_point_c($1);}
       
  1912 | integer_s
       
  1913 ;
       
  1914 
       
  1915 fixed_point_ms:
       
  1916   fixed_point_ms_token
       
  1917 	{$$ = new fixed_point_c($1);}
       
  1918 | integer_ms
       
  1919 ;
       
  1920 
       
  1921 
       
  1922 fixed_point:
       
  1923   fixed_point_token
       
  1924 	{$$ = new fixed_point_c($1);}
       
  1925 | integer
       
  1926 ;
       
  1927 
       
  1928 
       
  1929 days:
       
  1930 /*  fixed_point ('d') */
       
  1931   fixed_point_d
       
  1932 	{$$ = new days_c($1, NULL);}
       
  1933 /*| integer ('d') ['_'] hours */
       
  1934 | integer_d hours
       
  1935 	{$$ = new days_c($1, $2);}
       
  1936 | integer_d '_' hours
       
  1937 	{$$ = new days_c($1, $3);}
       
  1938 ;
       
  1939 
       
  1940 
       
  1941 hours:
       
  1942 /*  fixed_point ('h') */
       
  1943   fixed_point_h
       
  1944 	{$$ = new hours_c($1, NULL);}
       
  1945 /*| integer ('h') ['_'] minutes */
       
  1946 | integer_h minutes
       
  1947 	{$$ = new hours_c($1, $2);}
       
  1948 | integer_h '_' minutes
       
  1949 	{$$ = new hours_c($1, $3);}
       
  1950 ;
       
  1951 
       
  1952 minutes:
       
  1953 /*  fixed_point ('m') */
       
  1954   fixed_point_m
       
  1955 	{$$ = new minutes_c($1, NULL);}
       
  1956 /*| integer ('m') ['_'] seconds */
       
  1957 | integer_m seconds
       
  1958 	{$$ = new minutes_c($1, $2);}
       
  1959 | integer_m '_' seconds
       
  1960 	{$$ = new minutes_c($1, $3);}
       
  1961 ;
       
  1962 
       
  1963 seconds:
       
  1964 /*  fixed_point ('s') */
       
  1965   fixed_point_s
       
  1966 	{$$ = new seconds_c($1, NULL);}
       
  1967 /*| integer ('s') ['_'] milliseconds */
       
  1968 | integer_s milliseconds
       
  1969 	{$$ = new seconds_c($1, $2);}
       
  1970 | integer_s '_' milliseconds
       
  1971 	{$$ = new seconds_c($1, $3);}
       
  1972 ;
       
  1973 
       
  1974 milliseconds:
       
  1975 /*  fixed_point ('ms') */
       
  1976   fixed_point_ms
       
  1977 	{$$ = new milliseconds_c($1);}
       
  1978 ;
       
  1979 
       
  1980 
       
  1981 
       
  1982 /************************************/
       
  1983 /* B 1.2.3.2 - Time of day and Date */
       
  1984 /************************************/
       
  1985 time_of_day:
       
  1986   TIME_OF_DAY '#' daytime
       
  1987 	{$$ = new time_of_day_c($3);}
       
  1988 ;
       
  1989 
       
  1990 
       
  1991 daytime:
       
  1992   day_hour ':' day_minute ':' day_second
       
  1993 	{$$ = new daytime_c($1, $3, $5);}
       
  1994 ;
       
  1995 
       
  1996 
       
  1997 day_hour: integer;
       
  1998 day_minute: integer;
       
  1999 day_second: fixed_point;
       
  2000 
       
  2001 
       
  2002 date:
       
  2003   DATE '#' date_literal
       
  2004 	{$$ = new date_c($3);}
       
  2005 | D_SHARP date_literal
       
  2006 	{$$ = new date_c($2);}
       
  2007 ;
       
  2008 
       
  2009 
       
  2010 date_literal:
       
  2011   year '-' month '-' day
       
  2012 	{$$ = new date_literal_c($1, $3, $5);}
       
  2013 ;
       
  2014 
       
  2015 
       
  2016 year: integer;
       
  2017 month: integer;
       
  2018 day: integer;
       
  2019 
       
  2020 
       
  2021 date_and_time:
       
  2022   DATE_AND_TIME '#' date_literal '-' daytime
       
  2023 	{$$ = new date_and_time_c($3, $5);}
       
  2024 ;
       
  2025 
       
  2026 
       
  2027 
       
  2028 
       
  2029 
       
  2030 
       
  2031 /**********************/
       
  2032 /* B 1.3 - Data Types */
       
  2033 /**********************/
       
  2034 /* Strangely, the following symbol does seem to be required! */
       
  2035 /*
       
  2036 data_type_name:
       
  2037   non_generic_type_name
       
  2038 | generic_type_name
       
  2039 ;
       
  2040 */
       
  2041 
       
  2042 non_generic_type_name:
       
  2043   elementary_type_name
       
  2044 | derived_type_name
       
  2045 ;
       
  2046 
       
  2047 
       
  2048 
       
  2049 /***********************************/
       
  2050 /* B 1.3.1 - Elementary Data Types */
       
  2051 /***********************************/
       
  2052 elementary_type_name:
       
  2053   numeric_type_name
       
  2054 | date_type_name
       
  2055 | bit_string_type_name
       
  2056 | elementary_string_type_name
       
  2057 | TIME		{$$ = new time_type_name_c();}
       
  2058 | BOOL		{$$ = new bool_type_name_c();}
       
  2059 /* NOTE: see note under the B 1.2.1 section of token
       
  2060  * and grouping type definition for reason why BOOL
       
  2061  * was added to this definition.
       
  2062  */
       
  2063 ;
       
  2064 
       
  2065 numeric_type_name:
       
  2066   integer_type_name
       
  2067 | real_type_name
       
  2068 ;
       
  2069 
       
  2070 integer_type_name:
       
  2071   signed_integer_type_name
       
  2072 | unsigned_integer_type_name
       
  2073 ;
       
  2074 
       
  2075 signed_integer_type_name:
       
  2076   SINT	{$$ = new sint_type_name_c();}
       
  2077 | INT	{$$ = new int_type_name_c();}
       
  2078 | DINT	{$$ = new dint_type_name_c();}
       
  2079 | LINT	{$$ = new lint_type_name_c();}
       
  2080 ;
       
  2081 
       
  2082 unsigned_integer_type_name:
       
  2083   USINT	{$$ = new usint_type_name_c();}
       
  2084 | UINT	{$$ = new uint_type_name_c();}
       
  2085 | UDINT	{$$ = new udint_type_name_c();}
       
  2086 | ULINT	{$$ = new ulint_type_name_c();}
       
  2087 ;
       
  2088 
       
  2089 real_type_name:
       
  2090   REAL	{$$ = new real_type_name_c();}
       
  2091 | LREAL	{$$ = new lreal_type_name_c();}
       
  2092 ;
       
  2093 
       
  2094 date_type_name:
       
  2095   DATE		{$$ = new date_type_name_c();}
       
  2096 | TIME_OF_DAY	{$$ = new tod_type_name_c();}
       
  2097 | TOD		{$$ = new tod_type_name_c();}
       
  2098 | DATE_AND_TIME	{$$ = new dt_type_name_c();}
       
  2099 | DT		{$$ = new dt_type_name_c();}
       
  2100 ;
       
  2101 
       
  2102 
       
  2103 bit_string_type_name:
       
  2104   BYTE	{$$ = new byte_type_name_c();}
       
  2105 | WORD	{$$ = new word_type_name_c();}
       
  2106 | DWORD	{$$ = new dword_type_name_c();}
       
  2107 | LWORD	{$$ = new lword_type_name_c();}
       
  2108 /* NOTE: see note under the B 1.2.1 section of token
       
  2109  * and grouping type definition for reason why the BOOL
       
  2110  * was omitted from this definition.
       
  2111  */
       
  2112 ;
       
  2113 
       
  2114 
       
  2115 /* Helper symbol to concentrate the instantiation
       
  2116  * of STRING and WSTRING into a single location.
       
  2117  *
       
  2118  * These two elements show up in several other rules,
       
  2119  * but we want to create the equivalent abstract syntax
       
  2120  * in a single location of this file, in order to make
       
  2121  * possible future changes easier to edit...
       
  2122  */
       
  2123 elementary_string_type_name:
       
  2124   STRING	{$$ = new string_type_name_c();}
       
  2125 | WSTRING	{$$ = new wstring_type_name_c();}
       
  2126 ;
       
  2127 
       
  2128 
       
  2129 
       
  2130 /********************************/
       
  2131 /* B 1.3.2 - Generic data types */
       
  2132 /********************************/
       
  2133 /* Strangely, the following symbol does seem to be required! */
       
  2134 /*
       
  2135 generic_type_name:
       
  2136   ANY
       
  2137 | ANY_DERIVED
       
  2138 | ANY_ELEMENTARY
       
  2139 | ANY_MAGNITUDE
       
  2140 | ANY_NUM
       
  2141 | ANY_REAL
       
  2142 | ANY_INT
       
  2143 | ANY_BIT
       
  2144 | ANY_STRING
       
  2145 | ANY_DATE
       
  2146 ;
       
  2147 */
       
  2148 
       
  2149 
       
  2150 /********************************/
       
  2151 /* B 1.3.3 - Derived data types */
       
  2152 /********************************/
       
  2153 
       
  2154 derived_type_name:
       
  2155   single_element_type_name
       
  2156 | prev_declared_array_type_name	{$$ = $1;}
       
  2157 | prev_declared_structure_type_name	{$$ = $1;}
       
  2158 | prev_declared_string_type_name	{$$ = $1;}
       
  2159 ;
       
  2160 
       
  2161 single_element_type_name:
       
  2162   prev_declared_simple_type_name		{$$ = $1;}
       
  2163 /* Include the following if arrays of function blocks are to be allowed!
       
  2164  * Since the standard does not allow them,
       
  2165  * we leave it commented out for the time being...
       
  2166  */
       
  2167 //| prev_declared_derived_function_block_name	{$$ = $1;}
       
  2168 | prev_declared_subrange_type_name		{$$ = $1;}
       
  2169 | prev_declared_enumerated_type_name		{$$ = $1;}
       
  2170 ;
       
  2171 
       
  2172 /* NOTE: in order to remove a reduce/reduce conflict,
       
  2173  *       all occurences of simple_type_name, etc...
       
  2174  *       have been replaced with identifier!
       
  2175  */
       
  2176 /*
       
  2177 simple_type_name: identifier;
       
  2178 subrange_type_name: identifier;
       
  2179 enumerated_type_name: identifier;
       
  2180 array_type_name: identifier;
       
  2181 structure_type_name: identifier;
       
  2182 */
       
  2183 
       
  2184 data_type_declaration:
       
  2185   TYPE type_declaration_list END_TYPE
       
  2186 	{$$ = new data_type_declaration_c($2);}
       
  2187 ;
       
  2188 
       
  2189 /* helper symbol for data_type_declaration */
       
  2190 type_declaration_list:
       
  2191   type_declaration ';'
       
  2192 	{$$ = new type_declaration_list_c(); $$->add_element($1);}
       
  2193 | type_declaration_list type_declaration ';'
       
  2194 	{$$ = $1; $$->add_element($2);}
       
  2195 ;
       
  2196 
       
  2197 type_declaration:
       
  2198   single_element_type_declaration
       
  2199 | array_type_declaration
       
  2200 | structure_type_declaration
       
  2201 | string_type_declaration
       
  2202 ;
       
  2203 
       
  2204 single_element_type_declaration:
       
  2205   simple_type_declaration
       
  2206 | subrange_type_declaration
       
  2207 | enumerated_type_declaration
       
  2208 ;
       
  2209 
       
  2210 simple_type_declaration:
       
  2211 /*  simple_type_name ':' simple_spec_init */
       
  2212   identifier ':' simple_spec_init
       
  2213 	{$$ = new simple_type_declaration_c($1, $3);
       
  2214 	 library_element_symtable.insert($1, prev_declared_simple_type_name_token);
       
  2215 	}
       
  2216 ;
       
  2217 
       
  2218 
       
  2219 simple_spec_init:
       
  2220   simple_specification
       
  2221   /* The following line was changed so that we wouldn't
       
  2222    * have the first element of a simple_spec_init_c()
       
  2223    * pointing to another simple_spec_init_c!
       
  2224    */
       
  2225 /*
       
  2226 | simple_specification ASSIGN constant
       
  2227 	{$$ = new simple_spec_init_c($1, $3);}
       
  2228 */
       
  2229 | elementary_type_name ASSIGN constant
       
  2230 	{$$ = new simple_spec_init_c($1, $3);}
       
  2231 | prev_declared_simple_type_name ASSIGN constant
       
  2232 	{$$ = new simple_spec_init_c($1, $3);}
       
  2233 ;
       
  2234 
       
  2235 /* When converting to C/C++, we need to know whether
       
  2236  * the elementary_type_name is being used in a variable
       
  2237  * declaration or elsewhere (ex. declaration of a derived
       
  2238  * type), so the abstract syntax has the elementary_type_name
       
  2239  * wrapped inside a simple_spec_init_c.
       
  2240  * The exact same thing occurs with prev_declared_simple_type_name.
       
  2241  *
       
  2242  * This is why in the definition of simple_spec_init,
       
  2243  * simple_specification was brocken up into its
       
  2244  * constituent components...
       
  2245  */
       
  2246 simple_specification:
       
  2247 // elementary_type_name | simple_type_name
       
  2248   elementary_type_name
       
  2249 	{$$ = new simple_spec_init_c($1, NULL);}
       
  2250 | prev_declared_simple_type_name
       
  2251 	{$$ = new simple_spec_init_c($1, NULL);}
       
  2252 ;
       
  2253 
       
  2254 
       
  2255 subrange_type_declaration:
       
  2256 /*  subrange_type_name ':' subrange_spec_init */
       
  2257   identifier ':' subrange_spec_init
       
  2258 	{$$ = new subrange_type_declaration_c($1, $3);
       
  2259 	 library_element_symtable.insert($1, prev_declared_subrange_type_name_token);
       
  2260 	}
       
  2261 ;
       
  2262 
       
  2263 subrange_spec_init:
       
  2264   subrange_specification
       
  2265 	{$$ = new subrange_spec_init_c($1, NULL);}
       
  2266 | subrange_specification ASSIGN signed_integer
       
  2267 	{$$ = new subrange_spec_init_c($1, $3);}
       
  2268 ;
       
  2269 
       
  2270 subrange_specification:
       
  2271   integer_type_name '(' subrange')'
       
  2272 	{$$ = new subrange_specification_c($1, $3);}
       
  2273 | prev_declared_subrange_type_name	{$$ = $1;}
       
  2274 ;
       
  2275 
       
  2276 
       
  2277 subrange:
       
  2278   signed_integer DOTDOT signed_integer
       
  2279 	{$$ = new subrange_c($1, $3);}
       
  2280 ;
       
  2281 
       
  2282 enumerated_type_declaration:
       
  2283 /*  enumerated_type_name ':' enumerated_spec_init */
       
  2284   identifier ':' enumerated_spec_init
       
  2285 	{$$ = new enumerated_type_declaration_c($1, $3);
       
  2286 	 library_element_symtable.insert($1, prev_declared_enumerated_type_name_token);
       
  2287 	}
       
  2288 ;
       
  2289 
       
  2290 
       
  2291 enumerated_spec_init:
       
  2292   enumerated_specification
       
  2293 	{$$ = new enumerated_spec_init_c($1, NULL);}
       
  2294 | enumerated_specification ASSIGN enumerated_value
       
  2295 	{$$ = new enumerated_spec_init_c($1, $3);}
       
  2296 ;
       
  2297 
       
  2298 enumerated_specification:
       
  2299   '(' enumerated_value_list ')'
       
  2300 	{$$ = $2;}
       
  2301 | prev_declared_enumerated_type_name	{$$ = $1;}
       
  2302 ;
       
  2303 
       
  2304 /* helper symbol for enumerated_specification */
       
  2305 enumerated_value_list:
       
  2306   enumerated_value
       
  2307 	{$$ = new enumerated_value_list_c(); $$->add_element($1);}
       
  2308 | enumerated_value_list ',' enumerated_value
       
  2309 	{$$ = $1; $$->add_element($3);}
       
  2310 ;
       
  2311 
       
  2312 
       
  2313 enumerated_value:
       
  2314   identifier
       
  2315 	{$$ = $1;}
       
  2316 | prev_declared_enumerated_type_name '#' any_identifier
       
  2317 	{$$ = new enumerated_value_c($1, $3);}
       
  2318 ;
       
  2319 
       
  2320 
       
  2321 
       
  2322 array_type_declaration:
       
  2323 /*  array_type_name ':' array_spec_init */
       
  2324   identifier ':' array_spec_init
       
  2325 	{$$ = new array_type_declaration_c($1, $3);
       
  2326 	 library_element_symtable.insert($1, prev_declared_array_type_name_token);
       
  2327 	}
       
  2328 ;
       
  2329 
       
  2330 array_spec_init:
       
  2331   array_specification
       
  2332 	{$$ = new array_spec_init_c($1, NULL);}
       
  2333 | array_specification ASSIGN array_initialization
       
  2334 	{$$ = new array_spec_init_c($1, $3);}
       
  2335 ;
       
  2336 
       
  2337 
       
  2338 array_specification:
       
  2339   prev_declared_array_type_name
       
  2340 	{$$ = $1;}
       
  2341 | ARRAY '[' array_subrange_list ']' OF non_generic_type_name
       
  2342 	{$$ = new array_specification_c($3, $6);}
       
  2343 ;
       
  2344 
       
  2345 /* helper symbol for array_specification */
       
  2346 array_subrange_list:
       
  2347   subrange
       
  2348 	{$$ = new array_subrange_list_c(); $$->add_element($1);}
       
  2349 | array_subrange_list ',' subrange
       
  2350 	{$$ = $1; $$->add_element($1);}
       
  2351 ;
       
  2352 
       
  2353 
       
  2354 array_initialization:
       
  2355   '[' array_initial_elements_list ']'
       
  2356 	{$$ = $2;}
       
  2357 ;
       
  2358 
       
  2359 
       
  2360 /* helper symbol for array_initialization */
       
  2361 array_initial_elements_list:
       
  2362   array_initial_elements
       
  2363 	{$$ = new array_initial_elements_list_c(); $$->add_element($1);}
       
  2364 | array_initial_elements_list ',' array_initial_elements
       
  2365 	{$$ = $1; $$->add_element($3);}
       
  2366 ;
       
  2367 
       
  2368 
       
  2369 array_initial_elements:
       
  2370   array_initial_element
       
  2371 | integer '(' ')'
       
  2372 | integer '(' array_initial_element ')'
       
  2373 	{$$ = new array_initial_elements_c($1, $3);}
       
  2374 ;
       
  2375 
       
  2376 
       
  2377 array_initial_element:
       
  2378   constant
       
  2379 | enumerated_value
       
  2380 | structure_initialization
       
  2381 | array_initialization
       
  2382 ;
       
  2383 
       
  2384 
       
  2385 
       
  2386 structure_type_declaration:
       
  2387 /*  structure_type_name ':' structure_specification */
       
  2388   identifier ':' structure_specification
       
  2389 	{$$ = new structure_type_declaration_c($1, $3);
       
  2390 	 library_element_symtable.insert($1, prev_declared_structure_type_name_token);
       
  2391 	}
       
  2392 ;
       
  2393 
       
  2394 
       
  2395 structure_specification:
       
  2396   structure_declaration
       
  2397 | initialized_structure
       
  2398 ;
       
  2399 
       
  2400 
       
  2401 initialized_structure:
       
  2402   prev_declared_structure_type_name
       
  2403 	{$$ = new initialized_structure_c($1, NULL);}
       
  2404 | prev_declared_structure_type_name ASSIGN structure_initialization
       
  2405 	{$$ = new initialized_structure_c($1, $3);}
       
  2406 ;
       
  2407 
       
  2408 
       
  2409 structure_declaration:
       
  2410   STRUCT structure_element_declaration_list END_STRUCT
       
  2411 	{$$ = $2;}
       
  2412 ;
       
  2413 
       
  2414 /* helper symbol for structure_declaration */
       
  2415 structure_element_declaration_list:
       
  2416   structure_element_declaration ';'
       
  2417 	{$$ = new structure_element_declaration_list_c(); $$->add_element($1);}
       
  2418 | structure_element_declaration_list structure_element_declaration ';'
       
  2419 	{$$ = $1; $$->add_element($2);}
       
  2420 ;
       
  2421 
       
  2422 
       
  2423 structure_element_declaration:
       
  2424   structure_element_name ':' simple_spec_init
       
  2425 	{$$ = new structure_element_declaration_c($1, $3);}
       
  2426 | structure_element_name ':' subrange_spec_init
       
  2427 	{$$ = new structure_element_declaration_c($1, $3);}
       
  2428 | structure_element_name ':' enumerated_spec_init
       
  2429 	{$$ = new structure_element_declaration_c($1, $3);}
       
  2430 | structure_element_name ':' array_spec_init
       
  2431 	{$$ = new structure_element_declaration_c($1, $3);}
       
  2432 | structure_element_name ':' initialized_structure
       
  2433 	{$$ = new structure_element_declaration_c($1, $3);}
       
  2434 ;
       
  2435 
       
  2436 
       
  2437 structure_element_name: any_identifier;
       
  2438 
       
  2439 
       
  2440 structure_initialization:
       
  2441   '(' structure_element_initialization_list ')'
       
  2442 	{$$ = $2;}
       
  2443 ;
       
  2444 
       
  2445 /* helper symbol for structure_initialization */
       
  2446 structure_element_initialization_list:
       
  2447   structure_element_initialization
       
  2448 	{$$ = new structure_element_initialization_list_c(); $$->add_element($1);}
       
  2449 | structure_element_initialization_list ',' structure_element_initialization
       
  2450 	{$$ = $1; $$->add_element($3);}
       
  2451 ;
       
  2452 
       
  2453 
       
  2454 structure_element_initialization:
       
  2455   structure_element_name ASSIGN constant
       
  2456 	{$$ = new structure_element_initialization_c($1, $3);}
       
  2457 | structure_element_name ASSIGN enumerated_value
       
  2458 	{$$ = new structure_element_initialization_c($1, $3);}
       
  2459 | structure_element_name ASSIGN array_initialization
       
  2460 	{$$ = new structure_element_initialization_c($1, $3);}
       
  2461 | structure_element_name ASSIGN structure_initialization
       
  2462 	{$$ = new structure_element_initialization_c($1, $3);}
       
  2463 ;
       
  2464 
       
  2465 /* NOTE: in order to remove a reduce/reduce conflict,
       
  2466  *       all occurences of string_type_name
       
  2467  *       have been replaced with identifier!
       
  2468  */
       
  2469 /*
       
  2470 string_type_name: identifier;
       
  2471 */
       
  2472 
       
  2473 string_type_declaration:
       
  2474 /*  string_type_name ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init */
       
  2475   identifier ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init
       
  2476 	{$$ = new string_type_declaration_c($1, $3, $4, $5);
       
  2477 	 library_element_symtable.insert($1, prev_declared_string_type_name_token);
       
  2478 	}
       
  2479 ;
       
  2480 
       
  2481 
       
  2482 /* helper symbol for string_type_declaration */
       
  2483 string_type_declaration_size:
       
  2484   '[' integer ']'
       
  2485 	{$$ = $2;}
       
  2486 /* REMOVED !! */
       
  2487 //|  /* empty */
       
  2488 //	{$$ = NULL;}
       
  2489 ;
       
  2490 /* The syntax contains a reduce/reduce conflict.
       
  2491  * The optional '[' <size> ']'
       
  2492  * has been changed to become mandatory to remove the conflict.
       
  2493  *
       
  2494  * The conflict arises because
       
  2495  *  new_str_type : STRING := "hello!"
       
  2496  * may be reduced to a string_type_declaration OR
       
  2497  * a simple_type_declaration.
       
  2498  *
       
  2499  * Our change forces it to be reduced to a
       
  2500  * simple_type_declaration!
       
  2501  * We chose this option because changing the definition
       
  2502  * of simple_spec_init would force us to change all the other
       
  2503  * rules in which it appears. The change we made has no
       
  2504  * side-effects!
       
  2505  */
       
  2506 
       
  2507 /* helper symbol for string_type_declaration */
       
  2508 string_type_declaration_init:
       
  2509   /* empty */
       
  2510 	{$$ = NULL;}
       
  2511 | ASSIGN character_string
       
  2512 	{$$ = $2;}
       
  2513 ;
       
  2514 
       
  2515 
       
  2516 
       
  2517 /*********************/
       
  2518 /* B 1.4 - Variables */
       
  2519 /*********************/
       
  2520 variable:
       
  2521   symbolic_variable
       
  2522 | direct_variable
       
  2523 ;
       
  2524 
       
  2525 
       
  2526 symbolic_variable:
       
  2527 /* NOTE: To be entirely correct, variable_name should be replacemed by
       
  2528  *         prev_declared_variable_name | prev_declared_fb_name | prev_declared_global_var_name
       
  2529  */
       
  2530   prev_declared_variable_name
       
  2531 	{$$ = new symbolic_variable_c($1);}
       
  2532 | prev_declared_fb_name
       
  2533 	{$$ = new symbolic_variable_c($1);}
       
  2534 | prev_declared_global_var_name
       
  2535 	{$$ = new symbolic_variable_c($1);}
       
  2536 | multi_element_variable
       
  2537 ;
       
  2538 
       
  2539 
       
  2540 /* NOTE: in section B 1.7, when configuring a program, symbolic_variable
       
  2541  *       is used. Nevertheless, during the parsing of a configuration,
       
  2542  *       the variables in question are out of scope, so we should
       
  2543  *       be allowing any_identifier instead of prev_declared_variable_name!
       
  2544  *
       
  2545  *       We therefore need a new any_symbolic_variable construct that
       
  2546  *       allows the use of any_identifier instead of previously declared
       
  2547  *       variables, function blocks, etc...
       
  2548  */
       
  2549 any_symbolic_variable:
       
  2550 // variable_name -> replaced by any_identifier
       
  2551   any_identifier
       
  2552 	{$$ = new symbolic_variable_c($1);}
       
  2553 | any_multi_element_variable
       
  2554 ;
       
  2555 
       
  2556 
       
  2557 /* for yet undeclared variable names ! */
       
  2558 variable_name: identifier;
       
  2559 
       
  2560 
       
  2561 
       
  2562 
       
  2563 
       
  2564 /********************************************/
       
  2565 /* B.1.4.1   Directly Represented Variables */
       
  2566 /********************************************/
       
  2567 direct_variable: direct_variable_token	{$$ = new direct_variable_c($1);};
       
  2568 
       
  2569 
       
  2570 
       
  2571 
       
  2572 /*************************************/
       
  2573 /* B.1.4.2   Multi-element Variables */
       
  2574 /*************************************/
       
  2575 multi_element_variable:
       
  2576   array_variable
       
  2577 | structured_variable
       
  2578 ;
       
  2579 
       
  2580 /* please see note above any_symbolic_variable */
       
  2581 any_multi_element_variable:
       
  2582   any_array_variable
       
  2583 | any_structured_variable
       
  2584 ;
       
  2585 
       
  2586 
       
  2587 array_variable:
       
  2588   subscripted_variable '[' subscript_list ']'
       
  2589 	{$$ = new array_variable_c($1, $3);}
       
  2590 ;
       
  2591 
       
  2592 /* please see note above any_symbolic_variable */
       
  2593 any_array_variable:
       
  2594   any_subscripted_variable '[' subscript_list ']'
       
  2595 	{$$ = new array_variable_c($1, $3);}
       
  2596 ;
       
  2597 
       
  2598 
       
  2599 subscripted_variable:
       
  2600   symbolic_variable
       
  2601 ;
       
  2602 
       
  2603 
       
  2604 /* please see note above any_symbolic_variable */
       
  2605 any_subscripted_variable:
       
  2606   any_symbolic_variable
       
  2607 ;
       
  2608 
       
  2609 
       
  2610 subscript_list:
       
  2611   subscript
       
  2612 	{$$ = new subscript_list_c(); $$->add_element($1);}
       
  2613 | subscript_list ',' subscript
       
  2614 	{$$ = $1; $$->add_element($3);}
       
  2615 ;
       
  2616 
       
  2617 
       
  2618 subscript:  expression;
       
  2619 
       
  2620 
       
  2621 structured_variable:
       
  2622   record_variable '.' field_selector
       
  2623 	{$$ = new structured_variable_c($1, $3);}
       
  2624 ;
       
  2625 
       
  2626 
       
  2627 /* please see note above any_symbolic_variable */
       
  2628 any_structured_variable:
       
  2629   any_record_variable '.' field_selector
       
  2630 	{$$ = new structured_variable_c($1, $3);}
       
  2631 ;
       
  2632 
       
  2633 
       
  2634 
       
  2635 record_variable:
       
  2636   symbolic_variable
       
  2637 ;
       
  2638 
       
  2639 
       
  2640 /* please see note above any_symbolic_variable */
       
  2641 any_record_variable:
       
  2642   any_symbolic_variable
       
  2643 ;
       
  2644 
       
  2645 
       
  2646 field_selector: any_identifier;
       
  2647 
       
  2648 
       
  2649 
       
  2650 
       
  2651 
       
  2652 
       
  2653 /******************************************/
       
  2654 /* B 1.4.3 - Declaration & Initialisation */
       
  2655 /******************************************/
       
  2656 input_declarations:
       
  2657   VAR_INPUT            input_declaration_list END_VAR
       
  2658 	{$$ = new input_declarations_c(NULL, $2);}
       
  2659 | VAR_INPUT RETAIN     input_declaration_list END_VAR
       
  2660 	{$$ = new input_declarations_c(new retain_option_c(), $3);}
       
  2661 | VAR_INPUT NON_RETAIN input_declaration_list END_VAR
       
  2662 	{$$ = new input_declarations_c(new non_retain_option_c(), $3);}
       
  2663 ;
       
  2664 
       
  2665 /* helper symbol for input_declarations */
       
  2666 input_declaration_list:
       
  2667   input_declaration ';'
       
  2668 	{$$ = new input_declaration_list_c(); $$->add_element($1);}
       
  2669 | input_declaration_list input_declaration ';'
       
  2670 	{$$ = $1; $$->add_element($2);}
       
  2671 ;
       
  2672 
       
  2673 
       
  2674 input_declaration:
       
  2675   var_init_decl
       
  2676 | edge_declaration
       
  2677 ;
       
  2678 
       
  2679 
       
  2680 edge_declaration:
       
  2681   var1_list ':' BOOL R_EDGE
       
  2682 	{$$ = new edge_declaration_c(new raising_edge_option_c(), $1);}
       
  2683 | var1_list ':' BOOL F_EDGE
       
  2684 	{$$ = new edge_declaration_c(new falling_edge_option_c(), $1);}
       
  2685 ;
       
  2686 
       
  2687 
       
  2688 var_init_decl:
       
  2689   var1_init_decl
       
  2690 | array_var_init_decl
       
  2691 | structured_var_init_decl
       
  2692 | fb_name_decl
       
  2693 | string_var_declaration
       
  2694 ;
       
  2695 
       
  2696 
       
  2697 
       
  2698 
       
  2699 var1_init_decl:
       
  2700   var1_list ':' simple_spec_init
       
  2701 	{$$ = new var1_init_decl_c($1, $3);}
       
  2702 | var1_list ':' subrange_spec_init
       
  2703 	{$$ = new var1_init_decl_c($1, $3);}
       
  2704 | var1_list ':' enumerated_spec_init
       
  2705 	{$$ = new var1_init_decl_c($1, $3);}
       
  2706 ;
       
  2707 
       
  2708 
       
  2709 var1_list:
       
  2710   variable_name
       
  2711 	{$$ = new var1_list_c(); $$->add_element($1);
       
  2712 	 variable_name_symtable.insert($1, prev_declared_variable_name_token);
       
  2713 	}
       
  2714  | var1_list ',' variable_name
       
  2715 	{$$ = $1; $$->add_element($3);
       
  2716 	 variable_name_symtable.insert($3, prev_declared_variable_name_token);
       
  2717 	}
       
  2718 ;
       
  2719 
       
  2720 
       
  2721 
       
  2722 array_var_init_decl:
       
  2723  var1_list ':' array_spec_init
       
  2724 	{$$ = new array_var_init_decl_c($1, $3);}
       
  2725 ;
       
  2726 
       
  2727 
       
  2728 structured_var_init_decl:
       
  2729   var1_list ':' initialized_structure
       
  2730 	{$$ = new structured_var_init_decl_c($1, $3);}
       
  2731 ;
       
  2732 
       
  2733 
       
  2734 /* NOTE: see notes above fb_name_list and var1_list
       
  2735  *       for reason why ':' was removed from this rule!
       
  2736  *       In essence, to remove a shift/reduce conflict,
       
  2737  *       the ':' was moved to var1_list and fb_name_list!
       
  2738  */
       
  2739 fb_name_decl:
       
  2740 /*  fb_name_list ':' function_block_type_name */
       
  2741   fb_name_list_with_colon function_block_type_name
       
  2742 	{$$ = new fb_name_decl_c($1, $2, NULL);}
       
  2743 /*| fb_name_list ':' function_block_type_name ASSIGN structure_initialization */
       
  2744 | fb_name_list_with_colon function_block_type_name ASSIGN structure_initialization
       
  2745 	{$$ = new fb_name_decl_c($1, $2, $4);}
       
  2746 ;
       
  2747 
       
  2748 
       
  2749 
       
  2750 /* NOTE: In order to remove a reduce/reduce conflict between
       
  2751  *       var1_list and fb_name_list, which are identical to each
       
  2752  *       other, fb_name_list has been redefined to be a var1_list.
       
  2753  *
       
  2754  *        In order to remove a further shift/reduce conflict, var1_list
       
  2755  *        is imediately transfomred into var1_list_with_colon
       
  2756  *        (i.e. it includes the ':' following the list), which
       
  2757  *        means that fb_name_list is built from a
       
  2758  *        var1_list_with_colon after all!
       
  2759  */
       
  2760 /*
       
  2761 fb_name_list:
       
  2762  (*  fb_name *)
       
  2763   identifier
       
  2764 	{$$ = new fb_name_list_c($1);
       
  2765 	 variable_name_symtable.insert($1, prev_declared_fb_name_token);
       
  2766 	}
       
  2767 (* | fb_name_list ',' fb_name *)
       
  2768 | fb_name_list ',' identifier
       
  2769 	{$$ = $1; $$->add_element($3);
       
  2770 	 variable_name_symtable.insert($3, prev_declared_fb_name_token);
       
  2771 	}
       
  2772 ;
       
  2773 */
       
  2774 
       
  2775 fb_name_list_with_colon:
       
  2776   var1_list_with_colon
       
  2777 	{$$ = new fb_name_list_c();
       
  2778 	 /* fill up the new fb_name_list_c object with the references
       
  2779 	  * contained in the var1_list_c object.
       
  2780 	  */
       
  2781 	 FOR_EACH_ELEMENT(elem, $1, {$$->add_element(elem);});
       
  2782 	 delete $1;
       
  2783 	 /* change the tokens associated with the symbols stored in
       
  2784 	  * the variable name symbol table from prev_declared_variable_name_token
       
  2785 	  * to prev_declared_fb_name_token
       
  2786 	  */
       
  2787 	 FOR_EACH_ELEMENT(elem, $$, {variable_name_symtable.set(elem, prev_declared_fb_name_token);});
       
  2788 	}
       
  2789 ;
       
  2790 
       
  2791 /* helper symbol for fb_name_list_with_colon */
       
  2792 var1_list_with_colon:
       
  2793   var1_list ':'
       
  2794 ;
       
  2795 
       
  2796 
       
  2797 // fb_name: identifier;
       
  2798 
       
  2799 
       
  2800 
       
  2801 output_declarations:
       
  2802   VAR_OUTPUT var_init_decl_list END_VAR
       
  2803 	{$$ = new output_declarations_c(NULL, $2);}
       
  2804 | VAR_OUTPUT RETAIN var_init_decl_list END_VAR
       
  2805 	{$$ = new output_declarations_c(new retain_option_c(), $3);}
       
  2806 | VAR_OUTPUT NON_RETAIN var_init_decl_list END_VAR
       
  2807 	{$$ = new output_declarations_c(new non_retain_option_c(), $3);}
       
  2808 ;
       
  2809 
       
  2810 
       
  2811 
       
  2812 input_output_declarations:
       
  2813   VAR_IN_OUT var_declaration_list END_VAR
       
  2814 	{$$ = new input_output_declarations_c($2);}
       
  2815 ;
       
  2816 
       
  2817 
       
  2818 
       
  2819 /* helper symbol for input_output_declarations */
       
  2820 var_declaration_list:
       
  2821   var_declaration ';'
       
  2822 	{$$ = new var_declaration_list_c(); $$->add_element($1);}
       
  2823 | var_declaration_list var_declaration ';'
       
  2824 	{$$ = $1; $$->add_element($2);}
       
  2825 ;
       
  2826 
       
  2827 
       
  2828 var_declaration:
       
  2829   temp_var_decl
       
  2830 | fb_name_decl
       
  2831 ;
       
  2832 
       
  2833 
       
  2834 temp_var_decl:
       
  2835   var1_declaration
       
  2836 | array_var_declaration
       
  2837 | structured_var_declaration
       
  2838 | string_var_declaration
       
  2839 ;
       
  2840 
       
  2841 var1_declaration:
       
  2842   var1_list  ':' simple_specification
       
  2843 	{$$ = new var1_init_decl_c($1, $3);}
       
  2844 | var1_list  ':' subrange_specification
       
  2845 	{$$ = new var1_init_decl_c($1, $3);}
       
  2846 | var1_list  ':' enumerated_specification
       
  2847 	{$$ = new var1_init_decl_c($1, $3);}
       
  2848 ;
       
  2849 
       
  2850 
       
  2851 
       
  2852 array_var_declaration:
       
  2853   var1_list ':' array_specification
       
  2854 	{$$ = new array_var_declaration_c($1, $3);}
       
  2855 ;
       
  2856 
       
  2857 structured_var_declaration:
       
  2858   var1_list ':' prev_declared_structure_type_name
       
  2859 	{$$ = new structured_var_declaration_c($1, $3);}
       
  2860 ;
       
  2861 
       
  2862 
       
  2863 var_declarations:
       
  2864   VAR var_init_decl_list END_VAR
       
  2865 	{$$ = new var_declarations_c(NULL, $2);}
       
  2866 | VAR CONSTANT var_init_decl_list END_VAR
       
  2867 	{$$ = new var_declarations_c(new constant_option_c(), $3);}
       
  2868 ;
       
  2869 
       
  2870 
       
  2871 retentive_var_declarations:
       
  2872   VAR RETAIN var_init_decl_list END_VAR
       
  2873 	{$$ = new retentive_var_declarations_c($3);}
       
  2874 ;
       
  2875 
       
  2876 
       
  2877 located_var_declarations:
       
  2878   VAR  located_var_decl_list END_VAR
       
  2879 	{$$ = new located_var_declarations_c(NULL, $2);}
       
  2880 | VAR CONSTANT located_var_decl_list END_VAR
       
  2881 	{$$ = new located_var_declarations_c(new constant_option_c(), $3);}
       
  2882 | VAR RETAIN located_var_decl_list END_VAR
       
  2883 	{$$ = new located_var_declarations_c(new retain_option_c(), $3);}
       
  2884 | VAR NON_RETAIN located_var_decl_list END_VAR
       
  2885 	{$$ = new located_var_declarations_c(new non_retain_option_c(), $3);}
       
  2886 ;
       
  2887 
       
  2888 
       
  2889 /* helper symbol for located_var_declarations */
       
  2890 located_var_decl_list:
       
  2891   located_var_decl ';'
       
  2892 	{$$ = new located_var_decl_list_c(); $$->add_element($1);}
       
  2893 | located_var_decl_list located_var_decl ';'
       
  2894 	{$$ = $1; $$->add_element($2);}
       
  2895 ;
       
  2896 
       
  2897 
       
  2898 located_var_decl:
       
  2899   variable_name location ':' located_var_spec_init
       
  2900 	{$$ = new located_var_decl_c($1, $2, $4);
       
  2901 	 variable_name_symtable.insert($1, prev_declared_variable_name_token);
       
  2902 	}
       
  2903 | location ':' located_var_spec_init
       
  2904 	{$$ = new located_var_decl_c(NULL, $1, $3);}
       
  2905 ;
       
  2906 
       
  2907 
       
  2908 
       
  2909 
       
  2910 external_var_declarations:
       
  2911   VAR_EXTERNAL external_declaration_list END_VAR
       
  2912 	{$$ = new external_var_declarations_c(NULL, $2);}
       
  2913 | VAR_EXTERNAL CONSTANT external_declaration_list END_VAR
       
  2914 	{$$ = new external_var_declarations_c(new constant_option_c(), $3);}
       
  2915 ;
       
  2916 
       
  2917 /* helper symbol for external_var_declarations */
       
  2918 external_declaration_list:
       
  2919   external_declaration ';'
       
  2920 	{$$ = new external_declaration_list_c(); $$->add_element($1);}
       
  2921 | external_declaration_list external_declaration';'
       
  2922 	{$$ = $1; $$->add_element($2);}
       
  2923 ;
       
  2924 
       
  2925 
       
  2926 external_declaration:
       
  2927   global_var_name ':' simple_specification
       
  2928 	{$$ = new external_declaration_c($1, $3);
       
  2929 	 variable_name_symtable.insert($1, prev_declared_variable_name_token);
       
  2930 	}
       
  2931 | global_var_name ':' subrange_specification
       
  2932 	{$$ = new external_declaration_c($1, $3);
       
  2933 	 variable_name_symtable.insert($1, prev_declared_variable_name_token);
       
  2934 	}
       
  2935 | global_var_name ':' enumerated_specification
       
  2936 	{$$ = new external_declaration_c($1, $3);
       
  2937 	 variable_name_symtable.insert($1, prev_declared_variable_name_token);
       
  2938 	}
       
  2939 | global_var_name ':' array_specification
       
  2940 	{$$ = new external_declaration_c($1, $3);
       
  2941 	 variable_name_symtable.insert($1, prev_declared_variable_name_token);
       
  2942 	}
       
  2943 | global_var_name ':' prev_declared_structure_type_name
       
  2944 	{$$ = new external_declaration_c($1, $3);
       
  2945 	 variable_name_symtable.insert($1, prev_declared_variable_name_token);
       
  2946 	}
       
  2947 | global_var_name ':' function_block_type_name
       
  2948 	{$$ = new external_declaration_c($1, $3);
       
  2949 	 variable_name_symtable.insert($1, prev_declared_fb_name_token);
       
  2950 	}
       
  2951 ;
       
  2952 
       
  2953 
       
  2954 global_var_name: identifier;
       
  2955 
       
  2956 
       
  2957 global_var_declarations:
       
  2958   VAR_GLOBAL global_var_decl_list END_VAR
       
  2959 	{$$ = new global_var_declarations_c(NULL, $2);}
       
  2960 | VAR_GLOBAL CONSTANT global_var_decl_list END_VAR
       
  2961 	{$$ = new global_var_declarations_c(new constant_option_c(), $3);}
       
  2962 | VAR_GLOBAL RETAIN global_var_decl_list END_VAR
       
  2963 	{$$ = new global_var_declarations_c(new retain_option_c(), $3);}
       
  2964 ;
       
  2965 
       
  2966 
       
  2967 /* helper symbol for global_var_declarations */
       
  2968 global_var_decl_list:
       
  2969   global_var_decl ';'
       
  2970 	{$$ = new global_var_decl_list_c(); $$->add_element($1);}
       
  2971 | global_var_decl_list global_var_decl ';'
       
  2972 	{$$ = $1; $$->add_element($2);}
       
  2973 ;
       
  2974 
       
  2975 
       
  2976 global_var_decl:
       
  2977   global_var_spec ':'
       
  2978 	{$$ = new global_var_decl_c($1, NULL);}
       
  2979 | global_var_spec ':' located_var_spec_init
       
  2980 	{$$ = new global_var_decl_c($1, $3);}
       
  2981 | global_var_spec ':' function_block_type_name
       
  2982 	{$$ = new global_var_decl_c($1, $3);}
       
  2983 ;
       
  2984 
       
  2985 
       
  2986 global_var_spec:
       
  2987   global_var_list	{$$ = $1;}
       
  2988 | location
       
  2989 | global_var_name location
       
  2990 	{$$ = new global_var_spec_c($1, $2);
       
  2991 	 variable_name_symtable.insert($1, prev_declared_global_var_name_token);
       
  2992 	}
       
  2993 
       
  2994 ;
       
  2995 
       
  2996 
       
  2997 located_var_spec_init:
       
  2998   simple_spec_init
       
  2999 | subrange_spec_init
       
  3000 | enumerated_spec_init
       
  3001 | array_spec_init
       
  3002 | initialized_structure
       
  3003 | single_byte_string_spec
       
  3004 | double_byte_string_spec
       
  3005 ;
       
  3006 
       
  3007 
       
  3008 location:
       
  3009   AT direct_variable
       
  3010 	{$$ = new location_c($2);}
       
  3011 ;
       
  3012 
       
  3013 
       
  3014 
       
  3015 global_var_list:
       
  3016   global_var_name
       
  3017 	{$$ = new global_var_list_c(); $$->add_element($1);
       
  3018 	 variable_name_symtable.insert($1, prev_declared_global_var_name_token);
       
  3019 	}
       
  3020 | global_var_list ',' global_var_name
       
  3021 	{$$ = $1; $$->add_element($3);
       
  3022 	 variable_name_symtable.insert($3, prev_declared_global_var_name_token);
       
  3023 	}
       
  3024 ;
       
  3025 
       
  3026 
       
  3027 
       
  3028 string_var_declaration:
       
  3029   single_byte_string_var_declaration
       
  3030 | double_byte_string_var_declaration
       
  3031 ;
       
  3032 
       
  3033 single_byte_string_var_declaration:
       
  3034   var1_list ':' single_byte_string_spec
       
  3035 	{$$ = new single_byte_string_var_declaration_c($1, $3);}
       
  3036 ;
       
  3037 
       
  3038 /* NOTE: The constructs
       
  3039  *
       
  3040  *       [W]STRING
       
  3041  *       and
       
  3042  *       [W]STRING ASSIGN single_byte_character_string
       
  3043  *
       
  3044  *       were removed as they are already contained
       
  3045  *       within a other constructs.
       
  3046  *
       
  3047  *       single_byte_string_spec is used in:
       
  3048  *        - single_byte_string_var_declaration ->
       
  3049  *           -> string_var_declaration ---> var_init_decl
       
  3050  *                                     |--> temp_var_decl
       
  3051  *                                     |--> var2_init_decl
       
  3052  *        - located_var_spec_init
       
  3053  *
       
  3054  *       STRING [ASSIGN string_constant] -> elementary_string_type_name ->
       
  3055  *        -> simple_spec -> simple_specification -> simple_spec_init ->
       
  3056  *        -> located_var_spec_init
       
  3057  *
       
  3058  *       STRING [ASSIGN string_constant] -> elementary_string_type_name ->
       
  3059  *        -> simple_spec -> simple_specification -> simple_spec_init ->
       
  3060  *        -> var1_init_decl -> var_init_decl
       
  3061  *
       
  3062  *       STRING [ASSIGN string_constant] -> elementary_string_type_name ->
       
  3063  *        -> simple_spec -> simple_specification -> simple_spec_init ->
       
  3064  *        -> var1_init_decl -> var2_init_decl
       
  3065  *
       
  3066  *       STRING [ASSIGN string_constant] -> elementary_string_type_name ->
       
  3067  *        -> simple_spec -> simple_specification ->
       
  3068  *        -> var1_declaration -> temp_var_decl
       
  3069  */
       
  3070 single_byte_string_spec:
       
  3071 /*  STRING
       
  3072 	{$$ = new single_byte_string_spec_c(NULL, NULL);}
       
  3073 */
       
  3074   STRING '[' integer ']'
       
  3075 	{$$ = new single_byte_string_spec_c($3, NULL);}
       
  3076 /*
       
  3077 | STRING ASSIGN single_byte_character_string
       
  3078 	{$$ = new single_byte_string_spec_c(NULL, $3);}
       
  3079 */
       
  3080 | STRING '[' integer ']' ASSIGN single_byte_character_string
       
  3081 	{$$ = new single_byte_string_spec_c($3, $6);}
       
  3082 ;
       
  3083 
       
  3084 
       
  3085 double_byte_string_var_declaration:
       
  3086   var1_list ':' double_byte_string_spec
       
  3087 	{$$ = new double_byte_string_var_declaration_c($1, $3);}
       
  3088 ;
       
  3089 
       
  3090 double_byte_string_spec:
       
  3091 /*  WSTRING
       
  3092 	{$$ = new double_byte_string_spec_c(NULL, NULL);}
       
  3093 */
       
  3094   WSTRING '[' integer ']'
       
  3095 	{$$ = new double_byte_string_spec_c($3, NULL);}
       
  3096 /*
       
  3097 | WSTRING ASSIGN double_byte_character_string
       
  3098 	{$$ = new double_byte_string_spec_c(NULL, $3);}
       
  3099 */
       
  3100 | WSTRING '[' integer ']' ASSIGN double_byte_character_string
       
  3101 	{$$ = new double_byte_string_spec_c($3, $6);}
       
  3102 ;
       
  3103 
       
  3104 
       
  3105 
       
  3106 incompl_located_var_declarations:
       
  3107   VAR            incompl_located_var_decl_list END_VAR
       
  3108 	{$$ = new incompl_located_var_declarations_c(NULL, $2);}
       
  3109 | VAR     RETAIN incompl_located_var_decl_list END_VAR
       
  3110 	{$$ = new incompl_located_var_declarations_c(new retain_option_c(), $3);}
       
  3111 | VAR NON_RETAIN incompl_located_var_decl_list END_VAR
       
  3112 	{$$ = new incompl_located_var_declarations_c(new non_retain_option_c(), $3);}
       
  3113 ;
       
  3114 
       
  3115 /* helper symbol for incompl_located_var_declarations */
       
  3116 incompl_located_var_decl_list:
       
  3117   incompl_located_var_decl ';'
       
  3118 	{$$ = new incompl_located_var_decl_list_c(); $$->add_element($1);}
       
  3119 | incompl_located_var_decl_list incompl_located_var_decl ';'
       
  3120 	{$$ = $1; $$->add_element($2);}
       
  3121 ;
       
  3122 
       
  3123 
       
  3124 incompl_located_var_decl:
       
  3125   variable_name incompl_location ':' var_spec
       
  3126 	{$$ = new incompl_located_var_decl_c($1, $2, $4);}
       
  3127 ;
       
  3128 
       
  3129 
       
  3130 incompl_location:
       
  3131   AT incompl_location_token
       
  3132 	{$$ = new incompl_location_c($2);}
       
  3133 ;
       
  3134 
       
  3135 
       
  3136 var_spec:
       
  3137   simple_specification
       
  3138 | subrange_specification
       
  3139 | enumerated_specification
       
  3140 | array_specification
       
  3141 | prev_declared_structure_type_name
       
  3142 | string_spec
       
  3143 ;
       
  3144 
       
  3145 
       
  3146 /* helper symbol for var_spec */
       
  3147 /* NOTE: The constructs
       
  3148  *
       
  3149  *       STRING
       
  3150  *       and
       
  3151  *       WSTRING
       
  3152  *
       
  3153  *       were removed as they are already contained
       
  3154  *       within a simple_specification.
       
  3155  */
       
  3156 string_spec:
       
  3157 /*  STRING
       
  3158 	{$$ = new single_byte_string_spec_c(NULL, NULL);}
       
  3159 */
       
  3160   STRING '[' integer ']'
       
  3161 	{$$ = new single_byte_string_spec_c($3, NULL);}
       
  3162 /*
       
  3163 | WSTRING
       
  3164 	{$$ = new double_byte_string_spec_c(NULL, NULL);}
       
  3165 */
       
  3166 | WSTRING '[' integer ']'
       
  3167 	{$$ = new double_byte_string_spec_c($3, NULL);}
       
  3168 ;
       
  3169 
       
  3170 
       
  3171 
       
  3172 
       
  3173 /* intermediate helper symbol for:
       
  3174  *  - non_retentive_var_decls
       
  3175  *  - output_declarations
       
  3176  *  - var_declarations
       
  3177  */
       
  3178 var_init_decl_list:
       
  3179   var_init_decl ';'
       
  3180 	{$$ = new var_init_decl_list_c(); $$->add_element($1);}
       
  3181 | var_init_decl_list var_init_decl ';'
       
  3182 	{$$ = $1; $$->add_element($2);}
       
  3183 ;
       
  3184 
       
  3185 
       
  3186 
       
  3187 
       
  3188 /***********************/
       
  3189 /* B 1.5.1 - Functions */
       
  3190 /***********************/
       
  3191 /* The following rules should be set such as:
       
  3192  * function_name: function_name_no_clashes | function_name_simpleop_clashes | function_name_expression_clashes
       
  3193  * function_name: function_name_no_NOT_clashes | function_name_NOT_clashes;
       
  3194  */
       
  3195 
       
  3196 function_name_no_clashes: prev_declared_derived_function_name | standard_function_name_no_clashes;
       
  3197 function_name_simpleop_clashes: standard_function_name_simpleop_clashes;
       
  3198 //function_name_expression_clashes: standard_function_name_expression_clashes;
       
  3199 
       
  3200 function_name_no_NOT_clashes: prev_declared_derived_function_name | standard_function_name_no_NOT_clashes;
       
  3201 //function_name_NOT_clashes: standard_function_name_NOT_clashes;
       
  3202 
       
  3203 /*
       
  3204 function_name:
       
  3205   prev_declared_derived_function_name
       
  3206 | standard_function_name
       
  3207 ;
       
  3208 */
       
  3209 
       
  3210 /* NOTE: The list of standard function names
       
  3211  *       includes the standard functions MOD(), NOT()
       
  3212  *
       
  3213  *       Strangely enough, MOD and NOT are reserved keywords,
       
  3214  *       so shouldn't be used for function names.
       
  3215  *
       
  3216  *       The specification contradicts itself!
       
  3217  *       Our workaround  is to treat MOD as a token,
       
  3218  *       but to include this token as a
       
  3219  *       standard_function_name.
       
  3220  *
       
  3221  *       The names of all other standard functions get
       
  3222  *       preloaded into the library_element_symbol_table
       
  3223  *       with the token value of
       
  3224  *       standard_function_name_token
       
  3225  *       Actually, simply for completeness, MOD is also
       
  3226  *       loaded into the library_element_symbol_table, but
       
  3227  *       it is irrelevant since flex will catch MOD as a
       
  3228  *       token, before it interprets it as an identifier,
       
  3229  *       and looks in the library_element_symbol_table to check
       
  3230  *       whether it has been previously declared.
       
  3231  *
       
  3232  * NOTE: The same as the above also occurs with the IL
       
  3233  *       operators NOT AND OR XOR ADD SUB MUL DIV MOD
       
  3234  *       GT GE EQ LT LE NE.
       
  3235  *       Note that MOD is once again in the list!
       
  3236  *       Anyway, we give these the same treatement as
       
  3237  *       MOD, since we are writing a parser for ST and
       
  3238  *       IL simultaneously. If this were not the case,
       
  3239  *       the ST parser would not need the tokens NOT AND ...
       
  3240  *
       
  3241  * NOTE: Note that 'NOT' is special, as it conflicts
       
  3242  *       with two operators: the  IL 'NOT' operator, and
       
  3243  *       the unary operator 'NOT' in ST!!
       
  3244  *
       
  3245  *  NOTE: The IL language is ambiguous, since using NOT, AND, ...
       
  3246  *       may be interpreted as either an IL operator, or
       
  3247  *       as a standard function call!
       
  3248  *       I (Mario) opted to interpret it as an IL operator.
       
  3249  *       This requires changing the syntax for IL language
       
  3250  *       function   calling, to exclude all function with
       
  3251  *       names that clash with IL operators. I therefore
       
  3252  *       created the constructs
       
  3253  *       function_name_without_clashes
       
  3254  *       standard_function_name_without_clashes
       
  3255  *       to include all function names, except those that clash
       
  3256  *       with IL operators. These constructs are only used
       
  3257  *       within the IL language!
       
  3258  */
       
  3259 /* The following rules should be set such as:
       
  3260  * standard_function_name: standard_function_name_no_clashes | standard_function_name_simpleop_clashes | standard_function_name_expression_clashes
       
  3261  * standard_function_name: standard_function_name_no_NOT_clashes | standard_function_name_NOT_clashes;
       
  3262  */
       
  3263 
       
  3264 /*
       
  3265 standard_function_name:
       
  3266   standard_function_name_no_clashes
       
  3267 | standard_function_name_expression_clashes
       
  3268 | standard_function_name_NOT_clashes
       
  3269 //| standard_function_name_simpleop_only_clashes
       
  3270 ;
       
  3271 */
       
  3272 
       
  3273 standard_function_name_no_NOT_clashes:
       
  3274   standard_function_name_no_clashes
       
  3275 | standard_function_name_expression_clashes
       
  3276 //| standard_function_name_simpleop_only_clashes
       
  3277 ;
       
  3278 
       
  3279 standard_function_name_no_clashes:
       
  3280   standard_function_name_token
       
  3281 	{$$ = new identifier_c($1);}
       
  3282 ;
       
  3283 
       
  3284 
       
  3285 standard_function_name_simpleop_clashes:
       
  3286   standard_function_name_NOT_clashes
       
  3287 //| standard_function_name_simpleop_only_clashes
       
  3288 ;
       
  3289 
       
  3290 standard_function_name_NOT_clashes:
       
  3291   NOT
       
  3292 	{$$ = new identifier_c(strdup("NOT"));}
       
  3293 ;
       
  3294 
       
  3295 /* Add here any other IL simple operators that collide
       
  3296  * with standard function names!
       
  3297  * Don't forget to uncomment the equivalent lines in
       
  3298  *   - standard_function_name_simpleop_clashes
       
  3299  *   - standard_function_name
       
  3300  *   - standard_function_name_no_NOT_clashes
       
  3301  */
       
  3302 /*
       
  3303 standard_function_name_simpleop_only_clashes:
       
  3304 ;
       
  3305 */
       
  3306 
       
  3307 standard_function_name_expression_clashes:
       
  3308   AND_operator	{$$ = il_operator_c_2_identifier_c($1);}
       
  3309 //NOTE: AND2 (corresponding to the source code string '&') does not clash
       
  3310 //      with a standard function name, so should be commented out!
       
  3311 //| AND2_operator	{$$ = il_operator_c_2_identifier_c($1);}
       
  3312 | OR_operator	{$$ = il_operator_c_2_identifier_c($1);}
       
  3313 | XOR_operator	{$$ = il_operator_c_2_identifier_c($1);}
       
  3314 | ADD_operator	{$$ = il_operator_c_2_identifier_c($1);}
       
  3315 | SUB_operator	{$$ = il_operator_c_2_identifier_c($1);}
       
  3316 | MUL_operator	{$$ = il_operator_c_2_identifier_c($1);}
       
  3317 | DIV_operator	{$$ = il_operator_c_2_identifier_c($1);}
       
  3318 | MOD_operator	{$$ = il_operator_c_2_identifier_c($1);}
       
  3319 | GT_operator	{$$ = il_operator_c_2_identifier_c($1);}
       
  3320 | GE_operator	{$$ = il_operator_c_2_identifier_c($1);}
       
  3321 | EQ_operator	{$$ = il_operator_c_2_identifier_c($1);}
       
  3322 | LT_operator	{$$ = il_operator_c_2_identifier_c($1);}
       
  3323 | LE_operator	{$$ = il_operator_c_2_identifier_c($1);}
       
  3324 | NE_operator	{$$ = il_operator_c_2_identifier_c($1);}
       
  3325 ;
       
  3326 
       
  3327 
       
  3328 derived_function_name:
       
  3329   identifier
       
  3330 | prev_declared_derived_function_name
       
  3331 	{$$ = $1;
       
  3332 	 if (not(allow_function_overloading))
       
  3333 	   ERROR;
       
  3334 	}
       
  3335 ;
       
  3336 
       
  3337 
       
  3338 function_declaration:
       
  3339 /*  FUNCTION derived_function_name ':' elementary_type_name io_OR_function_var_declarations_list function_body END_FUNCTION */
       
  3340   function_name_declaration ':' elementary_type_name io_OR_function_var_declarations_list function_body END_FUNCTION
       
  3341 	{$$ = new function_declaration_c($1, $3, $4, $5);
       
  3342 	 variable_name_symtable.pop();
       
  3343 	 if (allow_function_overloading) {
       
  3344 	   switch (library_element_symtable.find_value($1)) {
       
  3345 	     case prev_declared_derived_function_name_token:
       
  3346 	       /* do nothing, already in map. */
       
  3347 	       break;
       
  3348 	     case BOGUS_TOKEN_ID:
       
  3349 	       /* Not yet in map. Must insert...*/
       
  3350 	       library_element_symtable.insert($1, prev_declared_derived_function_name_token);
       
  3351 	       break;
       
  3352 	     default:
       
  3353 	       /* Already in map but associated with something else other than a funtion name! */
       
  3354 	       ERROR;
       
  3355 	   }
       
  3356 	 } else {
       
  3357 	   library_element_symtable.insert($1, prev_declared_derived_function_name_token);
       
  3358 	 }
       
  3359 	}
       
  3360 /* | FUNCTION derived_function_name ':' derived_type_name io_OR_function_var_declarations_list function_body END_FUNCTION */
       
  3361 | function_name_declaration ':' derived_type_name io_OR_function_var_declarations_list function_body END_FUNCTION
       
  3362 	{$$ = new function_declaration_c($1, $3, $4, $5);
       
  3363 	 variable_name_symtable.pop();
       
  3364 	 if (allow_function_overloading) {
       
  3365 	   switch (library_element_symtable.find_value($1)) {
       
  3366 	     case prev_declared_derived_function_name_token: /* do nothing, already in map. */ break;
       
  3367 	     case BOGUS_TOKEN_ID: library_element_symtable.insert($1, prev_declared_derived_function_name_token); break;
       
  3368 	     default: ERROR;
       
  3369 	   }
       
  3370 	 } else {
       
  3371 	   library_element_symtable.insert($1, prev_declared_derived_function_name_token);
       
  3372 	 }
       
  3373 	}
       
  3374 ;
       
  3375 
       
  3376 /* helper symbol for function_declaration */
       
  3377 /* NOTE: due to reduce/reduce conflicts between identifiers
       
  3378  *       being reduced to either a variable or an enumerator value,
       
  3379  *       we were forced to keep a symbol table of the names
       
  3380  *       of all declared variables. Variables are no longer
       
  3381  *       created from simple identifier_token, but from
       
  3382  *       prev_declared_variable_name_token.
       
  3383  *
       
  3384  *       BUT, in functions the function name itself may be used as
       
  3385  *       a variable! In order to be able to parse this correctly,
       
  3386  *       the token parser (flex) must return a prev_declared_variable_name_token
       
  3387  *       when it comes across the function name, while parsing
       
  3388  *       the function itself.
       
  3389  *       We do this by inserting the function name into the variable
       
  3390  *       symbol table, and having flex return a prev_declared_variable_name_token
       
  3391  *       whenever it comes across it.
       
  3392  *       When we finish parsing the function the variable name
       
  3393  *       symbol table is cleared of all entries, and the function
       
  3394  *       name is inserted into the library element symbol table. This
       
  3395  *       means that from then onwards flex will return a
       
  3396  *       derived_function_name_token whenever it comes across the
       
  3397  *       function name.
       
  3398  *
       
  3399  *       In order to insert the function name into the variable_name
       
  3400  *       symbol table BEFORE the function body gets parsed, we
       
  3401  *       need the parser to reduce a construct that contains the
       
  3402  *       the function name. That is why we created this extra
       
  3403  *       construct (function_name_declaration), i.e. to force
       
  3404  *       the parser to reduce it, before parsing the function body!
       
  3405  */
       
  3406 function_name_declaration:
       
  3407   FUNCTION derived_function_name
       
  3408 	{$$ = $2;
       
  3409 	 /* the function name functions as a
       
  3410 	  * variable within the function itself!
       
  3411 	  *
       
  3412 	  * Remember that the variable_name_symtable
       
  3413 	  * is cleared once the end of the function
       
  3414 	  * is parsed.
       
  3415 	  */
       
  3416 	 variable_name_symtable.insert($2, prev_declared_variable_name_token);
       
  3417 	}
       
  3418 ;
       
  3419 
       
  3420 
       
  3421 
       
  3422 /* intermediate helper symbol for function_declaration */
       
  3423 io_OR_function_var_declarations_list:
       
  3424   /* empty */
       
  3425 	{$$ = new var_declarations_list_c();}
       
  3426 | io_OR_function_var_declarations_list io_var_declarations
       
  3427 	{$$ = $1; $$->add_element($2);}
       
  3428 | io_OR_function_var_declarations_list function_var_decls
       
  3429 	{$$ = $1; $$->add_element($2);}
       
  3430 ;
       
  3431 
       
  3432 
       
  3433 io_var_declarations:
       
  3434   input_declarations
       
  3435 | output_declarations
       
  3436 | input_output_declarations
       
  3437 ;
       
  3438 
       
  3439 
       
  3440 function_var_decls:
       
  3441   VAR CONSTANT var2_init_decl_list END_VAR
       
  3442 	{$$ = new function_var_decls_c(new constant_option_c(), $3);}
       
  3443 | VAR var2_init_decl_list END_VAR
       
  3444 	{$$ = new function_var_decls_c(NULL, $2);}
       
  3445 ;
       
  3446 
       
  3447 /* intermediate helper symbol for function_var_decls */
       
  3448 var2_init_decl_list:
       
  3449   var2_init_decl ';'
       
  3450 	{$$ = new var2_init_decl_list_c(); $$->add_element($1);}
       
  3451 | var2_init_decl_list var2_init_decl ';'
       
  3452 	{$$ = $1; $$->add_element($2);}
       
  3453 ;
       
  3454 
       
  3455 
       
  3456 function_body:
       
  3457   statement_list	{$$ = $1;} /* if we leave it for the default action we get a type clash! */
       
  3458 | instruction_list	{$$ = $1;} /* if we leave it for the default action we get a type clash! */
       
  3459 /*
       
  3460 | ladder_diagram
       
  3461 | function_block_diagram
       
  3462 */
       
  3463 ;
       
  3464 
       
  3465 
       
  3466 var2_init_decl:
       
  3467   var1_init_decl
       
  3468 | array_var_init_decl
       
  3469 | structured_var_init_decl
       
  3470 | string_var_declaration
       
  3471 ;
       
  3472 
       
  3473 
       
  3474 
       
  3475 /*****************************/
       
  3476 /* B 1.5.2 - Function Blocks */
       
  3477 /*****************************/
       
  3478 function_block_type_name:
       
  3479   prev_declared_derived_function_block_name
       
  3480 | standard_function_block_name
       
  3481 ;
       
  3482 
       
  3483 
       
  3484 standard_function_block_name: standard_function_block_name_token {$$ = new identifier_c($1);};
       
  3485 
       
  3486 derived_function_block_name: identifier;
       
  3487 
       
  3488 
       
  3489 function_block_declaration:
       
  3490   FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations_list function_block_body END_FUNCTION_BLOCK
       
  3491 	{$$ = new function_block_declaration_c($2, $3, $4);
       
  3492 	 library_element_symtable.insert($2, prev_declared_derived_function_block_name_token);
       
  3493 	 /* Clear the variable_name_symtable. Since
       
  3494 	  * we have finished parsing the function block,
       
  3495 	  * the variable names are now out of scope, so
       
  3496 	  * are no longer valid!
       
  3497 	  */
       
  3498 	 variable_name_symtable.pop();
       
  3499 	}
       
  3500 ;
       
  3501 
       
  3502 
       
  3503 
       
  3504 /* intermediate helper symbol for function_declaration */
       
  3505 /*  { io_var_declarations | other_var_declarations }   */
       
  3506 /*
       
  3507  * NOTE: we re-use the var_declarations_list_c
       
  3508  */
       
  3509 io_OR_other_var_declarations_list:
       
  3510   /* empty */
       
  3511 	{$$ = new var_declarations_list_c();}
       
  3512 | io_OR_other_var_declarations_list io_var_declarations
       
  3513 	{$$ = $1; $$->add_element($2);}
       
  3514 | io_OR_other_var_declarations_list other_var_declarations
       
  3515 	{$$ = $1; $$->add_element($2);}
       
  3516 ;
       
  3517 
       
  3518 /* NOTE:
       
  3519  *  The IEC specification gives the following definition:
       
  3520  *  other_var_declarations ::=
       
  3521  *     external_var_declarations
       
  3522  *   | var_declarations
       
  3523  *   | retentive_var_declarations
       
  3524  *   | non_retentive_var_declarations
       
  3525  *   | temp_var_decls
       
  3526  *   | incompl_located_var_declarations
       
  3527  *
       
  3528  *  Nvertheless, the symbol non_retentive_var_declarations
       
  3529  *  is not defined in the spec. This seems to me (Mario)
       
  3530  *  to be a typo, so non_retentive_var_declarations
       
  3531  *  has been replaced with non_retentive_var_decls
       
  3532  *  in the following rule!
       
  3533  */
       
  3534 other_var_declarations:
       
  3535   temp_var_decls
       
  3536 | non_retentive_var_decls
       
  3537 | external_var_declarations
       
  3538 | var_declarations
       
  3539 | retentive_var_declarations
       
  3540 | incompl_located_var_declarations
       
  3541 ;
       
  3542 
       
  3543 
       
  3544 temp_var_decls:
       
  3545   VAR_TEMP temp_var_decls_list END_VAR
       
  3546 	{$$ = new temp_var_decls_c($2);}
       
  3547 ;
       
  3548 
       
  3549 
       
  3550 /* intermediate helper symbol for temp_var_decls */
       
  3551 temp_var_decls_list:
       
  3552   temp_var_decl ';'
       
  3553 	{$$ = new temp_var_decls_list_c(); $$->add_element($1);}
       
  3554 | temp_var_decls_list temp_var_decl ';'
       
  3555 	{$$ = $1; $$->add_element($2);}
       
  3556 ;
       
  3557 
       
  3558 
       
  3559 non_retentive_var_decls:
       
  3560   VAR NON_RETAIN var_init_decl_list END_VAR
       
  3561 	{$$ = new non_retentive_var_decls_c($3);}
       
  3562 ;
       
  3563 
       
  3564 
       
  3565 
       
  3566 function_block_body:
       
  3567   statement_list	{$$ = $1;}
       
  3568 | instruction_list	{$$ = $1;}
       
  3569 /*
       
  3570 | sequential_function_chart
       
  3571 | ladder_diagram
       
  3572 | function_block_diagram
       
  3573 | <other languages>
       
  3574 */
       
  3575 ;
       
  3576 
       
  3577 
       
  3578 
       
  3579 
       
  3580 /**********************/
       
  3581 /* B 1.5.3 - Programs */
       
  3582 /**********************/
       
  3583 program_type_name: identifier;
       
  3584 
       
  3585 
       
  3586 program_declaration:
       
  3587   PROGRAM program_type_name program_var_declarations_list function_block_body END_PROGRAM
       
  3588 	{$$ = new program_declaration_c($2, $3, $4);
       
  3589 	 library_element_symtable.insert($2, prev_declared_program_type_name_token);
       
  3590 	 /* Clear the variable_name_symtable. Since
       
  3591 	  * we have finished parsing the program declaration,
       
  3592 	  * the variable names are now out of scope, so
       
  3593 	  * are no longer valid!
       
  3594 	  */
       
  3595 	 variable_name_symtable.pop();
       
  3596 	}
       
  3597 ;
       
  3598 
       
  3599 
       
  3600 /* helper symbol for program_declaration */
       
  3601 /*
       
  3602  * NOTE: we re-use the var_declarations_list_c
       
  3603  */
       
  3604 program_var_declarations_list:
       
  3605   /* empty */
       
  3606 	{$$ = new var_declarations_list_c();}
       
  3607 | program_var_declarations_list io_var_declarations
       
  3608 	{$$ = $1; $$->add_element($2);}
       
  3609 | program_var_declarations_list other_var_declarations
       
  3610 	{$$ = $1; $$->add_element($2);}
       
  3611 | program_var_declarations_list located_var_declarations
       
  3612 	{$$ = $1; $$->add_element($2);}
       
  3613 /*
       
  3614 | program_var_declarations_list program_access_decls
       
  3615 	{$$ = $1; $$->add_element($2);}
       
  3616 */
       
  3617 ;
       
  3618 
       
  3619 
       
  3620 /* TODO ... */
       
  3621 /*
       
  3622 program_access_decls:
       
  3623   VAR_ACCESS program_access_decl_list END_VAR
       
  3624 ;
       
  3625 */
       
  3626 
       
  3627 /* helper symbol for program_access_decls */
       
  3628 /*
       
  3629 program_access_decl_list:
       
  3630   program_access_decl ';'
       
  3631 | program_access_decl_list program_access_decl ';'
       
  3632 ;
       
  3633 */
       
  3634 
       
  3635 /*
       
  3636 program_access_decl:
       
  3637   access_name ':' symbolic_variable ':' non_generic_type_name
       
  3638 | access_name ':' symbolic_variable ':' non_generic_type_name direction
       
  3639 ;
       
  3640 */
       
  3641 
       
  3642 
       
  3643 
       
  3644 /********************************************/
       
  3645 /* B 1.6 Sequential Function Chart elements */
       
  3646 /********************************************/
       
  3647 /* TODO ... */
       
  3648 
       
  3649 /*
       
  3650 sequential_function_chart:
       
  3651   sfc_network
       
  3652 | sequential_function_chart sfc_network
       
  3653 ;
       
  3654 
       
  3655 sfc_network:
       
  3656   initial_step
       
  3657 | sfc_network step
       
  3658 | sfc_network transition
       
  3659 | sfc_network action
       
  3660 ;
       
  3661 
       
  3662 initial_step:
       
  3663   INITIAL_STEP step_name ':' action_association_list END_STEP
       
  3664 ;
       
  3665 
       
  3666 step:
       
  3667   STEP step_name ':' action_association_list END_STEP
       
  3668 ;
       
  3669 
       
  3670 /* helper symbol for:
       
  3671  *  - initial_step
       
  3672  *  - step
       
  3673  *
       
  3674 action_association_list:
       
  3675   /* empty *
       
  3676 | action_association_list action_association ';'
       
  3677 ;
       
  3678 
       
  3679 step_name: identifier;
       
  3680 
       
  3681 action_association:
       
  3682   action_name '(' action_qualifier indicator_name_list ')'
       
  3683 ;
       
  3684 
       
  3685 /* helper symbol for action_association *
       
  3686 indicator_name_list:
       
  3687   /* empty *
       
  3688 | indicator_name_list ',' indicator_name
       
  3689 ;
       
  3690 
       
  3691 action_name: identifier;
       
  3692 
       
  3693 action_qualifier:
       
  3694   /* empty *
       
  3695 | N
       
  3696 | R
       
  3697 | S
       
  3698 | P
       
  3699 | timed_qualifier ',' action_time
       
  3700 ;
       
  3701 
       
  3702 timed_qualifier:
       
  3703   L
       
  3704 | D
       
  3705 | SD
       
  3706 | DS
       
  3707 | SL
       
  3708 ;
       
  3709 
       
  3710 action_time:
       
  3711   duration
       
  3712 | variable_name
       
  3713 ;
       
  3714 
       
  3715 indicator_name: variable_name;
       
  3716 
       
  3717 transition:
       
  3718   TRANSITION FROM steps TO steps transition_condition END_TRANSITION
       
  3719 | TRANSITION transition_name FROM steps TO steps transition_condition END_TRANSITION
       
  3720 | TRANSITION '(' PRIORITY ASSIGN integer ')' FROM steps TO steps transition_condition END_TRANSITION
       
  3721 | TRANSITION transition_name '(' PRIORITY ASSIGN integer ')' FROM steps TO steps transition_condition END_TRANSITION
       
  3722 ;
       
  3723 
       
  3724 transition_name: identifier;
       
  3725 
       
  3726 steps:
       
  3727   step_name
       
  3728 | '(' step_name_list ')'
       
  3729 ;
       
  3730 
       
  3731 
       
  3732 step_name_list:
       
  3733   step_name ',' step_name
       
  3734 | step_name_list ',' step_name
       
  3735 ;
       
  3736 
       
  3737 
       
  3738 transition_condition:
       
  3739   ':' simple_instruction_list
       
  3740 | ASSIGN expression ';'
       
  3741 | ':' fbd_network
       
  3742 | ':' rung
       
  3743 ;
       
  3744 
       
  3745 action:
       
  3746   ACTION action_name ':' function_block_body END_ACTION
       
  3747 ;
       
  3748 */
       
  3749 
       
  3750 /********************************/
       
  3751 /* B 1.7 Configuration elements */
       
  3752 /********************************/
       
  3753 /* NOTE:
       
  3754  * It is not clear from reading the specification to which namespace
       
  3755  * the names of resources, tasks and programs belong to.
       
  3756  *
       
  3757  * The following syntax assumes that resource and program names belong to the
       
  3758  * same namespace as the variables defined within
       
  3759  * the resource/configuration (i.e. VAR_GLOBAL).
       
  3760  * Task names belong to a namespace all of their own, since they don't
       
  3761  * produce conflicts in the syntax parser, so we might just as well
       
  3762  * leave them be! ;-)
       
  3763  * The above decision was made taking into
       
  3764  * account that inside a VAR_CONFIG declaration global variables
       
  3765  * may be referenced starting off from the resource name as:
       
  3766  *   resource_name.program_name.variable_name
       
  3767  * Notice how resource names and program names are used in a very similar
       
  3768  * manner as are variable names.
       
  3769  * Using a single namespace for all the above mentioned names
       
  3770  * also makes it easier to write the syntax parser!! ;-) Using a private
       
  3771  * namespace for each of the name types (resource names, program names,
       
  3772  * global varaiable names), i.e. letting the names be re-used across
       
  3773  * each of the groups (resource, program, global variables), produces
       
  3774  * reduce/reduce conflicts in the syntax parser. Actually, it is only
       
  3775  * the resource names that need to be distinguished into a 
       
  3776  * prev_delcared_resource_name so as not to conflict with [gloabl] variable
       
  3777  * names in the 'data' construct.
       
  3778  * The program names are only tracked to make sure that two programs do not
       
  3779  * get the same name.
       
  3780  *
       
  3781  * Using a single namespace does have the drawback that the user will
       
  3782  * not be able to re-use names for resources or programs if these
       
  3783  * have already been used to name a variable!
       
  3784  *
       
  3785  * If it ever becomes necessary to change this interpretation of
       
  3786  * the syntax, then this section of the syntax parser must be updated!
       
  3787  */
       
  3788 prev_declared_global_var_name: prev_declared_global_var_name_token {$$ = new identifier_c($1);};
       
  3789 prev_declared_resource_name: prev_declared_resource_name_token {$$ = new identifier_c($1);};
       
  3790 prev_declared_program_name: prev_declared_program_name_token {$$ = new identifier_c($1);};
       
  3791 // prev_declared_task_name: prev_declared_task_name_token {$$ = new identifier_c($1);};
       
  3792 
       
  3793 
       
  3794 
       
  3795 
       
  3796 
       
  3797 
       
  3798 configuration_name: identifier;
       
  3799 
       
  3800 /* NOTE: The specification states that valid resource type names
       
  3801  *       are implementation defined, i.e. each implementaion will define
       
  3802  *       what resource types it supports.
       
  3803  *       We are implementing this syntax parser to be used by any
       
  3804  *       implementation, so at the moment we accept any identifier
       
  3805  *       as a resource type name.
       
  3806  *       This implementation should probably be changed in the future. We
       
  3807  *       should probably have a resource_type_name_token, and let the
       
  3808  *       implementation load the global symbol library with the
       
  3809  *       accepted resource type names before parsing the code.
       
  3810  *
       
  3811  */
       
  3812 resource_type_name: any_identifier;
       
  3813 
       
  3814 configuration_declaration:
       
  3815   CONFIGURATION configuration_name
       
  3816    optional_global_var_declarations
       
  3817    single_resource_declaration
       
  3818    {variable_name_symtable.pop();}
       
  3819    optional_access_declarations
       
  3820    optional_instance_specific_initializations
       
  3821   END_CONFIGURATION
       
  3822 	{$$ = new configuration_declaration_c($2, $3, $4, $6, $7);
       
  3823 	 library_element_symtable.insert($2, prev_declared_configuration_name_token);
       
  3824 	 variable_name_symtable.pop();
       
  3825 	}
       
  3826 | CONFIGURATION configuration_name
       
  3827    optional_global_var_declarations
       
  3828    resource_declaration_list
       
  3829    optional_access_declarations
       
  3830    optional_instance_specific_initializations
       
  3831  END_CONFIGURATION
       
  3832 	{$$ = new configuration_declaration_c($2, $3, $4, $5, $6);
       
  3833 	 library_element_symtable.insert($2, prev_declared_configuration_name_token);
       
  3834 	 variable_name_symtable.pop();
       
  3835 	}
       
  3836 | CONFIGURATION error END_CONFIGURATION
       
  3837 	{$$ = NULL;
       
  3838 	 print_err_msg(current_filename, @2.last_line, "error in configuration declaration.");
       
  3839 	 /* yychar */
       
  3840 	 yyerrok;
       
  3841 	}
       
  3842 ;
       
  3843 
       
  3844 // helper symbol for
       
  3845 //  - configuration_declaration
       
  3846 //  - resource_declaration
       
  3847 //
       
  3848 optional_global_var_declarations:
       
  3849   // empty
       
  3850 	{$$ = NULL;}
       
  3851 | global_var_declarations
       
  3852 ;
       
  3853 
       
  3854 
       
  3855 // helper symbol for configuration_declaration //
       
  3856 optional_access_declarations:
       
  3857   // empty
       
  3858 	{$$ = NULL;}
       
  3859 //| access_declarations
       
  3860 ;
       
  3861 
       
  3862 // helper symbol for configuration_declaration //
       
  3863 optional_instance_specific_initializations:
       
  3864   // empty
       
  3865 	{$$ = NULL;}
       
  3866 | instance_specific_initializations
       
  3867 ;
       
  3868 
       
  3869 // helper symbol for configuration_declaration //
       
  3870 resource_declaration_list:
       
  3871   resource_declaration
       
  3872 	{$$ = new resource_declaration_list_c(); $$->add_element($1);}
       
  3873 | resource_declaration_list resource_declaration
       
  3874 	{$$ = $1; $$->add_element($2);}
       
  3875 ;
       
  3876 
       
  3877 
       
  3878 resource_declaration:
       
  3879   RESOURCE {variable_name_symtable.push();} resource_name ON resource_type_name
       
  3880    optional_global_var_declarations
       
  3881    single_resource_declaration
       
  3882   END_RESOURCE
       
  3883 	{$$ = new resource_declaration_c($3, $5, $6, $7);
       
  3884          variable_name_symtable.pop();
       
  3885 	 variable_name_symtable.insert($3, prev_declared_resource_name_token);
       
  3886 	}
       
  3887 ;
       
  3888 
       
  3889 
       
  3890 single_resource_declaration:
       
  3891  task_configuration_list program_configuration_list
       
  3892 	{$$ = new single_resource_declaration_c($1, $2);}
       
  3893 ;
       
  3894 
       
  3895 
       
  3896 // helper symbol for single_resource_declaration //
       
  3897 task_configuration_list:
       
  3898   // empty
       
  3899 	{$$ = new task_configuration_list_c();}
       
  3900 | task_configuration_list task_configuration ';'
       
  3901 	{$$ = $1; $$->add_element($2);}
       
  3902 ;
       
  3903 
       
  3904 
       
  3905 // helper symbol for single_resource_declaration //
       
  3906 program_configuration_list:
       
  3907   program_configuration ';'
       
  3908 	{$$ = new program_configuration_list_c(); $$->add_element($1);}
       
  3909 | program_configuration_list program_configuration ';'
       
  3910 	{$$ = $1; $$->add_element($2);}
       
  3911 ;
       
  3912 
       
  3913 
       
  3914 resource_name: identifier;
       
  3915 
       
  3916 /*
       
  3917 access_declarations:
       
  3918  VAR_ACCESS access_declaration_list END_VAR
       
  3919 	{$$ = NULL;}
       
  3920 ;
       
  3921 
       
  3922 // helper symbol for access_declarations //
       
  3923 access_declaration_list:
       
  3924   access_declaration ';'
       
  3925 | access_declaration_list access_declaration ';'
       
  3926 ;
       
  3927 
       
  3928 
       
  3929 access_declaration:
       
  3930   access_name ':' access_path ':' non_generic_type_name
       
  3931 | access_name ':' access_path ':' non_generic_type_name direction
       
  3932 ;
       
  3933 
       
  3934 
       
  3935 access_path:
       
  3936   direct_variable
       
  3937 | prev_delcared_resource_name '.' direct_variable
       
  3938 | any_fb_name_list symbolic_variable
       
  3939 | prev_delcared_resource_name '.' any_fb_name_list symbolic_variable
       
  3940 | prev_delcared_program_name '.'  any_fb_name_list symbolic_variable
       
  3941 | prev_delcared_resource_name '.' prev_delcared_program_name '.' any_fb_name_list symbolic_variable
       
  3942 ;
       
  3943 */
       
  3944 
       
  3945 // helper symbol for
       
  3946 //  - access_path
       
  3947 //  - instance_specific_init
       
  3948 //
       
  3949 /* NOTE: The fb_name_list refers to funtion block variables
       
  3950  *       that have been declared in a scope outside the one we are
       
  3951  *       currently parsing, so we must accept them to be any_identifier!
       
  3952  *
       
  3953  *       Beware that other locations of this syntax parser also require
       
  3954  *       a fb_name_list. In those locations the function blocks are being declared,
       
  3955  *       so only currently un-used identifiers (i.e. identifier) may be accepted.
       
  3956  *
       
  3957  *       In order to distinguish the two, here we use any_fb_name_list, while
       
  3958  *       in the the locations we simply use fb_name_list!
       
  3959  */
       
  3960 any_fb_name_list:
       
  3961   // empty
       
  3962 	{$$ = new any_fb_name_list_c();}
       
  3963 //| fb_name_list fb_name '.'
       
  3964 | any_fb_name_list any_identifier '.'
       
  3965 	{$$ = $1; $$->add_element($2);}
       
  3966 ;
       
  3967 
       
  3968 
       
  3969 
       
  3970 global_var_reference:
       
  3971 //  [resource_name '.'] global_var_name ['.' structure_element_name] //
       
  3972                                   prev_declared_global_var_name
       
  3973 	{$$ = new global_var_reference_c(NULL, $1, NULL);}
       
  3974 |                                 prev_declared_global_var_name '.' structure_element_name
       
  3975 	{$$ = new global_var_reference_c(NULL, $1, $3);}
       
  3976 | prev_declared_resource_name '.' prev_declared_global_var_name
       
  3977 	{$$ = new global_var_reference_c($1, $3, NULL);}
       
  3978 | prev_declared_resource_name '.' prev_declared_global_var_name '.' structure_element_name
       
  3979 	{$$ = new global_var_reference_c($1, $3, $5);}
       
  3980 ;
       
  3981 
       
  3982 
       
  3983 //access_name: identifier;
       
  3984 
       
  3985 
       
  3986 program_output_reference:
       
  3987 /* NOTE:
       
  3988  * program_output_reference is merely used within data_source.
       
  3989  * data_source is merely used within task_initialization
       
  3990  * task_initialization appears in a configuration declaration
       
  3991  * _before_ the programs are declared, so we cannot use
       
  3992  * prev_declared_program_name, as what might seem correct at first.
       
  3993  *
       
  3994  * The semantic checker must later check whether the identifier
       
  3995  * used really refers to a program declared after the task
       
  3996  * initialization!
       
  3997  */
       
  3998 //  prev_declared_program_name '.' symbolic_variable
       
  3999   program_name '.' symbolic_variable
       
  4000 	{$$ = new program_output_reference_c($1, $3);}
       
  4001 ;
       
  4002 
       
  4003 program_name: identifier;
       
  4004 
       
  4005 /*
       
  4006 direction:
       
  4007   READ_WRITE
       
  4008 	{$$ = NULL;}
       
  4009 | READ_ONLY
       
  4010 	{$$ = NULL;}
       
  4011 ;
       
  4012 */
       
  4013 
       
  4014 task_configuration:
       
  4015   TASK task_name task_initialization
       
  4016 	{$$ = new task_configuration_c($2, $3);}
       
  4017 ;
       
  4018 
       
  4019 /* NOTE: The specification does nopt mention the namespace to which task names
       
  4020  *       should belong to. Unlike resource and program names, for the moment we
       
  4021  *       let the task names belong to their own private namespace, as they do not
       
  4022  *       produce any conflicts in the syntax parser.
       
  4023  *       If in the future our interpretation of the spec. turns out to be incorrect,
       
  4024  *       the definition of task_name may have to be changed!
       
  4025  */
       
  4026 task_name: any_identifier;
       
  4027 
       
  4028 task_initialization:
       
  4029 //  '(' [SINGLE ASSIGN data_source ','] [INTERVAL ASSIGN data_source ','] PRIORITY ASSIGN integer ')' //
       
  4030   '(' PRIORITY ASSIGN integer ')'
       
  4031 	{$$ = new task_initialization_c(NULL, NULL, $4);}
       
  4032 | '(' SINGLE ASSIGN data_source ','   PRIORITY ASSIGN integer ')'
       
  4033 	{$$ = new task_initialization_c($4, NULL, $8);}
       
  4034 | '(' INTERVAL ASSIGN data_source ',' PRIORITY ASSIGN integer ')'
       
  4035 	{$$ = new task_initialization_c(NULL, $4, $8);}
       
  4036 | '(' SINGLE ASSIGN data_source ',' INTERVAL ASSIGN data_source ',' PRIORITY ASSIGN integer ')'
       
  4037 	{$$ = new task_initialization_c($4, $8, $12);}
       
  4038 ;
       
  4039 
       
  4040 data_source:
       
  4041   constant
       
  4042 | global_var_reference
       
  4043 | program_output_reference
       
  4044 | direct_variable
       
  4045 ;
       
  4046 
       
  4047 program_configuration:
       
  4048 //  PROGRAM [RETAIN | NON_RETAIN] program_name [WITH task_name] ':' program_type_name ['(' prog_conf_elements ')'] //
       
  4049   PROGRAM program_name optional_task_name ':' prev_declared_program_type_name optional_prog_conf_elements
       
  4050 	{$$ = new program_configuration_c(NULL, $2, $3, $5, $6);
       
  4051 	 variable_name_symtable.insert($2, prev_declared_program_name_token);
       
  4052 	}
       
  4053 | PROGRAM RETAIN program_name optional_task_name ':' prev_declared_program_type_name optional_prog_conf_elements
       
  4054 	{$$ = new program_configuration_c(new retain_option_c(), $3, $4, $6, $7);
       
  4055 	 variable_name_symtable.insert($3, prev_declared_program_name_token);
       
  4056 	}
       
  4057 | PROGRAM NON_RETAIN program_name optional_task_name ':' prev_declared_program_type_name optional_prog_conf_elements
       
  4058 	{$$ = new program_configuration_c(new non_retain_option_c(), $3, $4, $6, $7);
       
  4059 	 variable_name_symtable.insert($3, prev_declared_program_name_token);
       
  4060 	}
       
  4061 ;
       
  4062 
       
  4063 // helper symbol for program_configuration //
       
  4064 optional_task_name:
       
  4065   // empty //
       
  4066 	{$$ = NULL;}
       
  4067 | WITH task_name
       
  4068 	{$$ = $2;}
       
  4069 ;
       
  4070 
       
  4071 // helper symbol for program_configuration //
       
  4072 optional_prog_conf_elements:
       
  4073   // empty //
       
  4074 	{$$ = NULL;}
       
  4075 | '(' prog_conf_elements ')'
       
  4076 	{$$ = $2;}
       
  4077 ;
       
  4078 
       
  4079 
       
  4080 prog_conf_elements:
       
  4081   prog_conf_element
       
  4082 	{$$ = new prog_conf_elements_c(); $$->add_element($1);}
       
  4083 | prog_conf_elements ',' prog_conf_element
       
  4084 	{$$ = $1; $$->add_element($3);}
       
  4085 ;
       
  4086 
       
  4087 
       
  4088 prog_conf_element:
       
  4089   fb_task
       
  4090 | prog_cnxn
       
  4091 ;
       
  4092 
       
  4093 
       
  4094 fb_task:
       
  4095   // fb_name WITH task_name
       
  4096 /* NOTE: The fb_name refers to funtion block variables
       
  4097  *       that have been declared in a scope outside the one we are
       
  4098  *       currently parsing, so we must accept them to be any_identifier!
       
  4099  */
       
  4100   any_identifier WITH task_name
       
  4101 	{$$ = new fb_task_c($1, $3);}
       
  4102 ;
       
  4103 
       
  4104 
       
  4105 /* NOTE:
       
  4106  *  The semantics of configuring a program are rather confusing, so here is
       
  4107  *  my (Mario) understanding on the issue...
       
  4108  *
       
  4109  *  A function/program may have as its input variables a simple variable
       
  4110  *  (BYTE, WORD, etc...), an array (ARRAY [1 .. 3] OF BYTE, ...) , or a structure.
       
  4111  *  Nevertheless, when calling this function from within a st or il language statement
       
  4112  *  it is not possible to allocate a value to a single element of the array or structure
       
  4113  *  typed input variable, as the accepted syntax is simply '(' variable_name ':=' variable ')'
       
  4114  *  Notice how the variable_name does not include things such as 'a.elem1' or 'a[1]'!
       
  4115  *
       
  4116  *  Nevertheless, when configuring a program from within a configuration,
       
  4117  *  it becomes possible to allocate values to individual elements of the
       
  4118  *  array or structured type input variable, as the syntax is now
       
  4119  *  '(' symbolic_variable ':=' data_sink|prog_data_source ')'
       
  4120  *  Notice how the symbolic_variable _does_ include things such as 'a.elem1' or 'a[1]'!
       
  4121  *
       
  4122  *  Conclusion: Unlike other locations in the syntax where SENDTO appears,
       
  4123  *  here it is not valid to replace symbolic_variable with any_identifier!
       
  4124  *  Nevertheless, it is also not correct to leave symbolic_variable as it is,
       
  4125  *  as we have defined it to only include previously declared variables,
       
  4126  *  which is not the case in this situation. Here symbolic_variable is refering
       
  4127  *  to variables that were defined within the scope of the program that is being
       
  4128  *  called, and _not_ within the scope of the configuration that is calling the
       
  4129  *  program, so the variables in question are not declared in the current scope!
       
  4130  *
       
  4131  *  We therefore need to define a new symbolic_variable, that accepts any_identifier
       
  4132  *  instead of previosuly declared variable names, to be used in the definition of
       
  4133  *  prog_cnxn!
       
  4134  */
       
  4135 prog_cnxn:
       
  4136   any_symbolic_variable ASSIGN prog_data_source
       
  4137 	{$$ = new prog_cnxn_assign_c($1, $3);}
       
  4138 | any_symbolic_variable SENDTO data_sink
       
  4139 	{$$ = new prog_cnxn_sendto_c($1, $3);}
       
  4140 ;
       
  4141 
       
  4142 prog_data_source:
       
  4143   constant
       
  4144 | enumerated_value
       
  4145 | global_var_reference
       
  4146 | direct_variable
       
  4147 ;
       
  4148 
       
  4149 data_sink:
       
  4150   global_var_reference
       
  4151 | direct_variable
       
  4152 ;
       
  4153 
       
  4154 instance_specific_initializations:
       
  4155  VAR_CONFIG instance_specific_init_list END_VAR
       
  4156 	{$$ = new instance_specific_initializations_c($2);}
       
  4157 ;
       
  4158 
       
  4159 // helper symbol for instance_specific_initializations //
       
  4160 instance_specific_init_list:
       
  4161   instance_specific_init ';'
       
  4162 	{$$ = new instance_specific_init_list_c(); $$->add_element($1);}
       
  4163 | instance_specific_init_list instance_specific_init ';'
       
  4164 	{$$ = $1; $$->add_element($2);}
       
  4165 ;
       
  4166 
       
  4167 
       
  4168 instance_specific_init:
       
  4169 //
       
  4170 //  resource_name '.' program_name '.' {fb_name '.'}
       
  4171 //  ((variable_name [location] ':' located_var_spec_init) | (fb_name ':' function_block_type_name ':=' structure_initialization))
       
  4172 //
       
  4173 //  prev_declared_resource_name '.' prev_declared_program_name '.' any_fb_name_list variable_name ':' located_var_spec_init
       
  4174 /* NOTE: variable_name has been changed to any_identifier (and not simply identifier) because the
       
  4175  *       variables being referenced have been declared outside the scope currently being parsed!
       
  4176  */
       
  4177 /* NOTE: program_name has not been changed to prev_declared_program_name because the
       
  4178  *       programs being referenced have been declared outside the scope currently being parsed!
       
  4179  *       The programs are only kept inside the scope of the resource in which they are defined.
       
  4180  */
       
  4181   prev_declared_resource_name '.' program_name '.' any_fb_name_list any_identifier ':' located_var_spec_init
       
  4182 	{$$ = new instance_specific_init_c($1, $3, $5, $6, NULL, $8);}
       
  4183 | prev_declared_resource_name '.' program_name '.' any_fb_name_list any_identifier location ':' located_var_spec_init
       
  4184 	{$$ = new instance_specific_init_c($1, $3, $5, $6, $7, $9);}
       
  4185 | prev_declared_resource_name '.' program_name '.' any_fb_name_list any_identifier ':' fb_initialization
       
  4186 	{$5->add_element($6); $$ = new instance_specific_init_c($1, $3, $5, NULL, NULL, $8);}
       
  4187 ;
       
  4188 
       
  4189 
       
  4190 /* helper symbol for instance_specific_init */
       
  4191 fb_initialization:
       
  4192   function_block_type_name ASSIGN structure_initialization
       
  4193 	{$$ = new fb_initialization_c($1, $3);}
       
  4194 ;
       
  4195 
       
  4196 /***********************************/
       
  4197 /* B 2.1 Instructions and Operands */
       
  4198 /***********************************/
       
  4199 /* helper symbol for many IL instructions, etc... */
       
  4200 /* eat up any extra EOL tokens... */
       
  4201 
       
  4202 eol_list:
       
  4203   EOL
       
  4204 | eol_list EOL
       
  4205 ;
       
  4206 
       
  4207 /*
       
  4208 eol_list:
       
  4209   '\n'
       
  4210 | eol_list '\n'
       
  4211 ;
       
  4212 */
       
  4213 
       
  4214 instruction_list:
       
  4215   il_instruction
       
  4216 	{$$ = new instruction_list_c(); $$->add_element($1);}
       
  4217 | instruction_list il_instruction
       
  4218 	{$$ = $1; $$->add_element($2);}
       
  4219 | instruction_list pragma
       
  4220 	{$$ = $1; $$->add_element($2);}
       
  4221 | instruction_list error
       
  4222 	{$$ = $1;
       
  4223 	 print_err_msg(current_filename, @2.last_line, "error in IL instruction.");
       
  4224 	 /* yychar */
       
  4225 	 yyerrok;
       
  4226 	}
       
  4227 ;
       
  4228 
       
  4229 
       
  4230 
       
  4231 il_instruction:
       
  4232   il_incomplete_instruction eol_list
       
  4233 	{$$ = new il_instruction_c(NULL, $1);}
       
  4234 | label ':' il_incomplete_instruction eol_list
       
  4235 	{$$ = new il_instruction_c($1, $3);}
       
  4236 ;
       
  4237 
       
  4238 
       
  4239 /* helper symbol for il_instruction */
       
  4240 il_incomplete_instruction:
       
  4241   il_simple_operation
       
  4242 | il_expression
       
  4243 | il_jump_operation
       
  4244 | il_fb_call
       
  4245 | il_formal_funct_call
       
  4246 | il_return_operator
       
  4247 ;
       
  4248 
       
  4249 
       
  4250 label: identifier;
       
  4251 
       
  4252 
       
  4253 
       
  4254 il_simple_operation:
       
  4255   il_simple_operator
       
  4256 	{$$ = new il_simple_operation_c($1, NULL);}
       
  4257 | il_simple_operator_noclash il_operand
       
  4258 	{$$ = new il_simple_operation_c($1, $2);}
       
  4259 | il_simple_operator_clash_il_operand
       
  4260 	{$$ = new il_simple_operation_c($1.first, $1.second);}
       
  4261 /* NOTE: the line
       
  4262  *         | il_simple_operator
       
  4263  *       already contains the 'NOT' operator, as well as all the
       
  4264  *       expression operators ('MOD', 'AND', etc...), all of which
       
  4265  *       may also be a function name! This means that these operators/functions,
       
  4266  *       without any operands, could be reduced to either an operator or a
       
  4267  *       function call. I (Mario) have chosen to reduce it to an operator.
       
  4268  *
       
  4269  *       The line
       
  4270  *         | function_name
       
  4271  *       has been replaced with the lines
       
  4272  *         | function_name_no_clashes
       
  4273  *       in order to include all possible function names except
       
  4274  *       those whose names coincide with operators !!
       
  4275  */
       
  4276 | function_name_no_clashes
       
  4277 	{$$ = new il_function_call_c($1, NULL);}
       
  4278 /* NOTE: the line
       
  4279  *         | il_simple_operator il_operand
       
  4280  *       already contains the 'NOT', 'MOD', etc. operators, followed by a single il_operand,
       
  4281  *       which may also be reduced to a function name with an operand_list of a single
       
  4282  *       il_operand! This would lead us to a reduce/reduce conflict!
       
  4283  *
       
  4284  *       I (Mario) have chosen to reduce it to an operand, rather than a function call.
       
  4285  *
       
  4286  *       The line
       
  4287  *         | function_name il_operand_list
       
  4288  *       has been replaced with the line
       
  4289  *         | function_name_no_clashes il_operand_list
       
  4290  *       in order to include all possible function names except
       
  4291  *       for the function names which clash with expression and simple operators.
       
  4292  *
       
  4293  *       Note that:
       
  4294  *       this alternative syntax does not cover the possibility of
       
  4295  *       the function 'NOT', 'MOD', etc... being called with more than one il_operand!
       
  4296  *       We therefore need to include an extra rule where the
       
  4297  *       function_name_expression_clashes and function_name_simpleop_clashes
       
  4298  *       are followed by a il_operand_list with __two__ or more il_operands!!
       
  4299  */
       
  4300 | function_name_no_clashes il_operand_list
       
  4301 	{$$ = new il_function_call_c($1, $2);}
       
  4302 | il_simple_operator_clash_il_operand ',' il_operand_list
       
  4303 	{list_c *list = new il_operand_list_c();
       
  4304 	 list->add_element($1.second);
       
  4305 	 FOR_EACH_ELEMENT(elem, $3, {list->add_element(elem);})
       
  4306 	 $$ = new il_function_call_c(il_operator_c_2_identifier_c($1.first), list);
       
  4307 	}
       
  4308 ;
       
  4309 
       
  4310 
       
  4311 
       
  4312 il_simple_operator_clash_il_operand:
       
  4313   il_simple_operator_clash il_operand
       
  4314 	{$$.first = $1; $$.second = $2;}
       
  4315 ;
       
  4316 
       
  4317 
       
  4318 
       
  4319 il_expression:
       
  4320   il_expr_operator_noclash '(' eol_list ')'
       
  4321 	{$$ = new il_expression_c($1, NULL, NULL);}
       
  4322 | il_expr_operator_noclash '(' il_operand eol_list ')'
       
  4323 	{$$ = new il_expression_c($1, $3, NULL);}
       
  4324 | il_expr_operator_noclash '(' eol_list simple_instr_list ')'
       
  4325 	{$$ = new il_expression_c($1, NULL, $4);}
       
  4326 | il_expr_operator_noclash '(' il_operand eol_list simple_instr_list ')'
       
  4327 	{$$ = new il_expression_c($1, $3, $5);}
       
  4328 /*
       
  4329 */
       
  4330 | il_expr_operator_clash '(' eol_list ')'
       
  4331 	{$$ = new il_expression_c($1, NULL, NULL);}
       
  4332 | il_expr_operator_clash '(' il_operand eol_list ')'
       
  4333 	{$$ = new il_expression_c($1, $3, NULL);}
       
  4334 | il_expr_operator_clash '(' il_operand eol_list simple_instr_list ')'
       
  4335 	{$$ = new il_expression_c($1, $3, $5);}
       
  4336 /*
       
  4337 */
       
  4338 | il_expr_operator_clash_eol_list simple_instr_list ')'
       
  4339 	{$$ = new il_expression_c($1, NULL, $2);}
       
  4340 ;
       
  4341 
       
  4342 
       
  4343 il_jump_operation:
       
  4344   il_jump_operator label
       
  4345 	{$$ = new il_jump_operation_c($1, $2);}
       
  4346 ;
       
  4347 
       
  4348 
       
  4349 il_fb_call:
       
  4350   il_call_operator prev_declared_fb_name
       
  4351 	{$$ = new il_fb_call_c($1, $2, NULL, NULL);}
       
  4352 | il_call_operator prev_declared_fb_name '(' ')'
       
  4353 	{$$ = new il_fb_call_c($1, $2, NULL, NULL);}
       
  4354 | il_call_operator prev_declared_fb_name '(' eol_list ')'
       
  4355 	{$$ = new il_fb_call_c($1, $2, NULL, NULL);}
       
  4356 | il_call_operator prev_declared_fb_name '(' il_operand_list ')'
       
  4357 	{$$ = new il_fb_call_c($1, $2, $4, NULL);}
       
  4358 | il_call_operator prev_declared_fb_name '(' eol_list il_param_list ')'
       
  4359 	{$$ = new il_fb_call_c($1, $2, NULL, $5);}
       
  4360 ;
       
  4361 
       
  4362 
       
  4363 /* NOTE: Please read note above the definition of function_name_without_clashes */
       
  4364 il_formal_funct_call:
       
  4365 /*  function_name '(' eol_list ')'  */
       
  4366 /* NOTE: il_formal_funct_call is only used in the definition of
       
  4367  *         - il_incomplete_instruction
       
  4368  *         - il_simple_instruction
       
  4369  *       In both of the above, il_expression also
       
  4370  *       shows up as another option. This means that the functions whose
       
  4371  *       names clash with expressions, followed by '(' eol_list ')', are
       
  4372  *       already included. We must therefore leave them out in this
       
  4373  *       definition in order to remove reduce/reduce conflicts.
       
  4374  *
       
  4375  *       In summary: 'MOD' '(' eol_list ')', and all other functions whose
       
  4376  *       names clash with expressions may be interpreted by the syntax by
       
  4377  *       two different routes. I (Mario) chose to interpret them
       
  4378  *       as operators, rather than as function calls!
       
  4379  */
       
  4380   function_name_no_clashes '(' eol_list ')'
       
  4381 	{$$ = new il_formal_funct_call_c($1, NULL);}
       
  4382 | function_name_simpleop_clashes '(' eol_list ')'
       
  4383 	{$$ = new il_formal_funct_call_c($1, NULL);}
       
  4384 /* | function_name '(' eol_list il_param_list ')' */
       
  4385 | function_name_no_clashes '(' eol_list il_param_list ')'
       
  4386 	{$$ = new il_formal_funct_call_c($1, $4);}
       
  4387 | function_name_simpleop_clashes '(' eol_list il_param_list ')'
       
  4388 	{$$ = new il_formal_funct_call_c($1, $4);}
       
  4389 /* the function_name_expression_clashes had to be first reduced to
       
  4390  * an intermediary symbol in order to remove a reduce/reduce conflict.
       
  4391  * In essence, the syntax requires more than one look ahead token
       
  4392  * in order to be parsed. We resolve this by reducing a collection of
       
  4393  * symbols into a temporary symbol (il_expr_operator_clash_eol_list), that
       
  4394  * will later be replaced by the correct symbol. The correct symbol will
       
  4395  * now be determined by a single look ahead token, as all the common
       
  4396  * symbols have been reduced to the temporary symbol
       
  4397  * il_expr_operator_clash_eol_list !
       
  4398  *
       
  4399  * Unfortunately, this work around results in the wrong symbol
       
  4400  * being created for the abstract syntax tree.
       
  4401  * We need to figure out which symbol was created, destroy it,
       
  4402  * and create the correct symbol for our case.
       
  4403  * This is a lot of work, so I put it in a function
       
  4404  * at the end of this file... il_operator_c_2_identifier_c()
       
  4405  */
       
  4406 | il_expr_operator_clash_eol_list il_param_list ')'
       
  4407 	{$$ = new il_formal_funct_call_c(il_operator_c_2_identifier_c($1), $2);}
       
  4408 ;
       
  4409 
       
  4410 
       
  4411 il_expr_operator_clash_eol_list:
       
  4412   il_expr_operator_clash '(' eol_list
       
  4413 	{$$ = $1;}
       
  4414 ;
       
  4415 
       
  4416 
       
  4417 il_operand:
       
  4418   variable
       
  4419 | enumerated_value
       
  4420 | constant
       
  4421 ;
       
  4422 
       
  4423 
       
  4424 il_operand_list:
       
  4425   il_operand
       
  4426 	{$$ = new il_operand_list_c(); $$->add_element($1);}
       
  4427 | il_operand_list ',' il_operand
       
  4428 	{$$ = $1; $$->add_element($3);}
       
  4429 ;
       
  4430 
       
  4431 
       
  4432 simple_instr_list:
       
  4433   il_simple_instruction
       
  4434 	{$$ = new simple_instr_list_c(); $$->add_element($1);}
       
  4435 | simple_instr_list il_simple_instruction
       
  4436 	{$$ = $1; $$->add_element($2);}
       
  4437 ;
       
  4438 
       
  4439 
       
  4440 il_simple_instruction:
       
  4441   il_simple_operation eol_list
       
  4442 | il_expression eol_list
       
  4443 | il_formal_funct_call eol_list
       
  4444 ;
       
  4445 
       
  4446 
       
  4447 /* NOTE: the correct definition of il_param_list is
       
  4448  * il_param_list ::= {il_param_instruction} il_param_last_instruction
       
  4449  *
       
  4450  * where {...} denotes zero or many il_param_instruction's.
       
  4451  *
       
  4452  * We could do this by defining the following:
       
  4453  * il_param_list: il_param_instruction_list il_param_last_instruction;
       
  4454  * il_param_instruction_list : ** empty ** | il_param_instruction_list il_param_instruction;
       
  4455  *
       
  4456  * Unfortunately, the above leads to reduce/reduce conflicts.
       
  4457  * The chosen alternative (as follows) does not have any conflicts!
       
  4458  * il_param_list: il_param_last_instruction | il_param_instruction_list il_param_last_instruction;
       
  4459  * il_param_instruction_list : il_param_instruction_list | il_param_instruction_list il_param_instruction;
       
  4460  */
       
  4461 il_param_list:
       
  4462   il_param_instruction_list il_param_last_instruction
       
  4463 	{$$ = $1; $$->add_element($2);}
       
  4464 | il_param_last_instruction
       
  4465 	{$$ = new il_param_list_c(); $$->add_element($1);}
       
  4466 ;
       
  4467 
       
  4468 
       
  4469 /* Helper symbol for il_param_list */
       
  4470 il_param_instruction_list:
       
  4471   il_param_instruction
       
  4472 	{$$ = new il_param_list_c(); $$->add_element($1);}
       
  4473 | il_param_instruction_list il_param_instruction
       
  4474 	{$$ = $1; $$->add_element($2);}
       
  4475 ;
       
  4476 
       
  4477 
       
  4478 il_param_instruction:
       
  4479   il_param_assignment ',' eol_list
       
  4480 | il_param_out_assignment ',' eol_list
       
  4481 ;
       
  4482 
       
  4483 
       
  4484 il_param_last_instruction:
       
  4485   il_param_assignment eol_list
       
  4486 | il_param_out_assignment eol_list
       
  4487 ;
       
  4488 
       
  4489 
       
  4490 il_param_assignment:
       
  4491   il_assign_operator il_operand
       
  4492 	{$$ = new il_param_assignment_c($1, $2, NULL);}
       
  4493 | il_assign_operator '(' eol_list simple_instr_list ')'
       
  4494 	{$$ = new il_param_assignment_c($1, NULL, $4);}
       
  4495 ;
       
  4496 
       
  4497 
       
  4498 il_param_out_assignment:
       
  4499   il_assign_out_operator variable
       
  4500 	{$$ = new il_param_out_assignment_c($1, $2);}
       
  4501 ;
       
  4502 
       
  4503 
       
  4504 
       
  4505 /*******************/
       
  4506 /* B 2.2 Operators */
       
  4507 /*******************/
       
  4508 sendto_identifier: sendto_identifier_token {$$ = new identifier_c($1);};
       
  4509 
       
  4510 
       
  4511 /* NOTE:
       
  4512  *  The spec includes the operator 'EQ '
       
  4513  * Note that EQ is followed by a space.
       
  4514  * I am considering this a typo, and defining the operator
       
  4515  * as 'EQ'
       
  4516  * (Mario)
       
  4517  */
       
  4518 LD_operator: 		LD 	{$$ = new LD_operator_c();};
       
  4519 LDN_operator: 		LDN 	{$$ = new LDN_operator_c();};
       
  4520 ST_operator: 		ST 	{$$ = new ST_operator_c();};
       
  4521 STN_operator: 		STN 	{$$ = new STN_operator_c();};
       
  4522 NOT_operator: 		NOT 	{$$ = new NOT_operator_c();};
       
  4523 S_operator: 		S 	{$$ = new S_operator_c();};
       
  4524 R_operator: 		R 	{$$ = new R_operator_c();};
       
  4525 S1_operator: 		S1 	{$$ = new S1_operator_c();};
       
  4526 R1_operator: 		R1 	{$$ = new R1_operator_c();};
       
  4527 CLK_operator: 		CLK 	{$$ = new CLK_operator_c();};
       
  4528 CU_operator: 		CU 	{$$ = new CU_operator_c();};
       
  4529 CD_operator: 		CD 	{$$ = new CD_operator_c();};
       
  4530 PV_operator: 		PV 	{$$ = new PV_operator_c();};
       
  4531 IN_operator: 		IN 	{$$ = new IN_operator_c();};
       
  4532 PT_operator: 		PT 	{$$ = new PT_operator_c();};
       
  4533 AND_operator: 		AND 	{$$ = new AND_operator_c();};
       
  4534 AND2_operator: 		AND2 	{$$ = new AND_operator_c();}; /* '&' in the source code! */
       
  4535 OR_operator: 		OR 	{$$ = new OR_operator_c();};
       
  4536 XOR_operator: 		XOR 	{$$ = new XOR_operator_c();};
       
  4537 ANDN_operator: 		ANDN 	{$$ = new ANDN_operator_c();};
       
  4538 ANDN2_operator:		ANDN2 	{$$ = new ANDN_operator_c();}; /* '&N' in the source code! */
       
  4539 ORN_operator: 		ORN 	{$$ = new ORN_operator_c();};
       
  4540 XORN_operator: 		XORN 	{$$ = new XORN_operator_c();};
       
  4541 ADD_operator: 		ADD 	{$$ = new ADD_operator_c();};
       
  4542 SUB_operator: 		SUB 	{$$ = new SUB_operator_c();};
       
  4543 MUL_operator: 		MUL 	{$$ = new MUL_operator_c();};
       
  4544 DIV_operator: 		DIV 	{$$ = new DIV_operator_c();};
       
  4545 MOD_operator: 		MOD 	{$$ = new MOD_operator_c();};
       
  4546 GT_operator: 		GT 	{$$ = new GT_operator_c();};
       
  4547 GE_operator: 		GE 	{$$ = new GE_operator_c();};
       
  4548 EQ_operator: 		EQ 	{$$ = new EQ_operator_c();};
       
  4549 LT_operator: 		LT 	{$$ = new LT_operator_c();};
       
  4550 LE_operator: 		LE 	{$$ = new LE_operator_c();};
       
  4551 NE_operator: 		NE 	{$$ = new NE_operator_c();};
       
  4552 CAL_operator: 		CAL 	{$$ = new CAL_operator_c();};
       
  4553 CALC_operator: 		CALC 	{$$ = new CALC_operator_c();};
       
  4554 CALCN_operator: 	CALCN 	{$$ = new CALCN_operator_c();};
       
  4555 RET_operator: 		RET 	{$$ = new RET_operator_c();};
       
  4556 RETC_operator: 		RETC 	{$$ = new RETC_operator_c();};
       
  4557 RETCN_operator: 	RETCN 	{$$ = new RETCN_operator_c();};
       
  4558 JMP_operator: 		JMP 	{$$ = new JMP_operator_c();};
       
  4559 JMPC_operator: 		JMPC 	{$$ = new JMPC_operator_c();};
       
  4560 JMPCN_operator: 	JMPCN 	{$$ = new JMPCN_operator_c();};
       
  4561 
       
  4562 /*
       
  4563  MAY CONFLICT WITH STANDARD FUNCTION NAMES!!!
       
  4564 
       
  4565 NOT_operator: NOT {new NOT_operator_c();};
       
  4566 
       
  4567 AND_operator: AND {new AND_operator_c();};
       
  4568 OR_operator: OR {new OR_operator_c();};
       
  4569 XOR_operator: XOR {new XOR_operator_c();};
       
  4570 
       
  4571 ADD_operator: ADD {new ADD_operator_c();};
       
  4572 SUB_operator: SUB {new SUB_operator_c();};
       
  4573 MUL_operator: MUL {new MUL_operator_c();};
       
  4574 DIV_operator: DIV {new DIV_operator_c();};
       
  4575 MOD_operator: MOD {new MOD_operator_c();};
       
  4576 
       
  4577 GT_operator: GT {new GT_operator_c();};
       
  4578 GE_operator: GE {new GE_operator_c();};
       
  4579 EQ_operator: EQ {new EQ_operator_c();};
       
  4580 LT_operator: LT {new LT_operator_c();};
       
  4581 LE_operator: LE {new LE_operator_c();};
       
  4582 NE_operator: NE {new NE_operator_c();};
       
  4583 */
       
  4584 
       
  4585 
       
  4586 il_simple_operator:
       
  4587   il_simple_operator_clash
       
  4588 | il_simple_operator_noclash
       
  4589 ;
       
  4590 
       
  4591 
       
  4592 il_simple_operator_noclash:
       
  4593   LD_operator
       
  4594 | LDN_operator
       
  4595 | ST_operator
       
  4596 | STN_operator
       
  4597 | S_operator
       
  4598 | R_operator
       
  4599 | S1_operator
       
  4600 | R1_operator
       
  4601 | CLK_operator
       
  4602 | CU_operator
       
  4603 | CD_operator
       
  4604 | PV_operator
       
  4605 | IN_operator
       
  4606 | PT_operator
       
  4607 | il_expr_operator_noclash
       
  4608 ;
       
  4609 
       
  4610 
       
  4611 il_simple_operator_clash:
       
  4612   il_simple_operator_clash1
       
  4613 | il_simple_operator_clash2
       
  4614 ;
       
  4615 
       
  4616 il_simple_operator_clash1:
       
  4617   NOT_operator
       
  4618 ;
       
  4619 
       
  4620 il_simple_operator_clash2:
       
  4621   il_expr_operator_clash
       
  4622 ;
       
  4623 
       
  4624 
       
  4625 /*
       
  4626 il_expr_operator:
       
  4627   il_expr_operator_noclash
       
  4628 | il_expr_operator_clash
       
  4629 ;
       
  4630 */
       
  4631 
       
  4632 il_expr_operator_clash:
       
  4633   AND_operator
       
  4634 | OR_operator
       
  4635 | XOR_operator
       
  4636 | ADD_operator
       
  4637 | SUB_operator
       
  4638 | MUL_operator
       
  4639 | DIV_operator
       
  4640 | MOD_operator
       
  4641 | GT_operator
       
  4642 | GE_operator
       
  4643 | EQ_operator
       
  4644 | LT_operator
       
  4645 | LE_operator
       
  4646 | NE_operator
       
  4647 ;
       
  4648 
       
  4649 
       
  4650 il_expr_operator_noclash:
       
  4651   ANDN_operator
       
  4652 | ANDN2_operator  /* string '&N' in source code! */
       
  4653 | AND2_operator  /* string '&' in source code! */
       
  4654 | ORN_operator
       
  4655 | XORN_operator
       
  4656 ;
       
  4657 
       
  4658 
       
  4659 
       
  4660 
       
  4661 il_assign_operator:
       
  4662 /*  variable_name ASSIGN */
       
  4663   any_identifier ASSIGN
       
  4664 ;
       
  4665 
       
  4666 
       
  4667 il_assign_out_operator:
       
  4668 /*  variable_name SENDTO */
       
  4669 /*  any_identifier SENDTO */
       
  4670   sendto_identifier SENDTO
       
  4671 	{$$ = new il_assign_out_operator_c(NULL, $1);}
       
  4672 /*| NOT variable_name SENDTO */
       
  4673 | NOT sendto_identifier SENDTO
       
  4674 	{$$ = new il_assign_out_operator_c(new not_paramassign_c(), $2);}
       
  4675 ;
       
  4676 
       
  4677 
       
  4678 il_call_operator:
       
  4679   CAL_operator
       
  4680 | CALC_operator
       
  4681 | CALCN_operator
       
  4682 ;
       
  4683 
       
  4684 
       
  4685 il_return_operator:
       
  4686   RET_operator
       
  4687 | RETC_operator
       
  4688 | RETCN_operator
       
  4689 ;
       
  4690 
       
  4691 
       
  4692 il_jump_operator:
       
  4693   JMP_operator
       
  4694 | JMPC_operator
       
  4695 | JMPCN_operator
       
  4696 ;
       
  4697 
       
  4698 
       
  4699 /***********************/
       
  4700 /* B 3.1 - Expressions */
       
  4701 /***********************/
       
  4702 expression:
       
  4703   xor_expression
       
  4704 | expression OR xor_expression
       
  4705 	{$$ = new or_expression_c($1, $3);}
       
  4706 ;
       
  4707 
       
  4708 xor_expression:
       
  4709   and_expression
       
  4710 | xor_expression XOR and_expression
       
  4711 	{$$ = new xor_expression_c($1, $3);}
       
  4712 ;
       
  4713 
       
  4714 and_expression:
       
  4715   comparison
       
  4716 | and_expression '&' comparison
       
  4717 	{$$ = new and_expression_c($1, $3);}
       
  4718 | and_expression AND comparison
       
  4719 	{$$ = new and_expression_c($1, $3);}
       
  4720 /* NOTE: The lexical parser never returns the token '&'.
       
  4721  *       The '&' string is interpreted by the lexcial parser as the token
       
  4722  *       AND2!
       
  4723  *       This means that the first rule with '&' is actually not required,
       
  4724  *       but we leave it in nevertheless just in case we later decide
       
  4725  *       to remove theh AND2 token...
       
  4726  */
       
  4727 | and_expression AND2 comparison
       
  4728 	{$$ = new and_expression_c($1, $3);}
       
  4729 ;
       
  4730 
       
  4731 comparison:
       
  4732   equ_expression
       
  4733 | comparison '=' equ_expression
       
  4734 	{$$ = new equ_expression_c($1, $3);}
       
  4735 | comparison OPER_NE equ_expression
       
  4736 	{$$ = new notequ_expression_c($1, $3);}
       
  4737 ;
       
  4738 
       
  4739 equ_expression:
       
  4740   add_expression
       
  4741 | equ_expression '<' add_expression
       
  4742 	{$$ = new lt_expression_c($1, $3);}
       
  4743 | equ_expression '>' add_expression
       
  4744 	{$$ = new gt_expression_c($1, $3);}
       
  4745 | equ_expression OPER_LE add_expression
       
  4746 	{$$ = new le_expression_c($1, $3);}
       
  4747 | equ_expression OPER_GE add_expression
       
  4748 	{$$ = new ge_expression_c($1, $3);}
       
  4749 ;
       
  4750 
       
  4751 /* Not required...
       
  4752 comparison_operator: '<' | '>' | '>=' '<='
       
  4753 */
       
  4754 
       
  4755 add_expression:
       
  4756   term
       
  4757 | add_expression '+' term
       
  4758 	{$$ = new add_expression_c($1, $3);}
       
  4759 | add_expression '-' term
       
  4760 	{$$ = new sub_expression_c($1, $3);}
       
  4761 ;
       
  4762 
       
  4763 /* Not required...
       
  4764 add_operator: '+' | '-'
       
  4765 */
       
  4766 
       
  4767 term:
       
  4768   power_expression
       
  4769 | term '*' power_expression
       
  4770 	{$$ = new mul_expression_c($1, $3);}
       
  4771 | term '/' power_expression
       
  4772 	{$$ = new div_expression_c($1, $3);}
       
  4773 | term MOD power_expression
       
  4774 	{$$ = new mod_expression_c($1, $3);}
       
  4775 ;
       
  4776 
       
  4777 /* Not required...
       
  4778 multiply_operator: '*' | '/' | 'MOD'
       
  4779 */
       
  4780 
       
  4781 power_expression:
       
  4782   unary_expression
       
  4783 | power_expression OPER_EXP unary_expression
       
  4784 	{$$ = new power_expression_c($1, $3);}
       
  4785 ;
       
  4786 
       
  4787 
       
  4788 unary_expression:
       
  4789   primary_expression
       
  4790 | '-' primary_expression
       
  4791 	{$$ = new neg_expression_c($2);}
       
  4792 | NOT primary_expression
       
  4793 	{$$ = new not_expression_c($2);}
       
  4794 ;
       
  4795 
       
  4796 /* Not required...
       
  4797 unary_operator: '-' | 'NOT'
       
  4798 */
       
  4799 
       
  4800 
       
  4801 /* NOTE: using constant as a possible symbol for primary_expression
       
  4802  *       leads to a reduce/reduce conflict.
       
  4803  *
       
  4804  *       The text '-9' may be parsed as either a
       
  4805  *       expression<-primary_expression<-constant<-signed_integer
       
  4806  *       (i.e. the constant 9 negative)
       
  4807  *       OR
       
  4808  *       expression<-unary_expression<-constant<-integer
       
  4809  *       (i.e. the constant 9, preceded by a unary negation)
       
  4810  *
       
  4811  *       To remove the conlfict, we only allow constants without
       
  4812  *       a preceding '-' to be used in primary_expression
       
  4813  */
       
  4814 primary_expression:
       
  4815 /* constant */
       
  4816   non_negative_constant
       
  4817 | enumerated_value
       
  4818 | variable
       
  4819 | '(' expression ')'
       
  4820 	{$$ = $2;}
       
  4821 |  function_invocation
       
  4822 ;
       
  4823 
       
  4824 
       
  4825 /* intermediate helper symbol for primary_expression */
       
  4826 /* NOTE: function_name includes the standard function name 'NOT' !
       
  4827  *       This introduces a reduce/reduce conflict, as NOT(var)
       
  4828  *       may be parsed as either a function_invocation, or a
       
  4829  *       unary_expression.
       
  4830  *
       
  4831  *       I (Mario) have opted to remove the possible reduction
       
  4832  *       to function invocation, which means replacing the rule
       
  4833  *           function_name '(' param_assignment_list ')'
       
  4834  *       with
       
  4835  *           function_name_no_NOT_clashes '(' param_assignment_list ')'
       
  4836  *
       
  4837  *       Notice how the new rule does not include the situation where
       
  4838  *       the function NOT is called with more than one parameter, which
       
  4839  *       the original rule does include! Callinf the NOT function with more
       
  4840  *       than one argument is probably a semantic error anyway, so it
       
  4841  *       doesn't make much sense to take it into account.
       
  4842  *
       
  4843  *       Nevertheless, if we were to to it entirely correctly,
       
  4844  *       leaving the semantic checks for the next compiler stage,
       
  4845  *       this syntax parser would need to include such a possibility.
       
  4846  *
       
  4847  *       We will leave this out for now. No need to complicate the syntax
       
  4848  *       more than the specification does by contradicting itself, and
       
  4849  *       letting names clash!
       
  4850  */
       
  4851 function_invocation:
       
  4852 /*  function_name '(' param_assignment_list ')' */
       
  4853   function_name_no_NOT_clashes '(' param_assignment_list ')'
       
  4854 	{$$ = new function_invocation_c($1, $3);}
       
  4855 ;
       
  4856 
       
  4857 
       
  4858 /********************/
       
  4859 /* B 3.2 Statements */
       
  4860 /********************/
       
  4861 statement_list:
       
  4862   /* empty */
       
  4863 	{$$ = new statement_list_c();}
       
  4864 | statement_list statement ';'
       
  4865 	{$$ = $1; $$->add_element($2);}
       
  4866 | statement_list pragma
       
  4867 	{$$ = $1; $$->add_element($2);}
       
  4868 | statement_list error ';'
       
  4869 	{$$ = $1;
       
  4870 	 print_err_msg(current_filename, @2.last_line, "error in statement.");
       
  4871 	 /* yychar */
       
  4872 	 yyerrok;
       
  4873 	}
       
  4874 ;
       
  4875 
       
  4876 
       
  4877 statement:
       
  4878   assignment_statement
       
  4879 | subprogram_control_statement
       
  4880 | selection_statement
       
  4881 | iteration_statement
       
  4882 ;
       
  4883 
       
  4884 
       
  4885 /*********************************/
       
  4886 /* B 3.2.1 Assignment Statements */
       
  4887 /*********************************/
       
  4888 assignment_statement:
       
  4889   variable ASSIGN expression
       
  4890 	{$$ = new assignment_statement_c($1, $3);}
       
  4891 ;
       
  4892 
       
  4893 
       
  4894 
       
  4895 
       
  4896 /*****************************************/
       
  4897 /* B 3.2.2 Subprogram Control Statements */
       
  4898 /*****************************************/
       
  4899 subprogram_control_statement:
       
  4900   fb_invocation
       
  4901 | return_statement
       
  4902 ;
       
  4903 
       
  4904 
       
  4905 return_statement:
       
  4906   RETURN	{$$ = new return_statement_c();}
       
  4907 ;
       
  4908 
       
  4909 
       
  4910 
       
  4911 fb_invocation:
       
  4912   prev_declared_fb_name '(' ')'
       
  4913 	{$$ = new fb_invocation_c($1, NULL);	}
       
  4914 | prev_declared_fb_name '(' param_assignment_list ')'
       
  4915 	{$$ = new fb_invocation_c($1, $3);}
       
  4916 ;
       
  4917 
       
  4918 
       
  4919 /* helper symbol for
       
  4920  * - fb_invocation
       
  4921  * - function_invocation
       
  4922  */
       
  4923 param_assignment_list:
       
  4924   param_assignment
       
  4925 	{$$ = new param_assignment_list_c(); $$->add_element($1);}
       
  4926 | param_assignment_list ',' param_assignment
       
  4927 	{$$ = $1; $$->add_element($3);}
       
  4928 ;
       
  4929 
       
  4930 
       
  4931 
       
  4932 param_assignment:
       
  4933 /*  variable_name ASSIGN expression */
       
  4934   any_identifier ASSIGN expression
       
  4935 	{$$ = new input_variable_param_assignment_c($1, $3);}
       
  4936 | expression
       
  4937 /*| variable_name SENDTO variable */
       
  4938 /*| any_identifier SENDTO variable */
       
  4939 | sendto_identifier SENDTO variable
       
  4940 	{$$ = new output_variable_param_assignment_c(NULL,$1, $3);}
       
  4941 /*| variable_name SENDTO variable */
       
  4942 /*| NOT any_identifier SENDTO variable*/
       
  4943 | NOT sendto_identifier SENDTO variable
       
  4944 	{$$ = new output_variable_param_assignment_c(new not_paramassign_c(),$2, $4);}
       
  4945 ;
       
  4946 
       
  4947 
       
  4948 
       
  4949 
       
  4950 
       
  4951 /********************************/
       
  4952 /* B 3.2.3 Selection Statements */
       
  4953 /********************************/
       
  4954 selection_statement:
       
  4955   if_statement
       
  4956 | case_statement
       
  4957 ;
       
  4958 
       
  4959 
       
  4960 if_statement:
       
  4961   IF expression THEN statement_list elseif_statement_list END_IF
       
  4962 	{$$ = new if_statement_c($2, $4, $5, NULL);}
       
  4963 | IF expression THEN statement_list elseif_statement_list ELSE statement_list END_IF
       
  4964 	{$$ = new if_statement_c($2, $4, $5, $7);}
       
  4965 ;
       
  4966 
       
  4967 /* helper symbol for if_statement */
       
  4968 elseif_statement_list:
       
  4969   /* empty */
       
  4970 	{$$ = new elseif_statement_list_c();}
       
  4971 | elseif_statement_list elseif_statement
       
  4972 	{$$ = $1; $$->add_element($2);}
       
  4973 ;
       
  4974 
       
  4975 /* helper symbol for elseif_statement_list */
       
  4976 elseif_statement:
       
  4977   ELSIF expression THEN statement_list
       
  4978 	{$$ = new elseif_statement_c($2, $4);}
       
  4979 ;
       
  4980 
       
  4981 
       
  4982 case_statement:
       
  4983   CASE expression OF case_element_list END_CASE
       
  4984 	{$$ = new case_statement_c($2, $4, NULL);}
       
  4985 | CASE expression OF case_element_list ELSE statement_list END_CASE
       
  4986 	{$$ = new case_statement_c($2, $4, $6);}
       
  4987 ;
       
  4988 
       
  4989 
       
  4990 /* helper symbol for case_statement */
       
  4991 case_element_list:
       
  4992   case_element
       
  4993 	{$$ = new case_element_list_c(); $$->add_element($1);}
       
  4994 | case_element_list case_element
       
  4995 	{$$ = $1; $$->add_element($2);}
       
  4996 ;
       
  4997 
       
  4998 
       
  4999 case_element:
       
  5000   case_list ':' statement_list
       
  5001 	{$$ = new case_element_c($1, $3);}
       
  5002 ;
       
  5003 
       
  5004 
       
  5005 case_list:
       
  5006   case_list_element
       
  5007 	{$$ = new case_list_c(); $$->add_element($1);}
       
  5008 | case_list ',' case_list_element
       
  5009 	{$$ = $1; $$->add_element($3);}
       
  5010 ;
       
  5011 
       
  5012 
       
  5013 case_list_element:
       
  5014   signed_integer
       
  5015 | enumerated_value
       
  5016 | subrange
       
  5017 ;
       
  5018 
       
  5019 
       
  5020 
       
  5021 
       
  5022 
       
  5023 /********************************/
       
  5024 /* B 3.2.4 Iteration Statements */
       
  5025 /********************************/
       
  5026 iteration_statement:
       
  5027   for_statement
       
  5028 | while_statement
       
  5029 | repeat_statement
       
  5030 | exit_statement
       
  5031 ;
       
  5032 
       
  5033 
       
  5034 for_statement:
       
  5035   FOR control_variable ASSIGN expression TO expression BY expression DO statement_list END_FOR
       
  5036 	{$$ = new for_statement_c($2, $4, $6, $8, $10);}
       
  5037 | FOR control_variable ASSIGN expression TO expression DO statement_list END_FOR
       
  5038 	{$$ = new for_statement_c($2, $4, $6, NULL, $8);}
       
  5039 ;
       
  5040 
       
  5041 /* The spec has the syntax
       
  5042  * control_variable: identifier;
       
  5043  * but then defines the semantics of control_variable
       
  5044  * (Section 3.3.2.4) as being of an integer type
       
  5045  * (e.g., SINT, INT, or DINT).
       
  5046  *
       
  5047  * Obviously this presuposes that the control_variable
       
  5048  * must have been declared in some VAR .. END_VAR
       
  5049  * construct, so I (Mario) changed the syntax to read
       
  5050  * control_variable: prev_declared_variable_name;
       
  5051 */
       
  5052 control_variable: prev_declared_variable_name {$$ = $1;};
       
  5053 
       
  5054 /* Integrated directly into for_statement */
       
  5055 /*
       
  5056 for_list:
       
  5057   expression TO expression [BY expression]
       
  5058 ;
       
  5059 */
       
  5060 
       
  5061 
       
  5062 while_statement:
       
  5063   WHILE expression DO statement_list END_WHILE
       
  5064 	{$$ = new while_statement_c($2, $4);}
       
  5065 ;
       
  5066 
       
  5067 
       
  5068 repeat_statement:
       
  5069   REPEAT statement_list UNTIL expression END_REPEAT
       
  5070 	{$$ = new repeat_statement_c($2, $4);}
       
  5071 ;
       
  5072 
       
  5073 
       
  5074 exit_statement:
       
  5075   EXIT	{$$ = new exit_statement_c();}
       
  5076 ;
       
  5077 
       
  5078 
       
  5079 
       
  5080 
       
  5081 
       
  5082 %%
       
  5083 
       
  5084 #include <stdio.h>	/* required for printf() */
       
  5085 #include <errno.h>
       
  5086 #include "../util/symtable.hh"
       
  5087 
       
  5088 /* variables defined in code generated by flex... */
       
  5089 extern FILE *yyin;
       
  5090 extern int yylineno;
       
  5091 
       
  5092 /* The following function is called automatically by bison whenever it comes across
       
  5093  * an error. Unfortunately it calls this function before executing the code that handles
       
  5094  * the error itself, so we cannot print out the correct line numbers of the error location
       
  5095  * over here.
       
  5096  * Our solution is to store the current error message in a global variable, and have all
       
  5097  * error action handlers call the function print_err_msg() after setting the location
       
  5098  * (line number) variable correctly.
       
  5099  */
       
  5100 const char *current_error_msg;
       
  5101 void yyerror (const char *error_msg) {
       
  5102   current_error_msg = error_msg;
       
  5103 /* fprintf(stderr, "error %d: %s\n", yynerrs // global variable //, error_msg); */
       
  5104   print_include_stack();
       
  5105 }
       
  5106 
       
  5107 
       
  5108 void print_err_msg(const char *filename, int lineno, const char *additional_error_msg) {
       
  5109   fprintf(stderr, "error %d: %s\n", yynerrs, additional_error_msg);
       
  5110   print_include_stack();
       
  5111   fprintf(stderr, "%s:%d: %s\n", filename, lineno, current_error_msg);
       
  5112 }
       
  5113 
       
  5114 /* Function only called from within flex!
       
  5115  *
       
  5116  * search for a symbol in either of the two symbol tables
       
  5117  * declared above, and return the token id of the first
       
  5118  * symbol found.
       
  5119  * Searches first in the variables, and only if not found
       
  5120  * does it continue searching in the library elements
       
  5121  */
       
  5122 int get_identifier_token(const char *identifier_str) {
       
  5123 //  std::cout << "get_identifier_token(" << identifier_str << "): \n";
       
  5124   int token_id;
       
  5125 
       
  5126   if ((token_id = variable_name_symtable.find_value(identifier_str)) == variable_name_symtable.end_value())
       
  5127     if ((token_id = library_element_symtable.find_value(identifier_str)) == library_element_symtable.end_value())
       
  5128       return identifier_token;
       
  5129   return token_id;
       
  5130 }
       
  5131 
       
  5132 
       
  5133 
       
  5134 /* convert between an il_operator to a function name */
       
  5135 /* This a kludge!
       
  5136  * It is required because our language requires more than one
       
  5137  * look ahead token, and bison only works with one!
       
  5138  */
       
  5139 #define op_2_str(op, str) {\
       
  5140   op ## _operator_c *ptr = dynamic_cast<op ## _operator_c *>(il_operator); \
       
  5141   if (ptr != NULL) name = str; \
       
  5142 }
       
  5143 
       
  5144 /* NOTE: this code is very ugly and un-eficient, but I (Mario) have many
       
  5145  *       more things to worry about right now, so just let it be...
       
  5146  */
       
  5147 symbol_c *il_operator_c_2_identifier_c(symbol_c *il_operator) {
       
  5148   const char *name = NULL;
       
  5149 
       
  5150   op_2_str(NOT, "NOT");
       
  5151 
       
  5152   op_2_str(AND, "AND");
       
  5153   op_2_str(OR, "OR");
       
  5154   op_2_str(XOR, "XOR");
       
  5155   op_2_str(ADD, "ADD");
       
  5156   op_2_str(SUB, "SUB");
       
  5157   op_2_str(MUL, "MUL");
       
  5158   op_2_str(DIV, "DIV");
       
  5159   op_2_str(MOD, "MOD");
       
  5160   op_2_str(GT, "GT");
       
  5161   op_2_str(GE, "GE");
       
  5162   op_2_str(EQ, "EQ");
       
  5163   op_2_str(LT, "LT");
       
  5164   op_2_str(LE, "LE");
       
  5165   op_2_str(NE, "NE");
       
  5166 
       
  5167   op_2_str(LD, "LD");
       
  5168   op_2_str(LDN, "LDN");
       
  5169   op_2_str(ST, "ST");
       
  5170   op_2_str(STN, "STN");
       
  5171 
       
  5172   op_2_str(S, "S");
       
  5173   op_2_str(R, "R");
       
  5174   op_2_str(S1, "S1");
       
  5175   op_2_str(R1, "R1");
       
  5176 
       
  5177   op_2_str(CLK, "CLK");
       
  5178   op_2_str(CU, "CU");
       
  5179   op_2_str(CD, "CD");
       
  5180   op_2_str(PV, "PV");
       
  5181   op_2_str(IN, "IN");
       
  5182   op_2_str(PT, "PT");
       
  5183 
       
  5184   op_2_str(ANDN, "ANDN");
       
  5185   op_2_str(ORN, "ORN");
       
  5186   op_2_str(XORN, "XORN");
       
  5187 
       
  5188   op_2_str(ADD, "ADD");
       
  5189   op_2_str(SUB, "SUB");
       
  5190   op_2_str(MUL, "MUL");
       
  5191   op_2_str(DIV, "DIV");
       
  5192 
       
  5193   op_2_str(GT, "GT");
       
  5194   op_2_str(GE, "GE");
       
  5195   op_2_str(EQ, "EQ");
       
  5196   op_2_str(LT, "LT");
       
  5197   op_2_str(LE, "LE");
       
  5198   op_2_str(NE, "NE");
       
  5199 
       
  5200   op_2_str(CAL, "CAL");
       
  5201   op_2_str(CALC, "CALC");
       
  5202   op_2_str(CALCN, "CALCN");
       
  5203   op_2_str(RET, "RET");
       
  5204   op_2_str(RETC, "RETC");
       
  5205   op_2_str(RETCN, "RETCN");
       
  5206   op_2_str(JMP, "JMP");
       
  5207   op_2_str(JMPC, "JMPC");
       
  5208   op_2_str(JMPCN, "JMPCN");
       
  5209 
       
  5210   if (name == NULL)
       
  5211     ERROR;
       
  5212 
       
  5213   free(il_operator);
       
  5214   return new identifier_c(strdup(name));
       
  5215 }
       
  5216 
       
  5217 
       
  5218 
       
  5219 
       
  5220 /*
       
  5221  * Join two strings together. Allocate space with malloc(3).
       
  5222  */
       
  5223 static char *strdup2(const char *a, const char *b) {
       
  5224   char *res = (char *)malloc(strlen(a) + strlen(b) + 1);
       
  5225 
       
  5226   if (!res)
       
  5227     return NULL;
       
  5228   return strcat(strcpy(res, a), b);  /* safe, actually */
       
  5229 }
       
  5230 
       
  5231 /*
       
  5232  * Join three strings together. Allocate space with malloc(3).
       
  5233  */
       
  5234 static char *strdup3(const char *a, const char *b, const char *c) {
       
  5235   char *res = (char *)malloc(strlen(a) + strlen(b) + strlen(c) + 1);
       
  5236 
       
  5237   if (!res)
       
  5238     return NULL;
       
  5239   return strcat(strcat(strcpy(res, a), b), c);  /* safe, actually */
       
  5240 }
       
  5241 
       
  5242 
       
  5243 
       
  5244 
       
  5245 const char *standard_function_names[] = {
       
  5246 // 2.5.1.5.1  Type conversion functions
       
  5247 /*
       
  5248  *_TO_**
       
  5249  TRUNC
       
  5250  *_BCD_TO_**
       
  5251  **_TO_BCD_*
       
  5252  (REAL or LREAL to SINT, INT, DINT or LINT)
       
  5253 */
       
  5254 "TRUNC",
       
  5255 "TIME_TO_REAL",
       
  5256 // 2.5.1.5.2  Numerical functions
       
  5257 //   Table 23 - Standard functions of one numeric variable
       
  5258 "ABS","SQRT","LN","LOG","EXP","SIN","COS","TAN","ASIN","ACOS","ATAN",
       
  5259 //   Table 24 - Standard arithmetic functions
       
  5260 "ADD","MUL","SUB","DIV","MOD"/* See note (a) */,"EXPT","MOVE",
       
  5261 // 2.5.1.5.3  Bit string functions
       
  5262 //   Table 25 - Standard bit shift functions
       
  5263 "SHL","SHR","ROR","ROL",
       
  5264 // 2.5.1.5.4  Selection and comparison functions
       
  5265 //   Table 26 - Standard bitwise Boolean functions
       
  5266 "AND","OR","XOR","NOT",
       
  5267 //   Table 27 - Standard selection functions
       
  5268 "SEL","MAX","MIN","LIMIT","MUX",
       
  5269 //   Table 28 - Standard comparison functions
       
  5270 "GT","GE","EQ","LE","LT","NE",
       
  5271 // 2.5.1.5.5  Character string functions
       
  5272 //   Table 29 - Standard character string functions
       
  5273 "LEN","LEFT","RIGHT","MID","CONCAT","INSERT","DELETE","REPLACE","FIND",
       
  5274 // 2.5.1.5.6  Functions of time data types
       
  5275 //   Table 30 - Functions of time data types
       
  5276 "ADD_TIME","ADD_TOD_TIME","ADD_DT_TIME","SUB_TIME","SUB_DATE_DATE",
       
  5277 "SUB_TOD_TIME","SUB_TOD_TOD","SUB_DT_TIME","SUB_DT_DT","MULTIME",
       
  5278 "DIVTIME","CONCAT_DATE_TOD",
       
  5279 // 2.5.1.5.7  Functions of enumerated data types
       
  5280 //   Table 31 - Functions of enumerated data types
       
  5281 // "SEL", /* already above! We cannot have duplicates! */
       
  5282 // "MUX", /* already above! We cannot have duplicates! */
       
  5283 // "EQ",  /* already above! We cannot have duplicates! */
       
  5284 // "NE",  /* already above! We cannot have duplicates! */
       
  5285 
       
  5286 /* end of array marker! Do not remove! */
       
  5287 NULL
       
  5288 
       
  5289 /* Note (a):
       
  5290  *  This function has a name equal to a reserved keyword.
       
  5291  *  This means that adding it here is irrelevant because the
       
  5292  *  lexical parser will consider it the XXX token before
       
  5293  *  it interprets it as an identifier and looks it up
       
  5294  *  in the library elements symbol table.
       
  5295  */
       
  5296 };
       
  5297 
       
  5298 
       
  5299 
       
  5300 
       
  5301 const char *standard_function_block_names[] = {
       
  5302 // 2.5.2.3.1  Bistable elements
       
  5303 //   Table 34 - Standard bistable function blocks
       
  5304 //"SR","RS",
       
  5305 // 2.5.2.3.2  Edge detection
       
  5306 //   Table 35 - Standard edge detection function blocks
       
  5307 "R_TRIG","F_TRIG",
       
  5308 // 2.5.2.3.3  Counters
       
  5309 //   Table 36 - Standard counter function blocks
       
  5310 "CTU","CTU_LINT","CTU_UDINT","CTU_ULINT",
       
  5311 "CTD","CTD_DINT","CTD_LINT","CTD_UDINT",
       
  5312 "CTUD","CTUD_DINT","CTUD_LINT","CTUD_ULINT",
       
  5313 // 2.5.2.3.4  Timers
       
  5314 //   Table 37 - Standard timer function blocks
       
  5315 "TP","TON","TOF",
       
  5316 /* end of array marker! Do not remove! */
       
  5317 NULL
       
  5318 };
       
  5319 
       
  5320 
       
  5321 #define LIBFILE "ieclib.txt"
       
  5322 #define DEF_LIBFILENAME LIBDIRECTORY "/" LIBFILE
       
  5323 
       
  5324 int stage1_2(const char *filename, const char *includedir, symbol_c **tree_root_ref) {
       
  5325   FILE *in_file = NULL, *lib_file = NULL;
       
  5326   char *libfilename = NULL;
       
  5327 
       
  5328   if((in_file = fopen(filename, "r")) == NULL) {
       
  5329     char *errmsg = strdup2("Error opening main file ", filename);
       
  5330     perror(errmsg);
       
  5331     free(errmsg);
       
  5332     return -1;
       
  5333   }
       
  5334 
       
  5335   if (includedir != NULL) {
       
  5336     if ((libfilename = strdup3(includedir, "/", LIBFILE)) == NULL) {
       
  5337       fprintf (stderr, "Out of memory. Bailing out!\n");
       
  5338       return -1;
       
  5339     }
       
  5340 
       
  5341     if((lib_file = fopen(libfilename, "r")) == NULL) {
       
  5342       char *errmsg = strdup2("Error opening library file ", libfilename);
       
  5343       perror(errmsg);
       
  5344       free(errmsg);
       
  5345     }
       
  5346   }
       
  5347 
       
  5348   if (lib_file == NULL) {
       
  5349     /* we try again... */
       
  5350     if ((libfilename = strdup(DEF_LIBFILENAME)) == NULL) {
       
  5351       fprintf (stderr, "Out of memory. Bailing out!\n");
       
  5352       return -1;
       
  5353     }
       
  5354 
       
  5355     if((lib_file = fopen(libfilename, "r")) == NULL) {
       
  5356       char *errmsg = strdup2("Error opening library file ", libfilename);
       
  5357       perror(errmsg);
       
  5358       free(errmsg);
       
  5359     }
       
  5360   }
       
  5361 
       
  5362   if (lib_file == NULL) {
       
  5363     /* we give up... */
       
  5364     free(libfilename);
       
  5365     fclose(in_file);
       
  5366     return -1;
       
  5367   }
       
  5368 
       
  5369   /* first parse the standard library file... */
       
  5370   yyin = lib_file;
       
  5371   yylineno = 1;
       
  5372   allow_function_overloading = true;
       
  5373   current_filename = libfilename;
       
  5374   if (yyparse() != 0)
       
  5375       ERROR;
       
  5376 
       
  5377   if (yynerrs > 0) {
       
  5378     fprintf (stderr, "\nFound %d error(s) in %s. Bailing out!\n", yynerrs /* global variable */, libfilename);
       
  5379     ERROR;
       
  5380   }
       
  5381   free(libfilename);
       
  5382   fclose(lib_file);
       
  5383 
       
  5384   /* if by any chance the library is not complete, we
       
  5385    * now add the missing reserved keywords to the list!!!
       
  5386    */
       
  5387   for(int i = 0; standard_function_names[i] != NULL; i++)
       
  5388     if (library_element_symtable.find_value(standard_function_names[i]) ==
       
  5389         library_element_symtable.end_value())
       
  5390       library_element_symtable.insert(standard_function_names[i], standard_function_name_token);
       
  5391 
       
  5392   for(int i = 0; standard_function_block_names[i] != NULL; i++)
       
  5393     if (library_element_symtable.find_value(standard_function_block_names[i]) ==
       
  5394         library_element_symtable.end_value())
       
  5395       library_element_symtable.insert(standard_function_block_names[i], standard_function_block_name_token);
       
  5396 
       
  5397 #if YYDEBUG
       
  5398   yydebug = 1;
       
  5399 #endif
       
  5400 
       
  5401   /* now parse the input file... */
       
  5402   yyin = in_file;
       
  5403   yylineno = 1;
       
  5404   allow_function_overloading = false;
       
  5405   current_filename = filename;
       
  5406   if (yyparse() != 0)
       
  5407     exit(EXIT_FAILURE);
       
  5408 
       
  5409   if (yynerrs > 0) {
       
  5410     fprintf (stderr, "\nFound %d error(s). Bailing out!\n", yynerrs /* global variable */);
       
  5411     exit(EXIT_FAILURE);
       
  5412   }
       
  5413 
       
  5414   if (tree_root_ref != NULL)
       
  5415     *tree_root_ref = tree_root;
       
  5416 
       
  5417   fclose(in_file);
       
  5418   return 0;
       
  5419 }
       
  5420 
       
  5421 
       
  5422