stage1_2/iec_bison.yy
changeset 354 0f24db96b519
parent 350 2c3c4dc34979
child 377 60b012b7793f
equal deleted inserted replaced
353:17bffb57a8c5 354:0f24db96b519
       
     1 /*
       
     2  *  matiec - a compiler for the programming languages defined in IEC 61131-3
       
     3  *
       
     4  *  Copyright (C) 2003-2011  Mario de Sousa (msousa@fe.up.pt)
       
     5  *  Copyright (C) 2007-2011  Laurent Bessard and Edouard Tisserant
       
     6  *
       
     7  *  This program is free software: you can redistribute it and/or modify
       
     8  *  it under the terms of the GNU General Public License as published by
       
     9  *  the Free Software Foundation, either version 3 of the License, or
       
    10  *  (at your option) any later version.
       
    11  *
       
    12  *  This program is distributed in the hope that it will be useful,
       
    13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    15  *  GNU General Public License for more details.
       
    16  *
       
    17  *  You should have received a copy of the GNU General Public License
       
    18  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
       
    19  *
       
    20  *
       
    21  * This code is made available on the understanding that it will not be
       
    22  * used in safety-critical situations without a full and competent review.
       
    23  */
       
    24 
       
    25 /*
       
    26  * An IEC 61131-3 compiler.
       
    27  *
       
    28  * Based on the
       
    29  * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10)
       
    30  *
       
    31  */
       
    32 
       
    33 /*
       
    34  * Stage 2
       
    35  * =======
       
    36  *
       
    37  *  This file contains the syntax definition of the textual
       
    38  *  languages IL and ST, as well as the textual version of SFC.
       
    39  *  The syntax parser, comprising the 2nd stage of the overall 
       
    40  *  compiler, is generated by runing bison on this file.
       
    41  */
       
    42 
       
    43 
       
    44 
       
    45 
       
    46 /**********************************************************************/
       
    47 /**********************************************************************/
       
    48 /**********************************************************************/
       
    49 /**********************************************************************/
       
    50 /*******                                                        *******/
       
    51 /*******   The following syntax does not have any conflicts.    *******/
       
    52 /*******                                                        *******/
       
    53 /*******   P L E A S E    K E E P    I T    T H A T    W A Y !  *******/
       
    54 /*******   ===================================================  *******/
       
    55 /*******                                                        *******/
       
    56 /**********************************************************************/
       
    57 /**********************************************************************/
       
    58 /**********************************************************************/
       
    59 /**********************************************************************/
       
    60 
       
    61 
       
    62 
       
    63 
       
    64 %{
       
    65 #include <string.h>	/* required for strdup()  */
       
    66 
       
    67 
       
    68 /* declare the token parser generated by flex... */
       
    69 int yylex(void);
       
    70 
       
    71 /* declare the error handler defined at the end of this file */
       
    72 void yyerror (const char *error_msg);
       
    73 
       
    74 /* produce a more verbose parsing error message */
       
    75 #define YYERROR_VERBOSE
       
    76 
       
    77 /* Include debuging code.
       
    78  * Printing of debug info must then be activated by setting
       
    79  * the variable yydebug to 1.
       
    80  */
       
    81 #define YYDEBUG 0
       
    82 
       
    83 
       
    84 /* file with declaration of absyntax classes... */
       
    85 #include "../absyntax/absyntax.hh"
       
    86 
       
    87 /* file with declaration of token constants. Generated by bison! */
       
    88 #include "iec_bison.h"
       
    89 
       
    90 /* The interface through which bison and flex interact. */
       
    91 #include "stage1_2_priv.hh"
       
    92 
       
    93 
       
    94 #include "../absyntax_utils/add_en_eno_param_decl.hh"	/* required for  add_en_eno_param_decl_c */
       
    95 
       
    96 /* an ugly hack!!
       
    97  * We will probably not need it when we decide
       
    98  *  to cut down the abstract syntax down to size.
       
    99  *  We keep it as it is until we get to write
       
   100  *  stages 3 and 4 of the compiler. Who knows,
       
   101  *  we might just find out that we really do need
       
   102  *  the abstract syntax tree to stay as it is
       
   103  *  afterall!
       
   104  */
       
   105 /* for each element <elem> in list_c * <list>
       
   106  * execute the code <code>
       
   107  */
       
   108 #define FOR_EACH_ELEMENT(elem, list, code) {		\
       
   109   symbol_c *elem;					\
       
   110   for(int i = 0; i < list->n; i++) {			\
       
   111     elem = list->elements[i];				\
       
   112     code;						\
       
   113   }							\
       
   114 }
       
   115 
       
   116 
       
   117 
       
   118 /* Macros used to pass the line and column locations when
       
   119  * creating a new object for the abstract syntax tree.
       
   120  */
       
   121 #define locloc(foo) foo.first_line, foo.first_column, foo.first_file, foo.first_order, foo.last_line, foo.last_column, foo.last_file, foo.last_order
       
   122 #define   locf(foo) foo.first_line, foo.first_column, foo.first_file, foo.first_order
       
   123 #define   locl(foo) foo.last_line,  foo.last_column,  foo.last_file,  foo.last_order
       
   124 
       
   125 /* Redefine the default action to take for each rule, so that the filenames are correctly processed... */
       
   126 # define YYLLOC_DEFAULT(Current, Rhs, N)                                \
       
   127          do                                                                  \
       
   128            if (N)                                                            \
       
   129              {                                                               \
       
   130                (Current).first_line   = YYRHSLOC(Rhs, 1).first_line;         \
       
   131                (Current).first_column = YYRHSLOC(Rhs, 1).first_column;       \
       
   132                (Current).first_file   = YYRHSLOC(Rhs, 1).first_file;         \
       
   133                (Current).first_order  = YYRHSLOC(Rhs, 1).first_order;        \
       
   134                (Current).last_line    = YYRHSLOC(Rhs, N).last_line;          \
       
   135                (Current).last_column  = YYRHSLOC(Rhs, N).last_column;        \
       
   136                (Current).last_file    = YYRHSLOC(Rhs, 1).last_file;          \
       
   137                (Current).last_order   = YYRHSLOC(Rhs, 1).last_order;         \
       
   138              }                                                               \
       
   139            else                                                              \
       
   140              {                                                               \
       
   141                (Current).first_line   = (Current).last_line   =              \
       
   142                  YYRHSLOC(Rhs, 0).last_line;                                 \
       
   143                (Current).first_column = (Current).last_column =              \
       
   144                  YYRHSLOC(Rhs, 0).last_column;                               \
       
   145                (Current).first_file   = (Current).last_file   =              \
       
   146                  YYRHSLOC(Rhs, 0).last_file;                                 \
       
   147                (Current).first_order  = (Current).last_order  =              \
       
   148                  YYRHSLOC(Rhs, 0).last_order;                                \
       
   149              }                                                               \
       
   150          while (0)
       
   151 
       
   152 
       
   153 /* A macro for printing out internal parser errors... */
       
   154 #define ERROR error_exit(__FILE__,__LINE__)
       
   155 /* function defined in main.cc */
       
   156 extern void error_exit(const char *file_name, int line_no);
       
   157 
       
   158 
       
   159 
       
   160 /*************************/
       
   161 /* global variables...   */
       
   162 /*************************/
       
   163 /* NOTE: For some strange reason bison ver 2.3 is including these declarations
       
   164  *       in the iec_bison.h file, which is in turn included by flex.
       
   165  *       We cannot therefore define any variables over here, but merely declare 
       
   166  *       their existance (otherwise we get errors when linking the code, since we
       
   167  *       would get a new variable defined each time iec_bison.h is included!).
       
   168  *       Even though the variables are declared 'extern' over here, they will in
       
   169  *       fact be defined towards the end of this same file (i.e. in the prologue)
       
   170  */
       
   171 
       
   172 
       
   173 /* NOTE: These variable are really parameters we would like the stage2__ function to pass
       
   174  *       to the yyparse() function. However, the yyparse() function is created automatically
       
   175  *       by bison, so we cannot add parameters to this function. The only other
       
   176  *       option is to use global variables! yuck!
       
   177  */
       
   178 
       
   179 /* A global flag used to tell the parser if overloaded funtions should be allowed.
       
   180  * The IEC 61131-3 standard allows overloaded funtions in the standard library,
       
   181  * but disallows them in user code...
       
   182  */
       
   183 extern bool allow_function_overloading;
       
   184 
       
   185 /* A flag to tell the compiler whether to allow the declaration
       
   186  * of extensible function (i.e. functions that may have a variable number of
       
   187  * input parameters, such as AND(word#33, word#44, word#55, word#66).
       
   188  * This is an extension to the standard syntax.
       
   189  * See comments below for details why we support this!
       
   190  */
       
   191 extern bool allow_extensible_function_parameters;
       
   192 
       
   193 /* A global flag used to tell the parser whether to include the full variable location
       
   194  * when printing out error messages...
       
   195  */
       
   196 extern bool full_token_loc;
       
   197 
       
   198 /* A pointer to the root of the parsing tree that will be generated 
       
   199  * by bison.
       
   200  */
       
   201 extern symbol_c *tree_root;
       
   202 
       
   203 
       
   204 
       
   205 /************************/
       
   206 /* forward declarations */
       
   207 /************************/
       
   208 /* The functions declared here are defined at the end of this file... */
       
   209 
       
   210 /* Convert an il_operator_c into an identifier_c */
       
   211 symbol_c *il_operator_c_2_identifier_c(symbol_c *il_operator);
       
   212 
       
   213 /* return if current token is a syntax element */
       
   214 /* ERROR_CHECK_BEGIN */
       
   215 bool is_current_syntax_token();
       
   216 /* ERROR_CHECK_END */
       
   217 
       
   218 /* print an error message */
       
   219 void print_err_msg(int first_line,
       
   220                    int first_column,
       
   221                    const char *first_filename,
       
   222                    long int first_order,
       
   223                    int last_line,
       
   224                    int last_column,
       
   225                    const char *last_filename,
       
   226                    long int last_order,
       
   227                    const char *additional_error_msg);
       
   228 %}
       
   229 
       
   230 
       
   231 
       
   232 
       
   233 // %glr-parser
       
   234 // %expect-rr 1
       
   235 
       
   236 
       
   237 /* The following definitions need to be inside a '%code requires' 
       
   238  * so that they are also included in the header files. If this were not the case,
       
   239  * YYLTYPE would be delcared as something in the iec.cc file, and another thing
       
   240  * (actually the default value of YYLTYPE) in the iec_bison.h heder file.
       
   241  */
       
   242 %code requires {
       
   243 /* define a new data type to store the locations, so we can also store
       
   244  * the filename in which the token is expressed.
       
   245  */
       
   246 /* NOTE: since this code will be placed in the iec_bison.h header file,
       
   247  * as well as the iec.cc file that also includes the iec_bison.h header file,
       
   248  * declaring the typedef struct yyltype__local here would result in a 
       
   249  * compilation error when compiling iec.cc, as this struct would be
       
   250  * declared twice.
       
   251  * We therefore use the #if !defined YYLTYPE ...
       
   252  * to make sure only the first declaration is parsed by the C++ compiler.
       
   253  *
       
   254  * At first glance it seems that what we really should do is delcare the
       
   255  * YYLTYPE directly as an anonymous struct, thus:
       
   256  * #define YYLTYPE struct{ ...}
       
   257  * however, this also results in compilation errors.
       
   258  *
       
   259  * I (Mario) think this is kind of a hack. If you know how to
       
   260  * do this re-declaration of YYLTYPE properly, please let me know!
       
   261  */
       
   262 #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
       
   263   typedef struct {
       
   264     int         first_line;
       
   265     int         first_column;
       
   266     const char *first_file;
       
   267     long int    first_order;
       
   268     int         last_line;
       
   269     int         last_column;
       
   270     const char *last_file;
       
   271     long int    last_order;
       
   272   } yyltype__local;
       
   273   #define YYLTYPE yyltype__local
       
   274 #endif
       
   275 }
       
   276 
       
   277 
       
   278 
       
   279 %union {
       
   280     symbol_c 	*leaf;
       
   281     list_c	*list;
       
   282     char 	*ID;	/* token value */
       
   283 }
       
   284 
       
   285 /*
       
   286  TODO: DO we need to define a destructor do free
       
   287        memory when recovering from errors, or do the
       
   288        class destructors already handle this?
       
   289        Following is example on how to define
       
   290        detructors, using the syntax:
       
   291        %destructor { CODE } SYMBOLS
       
   292 %union
       
   293       {
       
   294         char *string;
       
   295       }
       
   296       %token <string> STRING
       
   297       %type  <string> string
       
   298       %destructor { free ($$); } STRING string
       
   299 */
       
   300 
       
   301 
       
   302 
       
   303 
       
   304 /*************************************/
       
   305 /* Prelimenary helpful constructs... */
       
   306 /*************************************/
       
   307 /* A token used to identify the very end of the input file
       
   308  * after all includes have already been processed.
       
   309  *
       
   310  * Flex automatically returns the token with value 0
       
   311  * at the end of the file. We therefore specify here
       
   312  * a token with that exact same value here, so we can use it
       
   313  * to detect the very end of the input files.
       
   314  */
       
   315 %token END_OF_INPUT 0
       
   316 
       
   317 /* A bogus token that, in principle, flex MUST NEVER generate */
       
   318 /* USE 1:
       
   319  * ======
       
   320  * This token is currently also being used as the default
       
   321  * initialisation value of the token_id member in
       
   322  * the symbol_c base class.
       
   323  *
       
   324  * USE 2
       
   325  * =====
       
   326  * This token may also be used in the future to remove
       
   327  * mysterious reduce/reduce conflicts due to the fact
       
   328  * that our grammar may not be LALR(1) but merely LR(1).
       
   329  * This means that bison cannot handle it without some
       
   330  * caoxing from ourselves. We will then need this token
       
   331  * to do the coaxing...
       
   332  */
       
   333 %token BOGUS_TOKEN_ID
       
   334 
       
   335 %type <leaf>	start
       
   336 
       
   337 %type <leaf>	any_identifier
       
   338 
       
   339 %token <ID>	prev_declared_variable_name_token
       
   340 %token <ID>	prev_declared_direct_variable_token
       
   341 %token <ID>	prev_declared_fb_name_token
       
   342 %type <leaf>	prev_declared_variable_name
       
   343 %type <leaf>	prev_declared_direct_variable
       
   344 %type <leaf>	prev_declared_fb_name
       
   345 
       
   346 %token  <ID>	prev_declared_simple_type_name_token
       
   347 %token  <ID>	prev_declared_subrange_type_name_token
       
   348 %token  <ID>	prev_declared_enumerated_type_name_token
       
   349 %token  <ID>	prev_declared_array_type_name_token
       
   350 %token  <ID>	prev_declared_structure_type_name_token
       
   351 %token  <ID>	prev_declared_string_type_name_token
       
   352 
       
   353 %type  <leaf>	prev_declared_simple_type_name
       
   354 %type  <leaf>	prev_declared_subrange_type_name
       
   355 %type  <leaf>	prev_declared_enumerated_type_name
       
   356 %type  <leaf>	prev_declared_array_type_name
       
   357 %type  <leaf>	prev_declared_structure_type_name
       
   358 %type  <leaf>	prev_declared_string_type_name
       
   359 
       
   360 %token <ID>	prev_declared_derived_function_name_token
       
   361 %token <ID>	prev_declared_derived_function_block_name_token
       
   362 %token <ID>	prev_declared_program_type_name_token
       
   363 %type  <leaf>	prev_declared_derived_function_name
       
   364 %type  <leaf>	prev_declared_derived_function_block_name
       
   365 %type  <leaf>	prev_declared_program_type_name
       
   366 
       
   367 
       
   368 
       
   369 
       
   370 /**********************************************************************************/
       
   371 /* B XXX - Things that are missing from the standard, but should have been there! */
       
   372 /**********************************************************************************/
       
   373 
       
   374 /* Pragmas that our compiler will accept.
       
   375  * See the comment in iec.flex for why these pragmas exist. 
       
   376  */
       
   377 %token          disable_code_generation_pragma_token
       
   378 %token          enable_code_generation_pragma_token
       
   379 %type <leaf>	disable_code_generation_pragma
       
   380 %type <leaf>	enable_code_generation_pragma
       
   381 
       
   382 
       
   383 /* All other pragmas that we do not support... */
       
   384 /* In most stage 4, the text inside the pragmas will simply be copied to the output file.
       
   385  * This allows us to insert C code (if using stage 4 generating C code) 
       
   386  * inside/interningled with the IEC 61131-3 code!
       
   387  */
       
   388 %token <ID>	pragma_token
       
   389 %type <leaf>	pragma
       
   390 
       
   391 /* The joining of all previous pragmas, i.e. any possible pragma */
       
   392 %type <leaf>	any_pragma
       
   393 
       
   394 
       
   395 /* Where do these tokens belong?? They are missing from the standard! */
       
   396 /* NOTE: There are other tokens related to these 'EN' ENO', that are also 
       
   397  * missing from the standard. However, their location in the annex B is 
       
   398  * relatively obvious, so they have been inserted in what seems to us their 
       
   399  * correct place in order to ease understanding of the parser...
       
   400  *
       
   401  * please read the comment above the definition of 'variable' in section B1.4 for details.
       
   402  */
       
   403 %token	EN
       
   404 %token	ENO
       
   405 %type <leaf>	en_identifier
       
   406 %type <leaf>	eno_identifier
       
   407 
       
   408 
       
   409 
       
   410 
       
   411 /***************************/
       
   412 /* B 0 - Programming Model */
       
   413 /***************************/
       
   414 %type <list>	library
       
   415 %type <leaf>	library_element_declaration
       
   416 
       
   417 
       
   418 /*******************************************/
       
   419 /* B 1.1 - Letters, digits and identifiers */
       
   420 /*******************************************/
       
   421 /* Done totally within flex...
       
   422   letter
       
   423   digit
       
   424   octal_digit
       
   425   hex_digit
       
   426 */
       
   427 %token <ID>	identifier_token
       
   428 %type  <leaf>	identifier
       
   429 
       
   430 /*********************/
       
   431 /* B 1.2 - Constants */
       
   432 /*********************/
       
   433 %type <leaf>	constant
       
   434 %type <leaf>	non_negative_constant
       
   435 
       
   436 /******************************/
       
   437 /* B 1.2.1 - Numeric Literals */
       
   438 /******************************/
       
   439 /* Done totally within flex...
       
   440   bit
       
   441 */
       
   442 %type  <leaf> numeric_literal
       
   443 %type  <leaf> integer_literal
       
   444 %type  <leaf> signed_integer
       
   445 %token <ID>   integer_token
       
   446 %type  <leaf> integer
       
   447 %token <ID>   binary_integer_token
       
   448 %type  <leaf> binary_integer
       
   449 %token <ID>   octal_integer_token
       
   450 %type  <leaf> octal_integer
       
   451 %token <ID>   hex_integer_token
       
   452 %type  <leaf> hex_integer
       
   453 %token <ID>   real_token
       
   454 %type  <leaf> real
       
   455 %type  <leaf> signed_real
       
   456 %type  <leaf> real_literal
       
   457 // %type  <leaf> exponent
       
   458 %type  <leaf> bit_string_literal
       
   459 %type  <leaf> boolean_literal
       
   460 
       
   461 %token safeboolean_true_literal_token
       
   462 %token safeboolean_false_literal_token
       
   463 %token boolean_true_literal_token
       
   464 %token boolean_false_literal_token
       
   465 
       
   466 %token FALSE
       
   467 %token TRUE
       
   468 
       
   469 
       
   470 /*******************************/
       
   471 /* B 1.2.2 - Character Strings */
       
   472 /*******************************/
       
   473 %token <ID>   single_byte_character_string_token
       
   474 %token <ID>   double_byte_character_string_token
       
   475 
       
   476 %type  <leaf> character_string
       
   477 %type  <leaf> single_byte_character_string
       
   478 %type  <leaf> double_byte_character_string
       
   479 
       
   480 
       
   481 /***************************/
       
   482 /* B 1.2.3 - Time Literals */
       
   483 /***************************/
       
   484 %type  <leaf> time_literal
       
   485 
       
   486 
       
   487 /************************/
       
   488 /* B 1.2.3.1 - Duration */
       
   489 /************************/
       
   490 %type  <leaf>	duration
       
   491 %type  <leaf>	interval
       
   492 %type  <leaf>	days
       
   493 %type  <leaf>	fixed_point
       
   494 %type  <leaf>	hours
       
   495 %type  <leaf>	minutes
       
   496 %type  <leaf>	seconds
       
   497 %type  <leaf>	milliseconds
       
   498 
       
   499 %type  <leaf>	integer_d
       
   500 %type  <leaf>	integer_h
       
   501 %type  <leaf>	integer_m
       
   502 %type  <leaf>	integer_s
       
   503 %type  <leaf>	integer_ms
       
   504 %type  <leaf>	fixed_point_d
       
   505 %type  <leaf>	fixed_point_h
       
   506 %type  <leaf>	fixed_point_m
       
   507 %type  <leaf>	fixed_point_s
       
   508 %type  <leaf>	fixed_point_ms
       
   509 
       
   510 %token <ID>	fixed_point_token
       
   511 %token <ID>	fixed_point_d_token
       
   512 %token <ID>	integer_d_token
       
   513 %token <ID>	fixed_point_h_token
       
   514 %token <ID>	integer_h_token
       
   515 %token <ID>	fixed_point_m_token
       
   516 %token <ID>	integer_m_token
       
   517 %token <ID>	fixed_point_s_token
       
   518 %token <ID>	integer_s_token
       
   519 %token <ID>	fixed_point_ms_token
       
   520 %token <ID>	integer_ms_token
       
   521 
       
   522 // %token TIME
       
   523 %token T_SHARP
       
   524 
       
   525 
       
   526 /************************************/
       
   527 /* B 1.2.3.2 - Time of day and Date */
       
   528 /************************************/
       
   529 %type  <leaf>	time_of_day
       
   530 %type  <leaf>	daytime
       
   531 %type  <leaf>	day_hour
       
   532 %type  <leaf>	day_minute
       
   533 %type  <leaf>	day_second
       
   534 %type  <leaf>	date
       
   535 %type  <leaf>	date_literal
       
   536 %type  <leaf>	year
       
   537 %type  <leaf>	month
       
   538 %type  <leaf>	day
       
   539 %type  <leaf>	date_and_time
       
   540 
       
   541 // %token TIME_OF_DAY
       
   542 // %token DATE
       
   543 %token D_SHARP
       
   544 // %token DATE_AND_TIME
       
   545 
       
   546 
       
   547 /**********************/
       
   548 /* B 1.3 - Data Types */
       
   549 /**********************/
       
   550 /* Strangely, the following symbol does seem to be required! */
       
   551 // %type  <leaf> data_type_name
       
   552 %type  <leaf> non_generic_type_name
       
   553 
       
   554 
       
   555 /***********************************/
       
   556 /* B 1.3.1 - Elementary Data Types */
       
   557 /***********************************/
       
   558 /* NOTES:
       
   559  *
       
   560  *    - To make the definition of bit_string_literal more
       
   561  *      concise, it is useful to use an extra non-terminal
       
   562  *      symbol (i.e. a grouping or construct) that groups the
       
   563  *      following elements (BYTE, WORD, DWORD, LWORD).
       
   564  *      Note that the definition of bit_string_type_name
       
   565  *      (according to the spec) includes the above elements
       
   566  *      and an extra BOOL.
       
   567  *      We could use an extra construct with the first four
       
   568  *      elements to be used solely in the definition of
       
   569  *      bit_string_literal, but with the objective of not
       
   570  *      having to replicate the actions (if we ever need
       
   571  *      to change them, they would need to be changed in both
       
   572  *      bit_string_type_name and the extra grouping), we
       
   573  *      have re-defined bit_string_type_name as only including
       
   574  *      the first four elements.
       
   575  *      In order to have our parser implement the specification
       
   576  *      correctly we have augmented every occurence of
       
   577  *      bit_string_type_name in other rules with the BOOL
       
   578  *      token. Since bit_string_type_name only appears in
       
   579  *      the rule for elementary_type_name, this does not
       
   580  *      seem to be a big concession to make!
       
   581  *
       
   582  *    - We have added a helper symbol to concentrate the
       
   583  *      instantiation of STRING and WSTRING into a single
       
   584  *      location (elementary_string_type_name).
       
   585  *      These two elements show up in several other rules,
       
   586  *      but we want to create the equivalent abstract syntax
       
   587  *      in a single location of this file, in order to make
       
   588  *      possible future changes easier to edit...
       
   589  */
       
   590 %type  <leaf>	elementary_type_name
       
   591 %type  <leaf>	numeric_type_name
       
   592 %type  <leaf>	integer_type_name
       
   593 %type  <leaf>	signed_integer_type_name
       
   594 %type  <leaf>	unsigned_integer_type_name
       
   595 %type  <leaf>	real_type_name
       
   596 %type  <leaf>	date_type_name
       
   597 %type  <leaf>	bit_string_type_name
       
   598 /* helper symbol to concentrate the instantiation
       
   599  * of STRING and WSTRING into a single location
       
   600  */
       
   601 %type  <leaf>	elementary_string_type_name
       
   602 
       
   603 %token BYTE
       
   604 %token WORD
       
   605 %token DWORD
       
   606 %token LWORD
       
   607 
       
   608 %token LREAL
       
   609 %token REAL
       
   610 
       
   611 %token SINT
       
   612 %token INT
       
   613 %token DINT
       
   614 %token LINT
       
   615 
       
   616 %token USINT
       
   617 %token UINT
       
   618 %token UDINT
       
   619 %token ULINT
       
   620 
       
   621 %token WSTRING
       
   622 %token STRING
       
   623 %token BOOL
       
   624 
       
   625 %token TIME
       
   626 %token DATE
       
   627 %token DATE_AND_TIME
       
   628 %token DT
       
   629 %token TIME_OF_DAY
       
   630 %token TOD
       
   631 
       
   632 /******************************************************/
       
   633 /* Symbols defined in                                 */
       
   634 /* "Safety Software Technical Specification,          */
       
   635 /*  Part 1: Concepts and Function Blocks,             */
       
   636 /*  Version 1.0 – Official Release"                   */
       
   637 /* by PLCopen - Technical Committee 5 - 2006-01-31    */
       
   638 /******************************************************/
       
   639 
       
   640 %token SAFEBYTE
       
   641 %token SAFEWORD
       
   642 %token SAFEDWORD
       
   643 %token SAFELWORD
       
   644 
       
   645 %token SAFELREAL
       
   646 %token SAFEREAL
       
   647 
       
   648 %token SAFESINT
       
   649 %token SAFEINT
       
   650 %token SAFEDINT
       
   651 %token SAFELINT
       
   652 
       
   653 %token SAFEUSINT
       
   654 %token SAFEUINT
       
   655 %token SAFEUDINT
       
   656 %token SAFEULINT
       
   657 
       
   658 %token SAFEWSTRING
       
   659 %token SAFESTRING
       
   660 %token SAFEBOOL
       
   661 
       
   662 %token SAFETIME
       
   663 %token SAFEDATE
       
   664 %token SAFEDATE_AND_TIME
       
   665 %token SAFEDT
       
   666 %token SAFETIME_OF_DAY
       
   667 %token SAFETOD
       
   668 
       
   669 /********************************/
       
   670 /* B 1.3.2 - Generic data types */
       
   671 /********************************/
       
   672 /* Strangely, the following symbol does seem to be required! */
       
   673 // %type  <leaf>	generic_type_name
       
   674 
       
   675 /* The following tokens do not seem to be used either
       
   676  * but we declare them so they become reserved words...
       
   677  */
       
   678 %token ANY
       
   679 %token ANY_DERIVED
       
   680 %token ANY_ELEMENTARY
       
   681 %token ANY_MAGNITUDE
       
   682 %token ANY_NUM
       
   683 %token ANY_REAL
       
   684 %token ANY_INT
       
   685 %token ANY_BIT
       
   686 %token ANY_STRING
       
   687 %token ANY_DATE
       
   688 
       
   689 
       
   690 /********************************/
       
   691 /* B 1.3.3 - Derived data types */
       
   692 /********************************/
       
   693 %type  <leaf>	derived_type_name
       
   694 %type  <leaf>	single_element_type_name
       
   695 // %type  <leaf>	simple_type_name
       
   696 // %type  <leaf>	subrange_type_name
       
   697 // %type  <leaf>	enumerated_type_name
       
   698 // %type  <leaf>	array_type_name
       
   699 // %type  <leaf>	structure_type_name
       
   700 
       
   701 %type  <leaf>	data_type_declaration
       
   702 /* helper symbol for data_type_declaration */
       
   703 %type  <list>	type_declaration_list
       
   704 %type  <leaf>	type_declaration
       
   705 %type  <leaf>	single_element_type_declaration
       
   706 
       
   707 %type  <leaf>	simple_type_declaration
       
   708 %type  <leaf>	simple_spec_init
       
   709 %type  <leaf>	simple_specification
       
   710 
       
   711 %type  <leaf>	subrange_type_declaration
       
   712 %type  <leaf>	subrange_spec_init
       
   713 %type  <leaf>	subrange_specification
       
   714 %type  <leaf>	subrange
       
   715 
       
   716 %type  <leaf>	enumerated_type_declaration
       
   717 %type  <leaf>	enumerated_spec_init
       
   718 %type  <leaf>	enumerated_specification
       
   719 /* helper symbol for enumerated_value */
       
   720 %type  <list>	enumerated_value_list
       
   721 %type  <leaf>	enumerated_value
       
   722 //%type  <leaf>	enumerated_value_without_identifier
       
   723 
       
   724 %type  <leaf>	array_type_declaration
       
   725 %type  <leaf>	array_spec_init
       
   726 %type  <leaf>	array_specification
       
   727 /* helper symbol for array_specification */
       
   728 %type  <list>	array_subrange_list
       
   729 %type  <leaf>	array_initialization
       
   730 /* helper symbol for array_initialization */
       
   731 %type  <list>	array_initial_elements_list
       
   732 %type  <leaf>	array_initial_elements
       
   733 %type  <leaf>	array_initial_element
       
   734 
       
   735 %type  <leaf>	structure_type_declaration
       
   736 %type  <leaf>	structure_specification
       
   737 %type  <leaf>	initialized_structure
       
   738 %type  <leaf>	structure_declaration
       
   739 /* helper symbol for structure_declaration */
       
   740 %type  <list>	structure_element_declaration_list
       
   741 %type  <leaf>	structure_element_declaration
       
   742 %type  <leaf>	structure_element_name
       
   743 %type  <leaf>	structure_initialization
       
   744 /* helper symbol for structure_initialization */
       
   745 %type  <list>	structure_element_initialization_list
       
   746 %type  <leaf>	structure_element_initialization
       
   747 
       
   748 //%type  <leaf>	string_type_name
       
   749 %type  <leaf>	string_type_declaration
       
   750 /* helper symbol for string_type_declaration */
       
   751 %type  <leaf>	string_type_declaration_size
       
   752 /* helper symbol for string_type_declaration */
       
   753 %type  <leaf>	string_type_declaration_init
       
   754 
       
   755 %token ASSIGN
       
   756 %token DOTDOT  /* ".." */
       
   757 %token TYPE
       
   758 %token END_TYPE
       
   759 %token ARRAY
       
   760 %token OF
       
   761 %token STRUCT
       
   762 %token END_STRUCT
       
   763 
       
   764 
       
   765 
       
   766 /*********************/
       
   767 /* B 1.4 - Variables */
       
   768 /*********************/
       
   769 %type  <leaf>	variable
       
   770 %type  <leaf>	symbolic_variable
       
   771 /* helper symbol for prog_cnxn */
       
   772 %type  <leaf>	any_symbolic_variable
       
   773 %type  <leaf>	variable_name
       
   774 
       
   775 
       
   776 
       
   777 
       
   778 /********************************************/
       
   779 /* B.1.4.1   Directly Represented Variables */
       
   780 /********************************************/
       
   781 /* Done totally within flex...
       
   782  location_prefix
       
   783  size_prefix
       
   784 */
       
   785 %token <ID>	direct_variable_token
       
   786 //%type  <leaf>	direct_variable
       
   787 
       
   788 
       
   789 /*************************************/
       
   790 /* B.1.4.2   Multi-element Variables */
       
   791 /*************************************/
       
   792 %type  <leaf>	multi_element_variable
       
   793 /* helper symbol for any_symbolic_variable */
       
   794 %type  <leaf>	any_multi_element_variable
       
   795 %type  <leaf>	array_variable
       
   796 /* helper symbol for any_symbolic_variable */
       
   797 %type  <leaf>	any_array_variable
       
   798 %type  <leaf>	subscripted_variable
       
   799 /* helper symbol for any_symbolic_variable */
       
   800 %type  <leaf>	any_subscripted_variable
       
   801 %type  <list>	subscript_list
       
   802 %type  <leaf>	subscript
       
   803 %type  <leaf>	structured_variable
       
   804 /* helper symbol for any_symbolic_variable */
       
   805 %type  <leaf>	any_structured_variable
       
   806 %type  <leaf>	record_variable
       
   807 /* helper symbol for any_symbolic_variable */
       
   808 %type  <leaf>	any_record_variable
       
   809 %type  <leaf>	field_selector
       
   810 
       
   811 
       
   812 /******************************************/
       
   813 /* B 1.4.3 - Declaration & Initialisation */
       
   814 /******************************************/
       
   815 %type  <leaf>	input_declarations
       
   816 /* helper symbol for input_declarations */
       
   817 %type  <list>	input_declaration_list
       
   818 %type  <leaf>	input_declaration
       
   819 %type  <leaf>	edge_declaration
       
   820 /* en_param_declaration is not in the standard, but should be! */
       
   821 %type  <leaf>	en_param_declaration
       
   822 %type  <leaf>	var_init_decl
       
   823 %type  <leaf>	var1_init_decl
       
   824 %type  <list>	var1_list
       
   825 %type  <leaf>	array_var_init_decl
       
   826 %type  <leaf>	structured_var_init_decl
       
   827 %type  <leaf>	fb_name_decl
       
   828 /* helper symbol for fb_name_decl */
       
   829 %type  <list>	fb_name_list_with_colon
       
   830 /* helper symbol for fb_name_list_with_colon */
       
   831 %type  <list>	var1_list_with_colon
       
   832 // %type  <list>	fb_name_list
       
   833 // %type  <leaf>	fb_name
       
   834 %type  <leaf>	output_declarations
       
   835 %type  <leaf>	var_output_init_decl
       
   836 %type  <list>	var_output_init_decl_list
       
   837 /* eno_param_declaration is not in the standard, but should be! */
       
   838 %type  <leaf>	eno_param_declaration
       
   839 %type  <leaf>	input_output_declarations
       
   840 /* helper symbol for input_output_declarations */
       
   841 %type  <list>	var_declaration_list
       
   842 %type  <leaf>	var_declaration
       
   843 %type  <leaf>	temp_var_decl
       
   844 %type  <leaf>	var1_declaration
       
   845 %type  <leaf>	array_var_declaration
       
   846 %type  <leaf>	structured_var_declaration
       
   847 %type  <leaf>	var_declarations
       
   848 %type  <leaf>	retentive_var_declarations
       
   849 %type  <leaf>	located_var_declarations
       
   850 /* helper symbol for located_var_declarations */
       
   851 %type  <list>	located_var_decl_list
       
   852 %type  <leaf>	located_var_decl
       
   853 %type  <leaf>	external_var_declarations
       
   854 /* helper symbol for external_var_declarations */
       
   855 %type  <list>	external_declaration_list
       
   856 %type  <leaf>	external_declaration
       
   857 %type  <leaf>	global_var_name
       
   858 %type  <leaf>	global_var_declarations
       
   859 /* helper symbol for global_var_declarations */
       
   860 %type  <list>	global_var_decl_list
       
   861 %type  <leaf>	global_var_decl
       
   862 %type  <leaf>	global_var_spec
       
   863 %type  <leaf>	located_var_spec_init
       
   864 %type  <leaf>	location
       
   865 %type  <list>	global_var_list
       
   866 %type  <leaf>	string_var_declaration
       
   867 %type  <leaf>	single_byte_string_var_declaration
       
   868 %type  <leaf>	single_byte_string_spec
       
   869 %type  <leaf>	double_byte_string_var_declaration
       
   870 %type  <leaf>	double_byte_string_spec
       
   871 %type  <leaf>	incompl_located_var_declarations
       
   872 /* helper symbol for incompl_located_var_declarations */
       
   873 %type  <list>	incompl_located_var_decl_list
       
   874 %type  <leaf>	incompl_located_var_decl
       
   875 %type  <leaf>	incompl_location
       
   876 %type  <leaf>	var_spec
       
   877 /* helper symbol for var_spec */
       
   878 %type  <leaf>	string_spec
       
   879 /* intermediate helper symbol for:
       
   880  *  - non_retentive_var_decls
       
   881  *  - var_declarations
       
   882  */
       
   883 %type  <list>	var_init_decl_list
       
   884 
       
   885 %token  <ID>	incompl_location_token
       
   886 
       
   887 %token VAR_INPUT
       
   888 %token VAR_OUTPUT
       
   889 %token VAR_IN_OUT
       
   890 %token VAR_EXTERNAL
       
   891 %token VAR_GLOBAL
       
   892 %token END_VAR
       
   893 %token RETAIN
       
   894 %token NON_RETAIN
       
   895 %token R_EDGE
       
   896 %token F_EDGE
       
   897 %token AT
       
   898 
       
   899 
       
   900 /***********************/
       
   901 /* B 1.5.1 - Functions */
       
   902 /***********************/
       
   903 // %type  <leaf>	function_name
       
   904 /* helper symbol for IL language */
       
   905 %type  <leaf>	function_name_no_clashes
       
   906 %type  <leaf>	function_name_simpleop_clashes
       
   907 //%type  <leaf>	function_name_expression_clashes
       
   908 /* helper symbols for ST language */
       
   909 //%type  <leaf>	function_name_NOT_clashes
       
   910 %type  <leaf>	function_name_no_NOT_clashes
       
   911 
       
   912 //%type  <leaf>	standard_function_name
       
   913 /* helper symbols for IL language */
       
   914 %type  <leaf>	standard_function_name_no_clashes
       
   915 %type  <leaf>	standard_function_name_simpleop_clashes
       
   916 %type  <leaf>	standard_function_name_expression_clashes
       
   917 /* helper symbols for ST language */
       
   918 %type  <leaf>	standard_function_name_NOT_clashes
       
   919 %type  <leaf>	standard_function_name_no_NOT_clashes
       
   920 
       
   921 %type  <leaf>	derived_function_name
       
   922 %type  <leaf>	function_declaration
       
   923 /* helper symbol for function_declaration */
       
   924 %type  <leaf>	function_name_declaration
       
   925 %type  <leaf>	io_var_declarations
       
   926 %type  <leaf>	function_var_decls
       
   927 %type  <leaf>	function_body
       
   928 %type  <leaf>	var2_init_decl
       
   929 /* intermediate helper symbol for function_declaration */
       
   930 %type  <list>	io_OR_function_var_declarations_list
       
   931 /* intermediate helper symbol for function_var_decls */
       
   932 %type  <list>	var2_init_decl_list
       
   933 
       
   934 %token <ID>	standard_function_name_token
       
   935 
       
   936 %token FUNCTION
       
   937 %token END_FUNCTION
       
   938 %token CONSTANT
       
   939 
       
   940 
       
   941 /*****************************/
       
   942 /* B 1.5.2 - Function Blocks */
       
   943 /*****************************/
       
   944 %type  <leaf>	function_block_type_name
       
   945 %type  <leaf>	standard_function_block_name
       
   946 %type  <leaf>	derived_function_block_name
       
   947 %type  <leaf>	function_block_declaration
       
   948 %type  <leaf>	other_var_declarations
       
   949 %type  <leaf>	temp_var_decls
       
   950 %type  <leaf>	non_retentive_var_decls
       
   951 %type  <leaf>	function_block_body
       
   952 /* intermediate helper symbol for function_declaration */
       
   953 %type  <list>	io_OR_other_var_declarations_list
       
   954 /* intermediate helper symbol for temp_var_decls */
       
   955 %type  <list>	temp_var_decls_list
       
   956 
       
   957 %token <ID>	standard_function_block_name_token
       
   958 
       
   959 %token FUNCTION_BLOCK
       
   960 %token END_FUNCTION_BLOCK
       
   961 %token VAR_TEMP
       
   962 // %token END_VAR
       
   963 %token VAR
       
   964 // %token NON_RETAIN
       
   965 // %token END_VAR
       
   966 
       
   967 
       
   968 /**********************/
       
   969 /* B 1.5.3 - Programs */
       
   970 /**********************/
       
   971 %type  <leaf>	program_type_name
       
   972 %type  <leaf>	program_declaration
       
   973 /* helper symbol for program_declaration */
       
   974 %type  <list>	program_var_declarations_list
       
   975 
       
   976 %token PROGRAM
       
   977 %token END_PROGRAM
       
   978 
       
   979 
       
   980 /********************************************/
       
   981 /* B 1.6 Sequential Function Chart elements */
       
   982 /********************************************/
       
   983 
       
   984 %type  <list>	sequential_function_chart
       
   985 %type  <list>	sfc_network
       
   986 %type  <leaf>	initial_step
       
   987 %type  <leaf>	step
       
   988 %type  <list>	action_association_list
       
   989 %type  <leaf>	step_name
       
   990 %type  <leaf>	action_association
       
   991 /* helper symbol for action_association */
       
   992 %type  <list>	indicator_name_list
       
   993 %type  <leaf>	action_name
       
   994 %type  <leaf>	action_qualifier
       
   995 %type  <leaf>	qualifier
       
   996 %type  <leaf>	timed_qualifier
       
   997 %type  <leaf>	action_time
       
   998 %type  <leaf>	indicator_name
       
   999 %type  <leaf>	transition
       
  1000 %type  <leaf>	steps
       
  1001 %type  <list>	step_name_list
       
  1002 %type  <leaf>	transition_priority
       
  1003 %type  <leaf>	transition_condition
       
  1004 %type  <leaf>	action
       
  1005 %type  <leaf>	action_body
       
  1006 %type  <leaf>	transition_name
       
  1007 
       
  1008 
       
  1009 // %token ASSIGN
       
  1010 %token ACTION
       
  1011 %token END_ACTION
       
  1012 
       
  1013 %token TRANSITION
       
  1014 %token END_TRANSITION
       
  1015 %token FROM
       
  1016 %token TO
       
  1017 %token PRIORITY
       
  1018 
       
  1019 %token INITIAL_STEP
       
  1020 %token STEP
       
  1021 %token END_STEP
       
  1022 
       
  1023 %token L
       
  1024 %token D
       
  1025 %token SD
       
  1026 %token DS
       
  1027 %token SL
       
  1028 
       
  1029 %token N
       
  1030 %token P
       
  1031 /* NOTE: the following two clash with the R and S IL operators.
       
  1032  * It will have to be handled when we include parsing of SFC...
       
  1033  */
       
  1034 /*
       
  1035 %token R
       
  1036 %token S
       
  1037 */
       
  1038 
       
  1039 
       
  1040 /********************************/
       
  1041 /* B 1.7 Configuration elements */
       
  1042 /********************************/
       
  1043 %type  <leaf>	configuration_name
       
  1044 %type  <leaf>	resource_type_name
       
  1045 %type  <leaf>	configuration_declaration
       
  1046 // helper symbol for
       
  1047 //  - configuration_declaration
       
  1048 //  - resource_declaration
       
  1049 //
       
  1050 %type  <leaf>	optional_global_var_declarations
       
  1051 // helper symbol for configuration_declaration
       
  1052 %type  <leaf>	optional_access_declarations
       
  1053 // helper symbol for configuration_declaration
       
  1054 %type  <leaf>	optional_instance_specific_initializations
       
  1055 // helper symbol for configuration_declaration
       
  1056 %type  <list>	resource_declaration_list
       
  1057 %type  <leaf>	resource_declaration
       
  1058 %type  <leaf>	single_resource_declaration
       
  1059 // helper symbol for single_resource_declaration
       
  1060 %type  <list>	task_configuration_list
       
  1061 // helper symbol for single_resource_declaration
       
  1062 %type  <list>	program_configuration_list
       
  1063 %type  <leaf>	resource_name
       
  1064 // %type  <leaf>	access_declarations
       
  1065 // helper symbol for access_declarations
       
  1066 // %type  <leaf>	access_declaration_list
       
  1067 // %type  <leaf>	access_declaration
       
  1068 // %type  <leaf>	access_path
       
  1069 // helper symbol for access_path
       
  1070 %type  <list>	any_fb_name_list
       
  1071 %type  <leaf>	global_var_reference
       
  1072 // %type  <leaf>	access_name
       
  1073 %type  <leaf>	program_output_reference
       
  1074 %type  <leaf>	program_name
       
  1075 // %type  <leaf>	direction
       
  1076 %type  <leaf>	task_configuration
       
  1077 %type  <leaf>	task_name
       
  1078 %type  <leaf>	task_initialization
       
  1079 // 3 helper symbols for task_initialization
       
  1080 %type  <leaf>	task_initialization_single
       
  1081 %type  <leaf>	task_initialization_interval
       
  1082 %type  <leaf>	task_initialization_priority
       
  1083 
       
  1084 %type  <leaf>	data_source
       
  1085 %type  <leaf>	program_configuration
       
  1086 // helper symbol for program_configuration
       
  1087 %type  <leaf>	optional_task_name
       
  1088 // helper symbol for program_configuration
       
  1089 %type  <leaf>	optional_prog_conf_elements
       
  1090 %type  <list>	prog_conf_elements
       
  1091 %type  <leaf>	prog_conf_element
       
  1092 %type  <leaf>	fb_task
       
  1093 %type  <leaf>	prog_cnxn
       
  1094 %type  <leaf>	prog_data_source
       
  1095 %type  <leaf>	data_sink
       
  1096 %type  <leaf>	instance_specific_initializations
       
  1097 // helper symbol for instance_specific_initializations
       
  1098 %type  <list>	instance_specific_init_list
       
  1099 %type  <leaf>	instance_specific_init
       
  1100 // helper symbol for instance_specific_init
       
  1101 %type  <leaf>	fb_initialization
       
  1102 
       
  1103 %type  <leaf>	prev_declared_global_var_name
       
  1104 %token  <ID>	prev_declared_global_var_name_token
       
  1105 
       
  1106 %type  <leaf>	prev_declared_program_name
       
  1107 %token  <ID>	prev_declared_program_name_token
       
  1108 
       
  1109 %type  <leaf>	prev_declared_resource_name
       
  1110 %token  <ID>	prev_declared_resource_name_token
       
  1111 
       
  1112 %token  <ID>	prev_declared_configuration_name_token
       
  1113 
       
  1114 // %type  <leaf>	prev_declared_task_name
       
  1115 // %token  <ID>	prev_declared_task_name_token
       
  1116 
       
  1117 %token CONFIGURATION
       
  1118 %token END_CONFIGURATION
       
  1119 %token TASK
       
  1120 %token RESOURCE
       
  1121 %token ON
       
  1122 %token END_RESOURCE
       
  1123 %token VAR_CONFIG
       
  1124 %token VAR_ACCESS
       
  1125 // %token END_VAR
       
  1126 %token WITH
       
  1127 // %token PROGRAM
       
  1128 // %token RETAIN
       
  1129 // %token NON_RETAIN
       
  1130 // %token PRIORITY
       
  1131 %token SINGLE
       
  1132 %token INTERVAL
       
  1133 %token READ_WRITE
       
  1134 %token READ_ONLY
       
  1135 
       
  1136 
       
  1137 /***********************************/
       
  1138 /* B 2.1 Instructions and Operands */
       
  1139 /***********************************/
       
  1140 %type  <list>	instruction_list
       
  1141 %type  <leaf>	il_instruction
       
  1142 %type  <leaf>	il_incomplete_instruction
       
  1143 %type  <leaf>	label
       
  1144 %type  <leaf>	il_simple_operation
       
  1145 // helper symbol for il_simple_operation
       
  1146 //%type <tmp_symbol> il_simple_operator_clash_il_operand
       
  1147 %type  <leaf>	il_expression
       
  1148 %type  <leaf>	il_jump_operation
       
  1149 %type  <leaf>	il_fb_call
       
  1150 %type  <leaf>	il_formal_funct_call
       
  1151 // helper symbol for il_formal_funct_call
       
  1152 %type  <leaf> il_expr_operator_clash_eol_list
       
  1153 %type  <leaf>	il_operand
       
  1154 %type  <list>	il_operand_list
       
  1155 // helper symbol for il_simple_operation
       
  1156 %type  <list>	il_operand_list2
       
  1157 %type  <list>	simple_instr_list
       
  1158 %type  <leaf>	il_simple_instruction
       
  1159 %type  <list>	il_param_list
       
  1160 %type  <list>	il_param_instruction_list
       
  1161 %type  <leaf>	il_param_instruction
       
  1162 %type  <leaf>	il_param_last_instruction
       
  1163 %type  <leaf>	il_param_assignment
       
  1164 %type  <leaf>	il_param_out_assignment
       
  1165 
       
  1166 %token EOL
       
  1167 
       
  1168 
       
  1169 /*******************/
       
  1170 /* B 2.2 Operators */
       
  1171 /*******************/
       
  1172 %token <ID>	sendto_identifier_token
       
  1173 %type  <leaf>	sendto_identifier
       
  1174 
       
  1175 %type  <leaf>	LD_operator
       
  1176 %type  <leaf>	LDN_operator
       
  1177 %type  <leaf>	ST_operator
       
  1178 %type  <leaf>	STN_operator
       
  1179 %type  <leaf>	NOT_operator
       
  1180 %type  <leaf>	S_operator
       
  1181 %type  <leaf>	R_operator
       
  1182 %type  <leaf>	S1_operator
       
  1183 %type  <leaf>	R1_operator
       
  1184 %type  <leaf>	CLK_operator
       
  1185 %type  <leaf>	CU_operator
       
  1186 %type  <leaf>	CD_operator
       
  1187 %type  <leaf>	PV_operator
       
  1188 %type  <leaf>	IN_operator
       
  1189 %type  <leaf>	PT_operator
       
  1190 %type  <leaf>	AND_operator
       
  1191 %type  <leaf>	AND2_operator
       
  1192 %type  <leaf>	OR_operator
       
  1193 %type  <leaf>	XOR_operator
       
  1194 %type  <leaf>	ANDN_operator
       
  1195 %type  <leaf>	ANDN2_operator
       
  1196 %type  <leaf>	ORN_operator
       
  1197 %type  <leaf>	XORN_operator
       
  1198 %type  <leaf>	ADD_operator
       
  1199 %type  <leaf>	SUB_operator
       
  1200 %type  <leaf>	MUL_operator
       
  1201 %type  <leaf>	DIV_operator
       
  1202 %type  <leaf>	MOD_operator
       
  1203 %type  <leaf>	GT_operator
       
  1204 %type  <leaf>	GE_operator
       
  1205 %type  <leaf>	EQ_operator
       
  1206 %type  <leaf>	LT_operator
       
  1207 %type  <leaf>	LE_operator
       
  1208 %type  <leaf>	NE_operator
       
  1209 %type  <leaf>	CAL_operator
       
  1210 %type  <leaf>	CALC_operator
       
  1211 %type  <leaf>	CALCN_operator
       
  1212 %type  <leaf>	RET_operator
       
  1213 %type  <leaf>	RETC_operator
       
  1214 %type  <leaf>	RETCN_operator
       
  1215 %type  <leaf>	JMP_operator
       
  1216 %type  <leaf>	JMPC_operator
       
  1217 %type  <leaf>	JMPCN_operator
       
  1218 
       
  1219 %type  <leaf>	il_simple_operator
       
  1220 %type  <leaf>	il_simple_operator_clash
       
  1221 %type  <leaf>	il_simple_operator_clash1
       
  1222 %type  <leaf>	il_simple_operator_clash2
       
  1223 %type  <leaf>	il_simple_operator_noclash
       
  1224 
       
  1225 //%type  <leaf>	il_expr_operator
       
  1226 %type  <leaf>	il_expr_operator_clash
       
  1227 %type  <leaf>	il_expr_operator_noclash
       
  1228 
       
  1229 %type  <leaf>	il_assign_operator
       
  1230 %type  <leaf>	il_assign_out_operator
       
  1231 %type  <leaf>	il_call_operator
       
  1232 %type  <leaf>	il_return_operator
       
  1233 %type  <leaf>	il_jump_operator
       
  1234 
       
  1235 
       
  1236 %token LD
       
  1237 %token LDN
       
  1238 %token ST
       
  1239 %token STN
       
  1240 %token NOT
       
  1241 %token S
       
  1242 %token R
       
  1243 %token S1
       
  1244 %token R1
       
  1245 %token CLK
       
  1246 %token CU
       
  1247 %token CD
       
  1248 %token PV
       
  1249 %token IN
       
  1250 %token PT
       
  1251 %token AND
       
  1252 %token AND2  /* character '&' in the source code*/
       
  1253 %token OR
       
  1254 %token XOR
       
  1255 %token ANDN
       
  1256 %token ANDN2 /* characters '&N' in the source code */
       
  1257 %token ORN
       
  1258 %token XORN
       
  1259 %token ADD
       
  1260 %token SUB
       
  1261 %token MUL
       
  1262 %token DIV
       
  1263 %token MOD
       
  1264 %token GT
       
  1265 %token GE
       
  1266 %token EQ
       
  1267 %token LT
       
  1268 %token LE
       
  1269 %token NE
       
  1270 %token CAL
       
  1271 %token CALC
       
  1272 %token CALCN
       
  1273 %token RET
       
  1274 %token RETC
       
  1275 %token RETCN
       
  1276 %token JMP
       
  1277 %token JMPC
       
  1278 %token JMPCN
       
  1279 
       
  1280 %token SENDTO   /* "=>" */
       
  1281 
       
  1282 
       
  1283 /***********************/
       
  1284 /* B 3.1 - Expressions */
       
  1285 /***********************/
       
  1286 /* NOTE:
       
  1287  *
       
  1288  *    - unary_operator, multiply_operator,
       
  1289  *      add_operator and comparison_operator
       
  1290  *      are not required. Their values are integrated
       
  1291  *      directly into other rules...
       
  1292  */
       
  1293 %type  <leaf>	expression
       
  1294 %type  <leaf>	xor_expression
       
  1295 %type  <leaf>	and_expression
       
  1296 %type  <leaf>	comparison
       
  1297 %type  <leaf>	equ_expression
       
  1298 // %type  <leaf>	comparison_operator
       
  1299 %type  <leaf>	add_expression
       
  1300 // %type  <leaf>	add_operator
       
  1301 %type  <leaf>	term
       
  1302 // %type  <leaf>	multiply_operator
       
  1303 %type  <leaf>	power_expression
       
  1304 %type  <leaf>	unary_expression
       
  1305 // %type  <leaf>	unary_operator
       
  1306 %type  <leaf>	primary_expression
       
  1307 %type  <leaf>	non_negative_primary_expression
       
  1308 /* intermediate helper symbol for primary_expression */
       
  1309 %type  <leaf>	function_invocation
       
  1310 
       
  1311 // %token AND
       
  1312 // %token XOR
       
  1313 // %token OR
       
  1314 // %token MOD
       
  1315 // %token NOT
       
  1316 %token OPER_NE
       
  1317 %token OPER_GE
       
  1318 %token OPER_LE
       
  1319 %token OPER_EXP
       
  1320 
       
  1321 
       
  1322 /********************/
       
  1323 /* B 3.2 Statements */
       
  1324 /********************/
       
  1325 %type <list> statement_list
       
  1326 %type <leaf> statement
       
  1327 
       
  1328 
       
  1329 
       
  1330 /*********************************/
       
  1331 /* B 3.2.1 Assignment Statements */
       
  1332 /*********************************/
       
  1333 %type <leaf> assignment_statement
       
  1334 // %token ASSIGN   /* ":=" */
       
  1335 
       
  1336 
       
  1337 /*****************************************/
       
  1338 /* B 3.2.2 Subprogram Control Statements */
       
  1339 /*****************************************/
       
  1340 %type <leaf>	subprogram_control_statement
       
  1341 %type <leaf>	return_statement
       
  1342 %type <leaf>	fb_invocation
       
  1343 // %type <leaf>	param_assignment
       
  1344 %type <leaf>	param_assignment_formal
       
  1345 %type <leaf>	param_assignment_nonformal
       
  1346 /* helper symbols for fb_invocation */
       
  1347 %type <list> param_assignment_formal_list
       
  1348 %type <list> param_assignment_nonformal_list
       
  1349 
       
  1350 // %token ASSIGN
       
  1351 // %token SENDTO   /* "=>" */
       
  1352 %token RETURN
       
  1353 
       
  1354 
       
  1355 /********************************/
       
  1356 /* B 3.2.3 Selection Statements */
       
  1357 /********************************/
       
  1358 %type <leaf>	selection_statement
       
  1359 %type <leaf>	if_statement
       
  1360 %type <leaf>	case_statement
       
  1361 %type <leaf>	case_element
       
  1362 %type <list>	case_list
       
  1363 %type <leaf>	case_list_element
       
  1364 /* helper symbol for if_statement */
       
  1365 %type <list>	elseif_statement_list
       
  1366 /* helper symbol for elseif_statement_list */
       
  1367 %type <leaf>	elseif_statement
       
  1368 /* helper symbol for case_statement */
       
  1369 %type <list>	case_element_list
       
  1370 
       
  1371 %token IF
       
  1372 %token THEN
       
  1373 %token ELSIF
       
  1374 %token ELSE
       
  1375 %token END_IF
       
  1376 
       
  1377 %token CASE
       
  1378 // %token OF
       
  1379 // %token ELSE
       
  1380 %token END_CASE
       
  1381 
       
  1382 
       
  1383 
       
  1384 /********************************/
       
  1385 /* B 3.2.4 Iteration Statements */
       
  1386 /********************************/
       
  1387 %type <leaf>	iteration_statement
       
  1388 %type <leaf>	for_statement
       
  1389 %type <leaf>	control_variable
       
  1390 %type <leaf>	while_statement
       
  1391 %type <leaf>	repeat_statement
       
  1392 %type <leaf>	exit_statement
       
  1393 /* Integrated directly into for_statement */
       
  1394 // %type <leaf>	for_list
       
  1395 
       
  1396 %token FOR
       
  1397 // %token ASSIGN
       
  1398 // %token TO
       
  1399 %token BY
       
  1400 %token DO
       
  1401 %token END_FOR
       
  1402 
       
  1403 %token WHILE
       
  1404 // %token DO
       
  1405 %token END_WHILE
       
  1406 
       
  1407 %token REPEAT
       
  1408 %token UNTIL
       
  1409 %token END_REPEAT
       
  1410 
       
  1411 %token EXIT
       
  1412 
       
  1413 
       
  1414 %%
       
  1415 
       
  1416 
       
  1417 
       
  1418 
       
  1419 /********************************************************/
       
  1420 /********************************************************/
       
  1421 /********************************************************/
       
  1422 /********************************************************/
       
  1423 /********************************************************/
       
  1424 /********************************************************/
       
  1425 /********************************************************/
       
  1426 /********************************************************/
       
  1427 /********************************************************/
       
  1428 /********************************************************/
       
  1429 /********************************************************/
       
  1430 /********************************************************/
       
  1431 /********************************************************/
       
  1432 /********************************************************/
       
  1433 /********************************************************/
       
  1434 /********************************************************/
       
  1435 /********************************************************/
       
  1436 /********************************************************/
       
  1437 /********************************************************/
       
  1438 /********************************************************/
       
  1439 /********************************************************/
       
  1440 /********************************************************/
       
  1441 /********************************************************/
       
  1442 /********************************************************/
       
  1443 /********************************************************/
       
  1444 /********************************************************/
       
  1445 /********************************************************/
       
  1446 /********************************************************/
       
  1447 /********************************************************/
       
  1448 /********************************************************/
       
  1449 /********************************************************/
       
  1450 /********************************************************/
       
  1451 /********************************************************/
       
  1452 /********************************************************/
       
  1453 /********************************************************/
       
  1454 /********************************************************/
       
  1455 /********************************************************/
       
  1456 /********************************************************/
       
  1457 /********************************************************/
       
  1458 /********************************************************/
       
  1459 /********************************************************/
       
  1460 /********************************************************/
       
  1461 /********************************************************/
       
  1462 /********************************************************/
       
  1463 /********************************************************/
       
  1464 
       
  1465 
       
  1466 start:
       
  1467   library	{$$ = $1;}
       
  1468 ;
       
  1469 
       
  1470 
       
  1471 /**********************************************************************************/
       
  1472 /* B XXX - Things that are missing from the standard, but should have been there! */
       
  1473 /**********************************************************************************/
       
  1474 
       
  1475 
       
  1476 /* the pragmas... */
       
  1477 
       
  1478 
       
  1479 disable_code_generation_pragma:
       
  1480   disable_code_generation_pragma_token	{$$ = new disable_code_generation_pragma_c(locloc(@$));}
       
  1481 
       
  1482 enable_code_generation_pragma:
       
  1483   enable_code_generation_pragma_token	{$$ = new enable_code_generation_pragma_c(locloc(@$));}
       
  1484 
       
  1485 pragma:
       
  1486   pragma_token	{$$ = new pragma_c($1, locloc(@$));}
       
  1487 
       
  1488 any_pragma:
       
  1489   disable_code_generation_pragma
       
  1490 | enable_code_generation_pragma
       
  1491 | pragma
       
  1492 ;
       
  1493 
       
  1494 
       
  1495 /* EN/ENO */
       
  1496 /* Tese tokens are essentially used as variable names, so we handle them 
       
  1497  * similarly to these...
       
  1498  */
       
  1499 en_identifier:
       
  1500   EN	{$$ = new identifier_c("EN", locloc(@$));}
       
  1501 ;
       
  1502 
       
  1503 eno_identifier:
       
  1504   ENO	{$$ = new identifier_c("ENO", locloc(@$));}
       
  1505 ;
       
  1506 
       
  1507 
       
  1508 
       
  1509 /*************************************/
       
  1510 /* Prelimenary helpful constructs... */
       
  1511 /*************************************/
       
  1512 
       
  1513 /* NOTE:
       
  1514  *       short version:
       
  1515  *       identifier is used for previously undeclared identifiers
       
  1516  *       any_identifier is used when any identifier, previously
       
  1517  *       declared or not, is required in the syntax.
       
  1518  *
       
  1519  *       long version:
       
  1520  *       When flex comes across an identifier, it first
       
  1521  *       searches through the currently declared variables,
       
  1522  *       functions, types, etc... to determine if it has
       
  1523  *       been previously declared.
       
  1524  *       Only if the identifier has not yet been declared
       
  1525  *       will it return an identifier_token (later turned into
       
  1526  *       an identifier symbol by the bison generated syntax parser).
       
  1527  *
       
  1528  *       Some constructs in the syntax, such as when calling
       
  1529  *       a function 'F(var1 := 1; var2 := 2);', will accept _any_
       
  1530  *       identifier in 'var1', even if it has been previously
       
  1531  *       declared in the current scope, since var1 belongs to
       
  1532  *       another scope (the variables declared in function F).
       
  1533  *
       
  1534  *       For the above reason, we need to define the symbol
       
  1535  *       any_identifier. All the symbols that may become an
       
  1536  *       any_identifier are expected to be stored in the
       
  1537  *       abstract syntax as a identifier_c
       
  1538  */
       
  1539 /* NOTE:
       
  1540  *  Type names, function names, function block type names and
       
  1541  *  program type names are considerd keywords once they are defined,
       
  1542  *  so may no longer be used for variable names!
       
  1543  *  BUT the spec is confusing on this issue, as it is not clear when
       
  1544  *  a function name should be considered as defined. If it is to be
       
  1545  *  considered defined only from the location from where it is declared
       
  1546  *  and onwards, it means that before it is declared its name may be
       
  1547  *  used for variable names!
       
  1548  *  This means that we must allow names previously used for functions
       
  1549  *  (et. al.) to also constitue an any_identifier!
       
  1550  */
       
  1551 any_identifier:
       
  1552   identifier
       
  1553 | prev_declared_fb_name
       
  1554 | prev_declared_variable_name
       
  1555 /**/
       
  1556 | prev_declared_enumerated_type_name
       
  1557 | prev_declared_simple_type_name
       
  1558 | prev_declared_subrange_type_name
       
  1559 | prev_declared_array_type_name
       
  1560 | prev_declared_structure_type_name
       
  1561 | prev_declared_string_type_name
       
  1562 | prev_declared_derived_function_name
       
  1563 | prev_declared_derived_function_block_name
       
  1564 | prev_declared_program_type_name
       
  1565 /**/
       
  1566 | prev_declared_resource_name
       
  1567 | prev_declared_program_name
       
  1568 | prev_declared_global_var_name
       
  1569 ;
       
  1570 
       
  1571 
       
  1572 prev_declared_variable_name: prev_declared_variable_name_token {$$ = new identifier_c($1, locloc(@$));};
       
  1573 prev_declared_fb_name: prev_declared_fb_name_token {$$ = new identifier_c($1, locloc(@$));};
       
  1574 
       
  1575 prev_declared_simple_type_name: prev_declared_simple_type_name_token {$$ = new identifier_c($1, locloc(@$));};
       
  1576 prev_declared_subrange_type_name: prev_declared_subrange_type_name_token {$$ = new identifier_c($1, locloc(@$));};
       
  1577 prev_declared_enumerated_type_name: prev_declared_enumerated_type_name_token {$$ = new identifier_c($1, locloc(@$));};
       
  1578 prev_declared_array_type_name: prev_declared_array_type_name_token {$$ = new identifier_c($1, locloc(@$));};
       
  1579 prev_declared_structure_type_name: prev_declared_structure_type_name_token {$$ = new identifier_c($1, locloc(@$));};
       
  1580 prev_declared_string_type_name: prev_declared_string_type_name_token {$$ = new identifier_c($1, locloc(@$));};
       
  1581 
       
  1582 prev_declared_derived_function_name: prev_declared_derived_function_name_token {$$ = new identifier_c($1, locloc(@$));};
       
  1583 prev_declared_derived_function_block_name: prev_declared_derived_function_block_name_token {$$ = new identifier_c($1, locloc(@$));};
       
  1584 prev_declared_program_type_name: prev_declared_program_type_name_token {$$ = new identifier_c($1, locloc(@$));};
       
  1585 
       
  1586 
       
  1587 
       
  1588 /***************************/
       
  1589 /* B 0 - Programming Model */
       
  1590 /***************************/
       
  1591 library:
       
  1592   /* empty */
       
  1593 	{if (tree_root == NULL)
       
  1594 	  tree_root = new library_c();
       
  1595 	 $$ = (list_c *)tree_root;
       
  1596 	}
       
  1597 | library library_element_declaration
       
  1598 	{$$ = $1; $$->add_element($2);}
       
  1599 | library any_pragma
       
  1600 	{$$ = $1; $$->add_element($2);}
       
  1601 /* ERROR_CHECK_BEGIN */
       
  1602 | library error library_element_declaration
       
  1603 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "unknown syntax error."); yyerrok;}
       
  1604 | library error END_OF_INPUT
       
  1605 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "unknown syntax error."); yyerrok;}
       
  1606 /* ERROR_CHECK_END */
       
  1607 ;
       
  1608 
       
  1609 
       
  1610 library_element_declaration:
       
  1611   data_type_declaration
       
  1612 | function_declaration
       
  1613 | function_block_declaration
       
  1614 | program_declaration
       
  1615 | configuration_declaration
       
  1616 ;
       
  1617 
       
  1618 
       
  1619 
       
  1620 /*******************************************/
       
  1621 /* B 1.1 - Letters, digits and identifiers */
       
  1622 /*******************************************/
       
  1623 /* NOTE: the spec defines identifier as:
       
  1624  *         identifier ::= (letter|('_' (letter|digit))) {['_'] (letter|digit)}
       
  1625  *       In essence, any sequence of letters or digits, starting with a letter
       
  1626  *       or '_'.
       
  1627  *
       
  1628  *       On section 2.1.3 (pg 26) , the spec states
       
  1629  *       "The keywords listed in annex C shall not be used for any other purpose,
       
  1630  *         e.g., variable names or extensions as defined in 1.5.1."
       
  1631  *       (NOTE: the spec itself does not follow this rule, as it defines standard
       
  1632  *       functions with names identidal to keywords, e.g. 'MOD', 'NOT' !!. This is
       
  1633  *       another issue altogether, and is worked around somewhere else...)
       
  1634  *
       
  1635  *       This means that we must re-define indentifier so as to exclude
       
  1636  *       any keywords defined in annex C.
       
  1637  *
       
  1638  *       Note also that the list includes
       
  1639  *          - Data type names
       
  1640  *          - Function names
       
  1641  *          - Function Block names
       
  1642  *       This means that any named used for a function name, data type name
       
  1643  *       or function block name, essentially becomes a keyword, and may therefore
       
  1644  *       no longer be re-used for any other use! (see NOTE 2)
       
  1645  *
       
  1646  *       In our case, excluding the keywords is achieved in the lexical parser,
       
  1647  *       by two mechanisms:
       
  1648  *         (1) giving higher priority to the keywords (tokens) than to identifiers,
       
  1649  *             so when the lexical parser finds a keyword it will be parsed as a
       
  1650  *             token before being parsed as an identifier.
       
  1651  *         (2) when an identifier is found that is not a keyword, the lexical parser
       
  1652  *             then looks in the global symbol table, and will not return an identifier
       
  1653  *             if the name has been previously used as a data type name, function name,
       
  1654  *             or function block name! (In these cases it will return a
       
  1655  *             prev_declared_function_name_token, etc...).
       
  1656  *
       
  1657  *       Unfortunately, the language (especially IL) uses tokens that are
       
  1658  *       not defined as keywords in the spec (e.g. 'IN', 'R1', 'S1', 'PT', etc...)!
       
  1659  *       This means that it is valid to name a function 'IN', a variable 'PT', etc...
       
  1660  *       In order to solve this potential ambiguity, flex only parses the above 
       
  1661  *       identifiers as keywords / tokens if we are currently parsing IL code.
       
  1662  *       When parsing all code other than IL code, the above identifiers are treated
       
  1663  *       just like any other identifier.
       
  1664  *
       
  1665  *
       
  1666  *
       
  1667  *
       
  1668  * NOTE 2:
       
  1669  *         I (Mario) find it strange that the writers of the spec really want
       
  1670  *         names previously used for function names, data type names or function
       
  1671  *         block names, to become full fledged keywords. I understand that they
       
  1672  *         do not want these names being used as variable names, but how about
       
  1673  *         enumeration values? How about structure element names?
       
  1674  *         If we interpret the spec literally, these would not be accepted,
       
  1675  *         which would probably burden the programmer quite a bit, in making sure
       
  1676  *         all these name don't clash!
       
  1677  *
       
  1678  *
       
  1679  *
       
  1680  * NOTE 3: The keywords, as specified in Annex C are...
       
  1681  *
       
  1682  *          - Data type names
       
  1683  *          - Function names
       
  1684  *          - Function Block names
       
  1685  *          - ACTION...END_ACTION
       
  1686  *          - ARRAY...OF
       
  1687  *          - AT
       
  1688  *          - CASE...OF...ELSE...END_CASE
       
  1689  *          - CONFIGURATION...END_CONFIGURATION
       
  1690  *          - CONSTANT
       
  1691  *          - EN, ENO
       
  1692  *          - EXIT
       
  1693  *          - FALSE
       
  1694  *          - F_EDGE
       
  1695  *          - FOR...TO...BY...DO...END_FOR
       
  1696  *          - FUNCTION...END_FUNCTION
       
  1697  *          - FUNCTION_BLOCK...END_FUNCTION_BLOCK
       
  1698  *          - IF...THEN...ELSIF...ELSE...END_IF
       
  1699  *          - INITIAL_STEP...END_STEP
       
  1700  *          - NOT, MOD, AND, XOR, OR
       
  1701  *          - PROGRAM...WITH...
       
  1702  *          - PROGRAM...END_PROGRAM
       
  1703  *          - R_EDGE
       
  1704  *          - READ_ONLY, READ_WRITE
       
  1705  *          - REPEAT...UNTIL...END_REPEAT
       
  1706  *          - RESOURCE...ON...END_RESOURCE
       
  1707  *          - RETAIN, NON_RETAIN
       
  1708  *          - RETURN
       
  1709  *          - STEP...END_STEP
       
  1710  *          - STRUCT...END_STRUCT
       
  1711  *          - TASK
       
  1712  *          - TRANSITION...FROM...TO...END_TRANSITION
       
  1713  *          - TRUE
       
  1714  *          - TYPE...END_TYPE
       
  1715  *          - VAR...END_VAR
       
  1716  *          - VAR_INPUT...END_VAR
       
  1717  *          - VAR_OUTPUT...END_VAR
       
  1718  *          - VAR_IN_OUT...END_VAR
       
  1719  *          - VAR_TEMP...END_VAR
       
  1720  *          - VAR_EXTERNAL...END_VAR
       
  1721  *          - VAR_ACCESS...END_VAR
       
  1722  *          - VAR_CONFIG...END_VAR
       
  1723  *          - VAR_GLOBAL...END_VAR
       
  1724  *          - WHILE...DO...END_WHILE
       
  1725  *          - WITH
       
  1726  */
       
  1727 
       
  1728 identifier:
       
  1729   identifier_token	{$$ = new identifier_c($1, locloc(@$));}
       
  1730 ;
       
  1731 
       
  1732 
       
  1733 
       
  1734 /*********************/
       
  1735 /* B 1.2 - Constants */
       
  1736 /*********************/
       
  1737 constant:
       
  1738   numeric_literal
       
  1739 | character_string
       
  1740 | time_literal
       
  1741 | bit_string_literal
       
  1742 | boolean_literal
       
  1743 /* NOTE: in order to remove reduce/reduce conflicts,
       
  1744  * [between -9.5 being parsed as 
       
  1745  *     (i)   a signed real, 
       
  1746  *     (ii)  or as a real preceded by the '-' operator
       
  1747  *  ]
       
  1748  *  we need to define a variant of the constant construct
       
  1749  *  where any constant is never preceded by the '-' character.
       
  1750  * In order to do this, we have borugh the signed_real 
       
  1751  * directly into the definition of the constant construct
       
  1752  * (so we can define another non_negative_constant
       
  1753  * construct that does not include it!)
       
  1754  */
       
  1755 | signed_real
       
  1756 /* NOTE: in order to remove reduce/reduce conflicts,
       
  1757  * unsigned_integer, signed_integer, binary_integer, octal_integer
       
  1758  * and hex_integer have been integrated directly into
       
  1759  * the constants construct, instead of belonging to
       
  1760  * both the bit_string_literal or integer_literal
       
  1761  * construct.
       
  1762  */
       
  1763 /* NOTE: unsigned_integer, although used in some
       
  1764  * rules, is not defined in the spec!
       
  1765  * We therefore replaced unsigned_integer as integer
       
  1766  */
       
  1767 /*| integer {} */  /* i.e. an unsigned_integer */ /* NOTE: already included as a signed integer! */
       
  1768 | signed_integer
       
  1769 | binary_integer
       
  1770 | octal_integer
       
  1771 | hex_integer
       
  1772 ;
       
  1773 
       
  1774 
       
  1775 /* NOTE: in order to remove reduce/reduce conflicts,
       
  1776  * [between -9.5 being parsed as 
       
  1777  *     (i)   a signed real, 
       
  1778  *     (ii)  or as a real preceded by the '-' operator
       
  1779  *  ]
       
  1780  *  we need to define a variant of the constant construct
       
  1781  *  where any constant is never preceded by the '-' character.
       
  1782  * In order to do this, we have borugh the signed_real 
       
  1783  * directly into the definition of the constant construct
       
  1784  * (so we can define another non_negative_constant
       
  1785  * construct that does not include it!)
       
  1786  */
       
  1787 non_negative_constant:
       
  1788   numeric_literal
       
  1789 | character_string
       
  1790 | time_literal
       
  1791 | bit_string_literal
       
  1792 | boolean_literal
       
  1793 /* NOTE: in order to remove reduce/reduce conflicts,
       
  1794  * [between -9.5 being parsed as 
       
  1795  *     (i)   a signed real, 
       
  1796  *     (ii)  or as a real preceded by the '-' operator
       
  1797  *  ]
       
  1798  *  we need to define a variant of the constant construct
       
  1799  *  where any constant is never preceded by the '-' character.
       
  1800  * In order to do this, we have borugh the signed_real 
       
  1801  * directly into the definition of the constant construct
       
  1802  * (so we can define another non_negative_constant
       
  1803  * construct that does not include it!)
       
  1804  */
       
  1805 /* | signed_real */
       
  1806 | real /* an unsigned real */
       
  1807 /* NOTE: in order to remove reduce/reduce conflicts,
       
  1808  * unsigned_integer, signed_integer, binary_integer, octal_integer
       
  1809  * and hex_integer have been integrated directly into
       
  1810  * the constants construct, instead of belonging to
       
  1811  * both the bit_string_literal or integer_literal
       
  1812  * construct.
       
  1813  */
       
  1814 /* NOTE: unsigned_integer, although used in some
       
  1815  * rules, is not defined in the spec!
       
  1816  * We therefore replaced unsigned_integer as integer
       
  1817  */
       
  1818 | integer  /* i.e. an unsigned_integer */
       
  1819 /* | signed_integer */
       
  1820 | binary_integer
       
  1821 | octal_integer
       
  1822 | hex_integer
       
  1823 ;
       
  1824 
       
  1825 
       
  1826 /******************************/
       
  1827 /* B 1.2.1 - Numeric Literals */
       
  1828 /******************************/
       
  1829 /* NOTES:
       
  1830  *
       
  1831  *    - integer is parsed by flex, but signed_integer
       
  1832  *      is parsed by bison. Flex cannot parse a signed
       
  1833  *      integer correctly!  For example: '123+456'
       
  1834  *      would be parsed by flex as an {integer} {signed_integer}
       
  1835  *      instead of {integer} '+' {integer}
       
  1836  *
       
  1837  *    - Neither flex nor bison can parse a real_literal
       
  1838  *      completely (and correctly).
       
  1839  *      Note that we cannot use the definition of real in bison as
       
  1840  *      real: signed_integer '.' integer [exponent]
       
  1841  *      exponent: {'E'|'e'} ['+'|'-'] integer
       
  1842  *      because 123e45 would be parsed by flex as
       
  1843  *      integer (123) identifier (e45).
       
  1844  *      I.e., flex never hands over an 'e' directly to
       
  1845  *      bison, but rather interprets it as an identifier.
       
  1846  *      I guess we could jump through hoops and get it
       
  1847  *      working in bison, but the following alternative
       
  1848  *      seems more straight forward...
       
  1849  *
       
  1850  *      We therefore had to break up the definition of
       
  1851  *      real_literal in discrete parts:
       
  1852  *      real_literal: [real_type_name '#'] singned_real
       
  1853  *      signed_real: ['+'|'-'] real
       
  1854  *      Flex handles real, while bison handles signed_real
       
  1855  *      and real_literal.
       
  1856  *
       
  1857  *    - According to the spec, integer '.' integer
       
  1858  *      may be reduced to either a real or a fixed_point.
       
  1859  *      It is nevertheless possible to figure out from the
       
  1860  *      context which of the two rules should be used in
       
  1861  *      the reduction.
       
  1862  *      Unfortunately, due to the issue described above
       
  1863  *      regarding the exponent of a real, the syntax
       
  1864  *      integer '.' integer
       
  1865  *      must be parsed by flex as a single token (i.e.
       
  1866  *      fixed_point_token). This means we must add fixed_point
       
  1867  *      to the definition of real!
       
  1868  *
       
  1869  *    - The syntax also uses a construct
       
  1870  *        fixed_point: integer ['.' integer]
       
  1871  *      Notice that real is not defined based on fixed point,
       
  1872  *      but rather off integer thus:
       
  1873  *        real: integer '.' integer [exponent]
       
  1874  *      This means that a real may not be composed of a single
       
  1875  *      integer, unlike the construct fixed_point!
       
  1876  *      This also means that a
       
  1877  *        integer '.' integer
       
  1878  *      could be reduced to either a real or a fixed_point
       
  1879  *      construct. It is probably possible to decide by looking
       
  1880  *      at the context, BUT:
       
  1881  *       Unfortunatley, due to the reasons explained way above,
       
  1882  *      a real (with an exponent) has to be handled by flex as a
       
  1883  *      whole. This means that we cannot leave to bison (the syntax
       
  1884  *      parser) the decision of how to reduce an
       
  1885  *        integer '.' integer
       
  1886  *      (either to real or to fixed_point)
       
  1887  *      The decision on how to reduce it would need to be done by
       
  1888  *      ther lexical analyser (i.e. flex). But flex cannot do this
       
  1889  *      sort of thing.
       
  1890  *      The solution I (Mario) adopted is to have flex return
       
  1891  *      a real_token on (notice that exponent is no longer optional)
       
  1892  *        integer '.' integer exponent
       
  1893  *      and to return a fixed_point_token when it finds
       
  1894  *        integer '.' integer
       
  1895  *      We now redefine real and fixed_point to be
       
  1896  *        fixed_point: fixed_point_token | integer
       
  1897  *        real: real_token | fixed_point_token
       
  1898  */
       
  1899 real:
       
  1900   real_token		{$$ = new real_c($1, locloc(@$));}
       
  1901 | fixed_point_token	{$$ = new real_c($1, locloc(@$));}
       
  1902 ;
       
  1903 
       
  1904 integer:	integer_token		{$$ = new integer_c($1, locloc(@$));};
       
  1905 binary_integer:	binary_integer_token	{$$ = new binary_integer_c($1, locloc(@$));};
       
  1906 octal_integer:	octal_integer_token	{$$ = new octal_integer_c($1, locloc(@$));};
       
  1907 hex_integer:	hex_integer_token	{$$ = new hex_integer_c($1, locloc(@$));};
       
  1908 
       
  1909 numeric_literal:
       
  1910   integer_literal
       
  1911 | real_literal
       
  1912 ;
       
  1913 
       
  1914 
       
  1915 integer_literal:
       
  1916   integer_type_name '#' signed_integer
       
  1917 	{$$ = new integer_literal_c($1, $3, locf(@1), locl(@3));}
       
  1918 | integer_type_name '#' binary_integer
       
  1919 	{$$ = new integer_literal_c($1, $3, locf(@1), locl(@3));}
       
  1920 | integer_type_name '#' octal_integer
       
  1921 	{$$ = new integer_literal_c($1, $3, locf(@1), locl(@3));}
       
  1922 | integer_type_name '#' hex_integer
       
  1923 	{$$ = new integer_literal_c($1, $3, locf(@1), locl(@3));}
       
  1924 /* NOTE: see note in the definition of constant for reason
       
  1925  * why signed_integer, binary_integer, octal_integer
       
  1926  * and hex_integer are missing here!
       
  1927  */
       
  1928 /* ERROR_CHECK_BEGIN */
       
  1929 | integer_type_name signed_integer
       
  1930 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "'#' missing between integer type name and value in integer literal."); yynerrs++;}
       
  1931 | integer_type_name binary_integer
       
  1932 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "'#' missing between integer type name and value in integer literal."); yynerrs++;}
       
  1933 | integer_type_name octal_integer
       
  1934 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "'#' missing between integer type name and value in integer literal."); yynerrs++;}
       
  1935 | integer_type_name hex_integer
       
  1936 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "'#' missing between integer type name and value in integer literal."); yynerrs++;}
       
  1937 | integer_type_name '#' error
       
  1938 	{$$ = NULL; 
       
  1939 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no value defined for integer literal.");}
       
  1940 	 else {print_err_msg(locf(@3), locl(@3), "invalid value for integer literal."); yyclearin;}
       
  1941 	 yyerrok;
       
  1942 	}
       
  1943 /* ERROR_CHECK_END */
       
  1944 ;
       
  1945 
       
  1946 signed_integer:
       
  1947   integer
       
  1948 | '+' integer   {$$ = $2;}
       
  1949 | '-' integer	{$$ = new neg_integer_c($2, locloc(@$));}
       
  1950 ;
       
  1951 
       
  1952 
       
  1953 real_literal:
       
  1954 /* NOTE: see note in the definition of constant for reason
       
  1955  * why signed_real is missing here!
       
  1956  */
       
  1957 /*  signed_real */
       
  1958   real_type_name '#' signed_real
       
  1959 	{$$ = new real_literal_c($1, $3, locf(@1), locl(@3));}
       
  1960 /* ERROR_CHECK_BEGIN */
       
  1961 | real_type_name signed_real
       
  1962 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "'#' missing between real type name and value in real literal."); yynerrs++;}
       
  1963 | real_type_name '#' error
       
  1964   {$$ = NULL;
       
  1965 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no value defined for real literal.");}
       
  1966 	 else {print_err_msg(locf(@3), locl(@3), "invalid value for real literal."); yyclearin;}
       
  1967 	 yyerrok;
       
  1968 	}
       
  1969 /* ERROR_CHECK_END */
       
  1970 ;
       
  1971 
       
  1972 
       
  1973 signed_real:
       
  1974   real
       
  1975 | '+' real	{$$ = $2;}
       
  1976 | '-' real	{$$ = new neg_real_c($2, locloc(@2));}
       
  1977 ;
       
  1978 
       
  1979 
       
  1980 
       
  1981 bit_string_literal:
       
  1982   bit_string_type_name '#' integer  /* i.e. unsigned_integer */
       
  1983 	{$$ = new bit_string_literal_c($1, $3, locf(@1), locl(@3));}
       
  1984 | bit_string_type_name '#' binary_integer
       
  1985 	{$$ = new bit_string_literal_c($1, $3, locf(@1), locl(@3));}
       
  1986 | bit_string_type_name '#' octal_integer
       
  1987 	{$$ = new bit_string_literal_c($1, $3, locf(@1), locl(@3));}
       
  1988 | bit_string_type_name '#' hex_integer
       
  1989 	{$$ = new bit_string_literal_c($1, $3, locf(@1), locl(@3));}
       
  1990 /* NOTE: see note in the definition of constant for reason
       
  1991  * why unsigned_integer, binary_integer, octal_integer
       
  1992  * and hex_integer are missing here!
       
  1993  */
       
  1994 /* NOTE: see note under the B 1.2.1 section of token
       
  1995  * and grouping type definition for reason why the use of
       
  1996  * bit_string_type_name, although seemingly incorrect, is
       
  1997  * really correct here!
       
  1998  */
       
  1999 /* ERROR_CHECK_BEGIN */
       
  2000 | bit_string_type_name integer
       
  2001 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "'#' missing between bit string type name and value in bit string literal."); yynerrs++;}
       
  2002 | bit_string_type_name binary_integer
       
  2003 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "'#' missing between bit string type name and value in bit string literal."); yynerrs++;}
       
  2004 | bit_string_type_name octal_integer
       
  2005 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "'#' missing between bit string type name and value in bit string literal."); yynerrs++;}
       
  2006 | bit_string_type_name hex_integer
       
  2007 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "'#' missing between bit string type name and value in bit string literal."); yynerrs++;}
       
  2008 | bit_string_type_name '#' error
       
  2009 	{$$ = NULL;
       
  2010 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no value defined for bit string literal.");}
       
  2011 	 else {print_err_msg(locf(@3), locl(@3), "invalid value for bit string literal."); yyclearin;}
       
  2012 	 yyerrok;
       
  2013 	}
       
  2014 /* ERROR_CHECK_END */
       
  2015 ;
       
  2016 
       
  2017 
       
  2018 boolean_literal:
       
  2019   boolean_true_literal_token
       
  2020 	{$$ = new boolean_literal_c(new bool_type_name_c(locloc(@$)),
       
  2021 				    new boolean_true_c(locloc(@$)),
       
  2022 				    locloc(@$));
       
  2023 	}
       
  2024 | boolean_false_literal_token
       
  2025 	{$$ = new boolean_literal_c(new bool_type_name_c(locloc(@$)),
       
  2026 				    new boolean_false_c(locloc(@$)),
       
  2027 				    locloc(@$));
       
  2028 	}
       
  2029 | safeboolean_true_literal_token
       
  2030 	{$$ = new boolean_literal_c(new safebool_type_name_c(locloc(@$)),
       
  2031 				    new boolean_true_c(locloc(@$)),
       
  2032 				    locloc(@$));
       
  2033 	}
       
  2034 | safeboolean_false_literal_token
       
  2035 	{$$ = new boolean_literal_c(new safebool_type_name_c(locloc(@$)),
       
  2036 				    new boolean_false_c(locloc(@$)),
       
  2037 				    locloc(@$));
       
  2038 	}
       
  2039 | FALSE
       
  2040 	{$$ = new boolean_literal_c(NULL,
       
  2041 				    new boolean_false_c(locloc(@$)),
       
  2042 				    locloc(@$));
       
  2043 	}
       
  2044 | TRUE
       
  2045 	{$$ = new boolean_literal_c(NULL,
       
  2046 				    new boolean_true_c(locloc(@$)),
       
  2047 				    locloc(@$));
       
  2048 	}
       
  2049 /*
       
  2050 |	BOOL '#' '1' {}
       
  2051 |	BOOL '#' '0' {}
       
  2052 */
       
  2053 /* NOTE: the rules
       
  2054  * BOOL '#' '1'
       
  2055  * and
       
  2056  * BOOL '#' '0'
       
  2057  * do not work as expected...
       
  2058  * Consider that we are using 'BOOL' and '#' as tokens
       
  2059  * that flex hands over to bison (yacc). Because flex would
       
  2060  * then parse the single '1' or '0' as an integer,
       
  2061  * the rule in bison would have to be
       
  2062  * BOOL '#' integer, followed by verifying of the
       
  2063  * integer has the correct value!
       
  2064  *
       
  2065  * We therefore have flex return TRUE whenever it
       
  2066  * comes across 'TRUE' or 'BOOL#1', and FALSE whenever
       
  2067  * it comes across 'FALSE' or 'BOOL#0'.
       
  2068  * Note that this means that flex will parse "BOOL#01"
       
  2069  * as FALSE followed by an integer ('1').
       
  2070  * Bison should detect this as an error, so we should
       
  2071  * be OK.
       
  2072  *
       
  2073  * Another option would be to change the rules to accept
       
  2074  * BOOL '#' integer
       
  2075  * but then check whether the integer has a correct
       
  2076  * value! At the moment I feel that the first option
       
  2077  * is more straight forward.
       
  2078  */
       
  2079 ;
       
  2080 
       
  2081 
       
  2082 
       
  2083 /*******************************/
       
  2084 /* B 1.2.2 - Character Strings */
       
  2085 /*******************************/
       
  2086 /* Transform the tokens given us by flex into leafs */
       
  2087 single_byte_character_string:	single_byte_character_string_token
       
  2088 	{$$ = new single_byte_character_string_c($1, locloc(@$));};
       
  2089 
       
  2090 double_byte_character_string:	double_byte_character_string_token
       
  2091 	{$$ = new double_byte_character_string_c($1, locloc(@$));};
       
  2092 
       
  2093 
       
  2094 character_string:
       
  2095   single_byte_character_string
       
  2096 | double_byte_character_string
       
  2097 ;
       
  2098 
       
  2099 
       
  2100 
       
  2101 
       
  2102 
       
  2103 /***************************/
       
  2104 /* B 1.2.3 - Time Literals */
       
  2105 /***************************/
       
  2106 time_literal:
       
  2107   time_of_day
       
  2108 | date
       
  2109 | date_and_time
       
  2110 | duration
       
  2111 ;
       
  2112 
       
  2113 
       
  2114 /************************/
       
  2115 /* B 1.2.3.1 - Duration */
       
  2116 /************************/
       
  2117 duration:
       
  2118 /*  (T | TIME) '#' ['-'] interval */
       
  2119 /* NOTE: since TIME is also a data type, it is a keyword
       
  2120  *       and may therefore be handled by a token.
       
  2121  *
       
  2122  *       Unfortunately T is not a data type, and therefore
       
  2123  *       not a keyword. This means that we may have variables named T!
       
  2124  *       Flex cannot return the token TIME when it comes across a single T!
       
  2125  *
       
  2126  *       We therefore have flex returning the token T_SHARP
       
  2127  *       when it comes across 'T#'
       
  2128  */
       
  2129   TIME '#' interval
       
  2130 	{$$ = new duration_c(new time_type_name_c(locloc(@1)), NULL, $3, locloc(@$));}
       
  2131 | TIME '#' '-' interval
       
  2132 	{$$ = new duration_c(new time_type_name_c(locloc(@1)), new neg_time_c(locloc(@$)), $4, locloc(@$));}
       
  2133 | T_SHARP interval
       
  2134 	{$$ = new duration_c(new time_type_name_c(locloc(@1)), NULL, $2, locloc(@$));}
       
  2135 | T_SHARP '-' interval
       
  2136 	{$$ = new duration_c(new time_type_name_c(locloc(@1)), new neg_time_c(locloc(@$)), $3, locloc(@$));}
       
  2137 | SAFETIME '#' interval
       
  2138 	{$$ = new duration_c(new safetime_type_name_c(locloc(@1)), NULL, $3, locloc(@$));}
       
  2139 | SAFETIME '#' '-' interval
       
  2140 	{$$ = new duration_c(new safetime_type_name_c(locloc(@1)), new neg_time_c(locloc(@$)), $4, locloc(@$));}
       
  2141 /* ERROR_CHECK_BEGIN */
       
  2142 | TIME interval
       
  2143 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "'#' missing between 'TIME' and interval in duration."); yynerrs++;}
       
  2144 | TIME '-' interval
       
  2145 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "'#' missing between 'TIME' and interval in duration."); yynerrs++;}
       
  2146 | TIME '#' error
       
  2147 	{$$ = NULL;
       
  2148 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no value defined for duration.");}
       
  2149 	 else {print_err_msg(locf(@3), locl(@3), "invalid value for duration."); yyclearin;}
       
  2150 	 yyerrok;
       
  2151 	}
       
  2152 | T_SHARP error
       
  2153 	{$$ = NULL;
       
  2154 	 if (is_current_syntax_token()) {print_err_msg(locl(@1), locf(@2), "no value defined for duration.");}
       
  2155 	 else {print_err_msg(locf(@2), locl(@2), "invalid value for duration."); yyclearin;}
       
  2156 	 yyerrok;
       
  2157 	}
       
  2158 /* ERROR_CHECK_END */
       
  2159 ;
       
  2160 
       
  2161 
       
  2162 interval:
       
  2163   days
       
  2164 | hours
       
  2165 | minutes
       
  2166 | seconds
       
  2167 | milliseconds
       
  2168 ;
       
  2169 
       
  2170 integer_d:  integer_d_token  {$$ = new integer_c($1, locloc(@$));};
       
  2171 integer_h:  integer_h_token  {$$ = new integer_c($1, locloc(@$));};
       
  2172 integer_m:  integer_m_token  {$$ = new integer_c($1, locloc(@$));};
       
  2173 integer_s:  integer_s_token  {$$ = new integer_c($1, locloc(@$));};
       
  2174 integer_ms: integer_ms_token {$$ = new integer_c($1, locloc(@$));};
       
  2175 
       
  2176 fixed_point_d:
       
  2177   fixed_point_d_token
       
  2178 	{$$ = new fixed_point_c($1, locloc(@$));}
       
  2179 | integer_d
       
  2180 ;
       
  2181 
       
  2182 fixed_point_h:
       
  2183   fixed_point_h_token
       
  2184 	{$$ = new fixed_point_c($1, locloc(@$));}
       
  2185 | integer_h
       
  2186 ;
       
  2187 
       
  2188 fixed_point_m:
       
  2189   fixed_point_m_token
       
  2190 	{$$ = new fixed_point_c($1, locloc(@$));}
       
  2191 | integer_m
       
  2192 ;
       
  2193 
       
  2194 fixed_point_s:
       
  2195   fixed_point_s_token
       
  2196 	{$$ = new fixed_point_c($1, locloc(@$));}
       
  2197 | integer_s
       
  2198 ;
       
  2199 
       
  2200 fixed_point_ms:
       
  2201   fixed_point_ms_token
       
  2202 	{$$ = new fixed_point_c($1, locloc(@$));}
       
  2203 | integer_ms
       
  2204 ;
       
  2205 
       
  2206 
       
  2207 fixed_point:
       
  2208   fixed_point_token
       
  2209 	{$$ = new fixed_point_c($1, locloc(@$));}
       
  2210 | integer
       
  2211 ;
       
  2212 
       
  2213 
       
  2214 days:
       
  2215 /*  fixed_point ('d') */
       
  2216   fixed_point_d
       
  2217 	{$$ = new days_c($1, NULL, locloc(@$));}
       
  2218 /*| integer ('d') ['_'] hours */
       
  2219 | integer_d hours
       
  2220 	{$$ = new days_c($1, $2, locloc(@$));}
       
  2221 | integer_d '_' hours
       
  2222 	{$$ = new days_c($1, $3, locloc(@$));}
       
  2223 /* ERROR_CHECK_BEGIN */
       
  2224 | integer_d '_' error
       
  2225 	{$$ = NULL;
       
  2226 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no value defined for hours in duration.");}
       
  2227 	 else {print_err_msg(locf(@3), locl(@3), "invalid value for hours in duration."); yyclearin;}
       
  2228 	 yyerrok;
       
  2229 	}
       
  2230 /* ERROR_CHECK_END */
       
  2231 ;
       
  2232 
       
  2233 
       
  2234 hours:
       
  2235 /*  fixed_point ('h') */
       
  2236   fixed_point_h
       
  2237 	{$$ = new hours_c($1, NULL, locloc(@$));}
       
  2238 /*| integer ('h') ['_'] minutes */
       
  2239 | integer_h minutes
       
  2240 	{$$ = new hours_c($1, $2, locloc(@$));}
       
  2241 | integer_h '_' minutes
       
  2242 	{$$ = new hours_c($1, $3, locloc(@$));}
       
  2243 /* ERROR_CHECK_BEGIN */
       
  2244 | integer_h '_' error
       
  2245 	{$$ = NULL;
       
  2246 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no value defined for minutes in duration.");}
       
  2247 	 else {print_err_msg(locf(@3), locl(@3), "invalid value for minutes in duration."); yyclearin;}
       
  2248 	 yyerrok;
       
  2249 	}
       
  2250 /* ERROR_CHECK_END */
       
  2251 
       
  2252 ;
       
  2253 
       
  2254 minutes:
       
  2255 /*  fixed_point ('m') */
       
  2256   fixed_point_m
       
  2257 	{$$ = new minutes_c($1, NULL, locloc(@$));}
       
  2258 /*| integer ('m') ['_'] seconds */
       
  2259 | integer_m seconds
       
  2260 	{$$ = new minutes_c($1, $2, locloc(@$));}
       
  2261 | integer_m '_' seconds
       
  2262 	{$$ = new minutes_c($1, $3, locloc(@$));}
       
  2263 /* ERROR_CHECK_BEGIN */
       
  2264 | integer_m '_' error
       
  2265 	{$$ = NULL;
       
  2266 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no value defined for seconds in duration.");}
       
  2267 	 else {print_err_msg(locf(@3), locl(@3), "invalid value for seconds in duration."); yyclearin;}
       
  2268 	 yyerrok;
       
  2269 	}
       
  2270 /* ERROR_CHECK_END */
       
  2271 ;
       
  2272 
       
  2273 seconds:
       
  2274 /*  fixed_point ('s') */
       
  2275   fixed_point_s
       
  2276 	{$$ = new seconds_c($1, NULL, locloc(@$));}
       
  2277 /*| integer ('s') ['_'] milliseconds */
       
  2278 | integer_s milliseconds
       
  2279 	{$$ = new seconds_c($1, $2, locloc(@$));}
       
  2280 | integer_s '_' milliseconds
       
  2281 	{$$ = new seconds_c($1, $3, locloc(@$));}
       
  2282 /* ERROR_CHECK_BEGIN */
       
  2283 | integer_s '_' error
       
  2284 	{$$ = NULL;
       
  2285 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no value defined for milliseconds in duration.");}
       
  2286 	 else {print_err_msg(locf(@3), locl(@3), "invalid value for milliseconds in duration."); yyclearin;}
       
  2287 	 yyerrok;
       
  2288 	}
       
  2289 /* ERROR_CHECK_END */
       
  2290 ;
       
  2291 
       
  2292 milliseconds:
       
  2293 /*  fixed_point ('ms') */
       
  2294   fixed_point_ms
       
  2295 	{$$ = new milliseconds_c($1, locloc(@$));}
       
  2296 ;
       
  2297 
       
  2298 
       
  2299 
       
  2300 /************************************/
       
  2301 /* B 1.2.3.2 - Time of day and Date */
       
  2302 /************************************/
       
  2303 time_of_day:
       
  2304   TIME_OF_DAY '#' daytime
       
  2305 	{$$ = new time_of_day_c(new tod_type_name_c(locloc(@1)), $3, locloc(@$));}
       
  2306 | SAFETIME_OF_DAY '#' daytime
       
  2307 	{$$ = new time_of_day_c(new safetod_type_name_c(locloc(@1)), $3, locloc(@$));}
       
  2308 /* ERROR_CHECK_BEGIN */
       
  2309 | TIME_OF_DAY daytime
       
  2310 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "'#' missing between 'TIME_OF_DAY' and daytime in time of day."); yynerrs++;}
       
  2311 | TIME_OF_DAY '#' error
       
  2312 	{$$ = NULL;
       
  2313 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no value defined for time of day.");}
       
  2314 	 else {print_err_msg(locf(@3), locl(@3), "invalid value for time of day."); yyclearin;}
       
  2315 	 yyerrok;
       
  2316 	}
       
  2317 /* ERROR_CHECK_END */
       
  2318 ;
       
  2319 
       
  2320 
       
  2321 daytime:
       
  2322   day_hour ':' day_minute ':' day_second
       
  2323 	{$$ = new daytime_c($1, $3, $5, locloc(@$));}
       
  2324 /* ERROR_CHECK_BEGIN */
       
  2325 | ':' day_minute ':' day_second
       
  2326   {$$ = NULL; print_err_msg(locf(@1), locl(@4), "no value defined for hours in daytime."); yynerrs++;}
       
  2327 | error ':' day_minute ':' day_second
       
  2328   {$$ = NULL; print_err_msg(locf(@1), locl(@1), "invalid value defined for hours in daytime."); yyerrok;}
       
  2329 | day_hour day_minute ':' day_second
       
  2330   {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between hours and minutes in daytime."); yynerrs++;}
       
  2331 | day_hour ':' ':' day_second
       
  2332 	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "no value defined for minutes in daytime."); yynerrs++;}
       
  2333 | day_hour ':' error ':' day_second
       
  2334 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid value defined for minutes in daytime."); yyerrok;}
       
  2335 | day_hour ':' day_minute day_second
       
  2336   {$$ = NULL; print_err_msg(locl(@3), locf(@4), "':' missing between minutes and seconds in daytime."); yynerrs++;}
       
  2337 | day_hour ':' day_minute ':' error
       
  2338   {$$ = NULL;
       
  2339 	 if (is_current_syntax_token()) {print_err_msg(locl(@4), locf(@5), "no value defined for seconds in daytime.");}
       
  2340 	 else {print_err_msg(locf(@5), locl(@5), "invalid value for seconds in daytime."); yyclearin;}
       
  2341 	 yyerrok;
       
  2342 	}
       
  2343 /* ERROR_CHECK_END */
       
  2344 ;
       
  2345 
       
  2346 
       
  2347 day_hour: integer;
       
  2348 day_minute: integer;
       
  2349 day_second: fixed_point;
       
  2350 
       
  2351 
       
  2352 date:
       
  2353   DATE '#' date_literal
       
  2354 	{$$ = new date_c(new date_type_name_c(locloc(@1)), $3, locloc(@$));}
       
  2355 | D_SHARP date_literal
       
  2356 	{$$ = new date_c(new date_type_name_c(locloc(@1)), $2, locloc(@$));}
       
  2357 | SAFEDATE '#' date_literal
       
  2358 	{$$ = new date_c(new safedate_type_name_c(locloc(@1)), $3, locloc(@$));}
       
  2359 /* ERROR_CHECK_BEGIN */
       
  2360 | DATE date_literal
       
  2361 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "'#' missing between 'DATE' and date literal in date."); yynerrs++;}
       
  2362 | DATE '#' error
       
  2363 	{$$ = NULL;
       
  2364 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no value defined for date.");}
       
  2365 	 else {print_err_msg(locf(@3), locl(@3), "invalid value for date."); yyclearin;}
       
  2366 	 yyerrok;
       
  2367 	}
       
  2368 | D_SHARP error
       
  2369   {$$ = NULL;
       
  2370 	 if (is_current_syntax_token()) {print_err_msg(locl(@1), locf(@2), "no value defined for date.");}
       
  2371 	 else {print_err_msg(locf(@2), locl(@2), "invalid value for date."); yyclearin;}
       
  2372 	 yyerrok;
       
  2373 	}
       
  2374 /* ERROR_CHECK_END */
       
  2375 ;
       
  2376 
       
  2377 
       
  2378 date_literal:
       
  2379   year '-' month '-' day
       
  2380 	{$$ = new date_literal_c($1, $3, $5, locloc(@$));}
       
  2381 /* ERROR_CHECK_BEGIN */
       
  2382 | '-' month '-' day
       
  2383   {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no value defined for year in date literal."); yynerrs++;}
       
  2384 | year month '-' day
       
  2385   {$$ = NULL; print_err_msg(locl(@1), locf(@2), "'-' missing between year and month in date literal."); yynerrs++;}
       
  2386 | year '-' '-' day
       
  2387 	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "no value defined for month in date literal."); yynerrs++;}
       
  2388 | year '-' error '-' day
       
  2389 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid value defined for month in date literal."); yyerrok;}
       
  2390 | year '-' month day
       
  2391   {$$ = NULL; print_err_msg(locl(@3), locf(@4), "'-' missing between month and day in date literal."); yynerrs++;}
       
  2392 | year '-' month '-' error
       
  2393   {$$ = NULL;
       
  2394 	 if (is_current_syntax_token()) {print_err_msg(locl(@4), locf(@5), "no value defined for day in date literal.");}
       
  2395 	 else {print_err_msg(locf(@5), locl(@5), "invalid value for day in date literal."); yyclearin;}
       
  2396 	 yyerrok;
       
  2397 	}
       
  2398 /* ERROR_CHECK_END */
       
  2399 ;
       
  2400 
       
  2401 
       
  2402 year: integer;
       
  2403 month: integer;
       
  2404 day: integer;
       
  2405 
       
  2406 
       
  2407 date_and_time:
       
  2408   DATE_AND_TIME '#' date_literal '-' daytime
       
  2409 	{$$ = new date_and_time_c(new dt_type_name_c(locloc(@1)), $3, $5, locloc(@$));}
       
  2410 | SAFEDATE_AND_TIME '#' date_literal '-' daytime
       
  2411 	{$$ = new date_and_time_c(new safedt_type_name_c(locloc(@1)), $3, $5, locloc(@$));}
       
  2412 /* ERROR_CHECK_BEGIN */
       
  2413 | DATE_AND_TIME date_literal '-' daytime
       
  2414 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "'#' missing between 'DATE_AND_TIME' and date literal in date and time."); yynerrs++;}
       
  2415 | DATE_AND_TIME '#' '-' daytime
       
  2416 	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "no value defined for date literal in date and time."); yynerrs++;}
       
  2417 | DATE_AND_TIME '#' error '-' daytime
       
  2418 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid value for date literal in date and time."); yyerrok;}
       
  2419 | DATE_AND_TIME '#' date_literal daytime
       
  2420 	{$$ = NULL; print_err_msg(locl(@3), locf(@4), "'-' missing between date literal and daytime in date and time."); yynerrs++;}
       
  2421 | DATE_AND_TIME '#' date_literal '-' error
       
  2422 	{$$ = NULL;
       
  2423 	 if (is_current_syntax_token()) {print_err_msg(locl(@4), locf(@5), "no value defined for daytime in date and time.");}
       
  2424 	 else {print_err_msg(locf(@5), locl(@5), "invalid value for daytime in date and time."); yyclearin;}
       
  2425 	 yyerrok;
       
  2426 	}
       
  2427 /* ERROR_CHECK_END */
       
  2428 ;
       
  2429 
       
  2430 
       
  2431 
       
  2432 
       
  2433 
       
  2434 
       
  2435 /**********************/
       
  2436 /* B 1.3 - Data Types */
       
  2437 /**********************/
       
  2438 /* Strangely, the following symbol does seem to be required! */
       
  2439 /*
       
  2440 data_type_name:
       
  2441   non_generic_type_name
       
  2442 | generic_type_name
       
  2443 ;
       
  2444 */
       
  2445 
       
  2446 non_generic_type_name:
       
  2447   elementary_type_name
       
  2448 | derived_type_name
       
  2449 ;
       
  2450 
       
  2451 
       
  2452 
       
  2453 /***********************************/
       
  2454 /* B 1.3.1 - Elementary Data Types */
       
  2455 /***********************************/
       
  2456     /******************************************************/
       
  2457     /* SAFExxxx Symbols defined in                        */
       
  2458     /* "Safety Software Technical Specification,          */
       
  2459     /*  Part 1: Concepts and Function Blocks,             */
       
  2460     /*  Version 1.0 – Official Release"                   */
       
  2461     /* by PLCopen - Technical Committee 5 - 2006-01-31    */
       
  2462     /******************************************************/
       
  2463 
       
  2464 elementary_type_name:
       
  2465   numeric_type_name
       
  2466 | date_type_name
       
  2467 | bit_string_type_name
       
  2468 | elementary_string_type_name
       
  2469 | TIME		{$$ = new time_type_name_c(locloc(@$));}
       
  2470 | BOOL		{$$ = new bool_type_name_c(locloc(@$));}
       
  2471 /* NOTE: see note under the B 1.2.1 section of token
       
  2472  * and grouping type definition for reason why BOOL
       
  2473  * was added to this definition.
       
  2474  */
       
  2475 | SAFETIME	{$$ = new safetime_type_name_c(locloc(@$));}
       
  2476 | SAFEBOOL	{$$ = new safebool_type_name_c(locloc(@$));}
       
  2477 ;
       
  2478 
       
  2479 numeric_type_name:
       
  2480   integer_type_name
       
  2481 | real_type_name
       
  2482 ;
       
  2483 
       
  2484 integer_type_name:
       
  2485   signed_integer_type_name
       
  2486 | unsigned_integer_type_name
       
  2487 ;
       
  2488 
       
  2489 signed_integer_type_name:
       
  2490   SINT		{$$ = new sint_type_name_c(locloc(@$));}
       
  2491 | INT		{$$ = new int_type_name_c(locloc(@$));}
       
  2492 | DINT		{$$ = new dint_type_name_c(locloc(@$));}
       
  2493 | LINT		{$$ = new lint_type_name_c(locloc(@$));}
       
  2494 | SAFESINT	{$$ = new safesint_type_name_c(locloc(@$));}
       
  2495 | SAFEINT	{$$ = new safeint_type_name_c(locloc(@$));}
       
  2496 | SAFEDINT	{$$ = new safedint_type_name_c(locloc(@$));}
       
  2497 | SAFELINT	{$$ = new safelint_type_name_c(locloc(@$));}
       
  2498 ;
       
  2499 
       
  2500 unsigned_integer_type_name:
       
  2501   USINT		{$$ = new usint_type_name_c(locloc(@$));}
       
  2502 | UINT		{$$ = new uint_type_name_c(locloc(@$));}
       
  2503 | UDINT		{$$ = new udint_type_name_c(locloc(@$));}
       
  2504 | ULINT		{$$ = new ulint_type_name_c(locloc(@$));}
       
  2505 | SAFEUSINT	{$$ = new safeusint_type_name_c(locloc(@$));}
       
  2506 | SAFEUINT	{$$ = new safeuint_type_name_c(locloc(@$));}
       
  2507 | SAFEUDINT	{$$ = new safeudint_type_name_c(locloc(@$));}
       
  2508 | SAFEULINT	{$$ = new safeulint_type_name_c(locloc(@$));}
       
  2509 ;
       
  2510 
       
  2511 real_type_name:
       
  2512   REAL		{$$ = new real_type_name_c(locloc(@$));}
       
  2513 | LREAL		{$$ = new lreal_type_name_c(locloc(@$));}
       
  2514 | SAFEREAL	{$$ = new safereal_type_name_c(locloc(@$));}
       
  2515 | SAFELREAL	{$$ = new safelreal_type_name_c(locloc(@$));}
       
  2516 ;
       
  2517 
       
  2518 date_type_name:
       
  2519   DATE			{$$ = new date_type_name_c(locloc(@$));}
       
  2520 | TIME_OF_DAY		{$$ = new tod_type_name_c(locloc(@$));}
       
  2521 | TOD			{$$ = new tod_type_name_c(locloc(@$));}
       
  2522 | DATE_AND_TIME		{$$ = new dt_type_name_c(locloc(@$));}
       
  2523 | DT			{$$ = new dt_type_name_c(locloc(@$));}
       
  2524 | SAFEDATE		{$$ = new safedate_type_name_c(locloc(@$));}
       
  2525 | SAFETIME_OF_DAY	{$$ = new safetod_type_name_c(locloc(@$));}
       
  2526 | SAFETOD		{$$ = new safetod_type_name_c(locloc(@$));}
       
  2527 | SAFEDATE_AND_TIME	{$$ = new safedt_type_name_c(locloc(@$));}
       
  2528 | SAFEDT		{$$ = new safedt_type_name_c(locloc(@$));}
       
  2529 ;
       
  2530 
       
  2531 
       
  2532 bit_string_type_name:
       
  2533   BYTE		{$$ = new byte_type_name_c(locloc(@$));}
       
  2534 | WORD		{$$ = new word_type_name_c(locloc(@$));}
       
  2535 | DWORD		{$$ = new dword_type_name_c(locloc(@$));}
       
  2536 | LWORD		{$$ = new lword_type_name_c(locloc(@$));}
       
  2537 | SAFEBYTE	{$$ = new safebyte_type_name_c(locloc(@$));}
       
  2538 | SAFEWORD	{$$ = new safeword_type_name_c(locloc(@$));}
       
  2539 | SAFEDWORD	{$$ = new safedword_type_name_c(locloc(@$));}
       
  2540 | SAFELWORD	{$$ = new safelword_type_name_c(locloc(@$));}
       
  2541 /* NOTE: see note under the B 1.2.1 section of token
       
  2542  * and grouping type definition for reason why the BOOL
       
  2543  * was omitted from this definition.
       
  2544  */
       
  2545 ;
       
  2546 
       
  2547 
       
  2548 /* Helper symbol to concentrate the instantiation
       
  2549  * of STRING and WSTRING into a single location.
       
  2550  *
       
  2551  * These two elements show up in several other rules,
       
  2552  * but we want to create the equivalent abstract syntax
       
  2553  * in a single location of this file, in order to make
       
  2554  * possible future changes easier to edit...
       
  2555  */
       
  2556 elementary_string_type_name:
       
  2557   STRING	{$$ = new string_type_name_c(locloc(@$));}
       
  2558 | WSTRING	{$$ = new wstring_type_name_c(locloc(@$));}
       
  2559 | SAFESTRING	{$$ = new safestring_type_name_c(locloc(@$));}
       
  2560 | SAFEWSTRING	{$$ = new safewstring_type_name_c(locloc(@$));}
       
  2561 ;
       
  2562 
       
  2563 
       
  2564 
       
  2565 /********************************/
       
  2566 /* B 1.3.2 - Generic data types */
       
  2567 /********************************/
       
  2568 /* Strangely, the following symbol does not seem to be required! */
       
  2569 /*
       
  2570 generic_type_name:
       
  2571   ANY
       
  2572 | ANY_DERIVED
       
  2573 | ANY_ELEMENTARY
       
  2574 | ANY_MAGNITUDE
       
  2575 | ANY_NUM
       
  2576 | ANY_REAL
       
  2577 | ANY_INT
       
  2578 | ANY_BIT
       
  2579 | ANY_STRING
       
  2580 | ANY_DATE
       
  2581 ;
       
  2582 */
       
  2583 
       
  2584 
       
  2585 /********************************/
       
  2586 /* B 1.3.3 - Derived data types */
       
  2587 /********************************/
       
  2588 
       
  2589 derived_type_name:
       
  2590   single_element_type_name
       
  2591 | prev_declared_array_type_name
       
  2592 | prev_declared_structure_type_name
       
  2593 | prev_declared_string_type_name
       
  2594 ;
       
  2595 
       
  2596 single_element_type_name:
       
  2597   prev_declared_simple_type_name
       
  2598 /* Include the following if arrays of function blocks are to be allowed!
       
  2599  * Since the standard does not allow them,
       
  2600  * we leave it commented out for the time being...
       
  2601  */
       
  2602 //| prev_declared_derived_function_block_name
       
  2603 | prev_declared_subrange_type_name
       
  2604 | prev_declared_enumerated_type_name
       
  2605 ;
       
  2606 
       
  2607 /* NOTE: in order to remove a reduce/reduce conflict,
       
  2608  *       all occurences of simple_type_name, etc...
       
  2609  *       have been replaced with identifier!
       
  2610  */
       
  2611 /*
       
  2612 simple_type_name: identifier;
       
  2613 subrange_type_name: identifier;
       
  2614 enumerated_type_name: identifier;
       
  2615 array_type_name: identifier;
       
  2616 structure_type_name: identifier;
       
  2617 */
       
  2618 
       
  2619 data_type_declaration:
       
  2620   TYPE type_declaration_list END_TYPE
       
  2621 	{$$ = new data_type_declaration_c($2, locloc(@$));}
       
  2622 /* ERROR_CHECK_BEGIN */
       
  2623 | TYPE END_TYPE
       
  2624 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "no data type declared in data type(s) declaration."); yynerrs++;}
       
  2625 | TYPE error type_declaration_list END_TYPE
       
  2626 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "unexpected token after 'TYPE' in data type(s) declaration."); yyerrok;}
       
  2627 | TYPE type_declaration_list error END_OF_INPUT
       
  2628 	{$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed data type(s) declaration."); yyerrok;}
       
  2629 | TYPE error END_TYPE
       
  2630 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in data type(s) declaration."); yyerrok;}
       
  2631 /* ERROR_CHECK_END */
       
  2632 ;
       
  2633 
       
  2634 /* helper symbol for data_type_declaration */
       
  2635 type_declaration_list:
       
  2636   type_declaration ';'
       
  2637 	{$$ = new type_declaration_list_c(locloc(@$)); $$->add_element($1);}
       
  2638 | type_declaration_list type_declaration ';'
       
  2639 	{$$ = $1; $$->add_element($2);}
       
  2640 /* ERROR_CHECK_BEGIN */
       
  2641 | error ';'
       
  2642 	{$$ = new type_declaration_list_c(locloc(@$)); print_err_msg(locf(@1), locl(@1), "invalid data type declaration."); yyerrok;}
       
  2643 | type_declaration error
       
  2644 	{$$ = new type_declaration_list_c(locloc(@$)); print_err_msg(locl(@1), locf(@2), "';' missing at end of data type declaration."); yyerrok;}
       
  2645 | type_declaration_list type_declaration error
       
  2646 	{$$ = $1; print_err_msg(locl(@2), locf(@3), "';' missing at end of data type declaration."); yyerrok;}
       
  2647 | type_declaration_list error ';'
       
  2648 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "invalid data type declaration."); yyerrok;}
       
  2649 | type_declaration_list ';'
       
  2650 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected ';' after data type declaration."); yynerrs++;}
       
  2651 /* ERROR_CHECK_END */
       
  2652 ;
       
  2653 
       
  2654 type_declaration:
       
  2655   single_element_type_declaration
       
  2656 | array_type_declaration
       
  2657 | structure_type_declaration
       
  2658 | string_type_declaration
       
  2659 ;
       
  2660 
       
  2661 single_element_type_declaration:
       
  2662   simple_type_declaration
       
  2663 | subrange_type_declaration
       
  2664 | enumerated_type_declaration
       
  2665 ;
       
  2666 
       
  2667 simple_type_declaration:
       
  2668 /*  simple_type_name ':' simple_spec_init */
       
  2669   identifier ':' simple_spec_init
       
  2670 	{$$ = new simple_type_declaration_c($1, $3, locloc(@$));
       
  2671 	 library_element_symtable.insert($1, prev_declared_simple_type_name_token);
       
  2672 	}
       
  2673 /* ERROR_CHECK_BEGIN */
       
  2674 | error ':' simple_spec_init
       
  2675 	{$$ = NULL; print_err_msg(locf(@1), locl(@1), "invalid name defined for data type declaration.");yyerrok;}
       
  2676 | identifier simple_spec_init
       
  2677 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between data type name and specification in simple type declaration."); yynerrs++;}
       
  2678 | identifier ':' error
       
  2679 	{$$ = NULL;
       
  2680 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no specification defined in data type declaration.");}
       
  2681 	 else {print_err_msg(locf(@3), locl(@3), "invalid specification in data type declaration."); yyclearin;}
       
  2682 	 yyerrok;
       
  2683 	}
       
  2684 /* ERROR_CHECK_END */
       
  2685 ;
       
  2686 
       
  2687 
       
  2688 simple_spec_init:
       
  2689   simple_specification
       
  2690   /* The following commented line was changed to the 
       
  2691    * next two lines so that we wouldn't
       
  2692    * have the first element of a simple_spec_init_c()
       
  2693    * pointing to another simple_spec_init_c!
       
  2694    */
       
  2695 /*
       
  2696 | simple_specification ASSIGN constant
       
  2697 	{$$ = new simple_spec_init_c($1, $3);}
       
  2698 */
       
  2699 | elementary_type_name ASSIGN constant
       
  2700 	{$$ = new simple_spec_init_c($1, $3, locloc(@$));}
       
  2701 | prev_declared_simple_type_name ASSIGN constant
       
  2702 	{$$ = new simple_spec_init_c($1, $3, locloc(@$));}
       
  2703 /* ERROR_CHECK_BEGIN */
       
  2704 | elementary_type_name constant
       
  2705 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':=' missing in specification with initialization."); yynerrs++;}
       
  2706 | prev_declared_simple_type_name constant
       
  2707 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':=' missing in specification with initialization."); yynerrs++;}
       
  2708 | elementary_type_name ASSIGN error
       
  2709 	{$$ = NULL;
       
  2710 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no initial value defined in specification with initialization.");}
       
  2711 	 else {print_err_msg(locf(@3), locl(@3), "invalid initial value in specification with initialization."); yyclearin;}
       
  2712 	 yyerrok;
       
  2713 	}
       
  2714 | prev_declared_simple_type_name ASSIGN error
       
  2715 	{$$ = NULL;
       
  2716 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no initial value defined in specification with initialization.");}
       
  2717 	 else {print_err_msg(locf(@3), locl(@3), "invalid initial value in specification with initialization."); yyclearin;}
       
  2718 	 yyerrok;
       
  2719 	}
       
  2720 /* ERROR_CHECK_END */
       
  2721 ;
       
  2722 
       
  2723 /* When converting to C/C++, we need to know whether
       
  2724  * the elementary_type_name is being used in a variable
       
  2725  * declaration or elsewhere (ex. declaration of a derived
       
  2726  * type), so the abstract syntax has the elementary_type_name
       
  2727  * wrapped inside a simple_spec_init_c.
       
  2728  * The exact same thing occurs with prev_declared_simple_type_name.
       
  2729  *
       
  2730  * This is why in the definition of simple_spec_init,
       
  2731  * simple_specification was brocken up into its
       
  2732  * constituent components...
       
  2733  */
       
  2734 simple_specification:
       
  2735 // elementary_type_name | simple_type_name
       
  2736   elementary_type_name
       
  2737 	{$$ = new simple_spec_init_c($1, NULL, locloc(@$));}
       
  2738 | prev_declared_simple_type_name
       
  2739 	{$$ = new simple_spec_init_c($1, NULL, locloc(@$));}
       
  2740 ;
       
  2741 
       
  2742 
       
  2743 subrange_type_declaration:
       
  2744 /*  subrange_type_name ':' subrange_spec_init */
       
  2745   identifier ':' subrange_spec_init
       
  2746 	{$$ = new subrange_type_declaration_c($1, $3, locloc(@$));
       
  2747 	 library_element_symtable.insert($1, prev_declared_subrange_type_name_token);
       
  2748 	}
       
  2749 /* ERROR_CHECK_BEGIN */
       
  2750 | error ':' subrange_spec_init
       
  2751 	{$$ = NULL; print_err_msg(locf(@1), locl(@1), "invalid name defined for subrange type declaration."); yyerrok;}
       
  2752 | identifier subrange_spec_init
       
  2753 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between data type name and specification in subrange type declaration."); yynerrs++;}
       
  2754 /* ERROR_CHECK_END */
       
  2755 ;
       
  2756 
       
  2757 subrange_spec_init:
       
  2758   subrange_specification
       
  2759 	{$$ = new subrange_spec_init_c($1, NULL, locloc(@$));}
       
  2760 | subrange_specification ASSIGN signed_integer
       
  2761 	{$$ = new subrange_spec_init_c($1, $3, locloc(@$));}
       
  2762 /* ERROR_CHECK_BEGIN */
       
  2763 | subrange_specification signed_integer
       
  2764 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':=' missing in subrange specification with initialization."); yynerrs++;}
       
  2765 | subrange_specification ASSIGN error
       
  2766 	{$$ = NULL;
       
  2767 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no initial value defined in subrange specification with initialization.");}
       
  2768 	 else {print_err_msg(locf(@3), locl(@3), "invalid initial value in subrange specification with initialization."); yyclearin;}
       
  2769 	 yyerrok;
       
  2770 	}
       
  2771 /* ERROR_CHECK_END */
       
  2772 ;
       
  2773 
       
  2774 subrange_specification:
       
  2775   integer_type_name '(' subrange ')'
       
  2776 	{$$ = new subrange_specification_c($1, $3, locloc(@$));}
       
  2777 | prev_declared_subrange_type_name
       
  2778   {$$ = new subrange_specification_c($1, NULL, locloc(@$));}
       
  2779 /* ERROR_CHECK_BEGIN */
       
  2780 | integer_type_name '(' ')'
       
  2781 	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "no subrange defined in subrange specification."); yynerrs++;}
       
  2782 | integer_type_name '(' error ')'
       
  2783 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid subrange defined in subrange specification."); yyerrok;}
       
  2784 | integer_type_name '(' subrange error
       
  2785 	{$$ = NULL; print_err_msg(locl(@3), locf(@4), "')' missing after subrange defined in subrange specification."); yyerrok;}
       
  2786 /* ERROR_CHECK_END */
       
  2787 ;
       
  2788 
       
  2789 
       
  2790 subrange:
       
  2791   signed_integer DOTDOT signed_integer
       
  2792 	{$$ = new subrange_c($1, $3, locloc(@$));}
       
  2793 /* ERROR_CHECK_BEGIN */
       
  2794 | signed_integer signed_integer
       
  2795 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "'..' missing between bounds in subrange definition."); yynerrs++;}
       
  2796 | signed_integer DOTDOT error
       
  2797 	{$$ = NULL;
       
  2798 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no value defined for upper bound in subrange definition.");}
       
  2799 	 else {print_err_msg(locf(@3), locl(@3), "invalid value for upper bound in subrange definition."); yyclearin;}
       
  2800 	 yyerrok;
       
  2801 	}
       
  2802 /* ERROR_CHECK_END */
       
  2803 ;
       
  2804 
       
  2805 enumerated_type_declaration:
       
  2806 /*  enumerated_type_name ':' enumerated_spec_init */
       
  2807   identifier ':' enumerated_spec_init
       
  2808 	{$$ = new enumerated_type_declaration_c($1, $3, locloc(@$));
       
  2809 	 library_element_symtable.insert($1, prev_declared_enumerated_type_name_token);
       
  2810 	}
       
  2811 /* ERROR_CHECK_BEGIN */
       
  2812 | error ':' enumerated_spec_init
       
  2813 	{$$ = NULL; print_err_msg(locf(@1), locl(@1), "invalid name defined for enumerated type declaration."); yyerrok;}
       
  2814 | identifier enumerated_spec_init
       
  2815 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between data type name and specification in enumerated type declaration."); yynerrs++;}
       
  2816 /* ERROR_CHECK_END */
       
  2817 ;
       
  2818 
       
  2819 
       
  2820 enumerated_spec_init:
       
  2821   enumerated_specification
       
  2822 	{$$ = new enumerated_spec_init_c($1, NULL, locloc(@$));}
       
  2823 | enumerated_specification ASSIGN enumerated_value
       
  2824 	{$$ = new enumerated_spec_init_c($1, $3, locloc(@$));}
       
  2825 /* ERROR_CHECK_BEGIN */
       
  2826 | enumerated_specification enumerated_value
       
  2827 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':=' missing in enumerated specification with initialization."); yynerrs++;}
       
  2828 | enumerated_specification ASSIGN error
       
  2829 	{$$ = NULL;
       
  2830 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no value defined in enumerated specification with initialization.");}
       
  2831 	 else {print_err_msg(locf(@3), locl(@3), "invalid value in enumerated specification with initialization."); yyclearin;}
       
  2832 	 yyerrok;
       
  2833 	}
       
  2834 /* ERROR_CHECK_END */
       
  2835 ;
       
  2836 
       
  2837 enumerated_specification:
       
  2838   '(' enumerated_value_list ')'
       
  2839 	{$$ = $2;}
       
  2840 | prev_declared_enumerated_type_name
       
  2841 /* ERROR_CHECK_BEGIN */
       
  2842 | '(' ')'
       
  2843 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "no enumerated value list defined in enumerated specification."); yynerrs++;}
       
  2844 | '(' error ')'
       
  2845 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid enumerated value list defined in enumerated specification.");yyerrok;}
       
  2846 | '(' enumerated_value_list error
       
  2847 	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "')' missing at the end of enumerated specification."); yyerrok;}
       
  2848 /* ERROR_CHECK_END */
       
  2849 ;
       
  2850 
       
  2851 /* helper symbol for enumerated_specification */
       
  2852 enumerated_value_list:
       
  2853   enumerated_value
       
  2854 	{$$ = new enumerated_value_list_c(locloc(@$)); $$->add_element($1);}
       
  2855 | enumerated_value_list ',' enumerated_value
       
  2856 	{$$ = $1; $$->add_element($3);}
       
  2857 /* ERROR_CHECK_BEGIN */
       
  2858 | enumerated_value_list enumerated_value
       
  2859 	{$$ = $1; print_err_msg(locl(@1), locf(@2), "',' missing in enumerated value list.");}
       
  2860 | enumerated_value_list ',' error
       
  2861 	{$$ = $1;
       
  2862 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no value defined in enumerated value list.");}
       
  2863 	 else {print_err_msg(locf(@3), locl(@3), "invalid value in enumerated value list."); yyclearin;}
       
  2864 	 yyerrok;
       
  2865 	}
       
  2866 /* ERROR_CHECK_END */
       
  2867 ;
       
  2868 
       
  2869 
       
  2870 enumerated_value:
       
  2871   identifier 
       
  2872   {$$ = new enumerated_value_c(NULL, $1, locloc(@$));}
       
  2873 | prev_declared_enumerated_type_name '#' any_identifier
       
  2874 	{$$ = new enumerated_value_c($1, $3, locloc(@$));}
       
  2875 /* ERROR_CHECK_BEGIN */
       
  2876 | prev_declared_enumerated_type_name any_identifier
       
  2877 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "'#' missing between enumerated type name and value in enumerated literal."); yynerrs++;}
       
  2878 | prev_declared_enumerated_type_name '#' error
       
  2879 	{$$ = NULL;
       
  2880 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no value defined for enumerated literal.");}
       
  2881 	 else {print_err_msg(locf(@3), locl(@3), "invalid value for enumerated literal."); yyclearin;}
       
  2882 	 yyerrok;
       
  2883 	}
       
  2884 /* ERROR_CHECK_END */
       
  2885 ;
       
  2886 
       
  2887 
       
  2888 /*
       
  2889 enumerated_value_without_identifier:
       
  2890   prev_declared_enumerated_type_name '#' any_identifier
       
  2891 	{$$ = new enumerated_value_c($1, $3, locloc(@$));}
       
  2892 ;
       
  2893 */
       
  2894 
       
  2895 
       
  2896 array_type_declaration:
       
  2897 /*  array_type_name ':' array_spec_init */
       
  2898   identifier ':' array_spec_init
       
  2899 	{$$ = new array_type_declaration_c($1, $3, locloc(@$));
       
  2900 	 library_element_symtable.insert($1, prev_declared_array_type_name_token);
       
  2901 	}
       
  2902 /* ERROR_CHECK_BEGIN */
       
  2903 | identifier array_spec_init
       
  2904 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between data type name and specification in array type declaration."); yynerrs++;}
       
  2905 /* ERROR_CHECK_END */
       
  2906 ;
       
  2907 
       
  2908 array_spec_init:
       
  2909   array_specification
       
  2910 	{$$ = new array_spec_init_c($1, NULL, locloc(@$));}
       
  2911 | array_specification ASSIGN array_initialization
       
  2912 	{$$ = new array_spec_init_c($1, $3, locloc(@$));}
       
  2913 /* ERROR_CHECK_BEGIN */
       
  2914 | array_specification array_initialization
       
  2915 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':=' missing in array specification with initialization."); yynerrs++;}
       
  2916 | array_specification ASSIGN error
       
  2917 	{$$ = NULL;
       
  2918 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no initial value defined in array specification with initialization.");}
       
  2919 	 else {print_err_msg(locf(@3), locl(@3), "invalid initial value in array specification with initialization."); yyclearin;}
       
  2920 	 yyerrok;
       
  2921 	}
       
  2922 /* ERROR_CHECK_END */
       
  2923 ;
       
  2924 
       
  2925 
       
  2926 array_specification:
       
  2927   prev_declared_array_type_name
       
  2928 | ARRAY '[' array_subrange_list ']' OF non_generic_type_name
       
  2929 	{$$ = new array_specification_c($3, $6, locloc(@$));}
       
  2930 /* ERROR_CHECK_BEGIN */
       
  2931 | ARRAY array_subrange_list ']' OF non_generic_type_name
       
  2932 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "'[' missing before subrange list in array specification."); yynerrs++;}
       
  2933 | ARRAY '[' ']' OF non_generic_type_name
       
  2934 	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "no subrange list defined in array specification."); yynerrs++;}
       
  2935 | ARRAY '[' error ']' OF non_generic_type_name
       
  2936 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid subrange list defined in array specification."); yyerrok;}
       
  2937 | ARRAY OF non_generic_type_name
       
  2938 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "no subrange list defined in array specification."); yynerrs++;}
       
  2939 | ARRAY error OF non_generic_type_name
       
  2940 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid subrange list defined in array specification."); yyerrok;}
       
  2941 | ARRAY '[' array_subrange_list OF non_generic_type_name
       
  2942 	{$$ = NULL; print_err_msg(locl(@3), locf(@4), "']' missing after subrange list in array specification."); yynerrs++;}
       
  2943 | ARRAY '[' array_subrange_list ']' non_generic_type_name
       
  2944 	{$$ = NULL; print_err_msg(locl(@4), locf(@5), "'OF' missing between subrange list and item type name in array specification."); yynerrs++;}
       
  2945 | ARRAY '[' array_subrange_list ']' OF error
       
  2946 	{$$ = NULL;
       
  2947 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no item data type defined in array specification.");}
       
  2948 	 else {print_err_msg(locf(@3), locl(@3), "invalid item data type in array specification."); yyclearin;}
       
  2949 	 yyerrok;
       
  2950 	}
       
  2951 /* ERROR_CHECK_END */
       
  2952 ;
       
  2953 
       
  2954 /* helper symbol for array_specification */
       
  2955 array_subrange_list:
       
  2956   subrange
       
  2957 	{$$ = new array_subrange_list_c(locloc(@$)); $$->add_element($1);}
       
  2958 | array_subrange_list ',' subrange
       
  2959 	{$$ = $1; $$->add_element($3);}
       
  2960 /* ERROR_CHECK_BEGIN */
       
  2961 | array_subrange_list subrange
       
  2962 	{$$ = $1; print_err_msg(locl(@1), locf(@2), "',' missing in subrange list."); yynerrs++;}
       
  2963 | array_subrange_list ',' error
       
  2964 	{$$ = $1;
       
  2965 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no subrange defined in subrange list.");}
       
  2966 	 else {print_err_msg(locf(@3), locl(@3), "invalid subrange in subrange list."); yyclearin;}
       
  2967 	 yyerrok;
       
  2968 	}
       
  2969 /* ERROR_CHECK_END */
       
  2970 ;
       
  2971 
       
  2972 
       
  2973 array_initialization:
       
  2974   '[' array_initial_elements_list ']'
       
  2975 	{$$ = $2;}
       
  2976 /* ERROR_CHECK_BEGIN */
       
  2977 | '[' ']'
       
  2978 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "no initial values list defined in array initialization."); yynerrs++;}
       
  2979 | '[' error ']'
       
  2980 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid initial values list defined in array initialization."); yyerrok;}
       
  2981 | '[' array_initial_elements_list error
       
  2982 	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "']' missing at the end of array initialization."); yyerrok;}
       
  2983 /* ERROR_CHECK_END */
       
  2984 ;
       
  2985 
       
  2986 
       
  2987 /* helper symbol for array_initialization */
       
  2988 array_initial_elements_list:
       
  2989   array_initial_elements
       
  2990 	{$$ = new array_initial_elements_list_c(locloc(@$)); $$->add_element($1);}
       
  2991 | array_initial_elements_list ',' array_initial_elements
       
  2992 	{$$ = $1; $$->add_element($3);}
       
  2993 /* ERROR_CHECK_BEGIN 
       
  2994 | array_initial_elements_list ',' error
       
  2995 	{$$ = $1;
       
  2996 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no array initial value in array initial values list.");}
       
  2997 	 else {print_err_msg(locf(@3), locl(@3), "invalid array initial value in array initial values list."); yyclearin;}
       
  2998 	 yyerrok;
       
  2999 	}
       
  3000 /* ERROR_CHECK_END */
       
  3001 ;
       
  3002 
       
  3003 
       
  3004 array_initial_elements:
       
  3005   array_initial_element
       
  3006 | integer '(' ')'
       
  3007 | integer '(' array_initial_element ')'
       
  3008 	{$$ = new array_initial_elements_c($1, $3, locloc(@$));}
       
  3009 /* ERROR_CHECK_BEGIN */
       
  3010 | integer '(' error ')'
       
  3011 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid array initial value in array initial values list."); yyerrok;}
       
  3012 | integer '(' array_initial_element error
       
  3013 	{$$ = NULL; print_err_msg(locl(@3), locf(@4), "')' missing at the end of array initial value in array initial values list."); yyerrok;}
       
  3014 /* ERROR_CHECK_END */
       
  3015 ;
       
  3016 
       
  3017 
       
  3018 array_initial_element:
       
  3019   constant
       
  3020 | enumerated_value
       
  3021 | structure_initialization
       
  3022 | array_initialization
       
  3023 ;
       
  3024 
       
  3025 
       
  3026 
       
  3027 structure_type_declaration:
       
  3028 /*  structure_type_name ':' structure_specification */
       
  3029   identifier ':' structure_specification
       
  3030 	{$$ = new structure_type_declaration_c($1, $3, locloc(@$));
       
  3031 	 library_element_symtable.insert($1, prev_declared_structure_type_name_token);
       
  3032 	}
       
  3033 /* ERROR_CHECK_BEGIN */
       
  3034 | identifier structure_specification
       
  3035 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between data type name and specification in structure type declaration."); yynerrs++;}
       
  3036 /* ERROR_CHECK_END */
       
  3037 ;
       
  3038 
       
  3039 
       
  3040 structure_specification:
       
  3041   structure_declaration
       
  3042 | initialized_structure
       
  3043 ;
       
  3044 
       
  3045 
       
  3046 initialized_structure:
       
  3047   prev_declared_structure_type_name
       
  3048 	{$$ = new initialized_structure_c($1, NULL, locloc(@$));}
       
  3049 | prev_declared_structure_type_name ASSIGN structure_initialization
       
  3050 	{$$ = new initialized_structure_c($1, $3, locloc(@$));}
       
  3051 /* ERROR_CHECK_BEGIN */
       
  3052 | prev_declared_structure_type_name structure_initialization
       
  3053 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':=' missing in structure specification with initialization."); yynerrs++;}
       
  3054 | prev_declared_structure_type_name ASSIGN error
       
  3055 	{$$ = NULL;
       
  3056 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no value defined in structure specification with initialization.");}
       
  3057 	 else {print_err_msg(locf(@3), locl(@3), "invalid value in structure specification with initialization."); yyclearin;}
       
  3058 	 yyerrok;
       
  3059 	}
       
  3060 /* ERROR_CHECK_END */
       
  3061 ;
       
  3062 
       
  3063 
       
  3064 structure_declaration:
       
  3065   STRUCT structure_element_declaration_list END_STRUCT
       
  3066 	{$$ = $2;}
       
  3067 /* ERROR_CHECK_BEGIN */
       
  3068 | STRUCT END_STRUCT
       
  3069 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "no structure element declared in structure type declaration."); yynerrs++;}
       
  3070 | STRUCT error structure_element_declaration_list END_STRUCT
       
  3071 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "unexpected token after 'STRUCT' in structure type declaration."); yyerrok;}
       
  3072 | STRUCT structure_element_declaration_list error END_OF_INPUT
       
  3073 	{$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed structure type declaration."); yyerrok;}
       
  3074 | STRUCT error END_STRUCT
       
  3075 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in structure type declaration."); yyerrok;}
       
  3076 /* ERROR_CHECK_END */
       
  3077 ;
       
  3078 
       
  3079 /* helper symbol for structure_declaration */
       
  3080 structure_element_declaration_list:
       
  3081   structure_element_declaration ';'
       
  3082 	{$$ = new structure_element_declaration_list_c(locloc(@$)); $$->add_element($1);}
       
  3083 | structure_element_declaration_list structure_element_declaration ';'
       
  3084 	{$$ = $1; $$->add_element($2);}
       
  3085 /* ERROR_CHECK_BEGIN */
       
  3086 | error ';'
       
  3087 	{$$ = new structure_element_declaration_list_c(locloc(@$)); print_err_msg(locf(@1), locl(@1), "invalid structure element declaration."); yyerrok;}
       
  3088 | structure_element_declaration error
       
  3089 	{$$ = new structure_element_declaration_list_c(locloc(@$)); print_err_msg(locl(@1), locf(@2), "';' missing at end of structure element declaration."); yyerrok;}
       
  3090 | structure_element_declaration_list structure_element_declaration error
       
  3091 	{$$ = $1; print_err_msg(locl(@2), locf(@3), "';' missing at end of structure element declaration."); yyerrok;}
       
  3092 | structure_element_declaration_list error ';'
       
  3093 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "invalid structure element declaration."); yyerrok;}
       
  3094 | structure_element_declaration_list ';'
       
  3095 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected ';' after structure element declaration."); yynerrs++;}
       
  3096 /* ERROR_CHECK_END */
       
  3097 ;
       
  3098 
       
  3099 
       
  3100 structure_element_declaration:
       
  3101   structure_element_name ':' simple_spec_init
       
  3102 	{$$ = new structure_element_declaration_c($1, $3, locloc(@$));}
       
  3103 | structure_element_name ':' subrange_spec_init
       
  3104 	{$$ = new structure_element_declaration_c($1, $3, locloc(@$));}
       
  3105 | structure_element_name ':' enumerated_spec_init
       
  3106 	{$$ = new structure_element_declaration_c($1, $3, locloc(@$));}
       
  3107 | structure_element_name ':' array_spec_init
       
  3108 	{$$ = new structure_element_declaration_c($1, $3, locloc(@$));}
       
  3109 | structure_element_name ':' initialized_structure
       
  3110 	{$$ = new structure_element_declaration_c($1, $3, locloc(@$));}
       
  3111 /* ERROR_CHECK_BEGIN */
       
  3112 | structure_element_name simple_spec_init
       
  3113 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between structure element name and simple specification."); yynerrs++;}
       
  3114 | structure_element_name subrange_spec_init
       
  3115 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between structure element name and subrange specification."); yynerrs++;}
       
  3116 | structure_element_name enumerated_spec_init
       
  3117 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between structure element name and enumerated specification."); yynerrs++;}
       
  3118 | structure_element_name array_spec_init
       
  3119 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between structure element name and array specification."); yynerrs++;}
       
  3120 | structure_element_name initialized_structure
       
  3121 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between structure element name and structure specification."); yynerrs++;}
       
  3122 | structure_element_name ':' error
       
  3123 	{$$ = NULL;
       
  3124 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no specification defined in structure element declaration.");}
       
  3125 	 else {print_err_msg(locf(@3), locl(@3), "invalid specification in structure element declaration."); yyclearin;}
       
  3126 	 yyerrok;
       
  3127 	}
       
  3128 /* ERROR_CHECK_END */
       
  3129 ;
       
  3130 
       
  3131 
       
  3132 structure_element_name: any_identifier;
       
  3133 
       
  3134 
       
  3135 structure_initialization:
       
  3136   '(' structure_element_initialization_list ')'
       
  3137 	{$$ = $2;}
       
  3138 /* ERROR_CHECK_BEGIN */
       
  3139 | '(' error ')'
       
  3140 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid structure element initialization list in structure initialization."); yyerrok;}
       
  3141 | '(' structure_element_initialization_list error
       
  3142 	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "expecting ')' at the end of structure element initialization list in structure initialization."); yyerrok;}
       
  3143 /* ERROR_CHECK_END */
       
  3144 ;
       
  3145 
       
  3146 /* helper symbol for structure_initialization */
       
  3147 structure_element_initialization_list:
       
  3148   structure_element_initialization
       
  3149 	{$$ = new structure_element_initialization_list_c(locloc(@$)); $$->add_element($1);}
       
  3150 | structure_element_initialization_list ',' structure_element_initialization
       
  3151 	{$$ = $1; $$->add_element($3);}
       
  3152 /* ERROR_CHECK_BEGIN 
       
  3153 | structure_element_initialization_list structure_element_initialization
       
  3154 	{$$ = $1; print_err_msg(locl(@1), locf(@2), "',' missing in structure element initialization list in structure initialization."); yynerrs++;}
       
  3155 | structure_element_initialization_list ',' error
       
  3156 	{$$ = $1;
       
  3157 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no structure element initialization defined in structure initialization.");}
       
  3158 	 else {print_err_msg(locf(@3), locl(@3), "invalid structure element initialization in structure initialization."); yyclearin;}
       
  3159 	 yyerrok;
       
  3160 	}
       
  3161 /* ERROR_CHECK_END */
       
  3162 ;
       
  3163 
       
  3164 
       
  3165 structure_element_initialization:
       
  3166   structure_element_name ASSIGN constant
       
  3167 	{$$ = new structure_element_initialization_c($1, $3, locloc(@$));}
       
  3168 | structure_element_name ASSIGN enumerated_value
       
  3169 	{$$ = new structure_element_initialization_c($1, $3, locloc(@$));}
       
  3170 | structure_element_name ASSIGN array_initialization
       
  3171 	{$$ = new structure_element_initialization_c($1, $3, locloc(@$));}
       
  3172 | structure_element_name ASSIGN structure_initialization
       
  3173 	{$$ = new structure_element_initialization_c($1, $3, locloc(@$));}
       
  3174 /* ERROR_CHECK_BEGIN */
       
  3175 | structure_element_name constant
       
  3176 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':=' missing in structure element initialization."); yynerrs++;}
       
  3177 | structure_element_name enumerated_value
       
  3178 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':=' missing in enumerated structure element initialization."); yynerrs++;}
       
  3179 | structure_element_name array_initialization
       
  3180 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':=' missing in array structure element initialization."); yynerrs++;}
       
  3181 | structure_element_name structure_initialization
       
  3182 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':=' missing in structured structure element initialization."); yynerrs++;}
       
  3183 | structure_element_name ASSIGN error
       
  3184 	{$$ = NULL;
       
  3185 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no initial value defined in structured structure element initialization.");}
       
  3186 	 else {print_err_msg(locf(@3), locl(@3), "invalid initial value in structured structure element initialization."); yyclearin;}
       
  3187 	 yyerrok;
       
  3188 	}
       
  3189 /* ERROR_CHECK_END */
       
  3190 ;
       
  3191 
       
  3192 /* NOTE: in order to remove a reduce/reduce conflict,
       
  3193  *       all occurences of string_type_name
       
  3194  *       have been replaced with identifier!
       
  3195  */
       
  3196 /*
       
  3197 string_type_name: identifier;
       
  3198 */
       
  3199 
       
  3200 string_type_declaration:
       
  3201 /*  string_type_name ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init */
       
  3202   identifier ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init
       
  3203 	{$$ = new string_type_declaration_c($1, $3, $4, $5, locloc(@$));
       
  3204 	 library_element_symtable.insert($1, prev_declared_string_type_name_token);
       
  3205 	}
       
  3206 ;
       
  3207 
       
  3208 
       
  3209 /* helper symbol for string_type_declaration */
       
  3210 string_type_declaration_size:
       
  3211   '[' integer ']'
       
  3212 	{$$ = $2;}
       
  3213 /* REMOVED !! */
       
  3214 //|  /* empty */
       
  3215 //	{$$ = NULL;}
       
  3216 ;
       
  3217 /* The syntax contains a reduce/reduce conflict.
       
  3218  * The optional '[' <size> ']'
       
  3219  * has been changed to become mandatory to remove the conflict.
       
  3220  *
       
  3221  * The conflict arises because
       
  3222  *  new_str_type : STRING := "hello!"
       
  3223  * may be reduced to a string_type_declaration OR
       
  3224  * a simple_type_declaration.
       
  3225  *
       
  3226  * Our change forces it to be reduced to a
       
  3227  * simple_type_declaration!
       
  3228  * We chose this option because changing the definition
       
  3229  * of simple_spec_init would force us to change all the other
       
  3230  * rules in which it appears. The change we made has no
       
  3231  * side-effects!
       
  3232  */
       
  3233 
       
  3234 /* helper symbol for string_type_declaration */
       
  3235 string_type_declaration_init:
       
  3236   /* empty */
       
  3237 	{$$ = NULL;}
       
  3238 | ASSIGN character_string
       
  3239 	{$$ = $2;}
       
  3240 ;
       
  3241 
       
  3242 
       
  3243 
       
  3244 /*********************/
       
  3245 /* B 1.4 - Variables */
       
  3246 /*********************/
       
  3247 /* NOTE: The standard is erroneous in it's definition of 'variable' because:
       
  3248  *         - The standard considers 'ENO' as a keyword...
       
  3249  *         - ...=> which means that it may never be parsed as an 'identifier'...
       
  3250  *         - ...=> and therefore may never be used as the name of a variable inside an expression.
       
  3251  *         - However, a function/FB must be able to assign the ENO parameter
       
  3252  *           it's value, doing it in an assignment statement, and therefore using the 'ENO'
       
  3253  *           character sequence as an identifier!
       
  3254  *        The obvious solution is to also allow the ENO keyword to be 
       
  3255  *         used as the name of a variable. Note that this variable may be used
       
  3256  *         even though it is not explicitly declared as a function/FB variable,
       
  3257  *         as the standard requires us to define it implicitly in this case!
       
  3258  *        There are three ways of achieving this:
       
  3259  *          (i) simply not define EN and ENO as keywords in flex (lexical analyser)
       
  3260  *              and let them be considered 'identifiers'. Aditionally, add some code
       
  3261  *              so that if they are not explicitly declared, we add them automatically to
       
  3262  *              the declaration of each Functions and FB, where they would then be parsed
       
  3263  *              as a previously_declared_variable.
       
  3264  *              This approach has the advantage the EN and ENO would automatically be valid
       
  3265  *              in every location where it needs to be valid, namely in the explicit declaration 
       
  3266  *              of these same variables, or when they are used within expressions.
       
  3267  *              However, this approach has the drawback that 
       
  3268  *              EN and ENO could then also be used anywhere a standard identifier is allowed,
       
  3269  *              including in the naming of Functions, FBs, Programs, Configurations, Resources, 
       
  3270  *              SFC Actions, SFC Steps, etc...
       
  3271  *              This would mean that we would then have to add a lexical analysis check
       
  3272  *              within the bison code (syntax analyser) to all the above constructs to make sure
       
  3273  *              that the identifier being used is not EN or ENO.
       
  3274  *         (ii) The other approach is to define EN and ENO as keywords / tokens in flex
       
  3275  *              (lexical analyser) and then change the syntax in bison to acomodate 
       
  3276  *              these tokens wherever they could correctly appear.
       
  3277  *              This has the drawback that we need to do some changes to the synax defintion.
       
  3278  *        (iii) Yet a another option is to mix the above two methods.
       
  3279  *              Define EN and ENO as tokens in flex, but change (only) the syntax for
       
  3280  *              variable declaration to allow these tokens to also be used in declaring variables.
       
  3281  *              From this point onwards these tokens are then considered a previously_declared_variable,
       
  3282  *              since flex will first check for this before even checking for tokens.
       
  3283  *
       
  3284  *              I (Mario) cuurretnly (2011) believe the cleanest method of achieving this goal
       
  3285  *              is to use option (iii)
       
  3286  *              However, considering that:
       
  3287  *                - I have already previously implemented option (ii);
       
  3288  *                - option (iii) requires that flex parse the previously_declared_variable
       
  3289  *                   before parsing any token. We already support this (remeber that this is 
       
  3290  *                   used mainly to allow some IL operators as well as PRIORITY, etc. tokens
       
  3291  *                   to be used as identifiers, since the standard does not define them as keywords),
       
  3292  *                   but this part of the code in flex is often commented out as usually people do not expect
       
  3293  *                   us to follow the standard in the strict sense, but rather consider those
       
  3294  *                   tokens as keywords;
       
  3295  *                considering the above, we currently carry on using option (ii).
       
  3296  */
       
  3297 variable:
       
  3298   symbolic_variable
       
  3299 | prev_declared_direct_variable
       
  3300 | eno_identifier
       
  3301 	{$$ = new symbolic_variable_c($1, locloc(@$));}
       
  3302 ;
       
  3303 
       
  3304 
       
  3305 symbolic_variable:
       
  3306 /* NOTE: To be entirely correct, variable_name must be replacemed by
       
  3307  *         prev_declared_variable_name | prev_declared_fb_name | prev_declared_global_var_name
       
  3308  */
       
  3309   prev_declared_fb_name
       
  3310 	{$$ = new symbolic_variable_c($1, locloc(@$));}
       
  3311 | prev_declared_global_var_name
       
  3312 	{$$ = new symbolic_variable_c($1, locloc(@$));}
       
  3313 | prev_declared_variable_name
       
  3314 	{$$ = new symbolic_variable_c($1, locloc(@$));}
       
  3315 | multi_element_variable
       
  3316 /*
       
  3317 | identifier
       
  3318 	{$$ = new symbolic_variable_c($1, locloc(@$));}
       
  3319 */
       
  3320 ;
       
  3321 
       
  3322 
       
  3323 /* NOTE: in section B 1.7, when configuring a program, symbolic_variable
       
  3324  *       is used. Nevertheless, during the parsing of a configuration,
       
  3325  *       the variables in question are out of scope, so we should
       
  3326  *       be allowing any_identifier instead of prev_declared_variable_name!
       
  3327  *
       
  3328  *       We therefore need a new any_symbolic_variable construct that
       
  3329  *       allows the use of any_identifier instead of previously declared
       
  3330  *       variables, function blocks, etc...
       
  3331  */
       
  3332 any_symbolic_variable:
       
  3333 // variable_name -> replaced by any_identifier
       
  3334   any_identifier
       
  3335 	{$$ = new symbolic_variable_c($1, locloc(@$));}
       
  3336 | any_multi_element_variable
       
  3337 ;
       
  3338 
       
  3339 
       
  3340 /* for yet undeclared variable names ! */
       
  3341 variable_name: identifier;
       
  3342 
       
  3343 
       
  3344 
       
  3345 
       
  3346 
       
  3347 /********************************************/
       
  3348 /* B.1.4.1   Directly Represented Variables */
       
  3349 /********************************************/
       
  3350 prev_declared_direct_variable: prev_declared_direct_variable_token	{$$ = new direct_variable_c($1, locloc(@$));};
       
  3351 
       
  3352 
       
  3353 
       
  3354 
       
  3355 /*************************************/
       
  3356 /* B.1.4.2   Multi-element Variables */
       
  3357 /*************************************/
       
  3358 multi_element_variable:
       
  3359   array_variable
       
  3360 | structured_variable
       
  3361 ;
       
  3362 
       
  3363 /* please see note above any_symbolic_variable */
       
  3364 any_multi_element_variable:
       
  3365   any_array_variable
       
  3366 | any_structured_variable
       
  3367 ;
       
  3368 
       
  3369 
       
  3370 array_variable:
       
  3371   subscripted_variable '[' subscript_list ']'
       
  3372 	{$$ = new array_variable_c($1, $3, locloc(@$));}
       
  3373 ;
       
  3374 
       
  3375 /* please see note above any_symbolic_variable */
       
  3376 any_array_variable:
       
  3377   any_subscripted_variable '[' subscript_list ']'
       
  3378 	{$$ = new array_variable_c($1, $3, locloc(@$));}
       
  3379 ;
       
  3380 
       
  3381 
       
  3382 subscripted_variable:
       
  3383   symbolic_variable
       
  3384 ;
       
  3385 
       
  3386 
       
  3387 /* please see note above any_symbolic_variable */
       
  3388 any_subscripted_variable:
       
  3389   any_symbolic_variable
       
  3390 ;
       
  3391 
       
  3392 
       
  3393 subscript_list:
       
  3394   subscript
       
  3395 	{$$ = new subscript_list_c(locloc(@$)); $$->add_element($1);}
       
  3396 | subscript_list ',' subscript
       
  3397 	{$$ = $1; $$->add_element($3);}
       
  3398 ;
       
  3399 
       
  3400 
       
  3401 subscript:  expression;
       
  3402 
       
  3403 
       
  3404 structured_variable:
       
  3405   record_variable '.' field_selector
       
  3406 	{$$ = new structured_variable_c($1, $3, locloc(@$));}
       
  3407 ;
       
  3408 
       
  3409 
       
  3410 /* please see note above any_symbolic_variable */
       
  3411 any_structured_variable:
       
  3412   any_record_variable '.' field_selector
       
  3413 	{$$ = new structured_variable_c($1, $3, locloc(@$));}
       
  3414 ;
       
  3415 
       
  3416 
       
  3417 
       
  3418 record_variable:
       
  3419   symbolic_variable
       
  3420 ;
       
  3421 
       
  3422 
       
  3423 /* please see note above any_symbolic_variable */
       
  3424 any_record_variable:
       
  3425   any_symbolic_variable
       
  3426 ;
       
  3427 
       
  3428 
       
  3429 field_selector: 
       
  3430   any_identifier
       
  3431 | eno_identifier
       
  3432 ;
       
  3433 
       
  3434 
       
  3435 
       
  3436 
       
  3437 
       
  3438 
       
  3439 /******************************************/
       
  3440 /* B 1.4.3 - Declaration & Initialisation */
       
  3441 /******************************************/
       
  3442 input_declarations:
       
  3443   VAR_INPUT            input_declaration_list END_VAR
       
  3444 	{$$ = new input_declarations_c(NULL, $2, new explicit_definition_c(), locloc(@$));}
       
  3445 | VAR_INPUT RETAIN     input_declaration_list END_VAR
       
  3446 	{$$ = new input_declarations_c(new retain_option_c(locloc(@2)), $3, new explicit_definition_c(), locloc(@$));}
       
  3447 | VAR_INPUT NON_RETAIN input_declaration_list END_VAR
       
  3448 	{$$ = new input_declarations_c(new non_retain_option_c(locloc(@2)), $3, new explicit_definition_c(), locloc(@$));}
       
  3449 /* ERROR_CHECK_BEGIN */
       
  3450 | VAR_INPUT END_VAR
       
  3451 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "no variable declared in input variable(s) declaration."); yynerrs++;}
       
  3452 | VAR_INPUT RETAIN END_VAR
       
  3453 	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable declared in retentive input variable(s) declaration."); yynerrs++;}
       
  3454 | VAR_INPUT NON_RETAIN END_VAR
       
  3455 	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable declared in non-retentive input variable(s) declaration."); yynerrs++;}
       
  3456 | VAR_INPUT error input_declaration_list END_VAR
       
  3457 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "unexpected token after 'VAR_INPUT' in input variable(s) declaration."); yyerrok;}
       
  3458 | VAR_INPUT RETAIN error input_declaration_list END_VAR
       
  3459 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "unexpected token after 'RETAIN' in retentive input variable(s) declaration."); yyerrok;}
       
  3460 | VAR_INPUT NON_RETAIN error input_declaration_list END_VAR
       
  3461 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "unexpected token after 'NON_RETAIN' in non-retentive input variable(s) declaration."); yyerrok;}
       
  3462 | VAR_INPUT input_declaration_list error END_OF_INPUT
       
  3463 	{$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed input variable(s) declaration."); yyerrok;}
       
  3464 | VAR_INPUT RETAIN input_declaration_list error END_OF_INPUT
       
  3465 	{$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed retentive input variable(s) declaration."); yyerrok;}
       
  3466 | VAR_INPUT NON_RETAIN input_declaration_list error END_OF_INPUT
       
  3467 	{$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed non-retentive input variable(s) declaration."); yyerrok;}
       
  3468 | VAR_INPUT error END_VAR
       
  3469 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in input variable(s) declaration."); yyerrok;}
       
  3470 | VAR_INPUT RETAIN error END_VAR
       
  3471 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "unknown error in retentive input variable(s) declaration."); yyerrok;}
       
  3472 | VAR_INPUT NON_RETAIN error END_VAR
       
  3473 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "unknown error in non-retentive input variable(s) declaration."); yyerrok;}
       
  3474 /* ERROR_CHECK_END */
       
  3475 ;
       
  3476 
       
  3477 /* helper symbol for input_declarations */
       
  3478 input_declaration_list:
       
  3479   input_declaration ';'
       
  3480 	{$$ = new input_declaration_list_c(locloc(@$)); $$->add_element($1);}
       
  3481 | input_declaration_list input_declaration ';'
       
  3482 	{$$ = $1; $$->add_element($2);}
       
  3483 /* ERROR_CHECK_BEGIN */
       
  3484 | error ';'
       
  3485 	{$$ = new input_declaration_list_c(locloc(@$)); print_err_msg(locf(@1), locl(@1), "invalid input variable(s) declaration."); yyerrok;}
       
  3486 | input_declaration error
       
  3487 	{$$ = new input_declaration_list_c(locloc(@$)); print_err_msg(locl(@1), locf(@2), "';' missing at end of input variable(s) declaration."); yyerrok;}
       
  3488 | input_declaration_list input_declaration error
       
  3489 	{$$ = $1; print_err_msg(locl(@2), locf(@3), "';' missing at end of input variable(s) declaration."); yyerrok;}
       
  3490 | input_declaration_list error ';'
       
  3491 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "invalid input variable(s) declaration."); yyerrok;}
       
  3492 | input_declaration_list ';'
       
  3493 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected ';' after input variable(s) declaration."); yynerrs++;}
       
  3494 /* ERROR_CHECK_END */
       
  3495 ;
       
  3496 
       
  3497 
       
  3498 /* NOTE: The formal definition of 'input_declaration' as defined in the standard is erroneous,
       
  3499  *       as it does not allow a user defined 'EN' input parameter. However,
       
  3500  *       The semantic description of the languages clearly states that this is allowed.
       
  3501  *       We have added the 'en_param_declaration' clause to cover for this.
       
  3502  */
       
  3503 input_declaration:
       
  3504   var_init_decl
       
  3505 | edge_declaration
       
  3506 | en_param_declaration
       
  3507 ;
       
  3508 
       
  3509 
       
  3510 edge_declaration:
       
  3511   var1_list ':' BOOL R_EDGE
       
  3512 	{$$ = new edge_declaration_c(new raising_edge_option_c(locloc(@3)), $1, locloc(@$));}
       
  3513 | var1_list ':' BOOL F_EDGE
       
  3514 	{$$ = new edge_declaration_c(new falling_edge_option_c(locloc(@3)), $1, locloc(@$));}
       
  3515 /* ERROR_CHECK_BEGIN */
       
  3516 | var1_list BOOL R_EDGE
       
  3517 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and specification in edge declaration."); yynerrs++;}
       
  3518 | var1_list BOOL F_EDGE
       
  3519 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and specification in edge declaration."); yynerrs++;}
       
  3520 | var1_list ':' BOOL R_EDGE F_EDGE
       
  3521 	{$$ = NULL; print_err_msg(locl(@5), locf(@5), "'R_EDGE' and 'F_EDGE' can't be present at the same time in edge declaration."); yynerrs++;}
       
  3522 | var1_list ':' BOOL F_EDGE R_EDGE
       
  3523 	{$$ = NULL; print_err_msg(locl(@5), locf(@5), "'R_EDGE' and 'F_EDGE' can't be present at the same time in edge declaration."); yynerrs++;}
       
  3524 | var1_list ':' R_EDGE
       
  3525 	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "'BOOL' missing in edge declaration."); yynerrs++;}
       
  3526 | var1_list ':' F_EDGE
       
  3527 	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "'BOOL' missing in edge declaration."); yynerrs++;}
       
  3528 /* ERROR_CHECK_END */
       
  3529 ;
       
  3530 
       
  3531 
       
  3532 /* NOTE: The formal definition of the standard is erroneous, as it simply does not
       
  3533  *       consider the EN and ENO keywords!
       
  3534  *       The semantic description of the languages clearly states that these may be
       
  3535  *       used in several ways. One of them is to declare an EN input parameter.
       
  3536  *       We have added the 'en_param_declaration' clause to cover for this.
       
  3537  *
       
  3538  *       Please read the comment above the definition of 'variable' in section B1.4 for details.
       
  3539  */
       
  3540 en_param_declaration:
       
  3541   en_identifier ':' BOOL ASSIGN boolean_literal
       
  3542   {$$ = new en_param_declaration_c($1, new bool_type_name_c(locloc(@$)), $5, new explicit_definition_c(), locloc(@$));}
       
  3543 | en_identifier ':' BOOL ASSIGN integer
       
  3544   {$$ = new en_param_declaration_c($1, new bool_type_name_c(locloc(@$)), $5, new explicit_definition_c(), locloc(@$));}
       
  3545 /* ERROR_CHECK_BEGIN */
       
  3546 | en_identifier BOOL ASSIGN boolean_literal
       
  3547 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and specification in EN declaration."); yynerrs++;}
       
  3548 | en_identifier BOOL ASSIGN integer
       
  3549 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and specification in EN declaration."); yynerrs++;}
       
  3550 | en_identifier ':' ASSIGN boolean_literal
       
  3551   {$$ = NULL; print_err_msg(locl(@2), locf(@3), "'BOOL' missing in EN declaration."); yynerrs++;}
       
  3552 | en_identifier ':' ASSIGN integer
       
  3553 	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "'BOOL' missing in EN declaration."); yynerrs++;}
       
  3554 | en_identifier ':' BOOL ASSIGN error
       
  3555 	{$$ = NULL;
       
  3556 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no specification defined in EN declaration.");}
       
  3557 	 else {print_err_msg(locf(@3), locl(@3), "invalid specification in EN declaration."); yyclearin;}
       
  3558 	 yyerrok;
       
  3559 	}
       
  3560 /* ERROR_CHECK_END */
       
  3561 ;
       
  3562 
       
  3563 var_init_decl:
       
  3564   var1_init_decl
       
  3565 | array_var_init_decl
       
  3566 | structured_var_init_decl
       
  3567 | fb_name_decl
       
  3568 | string_var_declaration
       
  3569 ;
       
  3570 
       
  3571 
       
  3572 
       
  3573 
       
  3574 var1_init_decl:
       
  3575   var1_list ':' simple_spec_init
       
  3576 	{$$ = new var1_init_decl_c($1, $3, locloc(@$));}
       
  3577 | var1_list ':' subrange_spec_init
       
  3578 	{$$ = new var1_init_decl_c($1, $3, locloc(@$));}
       
  3579 | var1_list ':' enumerated_spec_init
       
  3580 	{$$ = new var1_init_decl_c($1, $3, locloc(@$));}
       
  3581 /* ERROR_CHECK_BEGIN */
       
  3582 | var1_list simple_spec_init
       
  3583 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and simple specification."); yynerrs++;}
       
  3584 | var1_list subrange_spec_init
       
  3585 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and subrange specification."); yynerrs++;}
       
  3586 | var1_list enumerated_spec_init
       
  3587 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and enumerated specification."); yynerrs++;}
       
  3588 | var1_list ':' error
       
  3589 	{$$ = NULL;
       
  3590 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no specification defined in variable declaration.");}
       
  3591 	 else {print_err_msg(locf(@3), locl(@3), "invalid specification in variable declaration."); yyclearin;}
       
  3592 	 yyerrok;
       
  3593 	}
       
  3594 /* ERROR_CHECK_END */
       
  3595 ;
       
  3596 
       
  3597 
       
  3598 /* NOTE: 
       
  3599  * The syntax 
       
  3600  *    variable_name DOTDOT 
       
  3601  * is an extension to the standard!!! 
       
  3602  *
       
  3603  * In order to be able to handle extensible standard functions
       
  3604  * (i.e. standard functions that may have a variable number of
       
  3605  * input parameters, such as AND(word#33, word#44, word#55, word#66),
       
  3606  * we have extended the acceptable syntax to allow var_name '..'
       
  3607  * in an input variable declaration.
       
  3608  *
       
  3609  * This allows us to parse the declaration of standard
       
  3610  * extensible functions and load their interface definition
       
  3611  * into the abstract syntax tree just like we do to other 
       
  3612  * user defined functions.
       
  3613  * This has the advantage that we can later do semantic
       
  3614  * checking of calls to functions (be it a standard or user defined
       
  3615  * function) in (almost) exactly the same way.
       
  3616  *
       
  3617  * Of course, we have a flag that disables this syntax when parsing user
       
  3618  * written code, so we only allow this extra syntax while parsing the 
       
  3619  * 'header' file that declares all the standard IEC 61131-3 functions.
       
  3620  */
       
  3621 var1_list:
       
  3622   variable_name
       
  3623 	{$$ = new var1_list_c(locloc(@$)); $$->add_element($1);
       
  3624 	 variable_name_symtable.insert($1, prev_declared_variable_name_token);
       
  3625 	}
       
  3626 | variable_name integer DOTDOT
       
  3627 	{$$ = new var1_list_c(locloc(@$)); $$->add_element(new extensible_input_parameter_c($1, $2, locloc(@$)));
       
  3628 	 variable_name_symtable.insert($1, prev_declared_variable_name_token);
       
  3629 	 if (!allow_extensible_function_parameters) print_err_msg(locf(@1), locl(@2), "invalid syntax in variable name declaration.");
       
  3630 	}
       
  3631  | var1_list ',' variable_name
       
  3632 	{$$ = $1; $$->add_element($3);
       
  3633 	 variable_name_symtable.insert($3, prev_declared_variable_name_token);
       
  3634 	}
       
  3635  | var1_list ',' variable_name integer DOTDOT
       
  3636 	{$$ = $1; $$->add_element(new extensible_input_parameter_c($3, $4, locloc(@$)));
       
  3637 	 variable_name_symtable.insert($3, prev_declared_variable_name_token);
       
  3638 	 if (!allow_extensible_function_parameters) print_err_msg(locf(@1), locl(@2), "invalid syntax in variable name declaration.");
       
  3639 	}
       
  3640 /* ERROR_CHECK_BEGIN */
       
  3641 | var1_list variable_name
       
  3642 	{$$ = $1; print_err_msg(locl(@1), locf(@2), "',' missing in variable list."); yynerrs++;}
       
  3643 | var1_list ',' error
       
  3644 	{$$ = $1;
       
  3645 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no variable name defined in variable declaration.");}
       
  3646 	 else {print_err_msg(locf(@3), locl(@3), "invalid variable name in variable declaration."); yyclearin;}
       
  3647 	 yyerrok;
       
  3648 	}
       
  3649 /* ERROR_CHECK_END */
       
  3650 ;
       
  3651 
       
  3652 
       
  3653 
       
  3654 array_var_init_decl:
       
  3655  var1_list ':' array_spec_init
       
  3656 	{$$ = new array_var_init_decl_c($1, $3, locloc(@$));}
       
  3657 /* ERROR_CHECK_BEGIN */
       
  3658 | var1_list array_spec_init
       
  3659 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and array specification."); yynerrs++;}
       
  3660 /* ERROR_CHECK_END */
       
  3661 ;
       
  3662 
       
  3663 
       
  3664 structured_var_init_decl:
       
  3665   var1_list ':' initialized_structure
       
  3666 	{$$ = new structured_var_init_decl_c($1, $3, locloc(@$));}
       
  3667 /* ERROR_CHECK_BEGIN */
       
  3668 | var1_list initialized_structure
       
  3669 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and structured specification."); yynerrs++;}
       
  3670 /* ERROR_CHECK_END */
       
  3671 ;
       
  3672 
       
  3673 
       
  3674 /* NOTE: see notes above fb_name_list and var1_list
       
  3675  *       for reason why ':' was removed from this rule!
       
  3676  *       In essence, to remove a shift/reduce conflict,
       
  3677  *       the ':' was moved to var1_list and fb_name_list!
       
  3678  */
       
  3679 fb_name_decl:
       
  3680 /*  fb_name_list ':' function_block_type_name */
       
  3681   fb_name_list_with_colon function_block_type_name
       
  3682 	{$$ = new fb_name_decl_c($1, $2, NULL, locloc(@$));}
       
  3683 /*| fb_name_list ':' function_block_type_name ASSIGN structure_initialization */
       
  3684 | fb_name_list_with_colon function_block_type_name ASSIGN structure_initialization
       
  3685 	{$$ = new fb_name_decl_c($1, $2, $4, locloc(@$));}
       
  3686 /* ERROR_CHECK_BEGIN */
       
  3687 | fb_name_list_with_colon ASSIGN structure_initialization
       
  3688 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "no function block type name defined in function block declaration with initialization."); yynerrs++;}
       
  3689 | fb_name_list_with_colon function_block_type_name structure_initialization
       
  3690 	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "':=' missing in function block declaration with initialization."); yynerrs++;}
       
  3691 | fb_name_list_with_colon function_block_type_name ASSIGN error
       
  3692 	{$$ = NULL;
       
  3693 	 if (is_current_syntax_token()) {print_err_msg(locl(@3), locf(@4), "no initialization defined in function block declaration.");}
       
  3694 	 else {print_err_msg(locf(@4), locl(@4), "invalid initialization in function block declaration."); yyclearin;}
       
  3695 	 yyerrok;
       
  3696 	}
       
  3697 /* ERROR_CHECK_END */
       
  3698 ;
       
  3699 
       
  3700 
       
  3701 
       
  3702 /* NOTE: In order to remove a reduce/reduce conflict between
       
  3703  *       var1_list and fb_name_list, which are identical to each
       
  3704  *       other, fb_name_list has been redefined to be a var1_list.
       
  3705  *
       
  3706  *        In order to remove a further shift/reduce conflict, var1_list
       
  3707  *        is imediately transfomred into var1_list_with_colon
       
  3708  *        (i.e. it includes the ':' following the list), which
       
  3709  *        means that fb_name_list is built from a
       
  3710  *        var1_list_with_colon after all!
       
  3711  */
       
  3712 /*
       
  3713 fb_name_list:
       
  3714  (*  fb_name *)
       
  3715   identifier
       
  3716 	{$$ = new fb_name_list_c($1);
       
  3717 	 variable_name_symtable.insert($1, prev_declared_fb_name_token);
       
  3718 	}
       
  3719 (* | fb_name_list ',' fb_name *)
       
  3720 | fb_name_list ',' identifier
       
  3721 	{$$ = $1; $$->add_element($3);
       
  3722 	 variable_name_symtable.insert($3, prev_declared_fb_name_token);
       
  3723 	}
       
  3724 ;
       
  3725 */
       
  3726 
       
  3727 fb_name_list_with_colon:
       
  3728   var1_list_with_colon
       
  3729 	{$$ = new fb_name_list_c(locloc(@$));
       
  3730 	 /* fill up the new fb_name_list_c object with the references
       
  3731 	  * contained in the var1_list_c object.
       
  3732 	  */
       
  3733 	 FOR_EACH_ELEMENT(elem, $1, {$$->add_element(elem);});
       
  3734 	 delete $1;
       
  3735 	 /* change the tokens associated with the symbols stored in
       
  3736 	  * the variable name symbol table from prev_declared_variable_name_token
       
  3737 	  * to prev_declared_fb_name_token
       
  3738 	  */
       
  3739 	 FOR_EACH_ELEMENT(elem, $$, {variable_name_symtable.set(elem, prev_declared_fb_name_token);});
       
  3740 	}
       
  3741 ;
       
  3742 
       
  3743 /* helper symbol for fb_name_list_with_colon */
       
  3744 var1_list_with_colon:
       
  3745   var1_list ':'
       
  3746 ;
       
  3747 
       
  3748 
       
  3749 // fb_name: identifier;
       
  3750 
       
  3751 
       
  3752 
       
  3753 output_declarations:
       
  3754   VAR_OUTPUT var_output_init_decl_list END_VAR
       
  3755 	{$$ = new output_declarations_c(NULL, $2, new explicit_definition_c(), locloc(@$));}
       
  3756 | VAR_OUTPUT RETAIN var_output_init_decl_list END_VAR
       
  3757 	{$$ = new output_declarations_c(new retain_option_c(locloc(@2)), $3, new explicit_definition_c(), locloc(@$));}
       
  3758 | VAR_OUTPUT NON_RETAIN var_output_init_decl_list END_VAR
       
  3759 	{$$ = new output_declarations_c(new non_retain_option_c(locloc(@2)), $3, new explicit_definition_c(), locloc(@$));}
       
  3760 /* ERROR_CHECK_BEGIN */
       
  3761 | VAR_OUTPUT END_VAR
       
  3762 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "no variable declared in output variable(s) declaration."); yynerrs++;}
       
  3763 | VAR_OUTPUT RETAIN END_VAR
       
  3764 	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable declared in retentive output variable(s) declaration."); yynerrs++;}
       
  3765 | VAR_OUTPUT NON_RETAIN END_VAR
       
  3766 	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable declared in non-retentive output variable(s) declaration."); yynerrs++;}
       
  3767 | VAR_OUTPUT error var_output_init_decl_list END_VAR
       
  3768 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "unexpected token after 'VAR_OUPUT' in output variable(s) declaration."); yyerrok;}
       
  3769 | VAR_OUTPUT RETAIN error var_output_init_decl_list END_VAR
       
  3770 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "unexpected token after 'RETAIN' in retentive output variable(s) declaration."); yyerrok;}
       
  3771 | VAR_OUTPUT NON_RETAIN error var_output_init_decl_list END_VAR
       
  3772 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "unexpected token after 'NON_RETAIN' in non-retentive output variable(s) declaration."); yyerrok;}
       
  3773 | VAR_OUTPUT var_output_init_decl_list error END_OF_INPUT
       
  3774 	{$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed output variable(s) declaration."); yyerrok;}
       
  3775 | VAR_OUTPUT RETAIN var_output_init_decl_list error END_OF_INPUT
       
  3776 	{$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed retentive output variable(s) declaration."); yyerrok;}
       
  3777 | VAR_OUTPUT NON_RETAIN var_output_init_decl_list error END_OF_INPUT
       
  3778 	{$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed non-retentive output variable(s) declaration."); yyerrok;}
       
  3779 | VAR_OUTPUT error END_VAR
       
  3780 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in output variable(s) declaration."); yyerrok;}
       
  3781 | VAR_OUTPUT RETAIN error END_VAR
       
  3782 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "unknown error in retentive output variable(s) declaration."); yyerrok;}
       
  3783 | VAR_OUTPUT NON_RETAIN error END_VAR
       
  3784 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "unknown error in non-retentive output variable(s) declaration."); yyerrok;}
       
  3785 /* ERROR_CHECK_END */
       
  3786 ;
       
  3787 
       
  3788 
       
  3789 /* NOTE: The formal definition of 'var_output_init_decl' as defined in the standard is erroneous,
       
  3790  *       as it does not allow a user defined 'ENO' output parameter. However,
       
  3791  *       The semantic description of the languages clearly states that this is allowed.
       
  3792  *       We have added the 'eno_param_declaration' clause to cover for this.
       
  3793  *
       
  3794  *       Please read the comment above the definition of 'variable' in section B1.4 for details.
       
  3795  */
       
  3796 var_output_init_decl:
       
  3797   var_init_decl
       
  3798 | eno_param_declaration
       
  3799 ;
       
  3800 
       
  3801 var_output_init_decl_list:
       
  3802   var_output_init_decl ';'
       
  3803 	{$$ = new var_init_decl_list_c(locloc(@$)); $$->add_element($1);}
       
  3804 | var_output_init_decl_list var_output_init_decl ';'
       
  3805 	{$$ = $1; $$->add_element($2);}
       
  3806 /* ERROR_CHECK_BEGIN */
       
  3807 | var_output_init_decl_list var_output_init_decl error
       
  3808 	{$$ = $1; print_err_msg(locl(@2), locf(@3), "';' missing at end of variable(s) declaration."); yyerrok;}
       
  3809 | var_output_init_decl_list error ';'
       
  3810 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "invalid variable(s) declaration."); yyerrok;}
       
  3811 /* ERROR_CHECK_END */
       
  3812 ;
       
  3813 
       
  3814 
       
  3815 /* NOTE: The formal definition of the standard is erroneous, as it simply does not
       
  3816  *       consider the EN and ENO keywords!
       
  3817  *       The semantic description of the languages clearly states that these may be
       
  3818  *       used in several ways. One of them is to declare an ENO output parameter.
       
  3819  *       We have added the 'eno_param_declaration' clause to cover for this.
       
  3820  *
       
  3821  *       Please read the comment above the definition of 'variable' in section B1.4 for details.
       
  3822  */
       
  3823 eno_param_declaration:
       
  3824   eno_identifier ':' BOOL
       
  3825   /* NOTE We do _NOT_ include this variable in the previously_declared_variable symbol table!
       
  3826    *      Please read the comment above the definition of 'variable' for the reason for this.
       
  3827    */
       
  3828   {$$ = new eno_param_declaration_c($1, new bool_type_name_c(locloc(@$)), new explicit_definition_c(), locloc(@$));}
       
  3829 /* ERROR_CHECK_BEGIN */
       
  3830 | eno_identifier BOOL
       
  3831 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and specification in ENO declaration."); yynerrs++;}
       
  3832 | eno_identifier ':' error
       
  3833 	{$$ = NULL;
       
  3834 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no specification defined in ENO declaration.");}
       
  3835 	 else {print_err_msg(locf(@3), locl(@3), "invalid specification in ENO declaration."); yyclearin;}
       
  3836 	 yyerrok;
       
  3837 	}
       
  3838 /* ERROR_CHECK_END */
       
  3839 ;
       
  3840 
       
  3841 
       
  3842 input_output_declarations:
       
  3843   VAR_IN_OUT var_declaration_list END_VAR
       
  3844 	{$$ = new input_output_declarations_c($2, locloc(@$));}
       
  3845 /* ERROR_CHECK_BEGIN */
       
  3846 | VAR_IN_OUT END_VAR
       
  3847 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "no variable declared in in_out variable(s) declaration."); yynerrs++;}
       
  3848 | VAR_IN_OUT error var_declaration_list END_VAR
       
  3849 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "unexpected token after 'VAR_IN_OUT' in in_out variable(s) declaration."); yyerrok;}
       
  3850 | VAR_IN_OUT var_declaration_list error END_OF_INPUT
       
  3851 	{$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed in_out variable(s) declaration."); yyerrok;}
       
  3852 | VAR_IN_OUT error END_VAR
       
  3853 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in in_out variable(s) declaration."); yyerrok;}
       
  3854 /* ERROR_CHECK_END */
       
  3855 ;
       
  3856 
       
  3857 
       
  3858 
       
  3859 /* helper symbol for input_output_declarations */
       
  3860 var_declaration_list:
       
  3861   var_declaration ';'
       
  3862 	{$$ = new var_declaration_list_c(locloc(@$)); $$->add_element($1);}
       
  3863 | var_declaration_list var_declaration ';'
       
  3864 	{$$ = $1; $$->add_element($2);}
       
  3865 /* ERROR_CHECK_BEGIN */
       
  3866 | error ';'
       
  3867 	{$$ = new var_declaration_list_c(locloc(@$)); print_err_msg(locf(@1), locl(@1), "invalid variable(s) declaration."); yyerrok;}
       
  3868 | var_declaration error
       
  3869 	{$$ = new var_declaration_list_c(locloc(@$)); print_err_msg(locl(@1), locf(@2), "';' missing at end of variable(s) declaration."); yyerrok;}
       
  3870 | var_declaration_list var_declaration error
       
  3871 	{$$ = $1; print_err_msg(locl(@2), locf(@3), "';' missing at end of variable(s) declaration."); yyerrok;}
       
  3872 | var_declaration_list error ';'
       
  3873 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "invalid variable(s) declaration."); yyerrok;}
       
  3874 | var_declaration_list ';'
       
  3875 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected ';' after variable(s) declaration."); yynerrs++;}
       
  3876 /* ERROR_CHECK_END */
       
  3877 ;
       
  3878 
       
  3879 
       
  3880 var_declaration:
       
  3881   temp_var_decl
       
  3882 | fb_name_decl
       
  3883 ;
       
  3884 
       
  3885 
       
  3886 temp_var_decl:
       
  3887   var1_declaration
       
  3888 | array_var_declaration
       
  3889 | structured_var_declaration
       
  3890 | string_var_declaration
       
  3891 ;
       
  3892 
       
  3893 var1_declaration:
       
  3894   var1_list ':' simple_specification
       
  3895 	{$$ = new var1_init_decl_c($1, $3, locloc(@$));}
       
  3896 | var1_list ':' subrange_specification
       
  3897 	{$$ = new var1_init_decl_c($1, $3, locloc(@$));}
       
  3898 | var1_list ':' enumerated_specification
       
  3899 	{$$ = new var1_init_decl_c($1, $3, locloc(@$));}
       
  3900 /* ERROR_CHECK_BEGIN */
       
  3901 | var1_list simple_specification
       
  3902 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and simple specification."); yynerrs++;}
       
  3903 | var1_list subrange_specification
       
  3904 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and subrange specification."); yynerrs++;}
       
  3905 | var1_list enumerated_specification
       
  3906 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and enumerated specification."); yynerrs++;}
       
  3907 /* ERROR_CHECK_END */
       
  3908 ;
       
  3909 
       
  3910 
       
  3911 
       
  3912 array_var_declaration:
       
  3913   var1_list ':' array_specification
       
  3914 	{$$ = new array_var_declaration_c($1, $3, locloc(@$));}
       
  3915 /* ERROR_CHECK_BEGIN */
       
  3916 | var1_list array_specification
       
  3917 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and array specification."); yynerrs++;}
       
  3918 /* ERROR_CHECK_END */
       
  3919 ;
       
  3920 
       
  3921 structured_var_declaration:
       
  3922   var1_list ':' prev_declared_structure_type_name
       
  3923 	{$$ = new structured_var_declaration_c($1, $3, locloc(@$));}
       
  3924 /* ERROR_CHECK_BEGIN */
       
  3925 | var1_list prev_declared_structure_type_name
       
  3926 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and structured specification."); yynerrs++;}
       
  3927 /* ERROR_CHECK_END */
       
  3928 ;
       
  3929 
       
  3930 
       
  3931 var_declarations:
       
  3932   VAR var_init_decl_list END_VAR
       
  3933 	{$$ = new var_declarations_c(NULL, $2, locloc(@$));}
       
  3934 | VAR CONSTANT var_init_decl_list END_VAR
       
  3935 	{$$ = new var_declarations_c(new constant_option_c(locloc(@2)), $3, locloc(@$));}
       
  3936 /* ERROR_CHECK_BEGIN */
       
  3937 | VAR END_VAR
       
  3938 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "no variable declared in variable(s) declaration."); yynerrs++;}
       
  3939 | VAR CONSTANT END_VAR
       
  3940 	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable declared in constant variable(s) declaration."); yynerrs++;}
       
  3941 | VAR error var_init_decl_list END_VAR
       
  3942 	{$$ = NULL; print_err_msg(locl(@1), locf(@3), "unexpected token after 'VAR' in variable(s) declaration."); yyerrok;}
       
  3943 | VAR CONSTANT error var_init_decl_list END_VAR
       
  3944 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "unexpected token after 'CONSTANT' in constant variable(s) declaration."); yyerrok;}
       
  3945 | VAR var_init_decl_list error END_OF_INPUT
       
  3946 	{$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed variable(s) declaration."); yyerrok;}
       
  3947 | VAR CONSTANT var_init_decl_list error END_OF_INPUT
       
  3948 	{$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed constant variable(s) declaration."); yyerrok;}
       
  3949 | VAR error END_VAR
       
  3950 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in variable(s) declaration."); yyerrok;}
       
  3951 | VAR CONSTANT error END_VAR
       
  3952 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "unknown error in constant variable(s) declaration."); yyerrok;}
       
  3953 /* ERROR_CHECK_END */
       
  3954 ;
       
  3955 
       
  3956 
       
  3957 retentive_var_declarations:
       
  3958   VAR RETAIN var_init_decl_list END_VAR
       
  3959 	{$$ = new retentive_var_declarations_c($3, locloc(@$));}
       
  3960 /* ERROR_CHECK_BEGIN */
       
  3961 | VAR RETAIN END_VAR
       
  3962 	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable declared in retentive variable(s) declaration."); yynerrs++;}
       
  3963 | VAR RETAIN error var_init_decl_list END_VAR
       
  3964 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "unexpected token after 'RETAIN' in retentive variable(s) declaration."); yyerrok;}
       
  3965 | VAR RETAIN var_init_decl_list error END_OF_INPUT
       
  3966 	{$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed retentive variable(s) declaration."); yyerrok;}
       
  3967 | VAR RETAIN error END_VAR
       
  3968 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "unknown error in retentive variable(s) declaration."); yyerrok;}
       
  3969 /* ERROR_CHECK_END */
       
  3970 ;
       
  3971 
       
  3972 
       
  3973 located_var_declarations:
       
  3974   VAR located_var_decl_list END_VAR
       
  3975 	{$$ = new located_var_declarations_c(NULL, $2, locloc(@$));}
       
  3976 | VAR CONSTANT located_var_decl_list END_VAR
       
  3977 	{$$ = new located_var_declarations_c(new constant_option_c(locloc(@2)), $3, locloc(@$));}
       
  3978 | VAR RETAIN located_var_decl_list END_VAR
       
  3979 	{$$ = new located_var_declarations_c(new retain_option_c(locloc(@2)), $3, locloc(@$));}
       
  3980 | VAR NON_RETAIN located_var_decl_list END_VAR
       
  3981 	{$$ = new located_var_declarations_c(new non_retain_option_c(locloc(@2)), $3, locloc(@$));}
       
  3982 /* ERROR_CHECK_BEGIN */
       
  3983 | VAR NON_RETAIN END_VAR
       
  3984 	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable declared in non-retentive located variable(s) declaration."); yynerrs++;}
       
  3985 | VAR error located_var_decl_list END_VAR
       
  3986 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "unexpected token after 'VAR' in located variable(s) declaration."); yyerrok;}
       
  3987 | VAR CONSTANT error located_var_decl_list END_VAR
       
  3988 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "unexpected token after 'CONSTANT' in constant located variable(s) declaration."); yyerrok;}
       
  3989 | VAR RETAIN error located_var_decl_list END_VAR
       
  3990 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "unexpected token after 'RETAIN' in retentive located variable(s) declaration."); yyerrok;}
       
  3991 | VAR NON_RETAIN error located_var_decl_list END_VAR
       
  3992 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "unexpected token after 'NON_RETAIN' in non-retentive located variable(s) declaration."); yyerrok;}
       
  3993 | VAR located_var_decl_list error END_OF_INPUT
       
  3994 	{$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed located variable(s) declaration."); yyerrok;}
       
  3995 | VAR CONSTANT located_var_decl_list error END_OF_INPUT
       
  3996 	{$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed constant located variable(s) declaration."); yyerrok;}
       
  3997 | VAR RETAIN located_var_decl_list error END_OF_INPUT
       
  3998 	{$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed retentive located variable(s) declaration."); yyerrok;}
       
  3999 | VAR NON_RETAIN located_var_decl_list error END_OF_INPUT
       
  4000 	{$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed non-retentive located variable(s) declaration."); yyerrok;}
       
  4001 | VAR NON_RETAIN error END_VAR
       
  4002 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "unknown error in non retentive variable(s) declaration."); yyerrok;}
       
  4003 /* ERROR_CHECK_END */
       
  4004 ;
       
  4005 
       
  4006 
       
  4007 /* helper symbol for located_var_declarations */
       
  4008 located_var_decl_list:
       
  4009   located_var_decl ';'
       
  4010 	{$$ = new located_var_decl_list_c(locloc(@$)); $$->add_element($1);}
       
  4011 | located_var_decl_list located_var_decl ';'
       
  4012 	{$$ = $1; $$->add_element($2);}
       
  4013 /* ERROR_CHECK_BEGIN */
       
  4014 | error ';'
       
  4015 	{$$ = new located_var_decl_list_c(locloc(@$)); print_err_msg(locf(@1), locl(@1), "invalid located variable declaration."); yyerrok;}
       
  4016 | located_var_decl error
       
  4017 	{$$ = new located_var_decl_list_c(locloc(@$)); print_err_msg(locl(@1), locf(@2), "';' missing at end of located variable declaration."); yyerrok;}
       
  4018 | located_var_decl_list located_var_decl error
       
  4019 	{$$ = $1; print_err_msg(locl(@2), locf(@3), "';' missing at end of located variable declaration."); yyerrok;}
       
  4020 | located_var_decl_list error ';'
       
  4021 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "invalid located variable declaration."); yyerrok;}
       
  4022 | located_var_decl_list ';'
       
  4023 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected ';' after located variable declaration."); yynerrs++;}
       
  4024 /* ERROR_CHECK_END */
       
  4025 ;
       
  4026 
       
  4027 
       
  4028 located_var_decl:
       
  4029   variable_name location ':' located_var_spec_init
       
  4030 	{$$ = new located_var_decl_c($1, $2, $4, locloc(@$));
       
  4031 	 variable_name_symtable.insert($1, prev_declared_variable_name_token);
       
  4032 	}
       
  4033 | location ':' located_var_spec_init
       
  4034 	{$$ = new located_var_decl_c(NULL, $1, $3, locloc(@$));}
       
  4035 /* ERROR_CHECK_BEGIN */
       
  4036 | variable_name location located_var_spec_init
       
  4037 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between located variable location and specification."); yynerrs++;}
       
  4038 | location located_var_spec_init
       
  4039 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between located variable location and specification."); yynerrs++;}
       
  4040 | variable_name location ':' error
       
  4041 	{$$ = NULL;
       
  4042 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no specification defined in located variable declaration.");}
       
  4043 	 else {print_err_msg(locf(@3), locl(@3), "invalid specification in located variable declaration."); yyclearin;}
       
  4044 	 yyerrok;
       
  4045 	}
       
  4046 | location ':' error
       
  4047 	{$$ = NULL;
       
  4048 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no specification defined in located variable declaration.");}
       
  4049 	 else {print_err_msg(locf(@3), locl(@3), "invalid specification in located variable declaration."); yyclearin;}
       
  4050 	 yyerrok;
       
  4051 	}
       
  4052 /* ERROR_CHECK_END */
       
  4053 ;
       
  4054 
       
  4055 
       
  4056 
       
  4057 
       
  4058 external_var_declarations:
       
  4059   VAR_EXTERNAL external_declaration_list END_VAR
       
  4060 	{$$ = new external_var_declarations_c(NULL, $2, locloc(@$));}
       
  4061 | VAR_EXTERNAL CONSTANT external_declaration_list END_VAR
       
  4062 	{$$ = new external_var_declarations_c(new constant_option_c(locloc(@2)), $3, locloc(@$));}
       
  4063 /* ERROR_CHECK_BEGIN */
       
  4064 | VAR_EXTERNAL END_VAR
       
  4065 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "no variable declared in external variable(s) declaration."); yynerrs++;}
       
  4066 | VAR_EXTERNAL CONSTANT END_VAR
       
  4067 	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable declared in constant external variable(s) declaration."); yynerrs++;}
       
  4068 | VAR_EXTERNAL error external_declaration_list END_VAR
       
  4069 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "unexpected token after 'VAR_EXTERNAL' in external variable(s) declaration."); yyerrok;}
       
  4070 | VAR_EXTERNAL CONSTANT error external_declaration_list END_VAR
       
  4071 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "unexpected token after 'CONSTANT' in constant external variable(s) declaration."); yyerrok;}
       
  4072 | VAR_EXTERNAL external_declaration_list error END_OF_INPUT
       
  4073 	{$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed external variable(s) declaration."); yyerrok;}
       
  4074 | VAR_EXTERNAL CONSTANT external_declaration_list error END_OF_INPUT
       
  4075 	{$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed constant external variable(s) declaration."); yyerrok;}
       
  4076 | VAR_EXTERNAL error END_VAR
       
  4077 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in external variable(s) declaration."); yyerrok;}
       
  4078 | VAR_EXTERNAL CONSTANT error END_VAR
       
  4079 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "unknown error in constant external variable(s) declaration."); yyerrok;}
       
  4080 /* ERROR_CHECK_END */
       
  4081 ;
       
  4082 
       
  4083 /* helper symbol for external_var_declarations */
       
  4084 external_declaration_list:
       
  4085   external_declaration ';'
       
  4086 	{$$ = new external_declaration_list_c(locloc(@$)); $$->add_element($1);}
       
  4087 | external_declaration_list external_declaration ';'
       
  4088 	{$$ = $1; $$->add_element($2);}
       
  4089 /* ERROR_CHECK_BEGIN */
       
  4090 | error ';'
       
  4091 	{$$ = new external_declaration_list_c(locloc(@$)); print_err_msg(locf(@1), locl(@1), "invalid external variable declaration."); yyerrok;}
       
  4092 | external_declaration error
       
  4093 	{$$ = new external_declaration_list_c(locloc(@$)); print_err_msg(locl(@1), locf(@2), "';' missing at end of external variable declaration."); yyerrok;}
       
  4094 | external_declaration_list external_declaration error
       
  4095 	{$$ = $1; print_err_msg(locl(@2), locf(@3), "';' missing at end of external variable declaration."); yyerrok;}
       
  4096 | external_declaration_list error ';'
       
  4097 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "invalid external variable declaration."); yyerrok;}
       
  4098 | external_declaration_list ';'
       
  4099 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected ';' after external variable declaration."); yynerrs++;}
       
  4100 /* ERROR_CHECK_END */
       
  4101 ;
       
  4102 
       
  4103 
       
  4104 external_declaration:
       
  4105   global_var_name ':' simple_specification
       
  4106 	{$$ = new external_declaration_c($1, $3, locloc(@$));
       
  4107 	 variable_name_symtable.insert($1, prev_declared_variable_name_token);
       
  4108 	}
       
  4109 | global_var_name ':' subrange_specification
       
  4110 	{$$ = new external_declaration_c($1, $3, locloc(@$));
       
  4111 	 variable_name_symtable.insert($1, prev_declared_variable_name_token);
       
  4112 	}
       
  4113 | global_var_name ':' enumerated_specification
       
  4114 	{$$ = new external_declaration_c($1, $3, locloc(@$));
       
  4115 	 variable_name_symtable.insert($1, prev_declared_variable_name_token);
       
  4116 	}
       
  4117 | global_var_name ':' array_specification
       
  4118 	{$$ = new external_declaration_c($1, $3, locloc(@$));
       
  4119 	 variable_name_symtable.insert($1, prev_declared_variable_name_token);
       
  4120 	}
       
  4121 | global_var_name ':' prev_declared_structure_type_name
       
  4122 	{$$ = new external_declaration_c($1, $3, locloc(@$));
       
  4123 	 variable_name_symtable.insert($1, prev_declared_variable_name_token);
       
  4124 	}
       
  4125 | global_var_name ':' function_block_type_name
       
  4126 	{$$ = new external_declaration_c($1, $3, locloc(@$));
       
  4127 	 variable_name_symtable.insert($1, prev_declared_fb_name_token);
       
  4128 	}
       
  4129 /* ERROR_CHECK_BEGIN */
       
  4130 | global_var_name simple_specification
       
  4131 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between external variable name and simple specification."); yynerrs++;}
       
  4132 | global_var_name subrange_specification
       
  4133 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between external variable name and subrange specification."); yynerrs++;}
       
  4134 | global_var_name enumerated_specification
       
  4135 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between external variable name and enumerated specification."); yynerrs++;}
       
  4136 | global_var_name array_specification
       
  4137 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between external variable name and array specification."); yynerrs++;}
       
  4138 | global_var_name prev_declared_structure_type_name
       
  4139 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between external variable name and structured specification."); yynerrs++;}
       
  4140 | global_var_name function_block_type_name
       
  4141 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between external variable name and function block type specification."); yynerrs++;}
       
  4142 | global_var_name ':' error
       
  4143 	{$$ = NULL;
       
  4144 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no specification defined in external variable declaration.");}
       
  4145 	 else {print_err_msg(locf(@3), locl(@3), "invalid specification in external variable declaration."); yyclearin;}
       
  4146 	 yyerrok;
       
  4147 	}
       
  4148 /* ERROR_CHECK_END */
       
  4149 ;
       
  4150 
       
  4151 
       
  4152 global_var_name: identifier;
       
  4153 
       
  4154 
       
  4155 global_var_declarations:
       
  4156   VAR_GLOBAL global_var_decl_list END_VAR
       
  4157 	{$$ = new global_var_declarations_c(NULL, $2, locloc(@$));}
       
  4158 | VAR_GLOBAL CONSTANT global_var_decl_list END_VAR
       
  4159 	{$$ = new global_var_declarations_c(new constant_option_c(locloc(@2)), $3, locloc(@$));}
       
  4160 | VAR_GLOBAL RETAIN global_var_decl_list END_VAR
       
  4161 	{$$ = new global_var_declarations_c(new retain_option_c(locloc(@2)), $3, locloc(@$));}
       
  4162 /* ERROR_CHECK_BEGIN */
       
  4163 | VAR_GLOBAL END_VAR
       
  4164 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "no variable declared in global variable(s) declaration."); yynerrs++;}
       
  4165 | VAR_GLOBAL CONSTANT END_VAR
       
  4166 	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable declared in constant global variable(s) declaration."); yynerrs++;}
       
  4167 | VAR_GLOBAL RETAIN END_VAR
       
  4168 	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable declared in retentive global variable(s) declaration."); yynerrs++;}
       
  4169 | VAR_GLOBAL error global_var_decl_list END_VAR
       
  4170 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "unexpected token after 'VAR_GLOBAL' in global variable(s) declaration."); yyerrok;}
       
  4171 | VAR_GLOBAL CONSTANT error global_var_decl_list END_VAR
       
  4172 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "unexpected token after 'CONSTANT' in constant global variable(s) declaration."); yyerrok;}
       
  4173 | VAR_GLOBAL RETAIN error global_var_decl_list END_VAR
       
  4174 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "unexpected token after 'RETAIN' in retentive global variable(s) declaration."); yyerrok;}
       
  4175 | VAR_GLOBAL global_var_decl_list error END_OF_INPUT
       
  4176   {$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed global variable(s) declaration."); yyerrok;}
       
  4177 | VAR_GLOBAL CONSTANT global_var_decl_list error END_OF_INPUT
       
  4178   {$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed constant global variable(s) declaration."); yyerrok;}
       
  4179 | VAR_GLOBAL RETAIN global_var_decl_list error END_OF_INPUT
       
  4180   {$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed retentive global variable(s) declaration."); yyerrok;}
       
  4181 | VAR_GLOBAL error END_VAR
       
  4182 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in global variable(s) declaration."); yyerrok;}
       
  4183 | VAR_GLOBAL CONSTANT error END_VAR
       
  4184 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "unknown error in constant global variable(s) declaration."); yyerrok;}
       
  4185 | VAR_GLOBAL RETAIN error END_VAR
       
  4186 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "unknown error in constant global variable(s) declaration."); yyerrok;}
       
  4187 /* ERROR_CHECK_END */
       
  4188 ;
       
  4189 
       
  4190 
       
  4191 /* helper symbol for global_var_declarations */
       
  4192 global_var_decl_list:
       
  4193   global_var_decl ';'
       
  4194 	{$$ = new global_var_decl_list_c(locloc(@$)); $$->add_element($1);}
       
  4195 | global_var_decl_list global_var_decl ';'
       
  4196 	{$$ = $1; $$->add_element($2);}
       
  4197 /* ERROR_CHECK_BEGIN */
       
  4198 | error ';'
       
  4199 	{$$ = new global_var_decl_list_c(locloc(@$)); print_err_msg(locf(@1), locl(@1), "invalid global variable(s) declaration."); yyerrok;}
       
  4200 | global_var_decl error
       
  4201 	{$$ = new global_var_decl_list_c(locloc(@$)); print_err_msg(locl(@1), locf(@2), "';' missing at end of global variable(s) declaration."); yyerrok;}
       
  4202 | global_var_decl_list global_var_decl error
       
  4203 	{$$ = $1; print_err_msg(locl(@1), locf(@2), "';' missing at end of global variable(s) declaration."); yyerrok;}
       
  4204 | global_var_decl_list error ';'
       
  4205 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "invalid global variable(s) declaration."); yyerrok;}
       
  4206 | global_var_decl_list ';'
       
  4207 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected ';' after global variable(s) declaration."); yynerrs++;}
       
  4208 /* ERROR_CHECK_END */
       
  4209 ;
       
  4210 
       
  4211 
       
  4212 global_var_decl:
       
  4213 /* NOTE : This possibility defined in standard has no sense and generate a conflict (disabled)
       
  4214   global_var_spec ':'
       
  4215 	{$$ = new global_var_decl_c($1, NULL, locloc(@$));}
       
  4216 */
       
  4217   global_var_spec ':' located_var_spec_init
       
  4218 	{$$ = new global_var_decl_c($1, $3, locloc(@$));}
       
  4219 | global_var_spec ':' function_block_type_name
       
  4220 	{$$ = new global_var_decl_c($1, $3, locloc(@$));}
       
  4221 /* ERROR_CHECK_BEGIN */
       
  4222 | global_var_list located_var_spec_init
       
  4223 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between global variable list and type specification."); yynerrs++;}
       
  4224 | global_var_name location located_var_spec_init
       
  4225 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between global variable specification and type specification."); yynerrs++;}
       
  4226 | global_var_spec function_block_type_name
       
  4227 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between global variable specification and function block type specification."); yynerrs++;}
       
  4228 | global_var_spec ':' error
       
  4229 	{$$ = NULL;
       
  4230 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no specification defined in global variable declaration.");}
       
  4231 	 else {print_err_msg(locf(@3), locl(@3), "invalid specification in global variable declaration."); yyclearin;}
       
  4232 	 yyerrok;
       
  4233 	}
       
  4234 /* ERROR_CHECK_END */
       
  4235 ;
       
  4236 
       
  4237 
       
  4238 global_var_spec:
       
  4239   global_var_list	{$$ = $1;}
       
  4240 | location
       
  4241 	{$$ = new global_var_spec_c(NULL, $1, locloc(@$));}
       
  4242 | global_var_name location
       
  4243 	{$$ = new global_var_spec_c($1, $2, locloc(@$));
       
  4244 	 variable_name_symtable.insert($1, prev_declared_global_var_name_token);
       
  4245 	}
       
  4246 ;
       
  4247 
       
  4248 
       
  4249 located_var_spec_init:
       
  4250   simple_spec_init
       
  4251 | subrange_spec_init
       
  4252 | enumerated_spec_init
       
  4253 | array_spec_init
       
  4254 | initialized_structure
       
  4255 | single_byte_string_spec
       
  4256 | double_byte_string_spec
       
  4257 ;
       
  4258 
       
  4259 
       
  4260 location:
       
  4261   AT direct_variable_token
       
  4262 	{$$ = new location_c(new direct_variable_c($2, locloc(@$)), locloc(@$));
       
  4263 	 direct_variable_symtable.insert($2, prev_declared_direct_variable_token);
       
  4264 	}
       
  4265 /* ERROR_CHECK_BEGIN */
       
  4266 | AT error
       
  4267 	{$$ = NULL;
       
  4268 	 if (is_current_syntax_token()) {print_err_msg(locl(@1), locf(@2), "no location defined in location declaration.");}
       
  4269 	 else {print_err_msg(locf(@2), locl(@2), "invalid location in global location declaration."); yyclearin;}
       
  4270 	 yyerrok;
       
  4271 	}
       
  4272 /* ERROR_CHECK_END */
       
  4273 ;
       
  4274 
       
  4275 
       
  4276 
       
  4277 global_var_list:
       
  4278   global_var_name
       
  4279 	{$$ = new global_var_list_c(locloc(@$)); $$->add_element($1);
       
  4280 	 variable_name_symtable.insert($1, prev_declared_global_var_name_token);
       
  4281 	}
       
  4282 | global_var_list ',' global_var_name
       
  4283 	{$$ = $1; $$->add_element($3);
       
  4284 	 variable_name_symtable.insert($3, prev_declared_global_var_name_token);
       
  4285 	}
       
  4286 /* ERROR_CHECK_BEGIN */
       
  4287 | global_var_list global_var_name
       
  4288 	{$$ = new global_var_list_c(locloc(@$)); print_err_msg(locl(@1), locf(@2), "',' missing in global variable list."); yynerrs++;}
       
  4289 | global_var_list ',' error
       
  4290 	{$$ = $1;
       
  4291 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no variable name defined in global variable declaration.");}
       
  4292 	 else {print_err_msg(locf(@3), locl(@3), "invalid variable name in global variable declaration."); yyclearin;}
       
  4293 	 yyerrok;
       
  4294 	}
       
  4295 /* ERROR_CHECK_END */
       
  4296 ;
       
  4297 
       
  4298 
       
  4299 
       
  4300 string_var_declaration:
       
  4301   single_byte_string_var_declaration
       
  4302 | double_byte_string_var_declaration
       
  4303 ;
       
  4304 
       
  4305 single_byte_string_var_declaration:
       
  4306   var1_list ':' single_byte_string_spec
       
  4307 	{$$ = new single_byte_string_var_declaration_c($1, $3, locloc(@$));}
       
  4308 /* ERROR_CHECK_BEGIN */
       
  4309 | var1_list single_byte_string_spec
       
  4310 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and string type specification."); yynerrs++;}
       
  4311 /* ERROR_CHECK_END */
       
  4312 ;
       
  4313 
       
  4314 /* NOTE: The constructs
       
  4315  *
       
  4316  *       [W]STRING
       
  4317  *       and
       
  4318  *       [W]STRING ASSIGN single_byte_character_string
       
  4319  *
       
  4320  *       were removed as they are already contained
       
  4321  *       within a other constructs.
       
  4322  *
       
  4323  *       single_byte_string_spec is used in:
       
  4324  *        - single_byte_string_var_declaration ->
       
  4325  *           -> string_var_declaration ---> var_init_decl
       
  4326  *                                     |--> temp_var_decl
       
  4327  *                                     |--> var2_init_decl
       
  4328  *        - located_var_spec_init
       
  4329  *
       
  4330  *       STRING [ASSIGN string_constant] -> elementary_string_type_name ->
       
  4331  *        -> simple_spec -> simple_specification -> simple_spec_init ->
       
  4332  *        -> located_var_spec_init
       
  4333  *
       
  4334  *       STRING [ASSIGN string_constant] -> elementary_string_type_name ->
       
  4335  *        -> simple_spec -> simple_specification -> simple_spec_init ->
       
  4336  *        -> var1_init_decl -> var_init_decl
       
  4337  *
       
  4338  *       STRING [ASSIGN string_constant] -> elementary_string_type_name ->
       
  4339  *        -> simple_spec -> simple_specification -> simple_spec_init ->
       
  4340  *        -> var1_init_decl -> var2_init_decl
       
  4341  *
       
  4342  *       STRING [ASSIGN string_constant] -> elementary_string_type_name ->
       
  4343  *        -> simple_spec -> simple_specification ->
       
  4344  *        -> var1_declaration -> temp_var_decl
       
  4345  */
       
  4346 single_byte_string_spec:
       
  4347 /*  STRING
       
  4348 	{$$ = new single_byte_string_spec_c(NULL, NULL);}
       
  4349 */
       
  4350   STRING '[' integer ']'
       
  4351 	{$$ = new single_byte_string_spec_c(new single_byte_limited_len_string_spec_c(new string_type_name_c(locloc(@1)), $3, locloc(@$)), NULL, locloc(@$));}
       
  4352 /*
       
  4353 | STRING ASSIGN single_byte_character_string
       
  4354 	{$$ = new single_byte_string_spec_c($1, NULL, $3, locloc(@$));}
       
  4355 */
       
  4356 | STRING '[' integer ']' ASSIGN single_byte_character_string
       
  4357 	{$$ = new single_byte_string_spec_c(new single_byte_limited_len_string_spec_c(new string_type_name_c(locloc(@1)), $3, locloc(@$)), $6, locloc(@$));}
       
  4358 /* ERROR_CHECK_BEGIN */
       
  4359 | STRING '[' error ']'
       
  4360 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid length value for limited string type specification."); yyerrok;}
       
  4361 | STRING '[' error ']' ASSIGN single_byte_character_string
       
  4362 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid length value for limited string type specification."); yyerrok;}
       
  4363 | STRING '[' ']'
       
  4364 	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "missing length value for limited string type specification."); yynerrs++;}
       
  4365 | STRING '[' ']' ASSIGN single_byte_character_string
       
  4366 	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "missing length value for limited string type specification."); yynerrs++;}
       
  4367 | STRING '[' integer error
       
  4368 	{$$ = NULL; print_err_msg(locl(@3), locf(@4), "expecting ']' after length definition for limited string type specification."); yyerrok;}
       
  4369 | STRING '[' integer ']' single_byte_character_string
       
  4370 	{$$ = NULL; print_err_msg(locl(@4), locf(@5), "':=' missing before limited string type initialization."); yynerrs++;}
       
  4371 | STRING '[' integer ']' ASSIGN error
       
  4372 	{$$ = NULL;
       
  4373 	 if (is_current_syntax_token()) {print_err_msg(locl(@5), locf(@6), "no initial value defined in limited string type initialization.");}
       
  4374 	 else {print_err_msg(locf(@6), locl(@6), "invalid initial value in limited string type initialization."); yyclearin;}
       
  4375 	 yyerrok;
       
  4376 	}
       
  4377 /* ERROR_CHECK_END */
       
  4378 ;
       
  4379 
       
  4380 
       
  4381 double_byte_string_var_declaration:
       
  4382   var1_list ':' double_byte_string_spec
       
  4383 	{$$ = new double_byte_string_var_declaration_c($1, $3, locloc(@$));}
       
  4384 /* ERROR_CHECK_BEGIN */
       
  4385 | var1_list double_byte_string_spec
       
  4386 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and double byte string type specification."); yynerrs++;}
       
  4387 /* ERROR_CHECK_END */
       
  4388 ;
       
  4389 
       
  4390 double_byte_string_spec:
       
  4391 /*  WSTRING
       
  4392 	{$$ = new double_byte_string_spec_c($1, NULL, NULL, locloc(@$));}
       
  4393 */
       
  4394   WSTRING '[' integer ']'
       
  4395 	{$$ = new double_byte_string_spec_c(new double_byte_limited_len_string_spec_c(new wstring_type_name_c(locloc(@1)), $3, locloc(@$)), NULL, locloc(@$));}
       
  4396 
       
  4397 /*
       
  4398 | WSTRING ASSIGN double_byte_character_string
       
  4399 	{$$ = new double_byte_string_spec_c($1, NULL, $3, locloc(@$));}
       
  4400 */
       
  4401 | WSTRING '[' integer ']' ASSIGN double_byte_character_string
       
  4402 	{$$ = new double_byte_string_spec_c(new double_byte_limited_len_string_spec_c(new wstring_type_name_c(locloc(@1)), $3, locloc(@$)), $6, locloc(@$));}
       
  4403 /* ERROR_CHECK_BEGIN */
       
  4404 | WSTRING '[' error ']'
       
  4405 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid length value for limited double byte string type specification."); yyerrok;}
       
  4406 | WSTRING '[' error ']' ASSIGN single_byte_character_string
       
  4407 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid length value for limited double byte string type specification."); yyerrok;}
       
  4408 | WSTRING '[' ']'
       
  4409 	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "missing length value for limited double byte string type specification."); yynerrs++;}
       
  4410 | WSTRING '[' ']' ASSIGN single_byte_character_string
       
  4411 	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "missing length value for limited double byte string type specification."); yynerrs++;}
       
  4412 | WSTRING '[' integer error
       
  4413 	{$$ = NULL; print_err_msg(locl(@3), locf(@4), "expecting ']' after length definition for limited double byte string type specification."); yyerrok;}
       
  4414 | WSTRING '[' integer ']' single_byte_character_string
       
  4415 	{$$ = NULL; print_err_msg(locl(@4), locf(@5), "':=' missing before limited double byte string type initialization."); yynerrs++;}
       
  4416 | WSTRING '[' integer ']' ASSIGN error
       
  4417 	{$$ = NULL;
       
  4418 	 if (is_current_syntax_token()) {print_err_msg(locl(@5), locf(@6), "no initial value defined double byte in limited string type initialization.");}
       
  4419 	 else {print_err_msg(locf(@6), locl(@6), "invalid initial value in limited double byte string type initialization."); yyclearin;}
       
  4420 	 yyerrok;
       
  4421 	}
       
  4422 /* ERROR_CHECK_END */
       
  4423 ;
       
  4424 
       
  4425 
       
  4426 
       
  4427 incompl_located_var_declarations:
       
  4428   VAR            incompl_located_var_decl_list END_VAR
       
  4429 	{$$ = new incompl_located_var_declarations_c(NULL, $2, locloc(@$));}
       
  4430 | VAR     RETAIN incompl_located_var_decl_list END_VAR
       
  4431 	{$$ = new incompl_located_var_declarations_c(new retain_option_c(locloc(@2)), $3, locloc(@$));}
       
  4432 | VAR NON_RETAIN incompl_located_var_decl_list END_VAR
       
  4433 	{$$ = new incompl_located_var_declarations_c(new non_retain_option_c(locloc(@2)), $3, locloc(@$));}
       
  4434 /* ERROR_CHECK_BEGIN */
       
  4435 | VAR incompl_located_var_decl_list error END_OF_INPUT
       
  4436   {$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed incomplete located variable(s) declaration."); yyerrok;}
       
  4437 | VAR RETAIN incompl_located_var_decl_list error END_OF_INPUT
       
  4438   {$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed incomplete retentive located variable(s) declaration."); yyerrok;}
       
  4439 | VAR NON_RETAIN incompl_located_var_decl_list error END_OF_INPUT
       
  4440   {$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed incomplete non-retentive located variable(s) declaration."); yyerrok;}
       
  4441 | VAR error incompl_located_var_decl_list END_VAR
       
  4442 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "unexpected token after 'VAR' in incomplete located variable(s) declaration."); yyerrok;}
       
  4443 | VAR RETAIN error incompl_located_var_decl_list END_VAR
       
  4444 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "unexpected token after 'RETAIN' in retentive located variable(s) declaration."); yyerrok;}
       
  4445 | VAR NON_RETAIN error incompl_located_var_decl_list END_VAR
       
  4446 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "unexpected token after 'NON_RETAIN' in non-retentive located variable(s) declaration."); yyerrok;}
       
  4447 /* ERROR_CHECK_END */
       
  4448 ;
       
  4449 
       
  4450 /* helper symbol for incompl_located_var_declarations */
       
  4451 incompl_located_var_decl_list:
       
  4452   incompl_located_var_decl ';'
       
  4453 	{$$ = new incompl_located_var_decl_list_c(locloc(@$)); $$->add_element($1);}
       
  4454 | incompl_located_var_decl_list incompl_located_var_decl ';'
       
  4455 	{$$ = $1; $$->add_element($2);}
       
  4456 /* ERROR_CHECK_BEGIN */
       
  4457 | incompl_located_var_decl error
       
  4458 	{$$ = new incompl_located_var_decl_list_c(locloc(@$)); print_err_msg(locl(@1), locf(@2), "';' missing at end of incomplete located variable declaration."); yyerrok;}
       
  4459 | incompl_located_var_decl_list incompl_located_var_decl error
       
  4460 	{$$ = $1; print_err_msg(locl(@2), locf(@3), "';' missing at end of incomplete located variable declaration."); yyerrok;}
       
  4461 | incompl_located_var_decl_list error ';'
       
  4462 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "invalid incomplete located variable declaration."); yyerrok;}
       
  4463 | incompl_located_var_decl_list ';'
       
  4464 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected ';' after incomplete located variable declaration."); yynerrs++;}
       
  4465 /* ERROR_CHECK_END */
       
  4466 ;
       
  4467 
       
  4468 
       
  4469 incompl_located_var_decl:
       
  4470   variable_name incompl_location ':' var_spec
       
  4471 	{$$ = new incompl_located_var_decl_c($1, $2, $4, locloc(@$));}
       
  4472 /* ERROR_CHECK_BEGIN */
       
  4473 | variable_name incompl_location var_spec
       
  4474 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between incomplete located variable and type specification."); yynerrs++;
       
  4475 	}
       
  4476 | variable_name incompl_location ':' error
       
  4477 	{$$ = NULL;
       
  4478 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no specification defined in incomplete located variable declaration.");}
       
  4479 	 else {print_err_msg(locf(@3), locl(@3), "invalid specification in incomplete located variable declaration."); yyclearin;}
       
  4480 	 yyerrok;
       
  4481 	}
       
  4482 /* ERROR_CHECK_END */
       
  4483 ;
       
  4484 
       
  4485 
       
  4486 incompl_location:
       
  4487   AT incompl_location_token
       
  4488 	{$$ = new incompl_location_c($2, locloc(@$));}
       
  4489 ;
       
  4490 
       
  4491 
       
  4492 var_spec:
       
  4493   simple_specification
       
  4494 | subrange_specification
       
  4495 | enumerated_specification
       
  4496 | array_specification
       
  4497 | prev_declared_structure_type_name
       
  4498 | string_spec
       
  4499 ;
       
  4500 
       
  4501 
       
  4502 /* helper symbol for var_spec */
       
  4503 string_spec:
       
  4504 /*  STRING
       
  4505 	{$$ = new single_byte_limited_len_string_spec_c($1, NULL, locloc(@$));}
       
  4506 */
       
  4507   STRING '[' integer ']'
       
  4508 	{$$ = new single_byte_limited_len_string_spec_c(new string_type_name_c(locloc(@1)), $3, locloc(@$));}
       
  4509 /*
       
  4510 | WSTRING
       
  4511 	{$$ = new double_byte_limited_len_string_spec_c($1, NULL, locloc(@$));}
       
  4512 */
       
  4513 | WSTRING '[' integer ']'
       
  4514 	{$$ = new double_byte_limited_len_string_spec_c(new wstring_type_name_c(locloc(@1)), $3, locloc(@$));}
       
  4515 ;
       
  4516 
       
  4517 
       
  4518 
       
  4519 
       
  4520 /* intermediate helper symbol for:
       
  4521  *  - non_retentive_var_decls
       
  4522  *  - var_declarations
       
  4523  */
       
  4524 var_init_decl_list:
       
  4525   var_init_decl ';'
       
  4526 	{$$ = new var_init_decl_list_c(locloc(@$)); $$->add_element($1);}
       
  4527 | var_init_decl_list var_init_decl ';'
       
  4528 	{$$ = $1; $$->add_element($2);}
       
  4529 /* ERROR_CHECK_BEGIN */
       
  4530 | var_init_decl_list var_init_decl error
       
  4531 	{$$ = $1; print_err_msg(locl(@2), locf(@3), "';' missing at end of variable(s) declaration."); yyerrok;}
       
  4532 | var_init_decl_list error ';'
       
  4533 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "invalid variable(s) declaration."); yyerrok;}
       
  4534 /* ERROR_CHECK_END */
       
  4535 ;
       
  4536 
       
  4537 
       
  4538 
       
  4539 
       
  4540 /***********************/
       
  4541 /* B 1.5.1 - Functions */
       
  4542 /***********************/
       
  4543 /*
       
  4544 function_name:
       
  4545   prev_declared_derived_function_name
       
  4546 | standard_function_name 
       
  4547 ;
       
  4548 */
       
  4549 
       
  4550 /* The following rules should be set such as:
       
  4551  * function_name: function_name_no_clashes | function_name_simpleop_clashes | function_name_expression_clashes
       
  4552  * function_name: function_name_no_NOT_clashes | function_name_NOT_clashes;
       
  4553  */
       
  4554 
       
  4555 function_name_no_clashes: prev_declared_derived_function_name | standard_function_name_no_clashes;
       
  4556 function_name_simpleop_clashes: standard_function_name_simpleop_clashes;
       
  4557 //function_name_expression_clashes: standard_function_name_expression_clashes;
       
  4558 
       
  4559 function_name_no_NOT_clashes: prev_declared_derived_function_name | standard_function_name_no_NOT_clashes;
       
  4560 //function_name_NOT_clashes: standard_function_name_NOT_clashes;
       
  4561 
       
  4562 
       
  4563 /* NOTE: The list of standard function names
       
  4564  *       includes the standard functions MOD(), NOT()
       
  4565  *
       
  4566  *       Strangely enough, MOD and NOT are reserved keywords,
       
  4567  *       so shouldn't be used for function names.
       
  4568  *
       
  4569  *       The specification contradicts itself!
       
  4570  *       Our workaround  is to treat MOD as a token,
       
  4571  *       but to include this token as a
       
  4572  *       standard_function_name.
       
  4573  *
       
  4574  *       The names of all other standard functions get
       
  4575  *       preloaded into the library_element_symbol_table
       
  4576  *       with the token value of
       
  4577  *       standard_function_name_token
       
  4578  *       Actually, simply for completeness, MOD is also
       
  4579  *       loaded into the library_element_symbol_table, but
       
  4580  *       it is irrelevant since flex will catch MOD as a
       
  4581  *       token, before it interprets it as an identifier,
       
  4582  *       and looks in the library_element_symbol_table to check
       
  4583  *       whether it has been previously declared.
       
  4584  *
       
  4585  * NOTE: The same as the above also occurs with the IL
       
  4586  *       operators NOT AND OR XOR ADD SUB MUL DIV MOD
       
  4587  *       GT GE EQ LT LE NE.
       
  4588  *       Note that MOD is once again in the list!
       
  4589  *       Anyway, we give these the same treatement as
       
  4590  *       MOD, since we are writing a parser for ST and
       
  4591  *       IL simultaneously. If this were not the case,
       
  4592  *       the ST parser would not need the tokens NOT AND ...
       
  4593  *
       
  4594  * NOTE: Note that 'NOT' is special, as it conflicts
       
  4595  *       with two operators: the  IL 'NOT' operator, and
       
  4596  *       the unary operator 'NOT' in ST!!
       
  4597  *
       
  4598  * NOTE: The IL language is ambiguous, since using NOT, AND, ...
       
  4599  *       may be interpreted as either an IL operator, or
       
  4600  *       as a standard function call!
       
  4601  *       I (Mario) opted to interpret it as an IL operator.
       
  4602  *       This requires changing the syntax for IL language
       
  4603  *       function   calling, to exclude all function with
       
  4604  *       names that clash with IL operators. I therefore
       
  4605  *       created the constructs
       
  4606  *       function_name_without_clashes
       
  4607  *       standard_function_name_without_clashes
       
  4608  *       to include all function names, except those that clash
       
  4609  *       with IL operators. These constructs are only used
       
  4610  *       within the IL language!
       
  4611  */
       
  4612 /* The following rules should be set such as:
       
  4613  * standard_function_name: standard_function_name_no_clashes | standard_function_name_simpleop_clashes | standard_function_name_expression_clashes
       
  4614  * standard_function_name: standard_function_name_no_NOT_clashes | standard_function_name_NOT_clashes;
       
  4615  */
       
  4616 
       
  4617 /*
       
  4618 standard_function_name:
       
  4619   standard_function_name_no_clashes
       
  4620 | standard_function_name_expression_clashes
       
  4621 | standard_function_name_NOT_clashes
       
  4622 //| standard_function_name_simpleop_only_clashes
       
  4623 ;
       
  4624 */
       
  4625 
       
  4626 standard_function_name_no_NOT_clashes:
       
  4627   standard_function_name_no_clashes
       
  4628 | standard_function_name_expression_clashes
       
  4629 //| standard_function_name_simpleop_only_clashes
       
  4630 ;
       
  4631 
       
  4632 standard_function_name_no_clashes:
       
  4633   standard_function_name_token
       
  4634 	{$$ = new identifier_c($1, locloc(@$));}
       
  4635 ;
       
  4636 
       
  4637 
       
  4638 standard_function_name_simpleop_clashes:
       
  4639   standard_function_name_NOT_clashes
       
  4640 //| standard_function_name_simpleop_only_clashes
       
  4641 ;
       
  4642 
       
  4643 standard_function_name_NOT_clashes:
       
  4644   NOT
       
  4645 	{$$ = new identifier_c(strdup("NOT"), locloc(@$));}
       
  4646 ;
       
  4647 
       
  4648 /* Add here any other IL simple operators that collide
       
  4649  * with standard function names!
       
  4650  * Don't forget to uncomment the equivalent lines in
       
  4651  *   - standard_function_name_simpleop_clashes
       
  4652  *   - standard_function_name
       
  4653  *   - standard_function_name_no_NOT_clashes
       
  4654  */
       
  4655 /*
       
  4656 standard_function_name_simpleop_only_clashes:
       
  4657 ;
       
  4658 */
       
  4659 
       
  4660 standard_function_name_expression_clashes:
       
  4661   AND	{$$ = new identifier_c(strdup("AND"), locloc(@$));}
       
  4662 | OR	{$$ = new identifier_c(strdup("OR"), locloc(@$));}
       
  4663 | XOR	{$$ = new identifier_c(strdup("XOR"), locloc(@$));}
       
  4664 | ADD	{$$ = new identifier_c(strdup("ADD"), locloc(@$));}
       
  4665 | SUB	{$$ = new identifier_c(strdup("SUB"), locloc(@$));}
       
  4666 | MUL	{$$ = new identifier_c(strdup("MUL"), locloc(@$));}
       
  4667 | DIV	{$$ = new identifier_c(strdup("DIV"), locloc(@$));}
       
  4668 | MOD	{$$ = new identifier_c(strdup("MOD"), locloc(@$));}
       
  4669 | GT	{$$ = new identifier_c(strdup("GT"), locloc(@$));}
       
  4670 | GE	{$$ = new identifier_c(strdup("GE"), locloc(@$));}
       
  4671 | EQ	{$$ = new identifier_c(strdup("EQ"), locloc(@$));}
       
  4672 | LT	{$$ = new identifier_c(strdup("LT"), locloc(@$));}
       
  4673 | LE	{$$ = new identifier_c(strdup("LE"), locloc(@$));}
       
  4674 | NE	{$$ = new identifier_c(strdup("NE"), locloc(@$));}
       
  4675 /*
       
  4676   AND_operator	{$$ = il_operator_c_2_identifier_c($1);}
       
  4677 //NOTE: AND2 (corresponding to the source code string '&') does not clash
       
  4678 //      with a standard function name, so should be commented out!
       
  4679 //| AND2_operator	{$$ = il_operator_c_2_identifier_c($1);}
       
  4680 | OR_operator	{$$ = il_operator_c_2_identifier_c($1);}
       
  4681 | XOR_operator	{$$ = il_operator_c_2_identifier_c($1);}
       
  4682 | ADD_operator	{$$ = il_operator_c_2_identifier_c($1);}
       
  4683 | SUB_operator	{$$ = il_operator_c_2_identifier_c($1);}
       
  4684 | MUL_operator	{$$ = il_operator_c_2_identifier_c($1);}
       
  4685 | DIV_operator	{$$ = il_operator_c_2_identifier_c($1);}
       
  4686 | MOD_operator	{$$ = il_operator_c_2_identifier_c($1);}
       
  4687 | GT_operator	{$$ = il_operator_c_2_identifier_c($1);}
       
  4688 | GE_operator	{$$ = il_operator_c_2_identifier_c($1);}
       
  4689 | EQ_operator	{$$ = il_operator_c_2_identifier_c($1);}
       
  4690 | LT_operator	{$$ = il_operator_c_2_identifier_c($1);}
       
  4691 | LE_operator	{$$ = il_operator_c_2_identifier_c($1);}
       
  4692 | NE_operator	{$$ = il_operator_c_2_identifier_c($1);}
       
  4693 */
       
  4694 ;
       
  4695 
       
  4696 
       
  4697 derived_function_name:
       
  4698   identifier
       
  4699 | prev_declared_derived_function_name
       
  4700 	{$$ = $1;
       
  4701 	 if (!allow_function_overloading) {
       
  4702 	   fprintf(stderr, "Function overloading not allowed. Invalid identifier %s\n", ((token_c *)($1))->value);
       
  4703 	   ERROR;
       
  4704 	 }
       
  4705 	}
       
  4706 | AND
       
  4707 	{$$ = new identifier_c("AND", locloc(@$));
       
  4708 	 if (!allow_function_overloading) print_err_msg(locloc(@1), "Function overloading \"AND\" not allowed. Invalid identifier\n");
       
  4709 	}
       
  4710 | OR
       
  4711 	{$$ = new identifier_c("OR", locloc(@$));
       
  4712 	 if (!allow_function_overloading) print_err_msg(locloc(@1), "Function overloading \"OR\" not allowed. Invalid identifier\n");
       
  4713 	}
       
  4714 | XOR
       
  4715 	{$$ = new identifier_c("XOR", locloc(@$));
       
  4716 	 if (!allow_function_overloading) print_err_msg(locloc(@1), "Function overloading \"XOR\" not allowed. Invalid identifier\n");
       
  4717 	}
       
  4718 | NOT
       
  4719 	{$$ = new identifier_c("NOT", locloc(@$));
       
  4720 	 if (!allow_function_overloading) print_err_msg(locloc(@1), "Function overloading \"NOT\" not allowed. Invalid identifier\n");
       
  4721 	}
       
  4722 | MOD
       
  4723 	{$$ = new identifier_c("MOD", locloc(@$));
       
  4724 	 if (!allow_function_overloading) print_err_msg(locloc(@1), "Function overloading \"MOD\" not allowed. Invalid identifier\n");
       
  4725 	}
       
  4726 ;
       
  4727 
       
  4728 
       
  4729 function_declaration:
       
  4730 /*  FUNCTION derived_function_name ':' elementary_type_name io_OR_function_var_declarations_list function_body END_FUNCTION */
       
  4731   function_name_declaration ':' elementary_type_name io_OR_function_var_declarations_list function_body END_FUNCTION
       
  4732 	{$$ = new function_declaration_c($1, $3, $4, $5, locloc(@$));
       
  4733 	 add_en_eno_param_decl_c::add_to($$); /* add EN and ENO declarations, if not already there */
       
  4734 	 variable_name_symtable.pop();
       
  4735 	 direct_variable_symtable.pop();
       
  4736 	 if (allow_function_overloading) {
       
  4737 	   switch (library_element_symtable.find_value($1)) {
       
  4738 	     case prev_declared_derived_function_name_token:
       
  4739 	       /* do nothing, already in map. */
       
  4740 	       break;
       
  4741 	     case BOGUS_TOKEN_ID:
       
  4742 	       /* Not yet in map. Must insert...*/
       
  4743 	       library_element_symtable.insert($1, prev_declared_derived_function_name_token);
       
  4744 	       break;
       
  4745 	     default:
       
  4746 	       /* Already in map but associated with something else other than a funtion name! */
       
  4747 	       ERROR;
       
  4748 	   }
       
  4749 	 } else {
       
  4750 	   library_element_symtable.insert($1, prev_declared_derived_function_name_token);
       
  4751 	 }
       
  4752 	}
       
  4753 /* | FUNCTION derived_function_name ':' derived_type_name io_OR_function_var_declarations_list function_body END_FUNCTION */
       
  4754 | function_name_declaration ':' derived_type_name io_OR_function_var_declarations_list function_body END_FUNCTION
       
  4755 	{$$ = new function_declaration_c($1, $3, $4, $5, locloc(@$));
       
  4756 	 add_en_eno_param_decl_c::add_to($$); /* add EN and ENO declarations, if not already there */
       
  4757 	 variable_name_symtable.pop();
       
  4758 	 direct_variable_symtable.pop();
       
  4759 	 if (allow_function_overloading) {
       
  4760 	   switch (library_element_symtable.find_value($1)) {
       
  4761 	     case prev_declared_derived_function_name_token: /* do nothing, already in map. */ break;
       
  4762 	     case BOGUS_TOKEN_ID: library_element_symtable.insert($1, prev_declared_derived_function_name_token); break;
       
  4763 	     default: ERROR;
       
  4764 	   }
       
  4765 	 } else {
       
  4766 	   library_element_symtable.insert($1, prev_declared_derived_function_name_token);
       
  4767 	 }
       
  4768 	}
       
  4769 /* ERROR_CHECK_BEGIN */
       
  4770 | function_name_declaration elementary_type_name io_OR_function_var_declarations_list function_body END_FUNCTION
       
  4771 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing after function name in function declaration."); yynerrs++;}
       
  4772 | function_name_declaration derived_type_name io_OR_function_var_declarations_list function_body END_FUNCTION
       
  4773 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing after function name in function declaration."); yynerrs++;}
       
  4774 | function_name_declaration ':' io_OR_function_var_declarations_list function_body END_FUNCTION
       
  4775 	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "no return type defined in function declaration."); yynerrs++;}
       
  4776 | function_name_declaration ':' error io_OR_function_var_declarations_list function_body END_FUNCTION
       
  4777 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid return type defined in function declaration."); yyerrok;}
       
  4778 | function_name_declaration ':' elementary_type_name function_body END_FUNCTION
       
  4779 	{$$ = NULL; print_err_msg(locl(@3), locf(@4), "no variable(s) declared in function declaration."); yynerrs++;}
       
  4780 | function_name_declaration ':' derived_type_name function_body END_FUNCTION
       
  4781 	{$$ = NULL; print_err_msg(locl(@3), locf(@4), "no variable(s) declared in function declaration."); yynerrs++;}
       
  4782 | function_name_declaration ':' elementary_type_name io_OR_function_var_declarations_list END_FUNCTION
       
  4783 	{$$ = NULL; print_err_msg(locl(@4), locf(@5), "no body defined in function declaration."); yynerrs++;}
       
  4784 | function_name_declaration ':' derived_type_name io_OR_function_var_declarations_list END_FUNCTION
       
  4785 	{$$ = NULL; print_err_msg(locl(@4), locf(@5), "no body defined in function declaration."); yynerrs++;}
       
  4786 | function_name_declaration ':' elementary_type_name END_FUNCTION
       
  4787 	{$$ = NULL; print_err_msg(locl(@3), locf(@4), "no variable(s) declared and body defined in function declaration."); yynerrs++;}
       
  4788 | function_name_declaration ':' derived_type_name END_FUNCTION
       
  4789 	{$$ = NULL; print_err_msg(locl(@3), locf(@4), "no variable(s) declared and body defined in function declaration."); yynerrs++;}
       
  4790 | function_name_declaration ':' elementary_type_name io_OR_function_var_declarations_list function_body END_OF_INPUT
       
  4791 	{$$ = NULL; print_err_msg(locf(@1), locf(@3), "unclosed function declaration."); yynerrs++;}
       
  4792 | function_name_declaration ':' derived_type_name io_OR_function_var_declarations_list function_body END_OF_INPUT
       
  4793 	{$$ = NULL; print_err_msg(locf(@1), locl(@3), "unclosed function declaration."); yynerrs++;}
       
  4794 | function_name_declaration error END_FUNCTION
       
  4795 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in function declaration."); yyerrok;}
       
  4796 /* ERROR_CHECK_END */
       
  4797 ;
       
  4798 
       
  4799 
       
  4800 
       
  4801 /* helper symbol for function_declaration */
       
  4802 /* NOTE: due to reduce/reduce conflicts between identifiers
       
  4803  *       being reduced to either a variable or an enumerator value,
       
  4804  *       we were forced to keep a symbol table of the names
       
  4805  *       of all declared variables. Variables are no longer
       
  4806  *       created from simple identifier_token, but from
       
  4807  *       prev_declared_variable_name_token.
       
  4808  *
       
  4809  *       BUT, in functions the function name itself may be used as
       
  4810  *       a variable! In order to be able to parse this correctly,
       
  4811  *       the token parser (flex) must return a prev_declared_variable_name_token
       
  4812  *       when it comes across the function name, while parsing
       
  4813  *       the function itself.
       
  4814  *       We do this by inserting the function name into the variable
       
  4815  *       symbol table, and having flex return a prev_declared_variable_name_token
       
  4816  *       whenever it comes across it.
       
  4817  *       When we finish parsing the function the variable name
       
  4818  *       symbol table is cleared of all entries, and the function
       
  4819  *       name is inserted into the library element symbol table. This
       
  4820  *       means that from then onwards flex will return a
       
  4821  *       derived_function_name_token whenever it comes across the
       
  4822  *       function name.
       
  4823  *
       
  4824  *       In order to insert the function name into the variable_name
       
  4825  *       symbol table BEFORE the function body gets parsed, we
       
  4826  *       need the parser to reduce a construct that contains the
       
  4827  *       the function name. That is why we created this extra
       
  4828  *       construct (function_name_declaration), i.e. to force
       
  4829  *       the parser to reduce it, before parsing the function body!
       
  4830  */
       
  4831 function_name_declaration:
       
  4832   FUNCTION derived_function_name
       
  4833 	{$$ = $2;
       
  4834 	 /* the function name functions as a
       
  4835 	  * variable within the function itself!
       
  4836 	  *
       
  4837 	  * Remember that the variable_name_symtable
       
  4838 	  * is cleared once the end of the function
       
  4839 	  * is parsed.
       
  4840 	  */
       
  4841 	 variable_name_symtable.insert($2, prev_declared_variable_name_token);
       
  4842 	}
       
  4843 /* ERROR_CHECK_BEGIN */
       
  4844 | FUNCTION error 
       
  4845 	{$$ = NULL;
       
  4846 	 if (is_current_syntax_token()) {print_err_msg(locl(@1), locf(@2), "no function name defined in function declaration.");}
       
  4847 	 else {print_err_msg(locf(@2), locl(@2), "invalid function name in function declaration."); yyclearin;}
       
  4848 	 yyerrok;
       
  4849 	}
       
  4850 /* ERROR_CHECK_END */
       
  4851 ;
       
  4852 
       
  4853 
       
  4854 
       
  4855 /* intermediate helper symbol for function_declaration */
       
  4856 io_OR_function_var_declarations_list:
       
  4857   io_var_declarations
       
  4858   {$$ = new var_declarations_list_c(locloc(@1));$$->add_element($1);}
       
  4859 | function_var_decls
       
  4860 	{$$ = new var_declarations_list_c(locloc(@1));$$->add_element($1);}
       
  4861 | io_OR_function_var_declarations_list io_var_declarations
       
  4862 	{$$ = $1; $$->add_element($2);}
       
  4863 | io_OR_function_var_declarations_list function_var_decls
       
  4864 	{$$ = $1; $$->add_element($2);}
       
  4865 /* ERROR_CHECK_BEGIN */
       
  4866 | io_OR_function_var_declarations_list retentive_var_declarations
       
  4867 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected retentive variable(s) declaration in function declaration."); yynerrs++;}
       
  4868 | io_OR_function_var_declarations_list located_var_declarations
       
  4869 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected located variable(s) declaration in function declaration."); yynerrs++;}
       
  4870 | io_OR_function_var_declarations_list external_var_declarations
       
  4871 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected external variable(s) declaration in function declaration."); yynerrs++;}
       
  4872 | io_OR_function_var_declarations_list global_var_declarations
       
  4873 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected global variable(s) declaration in function declaration."); yynerrs++;}
       
  4874 | io_OR_function_var_declarations_list incompl_located_var_declarations
       
  4875 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected incomplete located variable(s) declaration in function declaration."); yynerrs++;}
       
  4876 | io_OR_function_var_declarations_list temp_var_decls
       
  4877 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected temporary located variable(s) declaration in function declaration."); yynerrs++;}
       
  4878 | io_OR_function_var_declarations_list non_retentive_var_decls
       
  4879 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected non-retentive variable(s) declaration in function declaration."); yynerrs++;}
       
  4880 /*| io_OR_function_var_declarations_list access_declarations
       
  4881 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected access variable(s) declaration in function declaration."); yynerrs++;}*/
       
  4882 | io_OR_function_var_declarations_list instance_specific_initializations
       
  4883 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected instance specific initialization(s) in function declaration."); yynerrs++;}
       
  4884 /* ERROR_CHECK_END */
       
  4885 ;
       
  4886 
       
  4887 
       
  4888 io_var_declarations:
       
  4889   input_declarations
       
  4890 | output_declarations
       
  4891 | input_output_declarations
       
  4892 ;
       
  4893 
       
  4894 
       
  4895 function_var_decls:
       
  4896   VAR CONSTANT var2_init_decl_list END_VAR
       
  4897 	{$$ = new function_var_decls_c(new constant_option_c(locloc(@2)), $3, locloc(@$));}
       
  4898 | VAR var2_init_decl_list END_VAR
       
  4899 	{$$ = new function_var_decls_c(NULL, $2, locloc(@$));}
       
  4900 /* ERROR_CHECK_BEGIN */
       
  4901 | VAR error var2_init_decl_list END_VAR
       
  4902 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "unexpected token after 'VAR' in function variable(s) declaration."); yyerrok;}
       
  4903 | VAR CONSTANT error var2_init_decl_list END_VAR
       
  4904 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "unexpected token after 'CONSTANT' in constant function variable(s) declaration."); yyerrok;}
       
  4905 | VAR var2_init_decl_list error END_OF_INPUT
       
  4906 	{$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed function variable(s) declaration."); yyerrok;}
       
  4907 | VAR CONSTANT var2_init_decl_list error END_OF_INPUT
       
  4908 	{$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed constant function variable(s) declaration."); yyerrok;}
       
  4909 /* ERROR_CHECK_END */
       
  4910 ;
       
  4911 
       
  4912 /* intermediate helper symbol for function_var_decls */
       
  4913 var2_init_decl_list:
       
  4914   var2_init_decl ';'
       
  4915 	{$$ = new var2_init_decl_list_c(locloc(@$)); $$->add_element($1);}
       
  4916 | var2_init_decl_list var2_init_decl ';'
       
  4917 	{$$ = $1; $$->add_element($2);}
       
  4918 /* ERROR_CHECK_BEGIN */
       
  4919 | var2_init_decl error
       
  4920 	{$$ = new var2_init_decl_list_c(locloc(@$)); print_err_msg(locl(@1), locf(@2), "';' missing at end of function variable(s) declaration."); yyerrok;}
       
  4921 | var2_init_decl_list var2_init_decl error
       
  4922 	{$$ = $1; print_err_msg(locl(@2), locf(@3), "';' missing at end of function variable(s) declaration."); yyerrok;}
       
  4923 | var2_init_decl_list error ';'
       
  4924 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "invalid function variable(s) declaration."); yyerrok;}
       
  4925 | var2_init_decl_list ';'
       
  4926 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected ';' after function variable(s) declaration."); yynerrs++;}
       
  4927 /* ERROR_CHECK_END */
       
  4928 ;
       
  4929 
       
  4930 
       
  4931 function_body:
       
  4932   statement_list	{$$ = $1;} /* if we leave it for the default action we get a type clash! */
       
  4933 | instruction_list	{$$ = $1;} /* if we leave it for the default action we get a type clash! */
       
  4934 /*
       
  4935 | ladder_diagram
       
  4936 | function_block_diagram
       
  4937 */
       
  4938 ;
       
  4939 
       
  4940 
       
  4941 var2_init_decl:
       
  4942   var1_init_decl
       
  4943 | array_var_init_decl
       
  4944 | structured_var_init_decl
       
  4945 | string_var_declaration
       
  4946 ;
       
  4947 
       
  4948 
       
  4949 
       
  4950 /*****************************/
       
  4951 /* B 1.5.2 - Function Blocks */
       
  4952 /*****************************/
       
  4953 function_block_type_name:
       
  4954   prev_declared_derived_function_block_name
       
  4955 | standard_function_block_name
       
  4956 ;
       
  4957 
       
  4958 
       
  4959 standard_function_block_name: standard_function_block_name_token {$$ = new identifier_c($1, locloc(@$));};
       
  4960 
       
  4961 derived_function_block_name: identifier;
       
  4962 
       
  4963 
       
  4964 function_block_declaration:
       
  4965   FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations_list function_block_body END_FUNCTION_BLOCK
       
  4966 	{$$ = new function_block_declaration_c($2, $3, $4, locloc(@$));
       
  4967 	 add_en_eno_param_decl_c::add_to($$); /* add EN and ENO declarations, if not already there */
       
  4968 	 library_element_symtable.insert($2, prev_declared_derived_function_block_name_token);
       
  4969 	 /* Clear the variable_name_symtable. Since
       
  4970 	  * we have finished parsing the function block,
       
  4971 	  * the variable names are now out of scope, so
       
  4972 	  * are no longer valid!
       
  4973 	  */
       
  4974 	 variable_name_symtable.pop();
       
  4975 	 direct_variable_symtable.pop();
       
  4976 	}
       
  4977 /* ERROR_CHECK_BEGIN */
       
  4978 | FUNCTION_BLOCK io_OR_other_var_declarations_list function_block_body END_FUNCTION_BLOCK
       
  4979   {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no function block name defined in function block declaration."); yynerrs++;}
       
  4980 | FUNCTION_BLOCK error io_OR_other_var_declarations_list function_block_body END_FUNCTION_BLOCK
       
  4981 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid function block name in function block declaration."); yyerrok;}
       
  4982 | FUNCTION_BLOCK derived_function_block_name function_block_body END_FUNCTION_BLOCK
       
  4983 	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable(s) declared in function declaration."); yynerrs++;}
       
  4984 | FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations_list END_FUNCTION_BLOCK
       
  4985 	{$$ = NULL; print_err_msg(locl(@3), locf(@4), "no body defined in function block declaration."); yynerrs++;}
       
  4986 | FUNCTION_BLOCK derived_function_block_name END_FUNCTION_BLOCK
       
  4987 	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable(s) declared and body defined in function block declaration."); yynerrs++;}
       
  4988 | FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations_list function_block_body END_OF_INPUT
       
  4989 	{$$ = NULL; print_err_msg(locf(@1), locl(@2), "no variable(s) declared and body defined in function block declaration."); yynerrs++;}	
       
  4990 | FUNCTION_BLOCK error END_FUNCTION_BLOCK
       
  4991 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in function block declaration."); yyerrok;}
       
  4992 /* ERROR_CHECK_END */
       
  4993 ;
       
  4994 
       
  4995 
       
  4996 
       
  4997 /* intermediate helper symbol for function_declaration */
       
  4998 /*  { io_var_declarations | other_var_declarations }   */
       
  4999 /*
       
  5000  * NOTE: we re-use the var_declarations_list_c
       
  5001  */
       
  5002 io_OR_other_var_declarations_list:
       
  5003   io_var_declarations
       
  5004   {$$ = new var_declarations_list_c(locloc(@$));$$->add_element($1);}
       
  5005 | other_var_declarations
       
  5006   {$$ = new var_declarations_list_c(locloc(@$));$$->add_element($1);}
       
  5007 | io_OR_other_var_declarations_list io_var_declarations
       
  5008 	{$$ = $1; $$->add_element($2);}
       
  5009 | io_OR_other_var_declarations_list other_var_declarations
       
  5010 	{$$ = $1; $$->add_element($2);}
       
  5011 /* ERROR_CHECK_BEGIN */
       
  5012 | io_OR_other_var_declarations_list located_var_declarations
       
  5013 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected located variable(s) declaration in function block declaration."); yynerrs++;}
       
  5014 | io_OR_other_var_declarations_list global_var_declarations
       
  5015 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected global variable(s) declaration in function block declaration."); yynerrs++;}
       
  5016 /*| io_OR_other_var_declarations_list access_declarations
       
  5017 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected access variable(s) declaration in function block declaration."); yynerrs++;}*/
       
  5018 | io_OR_other_var_declarations_list instance_specific_initializations
       
  5019 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected instance specific initialization(s) in function block declaration."); yynerrs++;}
       
  5020 /* ERROR_CHECK_END */
       
  5021 ;
       
  5022 
       
  5023 /* NOTE:
       
  5024  *  The IEC specification gives the following definition:
       
  5025  *  other_var_declarations ::=
       
  5026  *     external_var_declarations
       
  5027  *   | var_declarations
       
  5028  *   | retentive_var_declarations
       
  5029  *   | non_retentive_var_declarations
       
  5030  *   | temp_var_decls
       
  5031  *   | incompl_located_var_declarations
       
  5032  *
       
  5033  *  Nvertheless, the symbol non_retentive_var_declarations
       
  5034  *  is not defined in the spec. This seems to me (Mario)
       
  5035  *  to be a typo, so non_retentive_var_declarations
       
  5036  *  has been replaced with non_retentive_var_decls
       
  5037  *  in the following rule!
       
  5038  */
       
  5039 other_var_declarations:
       
  5040   temp_var_decls
       
  5041 | non_retentive_var_decls
       
  5042 | external_var_declarations
       
  5043 | var_declarations
       
  5044 | retentive_var_declarations
       
  5045 | incompl_located_var_declarations
       
  5046 ;
       
  5047 
       
  5048 
       
  5049 temp_var_decls:
       
  5050   VAR_TEMP temp_var_decls_list END_VAR
       
  5051 	{$$ = new temp_var_decls_c($2, locloc(@$));}
       
  5052 /* ERROR_CHECK_BEGIN */
       
  5053 | VAR_TEMP END_VAR
       
  5054 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "no variable declared in temporary variable(s) declaration."); yynerrs++;}
       
  5055 | VAR_TEMP temp_var_decls_list error END_OF_INPUT
       
  5056 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "unclosed temporary variable(s) declaration."); yyerrok;}
       
  5057 | VAR_TEMP error temp_var_decls_list END_VAR
       
  5058 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "unexpected token after 'VAR_TEMP' in function variable(s) declaration."); yyerrok;}
       
  5059 /* ERROR_CHECK_END */
       
  5060 ;
       
  5061 
       
  5062 
       
  5063 /* intermediate helper symbol for temp_var_decls */
       
  5064 temp_var_decls_list:
       
  5065   temp_var_decl ';'
       
  5066 	{$$ = new temp_var_decls_list_c(locloc(@$)); $$->add_element($1);}
       
  5067 | temp_var_decls_list temp_var_decl ';'
       
  5068 	{$$ = $1; $$->add_element($2);}
       
  5069 /* ERROR_CHECK_BEGIN */
       
  5070 | error ';'
       
  5071 	{$$ = new temp_var_decls_list_c(locloc(@$)); print_err_msg(locf(@1), locl(@1), "invalid temporary variable(s) declaration."); yyerrok;}
       
  5072 | temp_var_decl error
       
  5073 	{$$ = new temp_var_decls_list_c(locloc(@$)); print_err_msg(locl(@1), locf(@2), "';' missing at end of temporary variable(s) declaration."); yyerrok;}
       
  5074 | temp_var_decls_list temp_var_decl error
       
  5075 	{$$ = $1; print_err_msg(locl(@2), locf(@3), "';' missing at end of temporary variable(s) declaration."); yyerrok;}
       
  5076 | temp_var_decls_list error ';'
       
  5077 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "invalid temporary variable(s) declaration."); yyerrok;}
       
  5078 | temp_var_decls_list ';'
       
  5079 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected ';' after temporary variable(s) declaration."); yynerrs++;}
       
  5080 /* ERROR_CHECK_END */
       
  5081 ;
       
  5082 
       
  5083 
       
  5084 non_retentive_var_decls:
       
  5085   VAR NON_RETAIN var_init_decl_list END_VAR
       
  5086 	{$$ = new non_retentive_var_decls_c($3, locloc(@$));}
       
  5087 /* ERROR_CHECK_BEGIN */
       
  5088 | VAR NON_RETAIN var_init_decl_list error END_OF_INPUT
       
  5089 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "unclosed non-retentive temporary variable(s) declaration."); yyerrok;}
       
  5090 | VAR NON_RETAIN error var_init_decl_list END_VAR
       
  5091 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "unexpected token after 'NON_RETAIN' in non-retentive temporary variable(s) declaration."); yyerrok;}
       
  5092 /* ERROR_CHECK_END */
       
  5093 ;
       
  5094 
       
  5095 
       
  5096 
       
  5097 function_block_body:
       
  5098   statement_list	{$$ = $1;}
       
  5099 | instruction_list	{$$ = $1;}
       
  5100 | sequential_function_chart	{$$ = $1;}
       
  5101 /*
       
  5102 | ladder_diagram
       
  5103 | function_block_diagram
       
  5104 | <other languages>
       
  5105 */
       
  5106 ;
       
  5107 
       
  5108 
       
  5109 
       
  5110 
       
  5111 /**********************/
       
  5112 /* B 1.5.3 - Programs */
       
  5113 /**********************/
       
  5114 program_type_name: identifier;
       
  5115 
       
  5116 
       
  5117 program_declaration:
       
  5118   PROGRAM program_type_name program_var_declarations_list function_block_body END_PROGRAM
       
  5119 	{$$ = new program_declaration_c($2, $3, $4, locloc(@$));
       
  5120 	 library_element_symtable.insert($2, prev_declared_program_type_name_token);
       
  5121 	 /* Clear the variable_name_symtable. Since
       
  5122 	  * we have finished parsing the program declaration,
       
  5123 	  * the variable names are now out of scope, so
       
  5124 	  * are no longer valid!
       
  5125 	  */
       
  5126 	 variable_name_symtable.pop();
       
  5127 	 direct_variable_symtable.pop();
       
  5128 	}
       
  5129 /* ERROR_CHECK_BEGIN */
       
  5130 | PROGRAM program_var_declarations_list function_block_body END_PROGRAM
       
  5131   {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no program name defined in program declaration.");}
       
  5132 | PROGRAM error program_var_declarations_list function_block_body END_PROGRAM
       
  5133 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid program name in program declaration."); yyerrok;}
       
  5134 | PROGRAM program_type_name function_block_body END_PROGRAM
       
  5135 	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable(s) declared in program declaration."); yynerrs++;}
       
  5136 | PROGRAM program_type_name program_var_declarations_list END_PROGRAM
       
  5137 	{$$ = NULL; print_err_msg(locl(@3), locf(@4), "no body defined in program declaration."); yynerrs++;}
       
  5138 | PROGRAM program_type_name END_PROGRAM
       
  5139 	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable(s) declared and body defined in program declaration."); yynerrs++;}
       
  5140 | PROGRAM program_type_name program_var_declarations_list function_block_body END_OF_INPUT
       
  5141 	{$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed program declaration."); yynerrs++;}
       
  5142 | PROGRAM error END_PROGRAM
       
  5143 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in program declaration."); yyerrok;}
       
  5144 /* ERROR_CHECK_END */
       
  5145 ;
       
  5146 
       
  5147 
       
  5148 /* helper symbol for program_declaration */
       
  5149 /*
       
  5150  * NOTE: we re-use the var_declarations_list_c
       
  5151  */
       
  5152 program_var_declarations_list:
       
  5153   io_var_declarations
       
  5154 	{$$ = new var_declarations_list_c(locloc(@$)); $$->add_element($1);}
       
  5155 | other_var_declarations
       
  5156 	{$$ = new var_declarations_list_c(locloc(@$)); $$->add_element($1);}
       
  5157 | located_var_declarations
       
  5158 	{$$ = new var_declarations_list_c(locloc(@$)); $$->add_element($1);}
       
  5159 | program_var_declarations_list io_var_declarations
       
  5160 	{$$ = $1; $$->add_element($2);}
       
  5161 | program_var_declarations_list other_var_declarations
       
  5162 	{$$ = $1; $$->add_element($2);}
       
  5163 | program_var_declarations_list located_var_declarations
       
  5164 	{$$ = $1; $$->add_element($2);}
       
  5165 /*
       
  5166 | program_var_declarations_list program_access_decls
       
  5167 	{$$ = $1; $$->add_element($2);}
       
  5168 */
       
  5169 /* ERROR_CHECK_BEGIN */
       
  5170 | program_var_declarations_list global_var_declarations
       
  5171 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected global variable(s) declaration in function block declaration."); yynerrs++;}
       
  5172 /*| program_var_declarations_list access_declarations
       
  5173 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected access variable(s) declaration in function block declaration."); yynerrs++;}*/
       
  5174 | program_var_declarations_list instance_specific_initializations
       
  5175 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected instance specific initialization(s) in function block declaration."); yynerrs++;
       
  5176 	}
       
  5177 /* ERROR_CHECK_END */
       
  5178 ;
       
  5179 
       
  5180 
       
  5181 /* TODO ... */
       
  5182 /*
       
  5183 program_access_decls:
       
  5184   VAR_ACCESS program_access_decl_list END_VAR
       
  5185 ;
       
  5186 */
       
  5187 
       
  5188 /* helper symbol for program_access_decls */
       
  5189 /*
       
  5190 program_access_decl_list:
       
  5191   program_access_decl ';'
       
  5192 | program_access_decl_list program_access_decl ';'
       
  5193 ;
       
  5194 */
       
  5195 
       
  5196 /*
       
  5197 program_access_decl:
       
  5198   access_name ':' symbolic_variable ':' non_generic_type_name
       
  5199 | access_name ':' symbolic_variable ':' non_generic_type_name direction
       
  5200 ;
       
  5201 */
       
  5202 
       
  5203 
       
  5204 
       
  5205 /********************************************/
       
  5206 /* B 1.6 Sequential Function Chart elements *
       
  5207 /********************************************/
       
  5208 
       
  5209 sequential_function_chart:
       
  5210   sfc_network
       
  5211 	{$$ = new sequential_function_chart_c(locloc(@$)); $$->add_element($1);}
       
  5212 | sequential_function_chart sfc_network
       
  5213 	{$$ = $1; $$->add_element($2);}
       
  5214 ;
       
  5215 
       
  5216 sfc_network:
       
  5217   initial_step
       
  5218 	{$$ = new sfc_network_c(locloc(@$)); $$->add_element($1);}
       
  5219 | sfc_network step
       
  5220 	{$$ = $1; $$->add_element($2);}
       
  5221 | sfc_network transition
       
  5222 	{$$ = $1; $$->add_element($2);}
       
  5223 | sfc_network action
       
  5224 	{$$ = $1; $$->add_element($2);}
       
  5225 /* ERROR_CHECK_BEGIN */
       
  5226 | sfc_network error 
       
  5227 	{$$ = $1; print_err_msg(locl(@1), locf(@2), "unexpected token after SFC network in sequencial function chart."); yyerrok;}
       
  5228 /* ERROR_CHECK_END */
       
  5229 ;
       
  5230 
       
  5231 initial_step:
       
  5232   INITIAL_STEP step_name ':' action_association_list END_STEP
       
  5233 //  INITIAL_STEP identifier ':' action_association_list END_STEP
       
  5234 	{$$ = new initial_step_c($2, $4, locloc(@$));}
       
  5235 /* ERROR_CHECK_BEGIN */
       
  5236 | INITIAL_STEP ':' action_association_list END_STEP
       
  5237   {$$ = NULL; print_err_msg(locf(@1), locl(@2), "no step name defined in initial step declaration."); yynerrs++;}
       
  5238 | INITIAL_STEP error ':' action_association_list END_STEP
       
  5239 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid step name defined in initial step declaration."); yyerrok;}
       
  5240 | INITIAL_STEP step_name action_association_list END_STEP
       
  5241 	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "':' missing after step name in initial step declaration."); yynerrs++;}
       
  5242 | INITIAL_STEP step_name ':' error END_STEP
       
  5243 	{$$ = NULL; print_err_msg(locf(@4), locl(@4), "invalid action association list in initial step declaration."); yyerrok;}
       
  5244 | INITIAL_STEP step_name ':' action_association_list END_OF_INPUT
       
  5245 	{$$ = NULL; print_err_msg(locf(@1), locl(@3), "unclosed initial step declaration."); yynerrs++;}
       
  5246 | INITIAL_STEP error END_STEP
       
  5247 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in initial step declaration."); yyerrok;}
       
  5248 /* ERROR_CHECK_END */
       
  5249 ;
       
  5250 
       
  5251 step:
       
  5252   STEP step_name ':' action_association_list END_STEP
       
  5253 //  STEP identifier ':' action_association_list END_STEP
       
  5254 	{$$ = new step_c($2, $4, locloc(@$));}
       
  5255 /* ERROR_CHECK_BEGIN */
       
  5256 | STEP ':' action_association_list END_STEP
       
  5257   {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no step name defined in step declaration."); yynerrs++;}
       
  5258 | STEP error ':' action_association_list END_STEP
       
  5259 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid step name defined in step declaration."); yyerrok;}
       
  5260 | STEP step_name action_association_list END_STEP
       
  5261 	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "':' missing after step name in step declaration."); yynerrs++;}
       
  5262 | STEP step_name ':' error END_STEP
       
  5263 	{$$ = NULL; print_err_msg(locf(@4), locl(@4), "invalid action association list in step declaration."); yyerrok;}
       
  5264 | STEP step_name ':' action_association_list END_OF_INPUT
       
  5265 	{$$ = NULL; print_err_msg(locf(@1), locl(@3), "invalid action association list in step declaration."); yynerrs++;}
       
  5266 | STEP error END_STEP
       
  5267 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in step declaration."); yyerrok;}
       
  5268 /* ERROR_CHECK_END */
       
  5269 ;
       
  5270 
       
  5271 /* helper symbol for:
       
  5272  *  - initial_step
       
  5273  *  - step
       
  5274  */
       
  5275 action_association_list:
       
  5276   /* empty */
       
  5277 	{$$ = new action_association_list_c(locloc(@$));}
       
  5278 | action_association_list action_association ';'
       
  5279 	{$$ = $1; $$->add_element($2);}
       
  5280 /* ERROR_CHECK_BEGIN */
       
  5281 | action_association_list action_association error
       
  5282 	{$$ = $1; print_err_msg(locl(@2), locf(@3), "';' missing at end of action association declaration."); yyerrok;}
       
  5283 | action_association_list ';'
       
  5284 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected ';' after action association declaration."); yynerrs++;}
       
  5285 /* ERROR_CHECK_END */
       
  5286 ;
       
  5287 
       
  5288 
       
  5289 // step_name: identifier;
       
  5290 step_name: any_identifier;
       
  5291 
       
  5292 action_association:
       
  5293   action_name '(' {cmd_goto_sfc_qualifier_state();} action_qualifier {cmd_pop_state();} indicator_name_list ')'
       
  5294 	{$$ = new action_association_c($1, $4, $6, locloc(@$));}
       
  5295 /* ERROR_CHECK_BEGIN */
       
  5296 /*| action_name '(' error ')'
       
  5297   {$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid qualifier defined in action association."); yyerrok;}*/
       
  5298 /* ERROR_CHECK_END */
       
  5299 ;
       
  5300 
       
  5301 /* helper symbol for action_association */
       
  5302 indicator_name_list:
       
  5303   /* empty */
       
  5304 	{$$ = new indicator_name_list_c(locloc(@$));}
       
  5305 | indicator_name_list ',' indicator_name
       
  5306 	{$$ = $1; $$->add_element($3);}
       
  5307 /* ERROR_CHECK_BEGIN */
       
  5308 | indicator_name_list indicator_name
       
  5309 	{$$ = $1; print_err_msg(locl(@1), locf(@2), "',' missing at end of action association declaration."); yynerrs++;}
       
  5310 | indicator_name_list ',' error
       
  5311 	{$$ = $1;
       
  5312 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no indicator defined in indicator list.");}
       
  5313 	 else {print_err_msg(locf(@3), locl(@3), "invalid indicator in indicator list."); yyclearin;}
       
  5314 	 yyerrok;
       
  5315 	}
       
  5316 /* ERROR_CHECK_END */
       
  5317 ;
       
  5318 
       
  5319 // action_name: identifier;
       
  5320 action_name: any_identifier;
       
  5321 
       
  5322 action_qualifier:
       
  5323   /* empty */
       
  5324 	{$$ = NULL;}
       
  5325 | qualifier
       
  5326 	{$$ = new action_qualifier_c($1, NULL, locloc(@$));}
       
  5327 | timed_qualifier ',' action_time
       
  5328 	{$$ = new action_qualifier_c($1, $3, locloc(@$));}
       
  5329 /* ERROR_CHECK_BEGIN */
       
  5330 | timed_qualifier action_time
       
  5331 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "',' missing between timed qualifier and action time in action qualifier."); yynerrs++;}
       
  5332 | timed_qualifier ',' error
       
  5333 	{$$ = NULL;
       
  5334 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no action time defined in action qualifier.");}
       
  5335 	 else {print_err_msg(locf(@3), locl(@3), "invalid action time in action qualifier."); yyclearin;}
       
  5336 	 yyerrok;
       
  5337 	}
       
  5338 /* ERROR_CHECK_END */
       
  5339 ;
       
  5340 
       
  5341 qualifier:
       
  5342   N		{$$ = new qualifier_c(strdup("N"), locloc(@$));}
       
  5343 | R		{$$ = new qualifier_c(strdup("R"), locloc(@$));}
       
  5344 | S		{$$ = new qualifier_c(strdup("S"), locloc(@$));}
       
  5345 | P		{$$ = new qualifier_c(strdup("P"), locloc(@$));}
       
  5346 ;
       
  5347 
       
  5348 timed_qualifier:
       
  5349   L		{$$ = new timed_qualifier_c(strdup("L"), locloc(@$));}
       
  5350 | D		{$$ = new timed_qualifier_c(strdup("D"), locloc(@$));}
       
  5351 | SD		{$$ = new timed_qualifier_c(strdup("SD"), locloc(@$));}
       
  5352 | DS		{$$ = new timed_qualifier_c(strdup("DS"), locloc(@$));}
       
  5353 | SL		{$$ = new timed_qualifier_c(strdup("SL"), locloc(@$));}
       
  5354 ;
       
  5355 
       
  5356 action_time:
       
  5357   duration
       
  5358 | variable
       
  5359 ;
       
  5360 
       
  5361 indicator_name: variable;
       
  5362 
       
  5363 // transition_name: identifier;
       
  5364 transition_name: any_identifier;
       
  5365 
       
  5366 
       
  5367 steps:
       
  5368   step_name
       
  5369 	{$$ = new steps_c($1, NULL, locloc(@$));}
       
  5370 | '(' step_name_list ')'
       
  5371 	{$$ = new steps_c(NULL, $2, locloc(@$));}
       
  5372 /* ERROR_CHECK_BEGIN */
       
  5373 | '(' step_name_list error
       
  5374 	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "expecting ')' at the end of step list in transition declaration."); yyerrok;}
       
  5375 | '(' error ')'
       
  5376 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid step list in transition declaration."); yyerrok;}
       
  5377 /* ERROR_CHECK_END */
       
  5378 ;
       
  5379 
       
  5380 step_name_list:
       
  5381   step_name ',' step_name
       
  5382 	{$$ = new step_name_list_c(locloc(@$)); $$->add_element($1); $$->add_element($3);}
       
  5383 | step_name_list ',' step_name
       
  5384 	{$$ = $1; $$->add_element($3);}
       
  5385 /* ERROR_CHECK_BEGIN */
       
  5386 | step_name_list step_name
       
  5387 	{$$ = $1; print_err_msg(locl(@1), locf(@2), "',' missing in step list."); yynerrs++;}
       
  5388 | step_name_list ',' error
       
  5389 	{$$ = $1;
       
  5390 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no step name defined in step list.");}
       
  5391 	 else {print_err_msg(locf(@3), locl(@3), "invalid step name in step list."); yyclearin;}
       
  5392 	 yyerrok;
       
  5393 	}
       
  5394 /* ERROR_CHECK_END */
       
  5395 ;
       
  5396 
       
  5397 
       
  5398 /* NOTE: flex will automatically pop() out of body_state to previous state.
       
  5399  *       We do not need to give a command from bison to return to previous flex state,
       
  5400  *       after forcing flex to go to body_state.
       
  5401  */
       
  5402 transition:
       
  5403   TRANSITION transition_priority
       
  5404     FROM steps TO steps 
       
  5405     {cmd_goto_body_state();} transition_condition 
       
  5406   END_TRANSITION 
       
  5407 	{$$ = new transition_c(NULL, $2, $4, $6, $8, locloc(@$));}
       
  5408 //| TRANSITION identifier FROM steps TO steps ... 
       
  5409 | TRANSITION transition_name transition_priority
       
  5410     FROM steps TO steps 
       
  5411     {cmd_goto_body_state();} transition_condition 
       
  5412   END_TRANSITION 
       
  5413 	{$$ = new transition_c($2, $3, $5, $7, $9, locloc(@$));}
       
  5414 /* ERROR_CHECK_BEGIN */
       
  5415 | TRANSITION error transition_priority FROM steps TO steps {cmd_goto_body_state();} transition_condition END_TRANSITION
       
  5416 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid transition name defined in transition declaration."); yyerrok;}
       
  5417 | TRANSITION transition_name error FROM steps TO steps {cmd_goto_body_state();} transition_condition END_TRANSITION
       
  5418 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid transition priority defined in transition declaration."); yyerrok;}
       
  5419 | TRANSITION transition_priority FROM TO steps {cmd_goto_body_state();} transition_condition END_TRANSITION
       
  5420 	{$$ = NULL; print_err_msg(locl(@3), locf(@4), "no origin step(s) defined in transition declaration."); yynerrs++;}
       
  5421 | TRANSITION transition_name transition_priority FROM TO steps {cmd_goto_body_state();} transition_condition END_TRANSITION
       
  5422 	{$$ = NULL; print_err_msg(locl(@4), locf(@5), "no origin step(s) defined in transition declaration."); yynerrs++;}
       
  5423 | TRANSITION transition_priority FROM error TO steps {cmd_goto_body_state();} transition_condition END_TRANSITION
       
  5424 	{$$ = NULL; print_err_msg(locf(@4), locl(@4), "invalid origin step(s) defined in transition declaration."); yyerrok;}
       
  5425 | TRANSITION transition_name transition_priority FROM error TO steps {cmd_goto_body_state();} transition_condition END_TRANSITION
       
  5426 	{$$ = NULL; print_err_msg(locf(@5), locl(@5), "invalid origin step(s) defined in transition declaration."); yyerrok;}
       
  5427 | TRANSITION transition_priority FROM steps steps {cmd_goto_body_state();} transition_condition END_TRANSITION
       
  5428 	{$$ = NULL; print_err_msg(locl(@4), locf(@5), "'TO' missing between origin step(s) and destination step(s) in transition declaration."); yynerrs++;}
       
  5429 | TRANSITION transition_name transition_priority FROM steps steps {cmd_goto_body_state();} transition_condition END_TRANSITION
       
  5430 	{$$ = NULL; print_err_msg(locl(@5), locf(@6), "'TO' missing between origin step(s) and destination step(s) in transition declaration."); yynerrs++;}
       
  5431 | TRANSITION transition_priority FROM steps TO {cmd_goto_body_state();} transition_condition END_TRANSITION
       
  5432 	{$$ = NULL; print_err_msg(locl(@5), locf(@7), "no destination step(s) defined in transition declaration."); yynerrs++;}
       
  5433 | TRANSITION transition_name transition_priority FROM steps TO {cmd_goto_body_state();} transition_condition END_TRANSITION
       
  5434 	{$$ = NULL; print_err_msg(locl(@6), locf(@8), "no destination step(s) defined in transition declaration."); yynerrs++;}
       
  5435 | TRANSITION transition_priority FROM steps TO error {cmd_goto_body_state();} transition_condition END_TRANSITION
       
  5436 	{$$ = NULL; print_err_msg(locf(@6), locl(@6), "invalid destination step(s) defined in transition declaration."); yyerrok;}
       
  5437 | TRANSITION transition_name transition_priority FROM steps TO error {cmd_goto_body_state();} transition_condition END_TRANSITION
       
  5438 	{$$ = NULL; print_err_msg(locf(@7), locl(@7), "invalid destination step(s) defined in transition declaration."); yyerrok;}
       
  5439 | TRANSITION transition_priority {cmd_goto_body_state();} transition_condition END_TRANSITION
       
  5440 	{$$ = NULL; print_err_msg(locl(@2), locf(@4), "no origin and destination step(s) defined in transition declaration."); yynerrs++;}
       
  5441 | TRANSITION transition_name transition_priority {cmd_goto_body_state();} transition_condition END_TRANSITION
       
  5442 	{$$ = NULL; print_err_msg(locl(@3), locf(@5), "no origin and destination step(s) defined in transition declaration."); yynerrs++;}
       
  5443 /*| TRANSITION transition_priority FROM steps TO steps {cmd_goto_body_state();} transition_condition error END_OF_INPUT
       
  5444   {$$ = NULL; print_err_msg(locf(@1), locl(@6), "unclosed transition declaration."); yyerrok;}
       
  5445 | TRANSITION transition_name transition_priority FROM steps TO steps {cmd_goto_body_state();} transition_condition error END_OF_INPUT
       
  5446   {$$ = NULL; print_err_msg(locf(@1), locl(@7), "unclosed transition declaration."); yyerrok;}*/
       
  5447 | TRANSITION error END_TRANSITION
       
  5448 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in transition declaration."); yyerrok;}
       
  5449 /* ERROR_CHECK_END */
       
  5450 ;
       
  5451 
       
  5452 transition_priority:
       
  5453   /* empty */
       
  5454   {$$ = NULL;}
       
  5455 | '(' {cmd_goto_sfc_priority_state();} PRIORITY {cmd_pop_state();} ASSIGN integer ')'
       
  5456 	{$$ = $6;}
       
  5457 /* ERROR_CHECK_BEGIN 
       
  5458 | '(' ASSIGN integer ')'
       
  5459 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "'PRIORITY' missing between '(' and ':=' in transition declaration with priority."); yynerrs++;}
       
  5460 | '(' error ASSIGN integer ')'
       
  5461 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "expecting 'PRIORITY' between '(' and ':=' in transition declaration with priority."); yyerrok;}
       
  5462  ERROR_CHECK_END */
       
  5463 ;
       
  5464 
       
  5465 
       
  5466 transition_condition:
       
  5467   ':' eol_list simple_instr_list
       
  5468 	{$$ = new transition_condition_c($3, NULL, locloc(@$));}
       
  5469 | ASSIGN expression ';'
       
  5470 	{$$ = new transition_condition_c(NULL, $2, locloc(@$));}
       
  5471 /* ERROR_CHECK_BEGIN */
       
  5472 | eol_list simple_instr_list
       
  5473 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing before IL condition in transition declaration."); yynerrs++;}
       
  5474 | ':' eol_list error
       
  5475 	{$$ = NULL;
       
  5476 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no instructions defined in IL condition of transition declaration.");}
       
  5477 	 else {print_err_msg(locf(@3), locl(@3), "invalid instructions in IL condition of transition declaration."); yyclearin;}
       
  5478 	 yyerrok;
       
  5479 	}
       
  5480 | ASSIGN ';'
       
  5481 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "no expression defined in ST condition of transition declaration."); yynerrs++;}
       
  5482 | ASSIGN error ';'
       
  5483 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid expression defined in ST condition of transition declaration."); yyerrok;}
       
  5484 | ASSIGN expression error
       
  5485 	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "expecting ';' after expression defined in ST condition of transition declaration."); yyerrok;}
       
  5486 /* ERROR_CHECK_END */
       
  5487 ;
       
  5488 
       
  5489 
       
  5490 
       
  5491 action:
       
  5492 //  ACTION identifier ':' ... 
       
  5493   ACTION action_name {cmd_goto_body_state();} action_body END_ACTION
       
  5494 	{$$ = new action_c($2, $4, locloc(@$));}
       
  5495 /* ERROR_CHECK_BEGIN */
       
  5496 | ACTION {cmd_goto_body_state();} action_body END_ACTION
       
  5497   {$$ = NULL; print_err_msg(locl(@1), locf(@3), "no action name defined in action declaration."); yynerrs++;}
       
  5498 | ACTION error {cmd_goto_body_state();} action_body END_ACTION
       
  5499 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid action name defined in action declaration."); yyerrok;}
       
  5500 | ACTION action_name {cmd_goto_body_state();} function_block_body END_ACTION
       
  5501 	{$$ = NULL; print_err_msg(locl(@2), locf(@4), "':' missing after action name in action declaration."); yynerrs++;}
       
  5502 /*| ACTION action_name {cmd_goto_body_state();} action_body END_OF_INPUT
       
  5503 	{$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed action declaration."); yyerrok;}*/
       
  5504 | ACTION error END_ACTION
       
  5505 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in action declaration."); yyerrok;}
       
  5506 /* ERROR_CHECK_END */
       
  5507 ;
       
  5508 
       
  5509 action_body:
       
  5510   ':' function_block_body
       
  5511   {$$ = $2;}
       
  5512 /* ERROR_CHECK_BEGIN */
       
  5513 | ':' error
       
  5514 	{$$ = NULL;
       
  5515 	 if (is_current_syntax_token()) {print_err_msg(locl(@1), locf(@2), "no body defined in action declaration.");}
       
  5516 	 else {print_err_msg(locf(@2), locl(@2), "invalid body defined in action declaration."); yyclearin;}
       
  5517 	 yyerrok;
       
  5518 	}
       
  5519 /* ERROR_CHECK_END */
       
  5520 ;
       
  5521 
       
  5522 
       
  5523 /********************************/
       
  5524 /* B 1.7 Configuration elements */
       
  5525 /********************************/
       
  5526 /* NOTE:
       
  5527  * It is not clear from reading the specification to which namespace
       
  5528  * the names of resources, tasks and programs belong to.
       
  5529  *
       
  5530  * The following syntax assumes that resource and program names belong to the
       
  5531  * same namespace as the variables defined within
       
  5532  * the resource/configuration (i.e. VAR_GLOBAL).
       
  5533  * Task names belong to a namespace all of their own, since they don't
       
  5534  * produce conflicts in the syntax parser, so we might just as well
       
  5535  * leave them be! ;-)
       
  5536  * The above decision was made taking into
       
  5537  * account that inside a VAR_CONFIG declaration global variables
       
  5538  * may be referenced starting off from the resource name as:
       
  5539  *   resource_name.program_name.variable_name
       
  5540  * Notice how resource names and program names are used in a very similar
       
  5541  * manner as are variable names.
       
  5542  * Using a single namespace for all the above mentioned names
       
  5543  * also makes it easier to write the syntax parser!! ;-) Using a private
       
  5544  * namespace for each of the name types (resource names, program names,
       
  5545  * global varaiable names), i.e. letting the names be re-used across
       
  5546  * each of the groups (resource, program, global variables), produces
       
  5547  * reduce/reduce conflicts in the syntax parser. Actually, it is only
       
  5548  * the resource names that need to be distinguished into a 
       
  5549  * prev_declared_resource_name so as not to conflict with [gloabl] variable
       
  5550  * names in the 'data' construct.
       
  5551  * The program names are only tracked to make sure that two programs do not
       
  5552  * get the same name.
       
  5553  *
       
  5554  * Using a single namespace does have the drawback that the user will
       
  5555  * not be able to re-use names for resources or programs if these
       
  5556  * have already been used to name a variable!
       
  5557  *
       
  5558  * If it ever becomes necessary to change this interpretation of
       
  5559  * the syntax, then this section of the syntax parser must be updated!
       
  5560  */
       
  5561 prev_declared_global_var_name: prev_declared_global_var_name_token {$$ = new identifier_c($1, locloc(@$));};
       
  5562 prev_declared_resource_name: prev_declared_resource_name_token {$$ = new identifier_c($1, locloc(@$));};
       
  5563 prev_declared_program_name: prev_declared_program_name_token {$$ = new identifier_c($1, locloc(@$));};
       
  5564 // prev_declared_task_name: prev_declared_task_name_token {$$ = new identifier_c($1, locloc(@$));};
       
  5565 
       
  5566 
       
  5567 
       
  5568 
       
  5569 
       
  5570 
       
  5571 configuration_name: identifier;
       
  5572 
       
  5573 /* NOTE: The specification states that valid resource type names
       
  5574  *       are implementation defined, i.e. each implementaion will define
       
  5575  *       what resource types it supports.
       
  5576  *       We are implementing this syntax parser to be used by any
       
  5577  *       implementation, so at the moment we accept any identifier
       
  5578  *       as a resource type name.
       
  5579  *       This implementation should probably be changed in the future. We
       
  5580  *       should probably have a resource_type_name_token, and let the
       
  5581  *       implementation load the global symbol library with the
       
  5582  *       accepted resource type names before parsing the code.
       
  5583  *
       
  5584  */
       
  5585 resource_type_name: any_identifier;
       
  5586 
       
  5587 configuration_declaration:
       
  5588   CONFIGURATION configuration_name
       
  5589    optional_global_var_declarations
       
  5590    single_resource_declaration
       
  5591    {variable_name_symtable.pop();
       
  5592     direct_variable_symtable.pop();}
       
  5593    optional_access_declarations
       
  5594    optional_instance_specific_initializations
       
  5595   END_CONFIGURATION
       
  5596 	{$$ = new configuration_declaration_c($2, $3, $4, $6, $7, locloc(@$));
       
  5597 	 library_element_symtable.insert($2, prev_declared_configuration_name_token);
       
  5598 	 variable_name_symtable.pop();
       
  5599 	 direct_variable_symtable.pop();
       
  5600 	}
       
  5601 | CONFIGURATION configuration_name
       
  5602    optional_global_var_declarations
       
  5603    resource_declaration_list
       
  5604    optional_access_declarations
       
  5605    optional_instance_specific_initializations
       
  5606  END_CONFIGURATION
       
  5607 	{$$ = new configuration_declaration_c($2, $3, $4, $5, $6, locloc(@$));
       
  5608 	 library_element_symtable.insert($2, prev_declared_configuration_name_token);
       
  5609 	 variable_name_symtable.pop();
       
  5610 	 direct_variable_symtable.pop();
       
  5611 }
       
  5612 /* ERROR_CHECK_BEGIN */
       
  5613 | CONFIGURATION 
       
  5614    optional_global_var_declarations
       
  5615    single_resource_declaration
       
  5616    {variable_name_symtable.pop();
       
  5617     direct_variable_symtable.pop();}
       
  5618    optional_access_declarations
       
  5619    optional_instance_specific_initializations
       
  5620   END_CONFIGURATION
       
  5621   {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no configuration name defined in configuration declaration."); yynerrs++;}
       
  5622 | CONFIGURATION
       
  5623    optional_global_var_declarations
       
  5624    resource_declaration_list
       
  5625    optional_access_declarations
       
  5626    optional_instance_specific_initializations
       
  5627   END_CONFIGURATION
       
  5628   {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no configuration name defined in configuration declaration."); yynerrs++;}
       
  5629 | CONFIGURATION error
       
  5630    optional_global_var_declarations
       
  5631    single_resource_declaration
       
  5632    {variable_name_symtable.pop();
       
  5633     direct_variable_symtable.pop();}
       
  5634    optional_access_declarations
       
  5635    optional_instance_specific_initializations
       
  5636   END_CONFIGURATION
       
  5637   {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid configuration name defined in configuration declaration."); yyerrok;}
       
  5638 | CONFIGURATION error
       
  5639    optional_global_var_declarations
       
  5640    resource_declaration_list
       
  5641    optional_access_declarations
       
  5642    optional_instance_specific_initializations
       
  5643   END_CONFIGURATION
       
  5644   {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid configuration name defined in configuration declaration."); yyerrok;}
       
  5645 | CONFIGURATION configuration_name
       
  5646    optional_global_var_declarations
       
  5647    optional_access_declarations
       
  5648    optional_instance_specific_initializations
       
  5649   END_CONFIGURATION
       
  5650   {$$ = NULL; print_err_msg(locl(@3), locf(@4), "no resource(s) defined in configuration declaration."); yynerrs++;}
       
  5651 | CONFIGURATION configuration_name
       
  5652    optional_global_var_declarations
       
  5653    error
       
  5654    optional_access_declarations
       
  5655    optional_instance_specific_initializations
       
  5656   END_CONFIGURATION
       
  5657   {$$ = NULL; print_err_msg(locf(@4), locl(@4), "invalid resource(s) defined in configuration declaration."); yyerrok;}
       
  5658 /*| CONFIGURATION configuration_name
       
  5659    optional_global_var_declarations
       
  5660    single_resource_declaration
       
  5661    {variable_name_symtable.pop();
       
  5662     direct_variable_symtable.pop();}
       
  5663    optional_access_declarations
       
  5664    optional_instance_specific_initializations
       
  5665   END_OF_INPUT
       
  5666   {$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed configuration declaration."); yyerrok;}*/
       
  5667 | CONFIGURATION configuration_name
       
  5668    optional_global_var_declarations
       
  5669    resource_declaration_list
       
  5670    optional_access_declarations
       
  5671    optional_instance_specific_initializations
       
  5672   END_OF_INPUT
       
  5673   {$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed configuration declaration."); yyerrok;}
       
  5674 | CONFIGURATION error END_CONFIGURATION
       
  5675 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in configuration declaration."); yyerrok;}
       
  5676 /* ERROR_CHECK_END */
       
  5677 ;
       
  5678 
       
  5679 // helper symbol for
       
  5680 //  - configuration_declaration
       
  5681 //  - resource_declaration
       
  5682 //
       
  5683 optional_global_var_declarations:
       
  5684   // empty
       
  5685 	{$$ = NULL;}
       
  5686 | global_var_declarations
       
  5687 ;
       
  5688 
       
  5689 
       
  5690 // helper symbol for configuration_declaration //
       
  5691 optional_access_declarations:
       
  5692   // empty
       
  5693 	{$$ = NULL;}
       
  5694 //| access_declarations
       
  5695 ;
       
  5696 
       
  5697 // helper symbol for configuration_declaration //
       
  5698 optional_instance_specific_initializations:
       
  5699   // empty
       
  5700 	{$$ = NULL;}
       
  5701 | instance_specific_initializations
       
  5702 ;
       
  5703 
       
  5704 // helper symbol for configuration_declaration //
       
  5705 resource_declaration_list:
       
  5706   resource_declaration
       
  5707 	{$$ = new resource_declaration_list_c(locloc(@$)); $$->add_element($1);}
       
  5708 | resource_declaration_list resource_declaration
       
  5709 	{$$ = $1; $$->add_element($2);}
       
  5710 /* ERROR_CHECK_BEGIN */
       
  5711 | resource_declaration_list error
       
  5712 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected token after resource declaration."); yyerrok;}
       
  5713 /* ERROR_CHECK_END */
       
  5714 ;
       
  5715 
       
  5716 
       
  5717 resource_declaration:
       
  5718   RESOURCE {variable_name_symtable.push();direct_variable_symtable.push();} resource_name ON resource_type_name
       
  5719    optional_global_var_declarations
       
  5720    single_resource_declaration
       
  5721   END_RESOURCE
       
  5722 	{$$ = new resource_declaration_c($3, $5, $6, $7, locloc(@$));
       
  5723 	 variable_name_symtable.pop();
       
  5724 	 direct_variable_symtable.pop();
       
  5725 	 variable_name_symtable.insert($3, prev_declared_resource_name_token);
       
  5726 	}
       
  5727 /* ERROR_CHECK_BEGIN */
       
  5728 | RESOURCE {variable_name_symtable.push();direct_variable_symtable.push();} ON resource_type_name
       
  5729    optional_global_var_declarations
       
  5730    single_resource_declaration
       
  5731   END_RESOURCE
       
  5732   {$$ = NULL; print_err_msg(locl(@1), locf(@3), "no resource name defined in resource declaration."); yynerrs++;}
       
  5733 /*|	RESOURCE {variable_name_symtable.push();direct_variable_symtable.push();} resource_name ON resource_type_name
       
  5734    optional_global_var_declarations
       
  5735    single_resource_declaration
       
  5736   END_OF_INPUT
       
  5737 	{$$ = NULL; print_err_msg(locf(@1), locl(@5), "unclosed resource declaration."); yyerrok;}*/
       
  5738 | RESOURCE error END_RESOURCE
       
  5739 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in resource declaration."); yyerrok;}
       
  5740 /* ERROR_CHECK_END */
       
  5741 ;
       
  5742 
       
  5743 
       
  5744 single_resource_declaration:
       
  5745  task_configuration_list program_configuration_list
       
  5746 	{$$ = new single_resource_declaration_c($1, $2, locloc(@$));}
       
  5747 ;
       
  5748 
       
  5749 
       
  5750 // helper symbol for single_resource_declaration //
       
  5751 task_configuration_list:
       
  5752   // empty
       
  5753 	{$$ = new task_configuration_list_c(locloc(@$));}
       
  5754 | task_configuration_list task_configuration ';'
       
  5755 	{$$ = $1; $$->add_element($2);}
       
  5756 /* ERROR_CHECK_BEGIN */
       
  5757 | task_configuration_list task_configuration error
       
  5758   {$$ = $1; print_err_msg(locl(@1), locf(@2), "';' missing at the end of task configuration in resource declaration."); yyerrok;}
       
  5759 | task_configuration_list ';'
       
  5760   {$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected ';' after task configuration in resource declaration."); yynerrs++;}
       
  5761 /* ERROR_CHECK_END */
       
  5762 ;
       
  5763 
       
  5764 
       
  5765 // helper symbol for single_resource_declaration //
       
  5766 program_configuration_list:
       
  5767   program_configuration ';'
       
  5768 	{$$ = new program_configuration_list_c(locloc(@$)); $$->add_element($1);}
       
  5769 | program_configuration_list program_configuration ';'
       
  5770 	{$$ = $1; $$->add_element($2);}
       
  5771 /* ERROR_CHECK_BEGIN */
       
  5772 | program_configuration error
       
  5773   {$$ = new program_configuration_list_c(locloc(@$)); print_err_msg(locl(@1), locf(@2), "';' missing at the end of program configuration in resource declaration."); yyerrok;}
       
  5774 | program_configuration_list program_configuration error
       
  5775   {$$ = $1; print_err_msg(locl(@2), locf(@3), "';' missing at the end of program configuration in resource declaration."); yyerrok;}
       
  5776 | program_configuration_list error ';'
       
  5777   {$$ = $1; print_err_msg(locf(@2), locl(@2), "invalid program configuration in resource declaration."); yyerrok;}
       
  5778 | program_configuration_list ';'
       
  5779   {$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected ';' after program configuration in resource declaration."); yynerrs++;}
       
  5780 /* ERROR_CHECK_END */
       
  5781 ;
       
  5782 
       
  5783 
       
  5784 resource_name: identifier;
       
  5785 
       
  5786 /*
       
  5787 access_declarations:
       
  5788  VAR_ACCESS access_declaration_list END_VAR
       
  5789 	{$$ = NULL;}
       
  5790 // ERROR_CHECK_BEGIN //
       
  5791 | VAR_ACCESS END_VAR
       
  5792 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "no variable declared in access variable(s) declaration."); yynerrs++;}
       
  5793 | VAR_ACCESS error access_declaration_list END_VAR
       
  5794 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "unexpected token after 'VAR_ACCESS' in access variable(s) declaration."); yyerrok;}
       
  5795 | VAR_ACCESS access_declaration_list error END_VAR
       
  5796 	{$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed access variable(s) declaration."); yyerrok;}
       
  5797 | VAR_ACCESS error END_VAR
       
  5798 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in access variable(s) declaration."); yyerrok;}
       
  5799 // ERROR_CHECK_END //
       
  5800 ;
       
  5801 
       
  5802 // helper symbol for access_declarations //
       
  5803 access_declaration_list:
       
  5804   access_declaration ';'
       
  5805 | access_declaration_list access_declaration ';'
       
  5806 // ERROR_CHECK_BEGIN //
       
  5807 | error ';'
       
  5808   {$$ = // create a new list //;
       
  5809 	 print_err_msg(locf(@1), locl(@1), "invalid access variable declaration."); yyerrok;}
       
  5810 | access_declaration error
       
  5811   {$$ = // create a new list //;
       
  5812 	 print_err_msg(locl(@1), locf(@2), "';' missing at the end of access variable declaration."); yyerrok;}
       
  5813 | access_declaration_list access_declaration error
       
  5814   {$$ = $1; print_err_msg(locl(@2), locf(@3), "';' missing at the end of access variable declaration."); yyerrok;}
       
  5815 | access_declaration_list error ';'
       
  5816   {$$ = $1; print_err_msg(locf(@2), locl(@2), "invalid access variable declaration."); yyerrok;}
       
  5817 | access_declaration_list ';'
       
  5818   {$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected ';' after access variable declaration."); yynerrs++;}
       
  5819 // ERROR_CHECK_END //
       
  5820 ;
       
  5821 
       
  5822 
       
  5823 access_declaration:
       
  5824   access_name ':' access_path ':' non_generic_type_name
       
  5825 | access_name ':' access_path ':' non_generic_type_name direction
       
  5826 ;
       
  5827 
       
  5828 
       
  5829 access_path:
       
  5830   prev_declared_direct_variable
       
  5831 | prev_declared_resource_name '.' prev_declared_direct_variable
       
  5832 | any_fb_name_list symbolic_variable
       
  5833 | prev_declared_resource_name '.' any_fb_name_list symbolic_variable
       
  5834 | prev_declared_program_name '.'  any_fb_name_list symbolic_variable
       
  5835 | prev_declared_resource_name '.' prev_declared_program_name '.' any_fb_name_list symbolic_variable
       
  5836 ;
       
  5837 */
       
  5838 
       
  5839 // helper symbol for
       
  5840 //  - access_path
       
  5841 //  - instance_specific_init
       
  5842 //
       
  5843 /* NOTE: The fb_name_list refers to funtion block variables
       
  5844  *       that have been declared in a scope outside the one we are
       
  5845  *       currently parsing, so we must accept them to be any_identifier!
       
  5846  *
       
  5847  *       Beware that other locations of this syntax parser also require
       
  5848  *       a fb_name_list. In those locations the function blocks are being declared,
       
  5849  *       so only currently un-used identifiers (i.e. identifier) may be accepted.
       
  5850  *
       
  5851  *       In order to distinguish the two, here we use any_fb_name_list, while
       
  5852  *       in the the locations we simply use fb_name_list!
       
  5853  */
       
  5854 any_fb_name_list:
       
  5855   // empty
       
  5856 	{$$ = new any_fb_name_list_c(locloc(@$));}
       
  5857 //| fb_name_list fb_name '.'
       
  5858 | any_fb_name_list any_identifier '.'
       
  5859 	{$$ = $1; $$->add_element($2);}
       
  5860 ;
       
  5861 
       
  5862 
       
  5863 
       
  5864 global_var_reference:
       
  5865 //  [resource_name '.'] global_var_name ['.' structure_element_name] //
       
  5866                                   prev_declared_global_var_name
       
  5867 	{$$ = new global_var_reference_c(NULL, $1, NULL, locloc(@$));}
       
  5868 |                                 prev_declared_global_var_name '.' structure_element_name
       
  5869 	{$$ = new global_var_reference_c(NULL, $1, $3, locloc(@$));}
       
  5870 | prev_declared_resource_name '.' prev_declared_global_var_name
       
  5871 	{$$ = new global_var_reference_c($1, $3, NULL, locloc(@$));}
       
  5872 | prev_declared_resource_name '.' prev_declared_global_var_name '.' structure_element_name
       
  5873 	{$$ = new global_var_reference_c($1, $3, $5, locloc(@$));}
       
  5874 ;
       
  5875 
       
  5876 
       
  5877 //access_name: identifier;
       
  5878 
       
  5879 
       
  5880 program_output_reference:
       
  5881 /* NOTE:
       
  5882  * program_output_reference is merely used within data_source.
       
  5883  * data_source is merely used within task_initialization
       
  5884  * task_initialization appears in a configuration declaration
       
  5885  * _before_ the programs are declared, so we cannot use
       
  5886  * prev_declared_program_name, as what might seem correct at first.
       
  5887  *
       
  5888  * The semantic checker must later check whether the identifier
       
  5889  * used really refers to a program declared after the task
       
  5890  * initialization!
       
  5891  */
       
  5892 //  prev_declared_program_name '.' symbolic_variable
       
  5893   program_name '.' symbolic_variable
       
  5894 	{$$ = new program_output_reference_c($1, $3, locloc(@$));}
       
  5895 ;
       
  5896 
       
  5897 program_name: identifier;
       
  5898 
       
  5899 /*
       
  5900 direction:
       
  5901   READ_WRITE
       
  5902 	{$$ = NULL;}
       
  5903 | READ_ONLY
       
  5904 	{$$ = NULL;}
       
  5905 ;
       
  5906 */
       
  5907 
       
  5908 task_configuration:
       
  5909   TASK task_name task_initialization
       
  5910 	{$$ = new task_configuration_c($2, $3, locloc(@$));}
       
  5911 /* ERROR_CHECK_BEGIN */
       
  5912 | TASK task_initialization
       
  5913   {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no task name defined in task declaration."); yynerrs++;}
       
  5914 | TASK error task_initialization
       
  5915   {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid task name defined in task declaration."); yyerrok;}
       
  5916 | TASK task_name error
       
  5917   {$$ = NULL;
       
  5918 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no task initialization defined in task declaration.");}
       
  5919 	 else {print_err_msg(locf(@3), locl(@3), "invalid task initialization in task declaration."); yyclearin;}
       
  5920 	 yyerrok;
       
  5921 	}
       
  5922 /* ERROR_CHECK_END */
       
  5923 ;
       
  5924 
       
  5925 /* NOTE: The specification does not mention the namespace to which task names
       
  5926  *       should belong to. Unlike resource and program names, for the moment we
       
  5927  *       let the task names belong to their own private namespace, as they do not
       
  5928  *       produce any conflicts in the syntax parser.
       
  5929  *       If in the future our interpretation of the spec. turns out to be incorrect,
       
  5930  *       the definition of task_name may have to be changed!
       
  5931  */
       
  5932 task_name: any_identifier;
       
  5933 
       
  5934 
       
  5935 task_initialization:
       
  5936 //  '(' [SINGLE ASSIGN data_source ','] [INTERVAL ASSIGN data_source ','] PRIORITY ASSIGN integer ')' //
       
  5937   '(' {cmd_goto_task_init_state();} task_initialization_single task_initialization_interval task_initialization_priority ')'
       
  5938 	{$$ = new task_initialization_c($3, $4, $5, locloc(@$));}
       
  5939 ;
       
  5940 
       
  5941 
       
  5942 task_initialization_single:
       
  5943 // [SINGLE ASSIGN data_source ',']
       
  5944   /* empty */
       
  5945 	{$$ = NULL;}
       
  5946 | SINGLE ASSIGN {cmd_pop_state();} data_source ',' {cmd_goto_task_init_state();} 
       
  5947 	{$$ = $4;}
       
  5948 /* ERROR_CHECK_BEGIN */
       
  5949 | SINGLE {cmd_pop_state();} data_source ',' {cmd_goto_task_init_state();}
       
  5950   {$$ = NULL; print_err_msg(locl(@1), locf(@3), "':=' missing after 'SINGLE' in task initialization."); yynerrs++;}
       
  5951 | SINGLE ASSIGN {cmd_pop_state();} ',' {cmd_goto_task_init_state();}
       
  5952   {$$ = NULL; print_err_msg(locl(@2), locf(@4), "no data source defined in 'SINGLE' statement of task initialization."); yynerrs++;}
       
  5953 | SINGLE ASSIGN {cmd_pop_state();} error ',' {cmd_goto_task_init_state();}
       
  5954   {$$ = NULL; print_err_msg(locf(@4), locl(@4), "invalid data source defined in 'SINGLE' statement of task initialization."); yyerrok;}
       
  5955 /* ERROR_CHECK_END */
       
  5956 ;
       
  5957 
       
  5958 
       
  5959 task_initialization_interval:
       
  5960 // [INTERVAL ASSIGN data_source ','] 
       
  5961   /* empty */
       
  5962 	{$$ = NULL;}
       
  5963 | INTERVAL ASSIGN {cmd_pop_state();} data_source ',' {cmd_goto_task_init_state();}
       
  5964 	{$$ = $4;}
       
  5965 /* ERROR_CHECK_BEGIN */
       
  5966 | INTERVAL {cmd_pop_state();} data_source ',' {cmd_goto_task_init_state();}
       
  5967   {$$ = NULL; print_err_msg(locl(@1), locf(@3), "':=' missing after 'INTERVAL' in task initialization.");}
       
  5968 | INTERVAL ASSIGN {cmd_pop_state();} ',' {cmd_goto_task_init_state();}
       
  5969   {$$ = NULL; print_err_msg(locl(@2), locf(@4), "no data source defined in 'INTERVAL' statement of task initialization."); yynerrs++;}
       
  5970 | INTERVAL ASSIGN {cmd_pop_state();} error ',' {cmd_goto_task_init_state();}
       
  5971   {$$ = NULL; print_err_msg(locf(@4), locl(@4), "invalid data source defined in 'INTERVAL' statement of task initialization."); yyerrok;}
       
  5972 /* ERROR_CHECK_END */
       
  5973 ;
       
  5974 
       
  5975 
       
  5976 
       
  5977 task_initialization_priority:
       
  5978 // PRIORITY ASSIGN integer
       
  5979   PRIORITY ASSIGN {cmd_pop_state();} integer 
       
  5980 	{$$ = $4;}
       
  5981 /* ERROR_CHECK_BEGIN */
       
  5982 | PRIORITY {cmd_pop_state();} integer
       
  5983   {$$ = NULL; print_err_msg(locl(@1), locf(@3), "':=' missing after 'PRIORITY' in task initialization."); yynerrs++;}
       
  5984 | PRIORITY ASSIGN {cmd_pop_state();} error
       
  5985   {$$ = NULL;
       
  5986 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@4), "no priority number defined in 'PRIORITY' statement of task initialization.");}
       
  5987 	 else {print_err_msg(locf(@4), locl(@4), "invalid priority number in 'PRIORITY' statement of task initialization."); yyclearin;}
       
  5988 	 yyerrok;
       
  5989 	}
       
  5990 /* ERROR_CHECK_END */
       
  5991 ;
       
  5992 
       
  5993 
       
  5994 
       
  5995 data_source:
       
  5996   constant
       
  5997 | global_var_reference
       
  5998 | program_output_reference
       
  5999 | prev_declared_direct_variable
       
  6000 ;
       
  6001 
       
  6002 program_configuration:
       
  6003 //  PROGRAM [RETAIN | NON_RETAIN] program_name [WITH task_name] ':' program_type_name ['(' prog_conf_elements ')'] //
       
  6004   PROGRAM program_name optional_task_name ':' prev_declared_program_type_name optional_prog_conf_elements
       
  6005 	{$$ = new program_configuration_c(NULL, $2, $3, $5, $6, locloc(@$));
       
  6006 	 variable_name_symtable.insert($2, prev_declared_program_name_token);
       
  6007 	}
       
  6008 | PROGRAM RETAIN program_name optional_task_name ':' prev_declared_program_type_name optional_prog_conf_elements
       
  6009 	{$$ = new program_configuration_c(new retain_option_c(locloc(@2)), $3, $4, $6, $7, locloc(@$));
       
  6010 	 variable_name_symtable.insert($3, prev_declared_program_name_token);
       
  6011 	}
       
  6012 | PROGRAM NON_RETAIN program_name optional_task_name ':' prev_declared_program_type_name optional_prog_conf_elements
       
  6013 	{$$ = new program_configuration_c(new non_retain_option_c(locloc(@2)), $3, $4, $6, $7, locloc(@$));
       
  6014 	 variable_name_symtable.insert($3, prev_declared_program_name_token);
       
  6015 	}
       
  6016 /* ERROR_CHECK_BEGIN */
       
  6017 | PROGRAM program_name optional_task_name ':' identifier optional_prog_conf_elements
       
  6018   {$$ = NULL; print_err_msg(locf(@5), locl(@5), "invalid program type name after ':' in program configuration."); yynerrs++;}
       
  6019 | PROGRAM RETAIN program_name optional_task_name ':' identifier optional_prog_conf_elements
       
  6020   {$$ = NULL; print_err_msg(locf(@6), locl(@6), "invalid program type name after ':' in program configuration."); yynerrs++;}
       
  6021 | PROGRAM NON_RETAIN program_name optional_task_name ':' identifier optional_prog_conf_elements
       
  6022   {$$ = NULL; print_err_msg(locf(@6), locl(@6), "invalid program type name after ':' in program configuration."); yynerrs++;}
       
  6023 | PROGRAM error program_name optional_task_name ':' prev_declared_program_type_name optional_prog_conf_elements
       
  6024   {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unexpected token after 'PROGRAM' in program configuration."); yyerrok;}
       
  6025 | PROGRAM RETAIN error program_name optional_task_name ':' prev_declared_program_type_name optional_prog_conf_elements
       
  6026   {$$ = NULL; print_err_msg(locf(@3), locl(@3), "unexpected token after 'RETAIN' in retentive program configuration."); yyerrok;}
       
  6027 | PROGRAM NON_RETAIN error program_name optional_task_name ':' prev_declared_program_type_name optional_prog_conf_elements
       
  6028   {$$ = NULL; print_err_msg(locf(@3), locl(@3), "unexpected token after 'NON_RETAIN' in non-retentive program configuration."); yyerrok;}
       
  6029 | PROGRAM optional_task_name ':' prev_declared_program_type_name optional_prog_conf_elements
       
  6030   {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no program name defined in program configuration."); yynerrs++;}
       
  6031 | PROGRAM RETAIN optional_task_name ':' prev_declared_program_type_name optional_prog_conf_elements
       
  6032   {$$ = NULL; print_err_msg(locl(@2), locf(@3), "no program name defined in retentive program configuration."); yynerrs++;}
       
  6033 | PROGRAM NON_RETAIN optional_task_name ':' prev_declared_program_type_name optional_prog_conf_elements
       
  6034   {$$ = NULL; print_err_msg(locl(@2), locf(@3), "no program name defined in non-retentive program configuration."); yynerrs++;}
       
  6035 | PROGRAM error optional_task_name ':' prev_declared_program_type_name optional_prog_conf_elements
       
  6036   {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid program name defined in program configuration."); yyerrok;}
       
  6037 | PROGRAM RETAIN error optional_task_name ':' prev_declared_program_type_name optional_prog_conf_elements
       
  6038   {$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid program name defined in retentive program configuration."); yyerrok;}
       
  6039 | PROGRAM NON_RETAIN error optional_task_name ':' prev_declared_program_type_name optional_prog_conf_elements
       
  6040   {$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid program name defined in non-retentive program configuration."); yyerrok;}
       
  6041 | PROGRAM program_name optional_task_name prev_declared_program_type_name optional_prog_conf_elements
       
  6042   {$$ = NULL; print_err_msg(locl(@3), locf(@4), "':' missing after program name or optional task name in program configuration."); yynerrs++;}
       
  6043 | PROGRAM RETAIN program_name optional_task_name prev_declared_program_type_name optional_prog_conf_elements
       
  6044   {$$ = NULL; print_err_msg(locl(@4), locf(@5), "':' missing after program name or optional task name in retentive program configuration."); yynerrs++;}
       
  6045 | PROGRAM NON_RETAIN program_name optional_task_name prev_declared_program_type_name optional_prog_conf_elements
       
  6046   {$$ = NULL; print_err_msg(locl(@4), locf(@5), "':' missing after program name or optional task name in non-retentive program configuration."); yynerrs++;}
       
  6047 | PROGRAM program_name optional_task_name ':' optional_prog_conf_elements
       
  6048   {$$ = NULL; print_err_msg(locl(@4), locf(@5), "no program type defined in program configuration."); yynerrs++;}
       
  6049 | PROGRAM RETAIN program_name optional_task_name ':' optional_prog_conf_elements
       
  6050   {$$ = NULL; print_err_msg(locl(@5), locf(@6), "no program type defined in retentive program configuration."); yynerrs++;}
       
  6051 | PROGRAM NON_RETAIN program_name optional_task_name ':' optional_prog_conf_elements
       
  6052   {$$ = NULL; print_err_msg(locl(@5), locf(@6), "no program type defined in non-retentive program configuration."); yynerrs++;}
       
  6053 /* ERROR_CHECK_END */
       
  6054 ;
       
  6055 
       
  6056 // helper symbol for program_configuration //
       
  6057 optional_task_name:
       
  6058   // empty //
       
  6059 	{$$ = NULL;}
       
  6060 | WITH task_name
       
  6061 	{$$ = $2;}
       
  6062 /* ERROR_CHECK_BEGIN */
       
  6063 | WITH error
       
  6064   {$$ = NULL;
       
  6065 	 if (is_current_syntax_token()) {print_err_msg(locl(@1), locf(@2), "no task name defined in optional task name of program configuration.");}
       
  6066 	 else {print_err_msg(locf(@2), locl(@2), "invalid task name in optional task name of program configuration."); yyclearin;}
       
  6067 	 yyerrok;
       
  6068 	}
       
  6069 /* ERROR_CHECK_END */
       
  6070 ;
       
  6071 
       
  6072 // helper symbol for program_configuration //
       
  6073 optional_prog_conf_elements:
       
  6074   // empty //
       
  6075 	{$$ = NULL;}
       
  6076 | '(' prog_conf_elements ')'
       
  6077 	{$$ = $2;}
       
  6078 /* ERROR_CHECK_BEGIN */
       
  6079 | '(' error ')'
       
  6080   {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid program configuration elements in program configuration."); yyerrok;}
       
  6081 | '(' prog_conf_elements error
       
  6082   {$$ = NULL; print_err_msg(locl(@2), locf(@3), "')' missing at the end of program configuration elements in program configuration."); yyerrok;}
       
  6083 /* ERROR_CHECK_END */
       
  6084 ;
       
  6085 
       
  6086 
       
  6087 prog_conf_elements:
       
  6088   prog_conf_element
       
  6089 	{$$ = new prog_conf_elements_c(locloc(@$)); $$->add_element($1);}
       
  6090 | prog_conf_elements ',' prog_conf_element
       
  6091 	{$$ = $1; $$->add_element($3);}
       
  6092 /* ERROR_CHECK_BEGIN */
       
  6093 | prog_conf_elements prog_conf_element
       
  6094   {$$ = $1; print_err_msg(locl(@1), locf(@2), "',' missing in program configuration elements list."); yynerrs++;}
       
  6095 | prog_conf_elements ',' error
       
  6096   {$$ = $1;
       
  6097 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no value defined for program configuration element in program configuration list.");}
       
  6098 	 else {print_err_msg(locf(@3), locl(@3), "invalid value for program configuration element in program configuration list."); yyclearin;}
       
  6099 	 yyerrok;
       
  6100 	}
       
  6101 /* ERROR_CHECK_END */
       
  6102 ;
       
  6103 
       
  6104 
       
  6105 prog_conf_element:
       
  6106   fb_task
       
  6107 | prog_cnxn
       
  6108 ;
       
  6109 
       
  6110 
       
  6111 fb_task:
       
  6112   // fb_name WITH task_name
       
  6113 /* NOTE: The fb_name refers to funtion block variables
       
  6114  *       that have been declared in a scope outside the one we are
       
  6115  *       currently parsing, so we must accept them to be any_identifier!
       
  6116  */
       
  6117   any_identifier WITH task_name
       
  6118 	{$$ = new fb_task_c($1, $3, locloc(@$));}
       
  6119 /* ERROR_CHECK_BEGIN */
       
  6120 | any_identifier WITH error
       
  6121   {$$ = NULL;
       
  6122 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no task name defined in function block configuration.");}
       
  6123 	 else {print_err_msg(locf(@3), locl(@3), "invalid task name in function block configuration."); yyclearin;}
       
  6124 	 yyerrok;
       
  6125 	}
       
  6126 /* ERROR_CHECK_END */
       
  6127 ;
       
  6128 
       
  6129 
       
  6130 /* NOTE:
       
  6131  *  The semantics of configuring a program are rather confusing, so here is
       
  6132  *  my (Mario) understanding on the issue...
       
  6133  *
       
  6134  *  A function/program may have as its input variables a simple variable
       
  6135  *  (BYTE, WORD, etc...), an array (ARRAY [1 .. 3] OF BYTE, ...) , or a structure.
       
  6136  *  Nevertheless, when calling this function from within a st or il language statement
       
  6137  *  it is not possible to allocate a value to a single element of the array or structure
       
  6138  *  typed input variable, as the accepted syntax is simply '(' variable_name ':=' variable ')'
       
  6139  *  Notice how the variable_name does not include things such as 'a.elem1' or 'a[1]'!
       
  6140  *
       
  6141  *  Nevertheless, when configuring a program from within a configuration,
       
  6142  *  it becomes possible to allocate values to individual elements of the
       
  6143  *  array or structured type input variable, as the syntax is now
       
  6144  *  '(' symbolic_variable ':=' data_sink|prog_data_source ')'
       
  6145  *  Notice how the symbolic_variable _does_ include things such as 'a.elem1' or 'a[1]'!
       
  6146  *
       
  6147  *  Conclusion: Unlike other locations in the syntax where SENDTO appears,
       
  6148  *  here it is not valid to replace symbolic_variable with any_identifier!
       
  6149  *  Nevertheless, it is also not correct to leave symbolic_variable as it is,
       
  6150  *  as we have defined it to only include previously declared variables,
       
  6151  *  which is not the case in this situation. Here symbolic_variable is refering
       
  6152  *  to variables that were defined within the scope of the program that is being
       
  6153  *  called, and _not_ within the scope of the configuration that is calling the
       
  6154  *  program, so the variables in question are not declared in the current scope!
       
  6155  *
       
  6156  *  We therefore need to define a new symbolic_variable, that accepts any_identifier
       
  6157  *  instead of previosuly declared variable names, to be used in the definition of
       
  6158  *  prog_cnxn!
       
  6159  */
       
  6160 prog_cnxn:
       
  6161   any_symbolic_variable ASSIGN prog_data_source
       
  6162 	{$$ = new prog_cnxn_assign_c($1, $3, locloc(@$));}
       
  6163 | any_symbolic_variable SENDTO data_sink
       
  6164 	{$$ = new prog_cnxn_sendto_c($1, $3, locloc(@$));}
       
  6165 /* ERROR_CHECK_BEGIN */
       
  6166 | any_symbolic_variable constant
       
  6167   {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':=' missing between parameter and value in program configuration element."); yynerrs++;}
       
  6168 | any_symbolic_variable enumerated_value
       
  6169   {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':=' missing between parameter and value in program configuration element."); yynerrs++;}
       
  6170 | any_symbolic_variable data_sink
       
  6171   {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':=' or '=>' missing between parameter and variable in program configuration element."); yynerrs++;}
       
  6172 | any_symbolic_variable ASSIGN error
       
  6173   {$$ = NULL;
       
  6174 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no value or variable defined in program configuration assignment element.");}
       
  6175 	 else {print_err_msg(locf(@3), locl(@3), "invalid value or variable in program configuration assignment element."); yyclearin;}
       
  6176 	 yyerrok;
       
  6177 	}
       
  6178 | any_symbolic_variable SENDTO error
       
  6179   {$$ = NULL;
       
  6180 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no variable defined in program configuration sendto element.");}
       
  6181 	 else {print_err_msg(locf(@3), locl(@3), "invalid variable in program configuration sendto element."); yyclearin;}
       
  6182 	 yyerrok;
       
  6183 	}
       
  6184 /* ERROR_CHECK_END */
       
  6185 ;
       
  6186 
       
  6187 prog_data_source:
       
  6188   constant
       
  6189 | enumerated_value
       
  6190 | global_var_reference
       
  6191 | prev_declared_direct_variable
       
  6192 ;
       
  6193 
       
  6194 data_sink:
       
  6195   global_var_reference
       
  6196 | prev_declared_direct_variable
       
  6197 ;
       
  6198 
       
  6199 instance_specific_initializations:
       
  6200  VAR_CONFIG instance_specific_init_list END_VAR
       
  6201 	{$$ = new instance_specific_initializations_c($2, locloc(@$));}
       
  6202 /* ERROR_CHECK_BEGIN */
       
  6203 | VAR_CONFIG END_VAR
       
  6204 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "no variable declared in configuration variable(s) initialization."); yynerrs++;}
       
  6205 | VAR_CONFIG error instance_specific_init_list END_VAR
       
  6206 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "unexpected token after 'VAR_CONFIG' in configuration variable(s) initialization."); yyerrok;}
       
  6207 | VAR_CONFIG instance_specific_init_list error END_OF_INPUT
       
  6208 	{$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed configuration variable(s) initialization."); yyerrok;}
       
  6209 | VAR_CONFIG error END_VAR
       
  6210 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in configuration variable(s) initialization."); yyerrok;}
       
  6211 /* ERROR_CHECK_END */
       
  6212 ;
       
  6213 
       
  6214 // helper symbol for instance_specific_initializations //
       
  6215 instance_specific_init_list:
       
  6216   instance_specific_init ';'
       
  6217 	{$$ = new instance_specific_init_list_c(locloc(@$)); $$->add_element($1);}
       
  6218 | instance_specific_init_list instance_specific_init ';'
       
  6219 	{$$ = $1; $$->add_element($2);}
       
  6220 /* ERROR_CHECK_BEGIN */
       
  6221 | error ';'
       
  6222   {$$ = new instance_specific_init_list_c(locloc(@$)); print_err_msg(locf(@1), locl(@1), "invalid configuration variable initialization."); yyerrok;}
       
  6223 | instance_specific_init error
       
  6224   {$$ = new instance_specific_init_list_c(locloc(@$)); print_err_msg(locl(@1), locf(@2), "';' missing at the end of configuration variable initialization."); yyerrok;}
       
  6225 | instance_specific_init_list instance_specific_init error
       
  6226   {$$ = $1; print_err_msg(locl(@2), locf(@3), "';' missing at the end of configuration variable initialization."); yyerrok;}
       
  6227 | instance_specific_init_list error ';'
       
  6228   {$$ = $1; print_err_msg(locf(@2), locl(@2), "invalid configuration variable initialization."); yyerrok;}
       
  6229 | instance_specific_init_list ';'
       
  6230   {$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected ';' after configuration variable initialization."); yynerrs++;}
       
  6231 /* ERROR_CHECK_END */
       
  6232 ;
       
  6233 
       
  6234 
       
  6235 instance_specific_init:
       
  6236 //
       
  6237 //  resource_name '.' program_name '.' {fb_name '.'}
       
  6238 //  ((variable_name [location] ':' located_var_spec_init) | (fb_name ':' function_block_type_name ':=' structure_initialization))
       
  6239 //
       
  6240 //  prev_declared_resource_name '.' prev_declared_program_name '.' any_fb_name_list variable_name ':' located_var_spec_init
       
  6241 /* NOTE: variable_name has been changed to any_identifier (and not simply identifier) because the
       
  6242  *       variables being referenced have been declared outside the scope currently being parsed!
       
  6243  */
       
  6244 /* NOTE: program_name has not been changed to prev_declared_program_name because the
       
  6245  *       programs being referenced have been declared outside the scope currently being parsed!
       
  6246  *       The programs are only kept inside the scope of the resource in which they are defined.
       
  6247  */
       
  6248   prev_declared_resource_name '.' program_name '.' any_fb_name_list any_identifier ':' located_var_spec_init
       
  6249 	{$$ = new instance_specific_init_c($1, $3, $5, $6, NULL, $8, locloc(@$));}
       
  6250 | prev_declared_resource_name '.' program_name '.' any_fb_name_list any_identifier location ':' located_var_spec_init
       
  6251 	{$$ = new instance_specific_init_c($1, $3, $5, $6, $7, $9, locloc(@$));}
       
  6252 | prev_declared_resource_name '.' program_name '.' any_fb_name_list any_identifier ':' fb_initialization
       
  6253 	{$5->add_element($6); $$ = new instance_specific_init_c($1, $3, $5, NULL, NULL, $8, locloc(@$));}
       
  6254 ;
       
  6255 
       
  6256 
       
  6257 /* helper symbol for instance_specific_init */
       
  6258 fb_initialization:
       
  6259   function_block_type_name ASSIGN structure_initialization
       
  6260 	{$$ = new fb_initialization_c($1, $3, locloc(@$));}
       
  6261 /* ERROR_CHECK_BEGIN */
       
  6262 | function_block_type_name structure_initialization
       
  6263   {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':=' missing between function block name and initialization in function block initialization."); yynerrs++;}
       
  6264 | function_block_type_name ASSIGN error
       
  6265   {$$ = NULL;
       
  6266 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no initial value defined in function block initialization.");}
       
  6267 	 else {print_err_msg(locf(@3), locl(@3), "invalid initial value in function block initialization."); yyclearin;}
       
  6268 	 yyerrok;
       
  6269 	}
       
  6270 /* ERROR_CHECK_END */
       
  6271 ;
       
  6272 
       
  6273 /***********************************/
       
  6274 /* B 2.1 Instructions and Operands */
       
  6275 /***********************************/
       
  6276 /* helper symbol for many IL instructions, etc... */
       
  6277 /* eat up any extra EOL tokens... */
       
  6278 
       
  6279 eol_list:
       
  6280   EOL
       
  6281 | eol_list EOL
       
  6282 ;
       
  6283 
       
  6284 
       
  6285 
       
  6286 instruction_list:
       
  6287   il_instruction
       
  6288 	{$$ = new instruction_list_c(locloc(@$)); $$->add_element($1);}
       
  6289 | any_pragma eol_list
       
  6290 	{$$ = new instruction_list_c(locloc(@$)); $$->add_element($1);}
       
  6291 | instruction_list il_instruction
       
  6292 	{$$ = $1; $$->add_element($2);}
       
  6293 | instruction_list any_pragma
       
  6294 	{$$ = $1; $$->add_element($2);}
       
  6295 ;
       
  6296 
       
  6297 
       
  6298 
       
  6299 il_instruction:
       
  6300   il_incomplete_instruction eol_list
       
  6301 	{$$ = new il_instruction_c(NULL, $1, locloc(@$));}
       
  6302 | label ':' il_incomplete_instruction eol_list
       
  6303 	{$$ = new il_instruction_c($1, $3, locloc(@$));}
       
  6304 | label ':' eol_list
       
  6305 	{$$ = new il_instruction_c($1, NULL, locloc(@$));}
       
  6306 /* ERROR_CHECK_BEGIN */
       
  6307 | error eol_list
       
  6308 	{$$ = NULL; print_err_msg(locf(@1), locl(@1), "invalid IL instruction."); yyerrok;}
       
  6309 | il_incomplete_instruction error
       
  6310 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "EOL missing at the end of IL instruction."); yyerrok;}
       
  6311 | error ':' il_incomplete_instruction eol_list
       
  6312 	{$$ = NULL; print_err_msg(locf(@1), locl(@1), "invalid label in IL instruction."); yyerrok;}
       
  6313 | label il_incomplete_instruction eol_list
       
  6314 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing after label in IL instruction."); yynerrs++;}
       
  6315 | label ':' error eol_list
       
  6316 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid IL instruction."); yyerrok;}
       
  6317 | label ':' il_incomplete_instruction error
       
  6318 	{$$ = NULL; print_err_msg(locl(@3), locf(@4), "EOL missing at the end of IL instruction."); yyerrok;}
       
  6319 /* ERROR_CHECK_END */
       
  6320 ;
       
  6321 
       
  6322 
       
  6323 /* helper symbol for il_instruction */
       
  6324 il_incomplete_instruction:
       
  6325   il_simple_operation
       
  6326 | il_expression
       
  6327 | il_jump_operation
       
  6328 | il_fb_call
       
  6329 | il_formal_funct_call
       
  6330 | il_return_operator
       
  6331 ;
       
  6332 
       
  6333 
       
  6334 label: identifier;
       
  6335 
       
  6336 
       
  6337 
       
  6338 il_simple_operation:
       
  6339 // (il_simple_operator [il_operand]) | (function_name [il_operand_list])
       
  6340   il_simple_operator
       
  6341 	{$$ = new il_simple_operation_c($1, NULL, locloc(@$));}
       
  6342 /*
       
  6343  * Note: Bison is getting confused with the following rule,
       
  6344  *       i.e. it is finding conflicts where there seemingly are really none.
       
  6345  *       The rule was therefore replaced by the equivalent following
       
  6346  *       two rules.
       
  6347  */
       
  6348 /*
       
  6349 | il_simple_operator il_operand
       
  6350 	{$$ = new il_simple_operation_c($1, $2, locloc(@$));}
       
  6351 */
       
  6352 | il_simple_operator_noclash il_operand
       
  6353 	{$$ = new il_simple_operation_c($1, $2, locloc(@$));}
       
  6354 | il_simple_operator_clash il_operand
       
  6355 	{$$ = new il_simple_operation_c($1, $2, locloc(@$));}
       
  6356 /* NOTE: the line
       
  6357  *         | il_simple_operator
       
  6358  *       already contains the 'NOT' operator, as well as all the
       
  6359  *       expression operators ('MOD', 'AND', etc...), all of which
       
  6360  *       may also be a function name! This means that these operators/functions,
       
  6361  *       without any operands, could be reduced to either an operator or a
       
  6362  *       function call. 
       
  6363  *
       
  6364  *       I (Mario) have chosen to reduce it to an operator.
       
  6365  *       In order to do this, we must remove from the syntax that defines
       
  6366  *       function calls all the functions whose names clash with the IL operators.
       
  6367  *
       
  6368  *       The line
       
  6369  *         | function_name
       
  6370  *       has been replaced with the lines
       
  6371  *         | function_name_no_clashes
       
  6372  *       in order to include all possible function names except
       
  6373  *       those whose names coincide with operators !!
       
  6374  */
       
  6375 | function_name_no_clashes
       
  6376 	{$$ = new il_function_call_c($1, NULL, locloc(@$));}
       
  6377 /* NOTE: the line
       
  6378  *         | il_simple_operator il_operand
       
  6379  *       already contains the 'NOT', 'MOD', etc. operators, followed by a single il_operand.
       
  6380  *       However, this same code (MOD x) may also be reduced to a function call to the MOD
       
  6381  *       function. This means that (MOD, AND,...) could be interpret as a function name
       
  6382  *       or as an IL operator! This would lead us to a reduce/reduce conflict!
       
  6383  *
       
  6384  *       I (Mario) have chosen to reduce it to an operand, rather than a function call.
       
  6385  *       In order to do this, we must remove from the syntax that defines
       
  6386  *       function calls all the functions whose names clash with the IL operators.
       
  6387  *
       
  6388  *       The line
       
  6389  *         | function_name il_operand_list
       
  6390  *       has been replaced with the line
       
  6391  *         | function_name_no_clashes il_operand_list
       
  6392  *       in order to include all possible function names except
       
  6393  *       for the function names which clash with expression and simple operators.
       
  6394  *
       
  6395  *       Note that:
       
  6396  *       this alternative syntax does not cover the possibility of
       
  6397  *       the function 'NOT', 'MOD', etc... being called with more than one il_operand,
       
  6398  *       in which case it is always a function call, and not an IL instruction.
       
  6399  *       We therefore need to include an extra rule where the
       
  6400  *       function_name_expression_clashes and function_name_simpleop_clashes
       
  6401  *       are followed by a il_operand_list with __two__ or more il_operands!!
       
  6402  */
       
  6403 | function_name_no_clashes il_operand_list
       
  6404 	{$$ = new il_function_call_c($1, $2, locloc(@$));}
       
  6405 | il_simple_operator_clash il_operand_list2
       
  6406 	{$$ = new il_function_call_c(il_operator_c_2_identifier_c($1), $2, locloc(@$));}
       
  6407 ;
       
  6408 
       
  6409 
       
  6410 
       
  6411 il_expression:
       
  6412 // il_expr_operator '(' [il_operand] EOL {EOL} [simple_instr_list] ')'
       
  6413 /*
       
  6414  * Note: Bison is getting confused with the use of il_expr_operator,
       
  6415  *       i.e. it is finding conflicts where there seemingly are really none.
       
  6416  *       il_expr_operator was therefore replaced by the equivalent 
       
  6417  *       il_expr_operator_noclash | il_expr_operator_clash.
       
  6418  */
       
  6419   il_expr_operator_noclash '(' eol_list ')'
       
  6420 	{$$ = new il_expression_c($1, NULL, NULL, locloc(@$));}
       
  6421 | il_expr_operator_noclash '(' il_operand eol_list ')'
       
  6422 	{$$ = new il_expression_c($1, $3, NULL, locloc(@$));}
       
  6423 | il_expr_operator_noclash '(' eol_list simple_instr_list ')'
       
  6424 	{$$ = new il_expression_c($1, NULL, $4, locloc(@$));}
       
  6425 | il_expr_operator_noclash '(' il_operand eol_list simple_instr_list ')'
       
  6426 	{$$ = new il_expression_c($1, $3, $5, locloc(@$));}
       
  6427 | il_expr_operator_clash '(' eol_list ')'
       
  6428 	{$$ = new il_expression_c($1, NULL, NULL, locloc(@$));}
       
  6429 | il_expr_operator_clash '(' il_operand eol_list ')'
       
  6430 	{$$ = new il_expression_c($1, $3, NULL, locloc(@$));}
       
  6431 | il_expr_operator_clash '(' il_operand eol_list simple_instr_list ')'
       
  6432 	{$$ = new il_expression_c($1, $3, $5, locloc(@$));}
       
  6433 | il_expr_operator_clash_eol_list simple_instr_list ')'
       
  6434 	{$$ = new il_expression_c($1, NULL, $2, locloc(@$));}
       
  6435 /* ERROR_CHECK_BEGIN */
       
  6436 | il_expr_operator_noclash '(' eol_list error
       
  6437   {$$ = NULL; print_err_msg(locl(@3), locf(@4), "')' missing at the end of IL expression."); yyerrok;}
       
  6438 | il_expr_operator_noclash '(' il_operand eol_list error
       
  6439   {$$ = NULL; print_err_msg(locl(@4), locf(@5), "')' missing at the end of IL expression."); yyerrok;}
       
  6440 | il_expr_operator_noclash '(' eol_list simple_instr_list error
       
  6441   {$$ = NULL; print_err_msg(locl(@4), locf(@5), "')' missing at the end of IL expression."); yyerrok;}
       
  6442 | il_expr_operator_noclash '(' il_operand eol_list simple_instr_list error
       
  6443   {$$ = NULL; print_err_msg(locl(@5), locf(@6), "')' missing at the end of IL expression."); yyerrok;}
       
  6444 | il_expr_operator_clash '(' il_operand eol_list error
       
  6445   {$$ = NULL; print_err_msg(locl(@4), locf(@5), "')' missing at the end of IL expression."); yyerrok;}
       
  6446 | il_expr_operator_clash '(' il_operand eol_list simple_instr_list error
       
  6447   {$$ = NULL; print_err_msg(locl(@5), locf(@6), "')' missing at the end of IL expression."); yyerrok;}
       
  6448 | il_expr_operator_clash_eol_list simple_instr_list error
       
  6449   {$$ = NULL; print_err_msg(locl(@2), locf(@3), "')' missing at the end of IL expression."); yyerrok;}
       
  6450 /* ERROR_CHECK_END */
       
  6451 ;
       
  6452 
       
  6453 
       
  6454 il_jump_operation:
       
  6455   il_jump_operator label
       
  6456 	{$$ = new il_jump_operation_c($1, $2, locloc(@$));}
       
  6457 /* ERROR_CHECK_BEGIN */
       
  6458 | il_jump_operator error
       
  6459   {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid label defined in IL jump operation."); yyerrok;}
       
  6460 /* ERROR_CHECK_END */
       
  6461 ;
       
  6462 
       
  6463 
       
  6464 il_fb_call:
       
  6465 // il_call_operator fb_name ['(' (EOL {EOL} [il_param_list]) | [il_operand_list] ')']
       
  6466   il_call_operator prev_declared_fb_name
       
  6467 	{$$ = new il_fb_call_c($1, $2, NULL, NULL, locloc(@$));}
       
  6468 | il_call_operator prev_declared_fb_name '(' ')'
       
  6469 	{$$ = new il_fb_call_c($1, $2, NULL, NULL, locloc(@$));}
       
  6470 | il_call_operator prev_declared_fb_name '(' eol_list ')'
       
  6471 	{$$ = new il_fb_call_c($1, $2, NULL, NULL, locloc(@$));}
       
  6472 | il_call_operator prev_declared_fb_name '(' il_operand_list ')'
       
  6473 	{$$ = new il_fb_call_c($1, $2, $4, NULL, locloc(@$));}
       
  6474 | il_call_operator prev_declared_fb_name '(' eol_list il_param_list ')'
       
  6475 	{$$ = new il_fb_call_c($1, $2, NULL, $5, locloc(@$));}
       
  6476 /* ERROR_CHECK_BEGIN */
       
  6477 | il_call_operator error
       
  6478   {$$ = NULL;
       
  6479 	 if (is_current_syntax_token()) {print_err_msg(locl(@1), locf(@2), "no function block name defined in IL function block call.");}
       
  6480 	 else {print_err_msg(locf(@2), locl(@2), "invalid function block name in IL function block call."); yyclearin;}
       
  6481 	 yyerrok;
       
  6482 	}
       
  6483 | il_call_operator '(' ')'
       
  6484   {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no function block name defined in IL function block call."); yynerrs++;}
       
  6485 | il_call_operator '(' eol_list ')'
       
  6486   {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no function block name defined in IL function block call."); yynerrs++;}
       
  6487 | il_call_operator '(' il_operand_list ')'
       
  6488   {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no function block name defined in IL function block call."); yynerrs++;}
       
  6489 | il_call_operator '(' eol_list il_param_list ')'
       
  6490   {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no function block name defined in IL function block call."); yynerrs++;}
       
  6491 | il_call_operator error '(' ')'
       
  6492   {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid function block name defined in IL function block call."); yyerrok;}
       
  6493 | il_call_operator error '(' eol_list ')'
       
  6494   {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid function block name defined in IL function block call."); yyerrok;}
       
  6495 | il_call_operator error '(' il_operand_list ')'
       
  6496   {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid function block name defined in IL function block call."); yyerrok;}
       
  6497 | il_call_operator error '(' eol_list il_param_list ')'
       
  6498   {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid function block name defined in IL function block call."); yyerrok;}
       
  6499 | il_call_operator prev_declared_fb_name ')'
       
  6500   {$$ = NULL; print_err_msg(locl(@2), locf(@3), "'(' missing after function block name defined in IL function block call."); yynerrs++;}
       
  6501 | il_call_operator prev_declared_fb_name il_operand_list ')'
       
  6502   {$$ = NULL; print_err_msg(locl(@2), locf(@3), "'(' missing after function block name defined in IL function block call."); yynerrs++;}
       
  6503 | il_call_operator prev_declared_fb_name '(' error
       
  6504   {$$ = NULL; print_err_msg(locl(@3), locf(@4), "')' missing at the end of IL function block call."); yyerrok;}
       
  6505 | il_call_operator prev_declared_fb_name '(' eol_list error
       
  6506   {$$ = NULL; print_err_msg(locl(@4), locf(@5), "')' missing at the end of IL function block call."); yyerrok;}
       
  6507 | il_call_operator prev_declared_fb_name '(' il_operand_list error
       
  6508   {$$ = NULL; print_err_msg(locl(@4), locf(@5), "')' missing at the end of IL function block call."); yyerrok;}
       
  6509 /* ERROR_CHECK_END */
       
  6510 ;
       
  6511 
       
  6512 
       
  6513 /* NOTE: Please read note above the definition of function_name_without_clashes */
       
  6514 il_formal_funct_call:
       
  6515 // function_name '(' EOL {EOL} [il_param_list] ')'
       
  6516 /*  function_name '(' eol_list ')'  */
       
  6517 /* NOTE: il_formal_funct_call is only used in the definition of
       
  6518  *         - il_incomplete_instruction
       
  6519  *         - il_simple_instruction
       
  6520  *       In both of the above, il_expression also
       
  6521  *       shows up as another option. This means that the functions whose
       
  6522  *       names clash with expressions, followed by '(' eol_list ')', are
       
  6523  *       already included. We must therefore leave them out in this
       
  6524  *       definition in order to remove reduce/reduce conflicts.
       
  6525  *
       
  6526  *       In summary: 'MOD' '(' eol_list ')', and all other functions whose
       
  6527  *       names clash with expressions may be interpreted by the syntax by
       
  6528  *       two different routes. I (Mario) chose to interpret them
       
  6529  *       as operators, rather than as function calls!
       
  6530  *       (AND MOD OR XOR ADD DIV EQ GT GE LT LE MUL NE SUB)
       
  6531  */
       
  6532   function_name_no_clashes '(' eol_list ')'
       
  6533 	{$$ = new il_formal_funct_call_c($1, NULL, locloc(@$));}
       
  6534 | function_name_simpleop_clashes '(' eol_list ')'
       
  6535 	{$$ = new il_formal_funct_call_c($1, NULL, locloc(@$));}
       
  6536 /* | function_name '(' eol_list il_param_list ')' */
       
  6537 /* For the above syntax, we no longer have two ways of interpreting the
       
  6538  * same syntax. The above is always a function call!
       
  6539  * However, some of the functions that we may be calling
       
  6540  * may have the same name as an IL operator. This means that
       
  6541  * flex will be parsing them and handing them over to bison as
       
  6542  * IL operator tokens, and not as function name tokens.
       
  6543  * (when parsing ST, flex no longer recognizes IL operators,
       
  6544  * so will always return the correct function name, unless that
       
  6545  * name also coincides with an operator used in ST -> XOR, OR, MOD, AND, NOT)
       
  6546  *
       
  6547  * We must therefore interpret the IL operators as function names!
       
  6548  */
       
  6549 | function_name_no_clashes '(' eol_list il_param_list ')'
       
  6550 	{$$ = new il_formal_funct_call_c($1, $4, locloc(@$));}
       
  6551 | function_name_simpleop_clashes '(' eol_list il_param_list ')'
       
  6552 	{$$ = new il_formal_funct_call_c($1, $4, locloc(@$));}
       
  6553 /* The following line should read:
       
  6554  *
       
  6555  * | function_name_expression_clashes '(' eol_list il_param_list ')'
       
  6556  *
       
  6557  * but the function_name_expression_clashes had to be first reduced to
       
  6558  * an intermediary symbol in order to remove a reduce/reduce conflict.
       
  6559  * In essence, the syntax requires more than one look ahead token
       
  6560  * in order to be parsed. We resolve this by reducing a collection of
       
  6561  * symbols into a temporary symbol (il_expr_operator_clash_eol_list), that
       
  6562  * will later be replaced by the correct symbol. The correct symbol will
       
  6563  * now be determined by a single look ahead token, as all the common
       
  6564  * symbols have been reduced to the temporary symbol
       
  6565  * il_expr_operator_clash_eol_list !
       
  6566  *
       
  6567  * Unfortunately, this work around results in the wrong symbol
       
  6568  * being created for the abstract syntax tree.
       
  6569  * We need to figure out which symbol was created, destroy it,
       
  6570  * and create the correct symbol for our case.
       
  6571  * This is a lot of work, so I put it in a function
       
  6572  * at the end of this file... il_operator_c_2_identifier_c()
       
  6573  */
       
  6574 | il_expr_operator_clash_eol_list il_param_list ')'
       
  6575 	{$$ = new il_formal_funct_call_c(il_operator_c_2_identifier_c($1), $2, locloc(@$));}
       
  6576 /* ERROR_CHECK_BEGIN */
       
  6577 | function_name_no_clashes '(' eol_list error ')'
       
  6578   {$$ = NULL; print_err_msg(locf(@4), locl(@4), "invalid parameter list defined in IL formal function call."); yyerrok;} 
       
  6579 | function_name_simpleop_clashes '(' eol_list error ')'
       
  6580   {$$ = NULL; print_err_msg(locf(@4), locl(@4), "invalid parameter list defined in IL formal function call."); yyerrok;} 
       
  6581 | il_expr_operator_clash_eol_list error ')'
       
  6582   {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid parameter list defined in IL formal function call."); yyerrok;} 
       
  6583 /* ERROR_CHECK_END */
       
  6584 ;
       
  6585 
       
  6586 
       
  6587 il_expr_operator_clash_eol_list:
       
  6588   il_expr_operator_clash '(' eol_list
       
  6589 	{$$ = $1;}
       
  6590 /* ERROR_CHECK_BEGIN */
       
  6591 | il_expr_operator_clash '(' error
       
  6592   {$$ = $1; print_err_msg(locl(@2), locf(@3), "EOL missing after '(' in IL instruction."); yyerrok;}
       
  6593 /* ERROR_CHECK_END */
       
  6594 ;
       
  6595 
       
  6596 
       
  6597 il_operand:
       
  6598   variable
       
  6599 | enumerated_value
       
  6600 | constant
       
  6601 ;
       
  6602 
       
  6603 
       
  6604 il_operand_list:
       
  6605   il_operand
       
  6606 	{$$ = new il_operand_list_c(locloc(@$)); $$->add_element($1);}
       
  6607 | il_operand_list2
       
  6608 ;
       
  6609 
       
  6610 
       
  6611 /* List with 2 or more il_operands */ 
       
  6612 il_operand_list2:
       
  6613   il_operand ',' il_operand 
       
  6614 	{$$ = new il_operand_list_c(locloc(@$)); $$->add_element($1); $$->add_element($3);}
       
  6615 | il_operand_list2 ',' il_operand
       
  6616 	{$$ = $1; $$->add_element($3);}
       
  6617 /* ERROR_CHECK_BEGIN */
       
  6618 | il_operand_list2 il_operand
       
  6619   {$$ = $1; print_err_msg(locl(@1), locf(@2), "',' missing in IL operand list."); yynerrs++;}
       
  6620 | il_operand ',' error
       
  6621   {$$ = new il_operand_list_c(locloc(@$));
       
  6622 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no operand defined in IL operand list.");}
       
  6623 	 else {print_err_msg(locf(@3), locl(@3), "invalid operand name in IL operand list."); yyclearin;}
       
  6624 	 yyerrok;
       
  6625 	}
       
  6626 /* ERROR_CHECK_END */
       
  6627 ;
       
  6628 
       
  6629 
       
  6630 simple_instr_list:
       
  6631   il_simple_instruction
       
  6632 	{$$ = new simple_instr_list_c(locloc(@$)); $$->add_element($1);}
       
  6633 | simple_instr_list il_simple_instruction
       
  6634 	{$$ = $1; $$->add_element($2);}
       
  6635 ;
       
  6636 
       
  6637 
       
  6638 il_simple_instruction:
       
  6639   il_simple_operation eol_list
       
  6640 | il_expression eol_list
       
  6641 | il_formal_funct_call eol_list
       
  6642 /* ERROR_CHECK_BEGIN */
       
  6643 | il_expression error
       
  6644   {$$ = NULL; print_err_msg(locl(@1), locf(@2), "EOL missing after expression IL instruction."); yyerrok;}
       
  6645 | il_formal_funct_call error
       
  6646   {$$ = NULL; print_err_msg(locl(@1), locf(@2), "EOL missing after formal function call IL instruction."); yyerrok;}
       
  6647 /* ERROR_CHECK_END */
       
  6648 ;
       
  6649 
       
  6650 
       
  6651 /* NOTE: the correct definition of il_param_list is
       
  6652  * il_param_list ::= {il_param_instruction} il_param_last_instruction
       
  6653  *
       
  6654  * where {...} denotes zero or many il_param_instruction's.
       
  6655  *
       
  6656  * We could do this by defining the following:
       
  6657  * il_param_list: il_param_instruction_list il_param_last_instruction;
       
  6658  * il_param_instruction_list : ** empty ** | il_param_instruction_list il_param_instruction;
       
  6659  *
       
  6660  * Unfortunately, the above leads to reduce/reduce conflicts.
       
  6661  * The chosen alternative (as follows) does not have any conflicts!
       
  6662  * il_param_list: il_param_last_instruction | il_param_instruction_list il_param_last_instruction;
       
  6663  * il_param_instruction_list : il_param_instruction_list | il_param_instruction_list il_param_instruction;
       
  6664  */
       
  6665 il_param_list:
       
  6666   il_param_instruction_list il_param_last_instruction
       
  6667 	{$$ = $1; $$->add_element($2);}
       
  6668 | il_param_last_instruction
       
  6669 	{$$ = new il_param_list_c(locloc(@$)); $$->add_element($1);}
       
  6670 /* ERROR_CHECK_BEGIN */
       
  6671 | il_param_instruction_list error
       
  6672   {$$ = $1; print_err_msg(locf(@2), locl(@2), "invalid parameter assignment in parameter assignment list."); yyerrok;}
       
  6673 | il_param_last_instruction il_param_last_instruction
       
  6674   {$$ = new il_param_list_c(locloc(@$)); print_err_msg(locl(@1), locf(@2), "',' missing at the end of parameter assignment in parameter assignment list."); yynerrs++;}
       
  6675 | il_param_instruction_list il_param_last_instruction il_param_last_instruction
       
  6676   {$$ = $1; print_err_msg(locl(@2), locf(@3), "',' missing at the end of parameter assignment in parameter assignment list."); yynerrs++;}
       
  6677 /* ERROR_CHECK_END */
       
  6678 ;
       
  6679 
       
  6680 
       
  6681 /* Helper symbol for il_param_list */
       
  6682 il_param_instruction_list:
       
  6683   il_param_instruction
       
  6684 	{$$ = new il_param_list_c(locloc(@$)); $$->add_element($1);}
       
  6685 | il_param_instruction_list il_param_instruction
       
  6686 	{$$ = $1; $$->add_element($2);}
       
  6687 /* ERROR_CHECK_BEGIN */
       
  6688 | il_param_last_instruction il_param_instruction
       
  6689   {$$ = new il_param_list_c(locloc(@$)); print_err_msg(locl(@1), locf(@2), "',' missing at the end of parameter assignment in parameter assignment list."); yynerrs++;}
       
  6690 | il_param_instruction_list il_param_last_instruction il_param_instruction
       
  6691   {$$ = $1; print_err_msg(locl(@2), locf(@3), "',' missing at the end of parameter assignment in parameter assignment list."); yynerrs++;}
       
  6692 /* ERROR_CHECK_END */
       
  6693 ;
       
  6694 
       
  6695 
       
  6696 il_param_instruction:
       
  6697   il_param_assignment ',' eol_list 
       
  6698 | il_param_out_assignment ',' eol_list
       
  6699 /* ERROR_CHECK_BEGIN */
       
  6700 | il_param_assignment ',' error
       
  6701   {$$ = NULL; print_err_msg(locl(@2), locf(@3), "EOL missing at the end of parameter assignment in parameter assignment list."); yyerrok;}
       
  6702 | il_param_out_assignment ',' error
       
  6703   {$$ = NULL; print_err_msg(locl(@2), locf(@3), "EOL missing at the end of parameter out assignment in parameter assignment list."); yyerrok;}
       
  6704 /* ERROR_CHECK_END */
       
  6705 ;
       
  6706 
       
  6707 
       
  6708 il_param_last_instruction:
       
  6709   il_param_assignment eol_list
       
  6710 | il_param_out_assignment eol_list
       
  6711 /* ERROR_CHECK_BEGIN */
       
  6712 | il_param_assignment error
       
  6713   {$$ = NULL; print_err_msg(locl(@1), locf(@2), "EOL missing at the end of last parameter assignment in parameter assignment list."); yyerrok;}
       
  6714 | il_param_out_assignment error
       
  6715   {$$ = NULL; print_err_msg(locl(@1), locf(@2), "EOL missing at the end of last parameter out assignment in parameter assignment list."); yyerrok;}
       
  6716 /* ERROR_CHECK_END */
       
  6717 
       
  6718 ;
       
  6719 
       
  6720 
       
  6721 il_param_assignment:
       
  6722   il_assign_operator il_operand
       
  6723 	{$$ = new il_param_assignment_c($1, $2, NULL, locloc(@$));}
       
  6724 | il_assign_operator '(' eol_list simple_instr_list ')'
       
  6725 	{$$ = new il_param_assignment_c($1, NULL, $4, locloc(@$));}
       
  6726 /* ERROR_CHECK_BEGIN */
       
  6727 | error il_operand
       
  6728   {$$ = NULL; print_err_msg(locf(@1), locl(@1), "invalid operator in parameter assignment."); yyerrok;}
       
  6729 | error '(' eol_list simple_instr_list ')'
       
  6730   {$$ = NULL; print_err_msg(locf(@1), locl(@1), "invalid operator in parameter assignment."); yyerrok;}
       
  6731 | il_assign_operator error
       
  6732   {$$ = NULL;
       
  6733 	 if (is_current_syntax_token()) {print_err_msg(locl(@1), locf(@2), "no operand defined in parameter assignment.");}
       
  6734 	 else {print_err_msg(locf(@2), locl(@2), "invalid operand in parameter assignment."); yyclearin;}
       
  6735 	 yyerrok;
       
  6736 	}
       
  6737 | il_assign_operator '(' eol_list ')'
       
  6738   {$$ = NULL; print_err_msg(locl(@3), locf(@4), "no instruction list defined in parameter assignment."); yynerrs++;}
       
  6739 | il_assign_operator '(' eol_list error ')'
       
  6740   {$$ = NULL; print_err_msg(locf(@4), locl(@4), "invalid instruction list defined in parameter assignment."); yyerrok;}
       
  6741 | il_assign_operator '(' eol_list simple_instr_list error
       
  6742   {$$ = NULL; print_err_msg(locl(@4), locf(@5), "')' missing at the end of instruction list defined in parameter assignment."); yyerrok;}
       
  6743 /* ERROR_CHECK_END */
       
  6744 ;
       
  6745 
       
  6746 
       
  6747 il_param_out_assignment:
       
  6748   il_assign_out_operator variable
       
  6749 	{$$ = new il_param_out_assignment_c($1, $2, locloc(@$));}
       
  6750 /* ERROR_CHECK_BEGIN */
       
  6751 | il_assign_out_operator error
       
  6752   {$$ = NULL;
       
  6753 	 if (is_current_syntax_token()) {print_err_msg(locl(@1), locf(@2), "no variable defined in IL operand list.");}
       
  6754 	 else {print_err_msg(locf(@2), locl(@2), "invalid variable in IL operand list."); yyclearin;}
       
  6755 	 yyerrok;
       
  6756 	}
       
  6757 /* ERROR_CHECK_END */
       
  6758 ;
       
  6759 
       
  6760 
       
  6761 
       
  6762 /*******************/
       
  6763 /* B 2.2 Operators */
       
  6764 /*******************/
       
  6765 sendto_identifier: sendto_identifier_token {$$ = new identifier_c($1, locloc(@$));};
       
  6766 
       
  6767 
       
  6768 /* NOTE:
       
  6769  *  The spec includes the operator 'EQ '
       
  6770  * Note that EQ is followed by a space.
       
  6771  * I am considering this a typo, and defining the operator
       
  6772  * as 'EQ'
       
  6773  * (Mario)
       
  6774  */
       
  6775 LD_operator: 		LD 	{$$ = new LD_operator_c(locloc(@$));};
       
  6776 LDN_operator: 		LDN 	{$$ = new LDN_operator_c(locloc(@$));};
       
  6777 ST_operator: 		ST 	{$$ = new ST_operator_c(locloc(@$));};
       
  6778 STN_operator: 		STN 	{$$ = new STN_operator_c(locloc(@$));};
       
  6779 NOT_operator: 		NOT 	{$$ = new NOT_operator_c(locloc(@$));};
       
  6780 S_operator: 		S 	{$$ = new S_operator_c(locloc(@$));};
       
  6781 R_operator: 		R 	{$$ = new R_operator_c(locloc(@$));};
       
  6782 S1_operator: 		S1 	{$$ = new S1_operator_c(locloc(@$));};
       
  6783 R1_operator: 		R1 	{$$ = new R1_operator_c(locloc(@$));};
       
  6784 CLK_operator: 		CLK 	{$$ = new CLK_operator_c(locloc(@$));};
       
  6785 CU_operator: 		CU 	{$$ = new CU_operator_c(locloc(@$));};
       
  6786 CD_operator: 		CD 	{$$ = new CD_operator_c(locloc(@$));};
       
  6787 PV_operator: 		PV 	{$$ = new PV_operator_c(locloc(@$));};
       
  6788 IN_operator: 		IN 	{$$ = new IN_operator_c(locloc(@$));};
       
  6789 PT_operator: 		PT 	{$$ = new PT_operator_c(locloc(@$));};
       
  6790 AND_operator: 		AND 	{$$ = new AND_operator_c(locloc(@$));};
       
  6791 AND2_operator: 		AND2 	{$$ = new AND_operator_c(locloc(@$));}; /* '&' in the source code! */
       
  6792 OR_operator: 		OR 	{$$ = new OR_operator_c(locloc(@$));};
       
  6793 XOR_operator: 		XOR 	{$$ = new XOR_operator_c(locloc(@$));};
       
  6794 ANDN_operator: 		ANDN 	{$$ = new ANDN_operator_c(locloc(@$));};
       
  6795 ANDN2_operator:		ANDN2 	{$$ = new ANDN_operator_c(locloc(@$));}; /* '&N' in the source code! */
       
  6796 ORN_operator: 		ORN 	{$$ = new ORN_operator_c(locloc(@$));};
       
  6797 XORN_operator: 		XORN 	{$$ = new XORN_operator_c(locloc(@$));};
       
  6798 ADD_operator: 		ADD 	{$$ = new ADD_operator_c(locloc(@$));};
       
  6799 SUB_operator: 		SUB 	{$$ = new SUB_operator_c(locloc(@$));};
       
  6800 MUL_operator: 		MUL 	{$$ = new MUL_operator_c(locloc(@$));};
       
  6801 DIV_operator: 		DIV 	{$$ = new DIV_operator_c(locloc(@$));};
       
  6802 MOD_operator: 		MOD 	{$$ = new MOD_operator_c(locloc(@$));};
       
  6803 GT_operator: 		GT 	{$$ = new GT_operator_c(locloc(@$));};
       
  6804 GE_operator: 		GE 	{$$ = new GE_operator_c(locloc(@$));};
       
  6805 EQ_operator: 		EQ 	{$$ = new EQ_operator_c(locloc(@$));};
       
  6806 LT_operator: 		LT 	{$$ = new LT_operator_c(locloc(@$));};
       
  6807 LE_operator: 		LE 	{$$ = new LE_operator_c(locloc(@$));};
       
  6808 NE_operator: 		NE 	{$$ = new NE_operator_c(locloc(@$));};
       
  6809 CAL_operator: 		CAL 	{$$ = new CAL_operator_c(locloc(@$));};
       
  6810 CALC_operator: 		CALC 	{$$ = new CALC_operator_c(locloc(@$));};
       
  6811 CALCN_operator: 	CALCN 	{$$ = new CALCN_operator_c(locloc(@$));};
       
  6812 RET_operator: 		RET 	{$$ = new RET_operator_c(locloc(@$));};
       
  6813 RETC_operator: 		RETC 	{$$ = new RETC_operator_c(locloc(@$));};
       
  6814 RETCN_operator: 	RETCN 	{$$ = new RETCN_operator_c(locloc(@$));};
       
  6815 JMP_operator: 		JMP 	{$$ = new JMP_operator_c(locloc(@$));};
       
  6816 JMPC_operator: 		JMPC 	{$$ = new JMPC_operator_c(locloc(@$));};
       
  6817 JMPCN_operator: 	JMPCN 	{$$ = new JMPCN_operator_c(locloc(@$));};
       
  6818 
       
  6819 
       
  6820 il_simple_operator:
       
  6821   il_simple_operator_clash
       
  6822 | il_simple_operator_noclash
       
  6823 ;
       
  6824 
       
  6825 
       
  6826 il_simple_operator_noclash:
       
  6827   LD_operator
       
  6828 | LDN_operator
       
  6829 | ST_operator
       
  6830 | STN_operator
       
  6831 | S_operator
       
  6832 | R_operator
       
  6833 | S1_operator
       
  6834 | R1_operator
       
  6835 | CLK_operator
       
  6836 | CU_operator
       
  6837 | CD_operator
       
  6838 | PV_operator
       
  6839 | IN_operator
       
  6840 | PT_operator
       
  6841 | il_expr_operator_noclash
       
  6842 ;
       
  6843 
       
  6844 
       
  6845 il_simple_operator_clash:
       
  6846   il_simple_operator_clash1
       
  6847 | il_simple_operator_clash2
       
  6848 ;
       
  6849 
       
  6850 il_simple_operator_clash1:
       
  6851   NOT_operator
       
  6852 ;
       
  6853 
       
  6854 il_simple_operator_clash2:
       
  6855   il_expr_operator_clash
       
  6856 ;
       
  6857 
       
  6858 
       
  6859 /*
       
  6860 il_expr_operator:
       
  6861   il_expr_operator_noclash
       
  6862 | il_expr_operator_clash
       
  6863 ;
       
  6864 */
       
  6865 
       
  6866 il_expr_operator_clash:
       
  6867   AND_operator
       
  6868 | OR_operator
       
  6869 | XOR_operator
       
  6870 | ADD_operator
       
  6871 | SUB_operator
       
  6872 | MUL_operator
       
  6873 | DIV_operator
       
  6874 | MOD_operator
       
  6875 | GT_operator
       
  6876 | GE_operator
       
  6877 | EQ_operator
       
  6878 | LT_operator
       
  6879 | LE_operator
       
  6880 | NE_operator
       
  6881 ;
       
  6882 
       
  6883 
       
  6884 il_expr_operator_noclash:
       
  6885   ANDN_operator
       
  6886 | ANDN2_operator  /* string '&N' in source code! */
       
  6887 | AND2_operator  /* string '&' in source code! */
       
  6888 | ORN_operator
       
  6889 | XORN_operator
       
  6890 ;
       
  6891 
       
  6892 
       
  6893 
       
  6894 
       
  6895 il_assign_operator:
       
  6896 /*  variable_name ASSIGN */
       
  6897   any_identifier ASSIGN
       
  6898 	{$$ = new il_assign_operator_c($1, locloc(@$));}
       
  6899 | en_identifier ASSIGN
       
  6900 	{$$ = new il_assign_operator_c($1, locloc(@$));}
       
  6901 | S1_operator ASSIGN
       
  6902 	{$$ = new il_assign_operator_c(il_operator_c_2_identifier_c($1), locloc(@$));}
       
  6903 | R1_operator ASSIGN
       
  6904 	{$$ = new il_assign_operator_c(il_operator_c_2_identifier_c($1), locloc(@$));}
       
  6905 | CLK_operator ASSIGN
       
  6906 	{$$ = new il_assign_operator_c(il_operator_c_2_identifier_c($1), locloc(@$));}
       
  6907 | CU_operator ASSIGN
       
  6908 	{$$ = new il_assign_operator_c(il_operator_c_2_identifier_c($1), locloc(@$));}
       
  6909 | CD_operator ASSIGN
       
  6910 	{$$ = new il_assign_operator_c(il_operator_c_2_identifier_c($1), locloc(@$));}
       
  6911 | PV_operator ASSIGN
       
  6912 	{$$ = new il_assign_operator_c(il_operator_c_2_identifier_c($1), locloc(@$));}
       
  6913 | IN_operator ASSIGN
       
  6914 	{$$ = new il_assign_operator_c(il_operator_c_2_identifier_c($1), locloc(@$));}
       
  6915 | PT_operator ASSIGN
       
  6916 	{$$ = new il_assign_operator_c(il_operator_c_2_identifier_c($1), locloc(@$));}
       
  6917 /* ERROR_CHECK_BEGIN */
       
  6918 | error ASSIGN
       
  6919   {$$ = NULL; print_err_msg(locf(@1), locl(@1), "invalid parameter defined in parameter assignment."); yyerrok;}
       
  6920 /* ERROR_CHECK_END */
       
  6921 ;
       
  6922 
       
  6923 
       
  6924 il_assign_out_operator:
       
  6925 /*  variable_name SENDTO */
       
  6926 /*  any_identifier SENDTO */
       
  6927   sendto_identifier SENDTO
       
  6928 	{$$ = new il_assign_out_operator_c(NULL, $1, locloc(@$));}
       
  6929 /* The following is not required, as the sendto_identifier_token returned by flex will 
       
  6930  * also include the 'ENO' identifier.
       
  6931  * The resulting abstract syntax tree is identical with or without this following rule,
       
  6932  * as both the eno_identifier and the sendto_identifier are stored as
       
  6933  * an identifier_c !!
       
  6934  *
       
  6935  * To understand why we must even explicitly consider the use of ENO here,  
       
  6936  * please read the comment above the definition of 'variable' in section B1.4 for details.
       
  6937  */
       
  6938 /*
       
  6939 | eno_identifier SENDTO
       
  6940 	{$$ = new il_assign_out_operator_c(NULL, $1, locloc(@$));}
       
  6941 */
       
  6942 /*| NOT variable_name SENDTO */
       
  6943 | NOT sendto_identifier SENDTO
       
  6944 	{$$ = new il_assign_out_operator_c(new not_paramassign_c(locloc(@1)), $2, locloc(@$));}
       
  6945 /* The following is not required, as the sendto_identifier_token returned by flex will 
       
  6946  * also include the 'ENO' identifier.
       
  6947  * The resulting abstract syntax tree is identical with or without this following rule,
       
  6948  * as both the eno_identifier and the sendto_identifier are stored as
       
  6949  * an identifier_c !!
       
  6950  *
       
  6951  * To understand why we must even explicitly consider the use of ENO here,  
       
  6952  * please read the comment above the definition of 'variable' in section B1.4 for details.
       
  6953  *
       
  6954  * NOTE: Removing the following rule also removes a shift/reduce conflict from the parser.
       
  6955  *       This conflict is not really an error/ambiguity in the syntax, but rather
       
  6956  *       due to the fact that more than a single look-ahead token would be required
       
  6957  *       to correctly parse the syntax, something that bison does not support.
       
  6958  *
       
  6959  *       The shift/reduce conflict arises because bison does not know whether
       
  6960  *       to parse the 'NOT ENO' in the following code
       
  6961  *         LD 1
       
  6962  *         funct_name (
       
  6963  *                      NOT ENO => bool_var,
       
  6964  *                      EN := TRUE
       
  6965  *                    )
       
  6966  *        as either a il_param_assignment (wrong!) or an il_param_out_assignment.(correct).
       
  6967  *        The '=>' delimiter (known as SEND_TO in this iec.y file) is a dead giveaway that 
       
  6968  *        it should be parsed as an il_param_out_assignment, but still, bison gets confused!
       
  6969  *        Bison considers the possibility of reducing the 'NOT ENO' as an NOT_operator with
       
  6970  *        the 'ENO' operand
       
  6971  *        (NOT_operator -> il_simple_operator -> il_simple_operation -> il_simple_instruction ->
       
  6972  *          -> simple_instr_list -> il_param_assignment)
       
  6973  *        instead of reducing it to an il_param_out_operator.
       
  6974  *        ( il_param_out_operator -> il_param_out_assignment)
       
  6975  *
       
  6976  *        Note that the shift/reduce conflict only manifests itself in the il_formal_funct_call,
       
  6977  *        where both the il_param_out_assignment and il_param_assignment are used!
       
  6978  * 
       
  6979  *          il_param_out_assignment --+--> il_param_instruction -> il_param_instruction_list --+
       
  6980  *                                    |                                                        |
       
  6981  *          il_param_assignment     --+                                                        |
       
  6982  *                                                                                             |
       
  6983  *                                                     il_formal_funct_call <- il_param_list <-+
       
  6984  *
       
  6985  */
       
  6986 /*
       
  6987 | NOT eno_identifier SENDTO
       
  6988 	{$$ = new il_assign_out_operator_c(new not_paramassign_c(locloc(@1)), $2, locloc(@$));}
       
  6989 */
       
  6990 /* ERROR_CHECK_BEGIN */
       
  6991 | error SENDTO
       
  6992   {$$ = NULL; print_err_msg(locf(@1), locl(@1), "invalid parameter defined in parameter out assignment."); yyerrok;}
       
  6993 | NOT SENDTO
       
  6994   {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no parameter defined in parameter out assignment."); yynerrs++;}
       
  6995 | NOT error SENDTO
       
  6996   {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid parameter defined in parameter out assignment."); yyerrok;}
       
  6997 /* ERROR_CHECK_END */
       
  6998 ;
       
  6999 
       
  7000 
       
  7001 il_call_operator:
       
  7002   CAL_operator
       
  7003 | CALC_operator
       
  7004 | CALCN_operator
       
  7005 ;
       
  7006 
       
  7007 
       
  7008 il_return_operator:
       
  7009   RET_operator
       
  7010 | RETC_operator
       
  7011 | RETCN_operator
       
  7012 ;
       
  7013 
       
  7014 
       
  7015 il_jump_operator:
       
  7016   JMP_operator
       
  7017 | JMPC_operator
       
  7018 | JMPCN_operator
       
  7019 ;
       
  7020 
       
  7021 
       
  7022 /***********************/
       
  7023 /* B 3.1 - Expressions */
       
  7024 /***********************/
       
  7025 expression:
       
  7026   xor_expression
       
  7027 | expression OR xor_expression
       
  7028 	{$$ = new or_expression_c($1, $3, locloc(@$));}
       
  7029 /* ERROR_CHECK_BEGIN */
       
  7030 | expression OR error
       
  7031   {$$ = NULL;
       
  7032 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined after 'OR' in ST expression.");}
       
  7033 	 else {print_err_msg(locf(@3), locl(@3), "invalid expression after 'OR' in ST expression."); yyclearin;}
       
  7034 	 yyerrok;
       
  7035 	}
       
  7036 /* ERROR_CHECK_END */
       
  7037 ;
       
  7038 
       
  7039 xor_expression:
       
  7040   and_expression
       
  7041 | xor_expression XOR and_expression
       
  7042 	{$$ = new xor_expression_c($1, $3, locloc(@$));}
       
  7043 /* ERROR_CHECK_BEGIN */
       
  7044 | xor_expression XOR error
       
  7045   {$$ = NULL;
       
  7046 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined after 'XOR' in ST expression.");}
       
  7047 	 else {print_err_msg(locf(@3), locl(@3), "invalid expression after 'XOR' in ST expression."); yyclearin;}
       
  7048 	 yyerrok;
       
  7049 	}
       
  7050 /* ERROR_CHECK_END */
       
  7051 ;
       
  7052 
       
  7053 and_expression:
       
  7054   comparison
       
  7055 | and_expression '&' comparison
       
  7056 	{$$ = new and_expression_c($1, $3, locloc(@$));}
       
  7057 | and_expression AND comparison
       
  7058 	{$$ = new and_expression_c($1, $3, locloc(@$));}
       
  7059 /* NOTE: The lexical parser never returns the token '&'.
       
  7060  *       The '&' string is interpreted by the lexcial parser as the token
       
  7061  *       AND2!
       
  7062  *       This means that the first rule with '&' is actually not required,
       
  7063  *       but we leave it in nevertheless just in case we later decide
       
  7064  *       to remove the AND2 token...
       
  7065  */
       
  7066 | and_expression AND2 comparison
       
  7067 	{$$ = new and_expression_c($1, $3, locloc(@$));}
       
  7068 /* ERROR_CHECK_BEGIN */
       
  7069 | and_expression '&' error
       
  7070   {$$ = NULL;
       
  7071 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined after '&' in ST expression.");}
       
  7072 	 else {print_err_msg(locf(@3), locl(@3), "invalid expression after '&' in ST expression."); yyclearin;}
       
  7073 	 yyerrok;
       
  7074 	}
       
  7075 | and_expression AND error
       
  7076   {$$ = NULL;
       
  7077 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined after 'AND' in ST expression.");}
       
  7078 	 else {print_err_msg(locf(@3), locl(@3), "invalid expression after 'AND' in ST expression."); yyclearin;}
       
  7079 	 yyerrok;
       
  7080 	}
       
  7081 | and_expression AND2 error
       
  7082   {$$ = NULL;
       
  7083 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined after '&' in ST expression.");}
       
  7084 	 else {print_err_msg(locf(@3), locl(@3), "invalid expression after '&' in ST expression."); yyclearin;}
       
  7085 	 yyerrok;
       
  7086 	}
       
  7087 /* ERROR_CHECK_END */
       
  7088 ;
       
  7089 
       
  7090 comparison:
       
  7091   equ_expression
       
  7092 | comparison '=' equ_expression
       
  7093 	{$$ = new equ_expression_c($1, $3, locloc(@$));}
       
  7094 | comparison OPER_NE equ_expression
       
  7095 	{$$ = new notequ_expression_c($1, $3, locloc(@$));}
       
  7096 /* ERROR_CHECK_BEGIN */
       
  7097 | comparison '=' error
       
  7098   {$$ = NULL;
       
  7099 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined after '=' in ST expression.");}
       
  7100 	 else {print_err_msg(locf(@3), locl(@3), "invalid expression after '=' in ST expression."); yyclearin;}
       
  7101 	 yyerrok;
       
  7102 	}
       
  7103 | comparison OPER_NE error
       
  7104   {$$ = NULL;
       
  7105 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined after '<>' in ST expression.");}
       
  7106 	 else {print_err_msg(locf(@3), locl(@3), "invalid expression after '<>' in ST expression."); yyclearin;}
       
  7107 	 yyerrok;
       
  7108 	}
       
  7109 /* ERROR_CHECK_END */
       
  7110 ;
       
  7111 
       
  7112 equ_expression:
       
  7113   add_expression
       
  7114 | equ_expression '<' add_expression
       
  7115 	{$$ = new lt_expression_c($1, $3, locloc(@$));}
       
  7116 | equ_expression '>' add_expression
       
  7117 	{$$ = new gt_expression_c($1, $3, locloc(@$));}
       
  7118 | equ_expression OPER_LE add_expression
       
  7119 	{$$ = new le_expression_c($1, $3, locloc(@$));}
       
  7120 | equ_expression OPER_GE add_expression
       
  7121 	{$$ = new ge_expression_c($1, $3, locloc(@$));}
       
  7122 /* ERROR_CHECK_BEGIN */
       
  7123 | equ_expression '<' error
       
  7124   {$$ = NULL;
       
  7125 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined after '<' in ST expression.");}
       
  7126 	 else {print_err_msg(locf(@3), locl(@3), "invalid expression after '<' in ST expression."); yyclearin;}
       
  7127 	 yyerrok;
       
  7128 	}
       
  7129 | equ_expression '>' error
       
  7130   {$$ = NULL;
       
  7131 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined after '>' in ST expression.");}
       
  7132 	 else {print_err_msg(locf(@3), locl(@3), "invalid expression after '>' in ST expression."); yyclearin;}
       
  7133 	 yyerrok;
       
  7134 	}
       
  7135 | equ_expression OPER_LE error
       
  7136   {$$ = NULL;
       
  7137 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined after '<=' in ST expression.");}
       
  7138 	 else {print_err_msg(locf(@3), locl(@3), "invalid expression after '<=' in ST expression."); yyclearin;}
       
  7139 	 yyerrok;
       
  7140 	}
       
  7141 | equ_expression OPER_GE error
       
  7142   {$$ = NULL;
       
  7143 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined after '>=' in ST expression.");}
       
  7144 	 else {print_err_msg(locf(@3), locl(@3), "invalid expression after '>=' in ST expression."); yyclearin;}
       
  7145 	 yyerrok;
       
  7146 	}
       
  7147 /* ERROR_CHECK_END */
       
  7148 ;
       
  7149 
       
  7150 /* Not required...
       
  7151 comparison_operator: '<' | '>' | '>=' '<='
       
  7152 */
       
  7153 
       
  7154 add_expression:
       
  7155   term
       
  7156 | add_expression '+' term
       
  7157 	{$$ = new add_expression_c($1, $3, locloc(@$));}
       
  7158 | add_expression '-' term
       
  7159 	{$$ = new sub_expression_c($1, $3, locloc(@$));}
       
  7160 /* ERROR_CHECK_BEGIN */
       
  7161 | add_expression '+' error
       
  7162   {$$ = NULL;
       
  7163 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined after '+' in ST expression.");}
       
  7164 	 else {print_err_msg(locf(@3), locl(@3), "invalid expression after '+' in ST expression."); yyclearin;}
       
  7165 	 yyerrok;
       
  7166 	}
       
  7167 | add_expression '-' error
       
  7168   {$$ = NULL;
       
  7169 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined after '-' in ST expression.");}
       
  7170 	 else {print_err_msg(locf(@3), locl(@3), "invalid expression after '-' in ST expression."); yyclearin;}
       
  7171 	 yyerrok;
       
  7172 	}
       
  7173 /* ERROR_CHECK_END */
       
  7174 ;
       
  7175 
       
  7176 /* Not required...
       
  7177 add_operator: '+' | '-'
       
  7178 */
       
  7179 
       
  7180 term:
       
  7181   power_expression
       
  7182 | term '*' power_expression
       
  7183 	{$$ = new mul_expression_c($1, $3, locloc(@$));}
       
  7184 | term '/' power_expression
       
  7185 	{$$ = new div_expression_c($1, $3, locloc(@$));}
       
  7186 | term MOD power_expression
       
  7187 	{$$ = new mod_expression_c($1, $3, locloc(@$));}
       
  7188 /* ERROR_CHECK_BEGIN */
       
  7189 | term '*' error
       
  7190   {$$ = NULL;
       
  7191 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined after '*' in ST expression.");}
       
  7192 	 else {print_err_msg(locf(@3), locl(@3), "invalid expression after '*' in ST expression."); yyclearin;}
       
  7193 	 yyerrok;
       
  7194 	}
       
  7195 | term '/' error
       
  7196   {$$ = NULL;
       
  7197 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined after '/' in ST expression.");}
       
  7198 	 else {print_err_msg(locf(@3), locl(@3), "invalid expression after '/' in ST expression."); yyclearin;}
       
  7199 	 yyerrok;
       
  7200 	}
       
  7201 | term MOD error
       
  7202   {$$ = NULL;
       
  7203 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined after 'MOD' in ST expression.");}
       
  7204 	 else {print_err_msg(locf(@3), locl(@3), "invalid expression after 'MOD' in ST expression."); yyclearin;}
       
  7205 	 yyerrok;
       
  7206 	}
       
  7207 /* ERROR_CHECK_END */
       
  7208 ;
       
  7209 
       
  7210 /* Not required...
       
  7211 multiply_operator: '*' | '/' | 'MOD'
       
  7212 */
       
  7213 
       
  7214 power_expression:
       
  7215   unary_expression
       
  7216 | power_expression OPER_EXP unary_expression
       
  7217 	{$$ = new power_expression_c($1, $3, locloc(@$));}
       
  7218 /* ERROR_CHECK_BEGIN */
       
  7219 | power_expression OPER_EXP error
       
  7220   {$$ = NULL;
       
  7221 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined after '**' in ST expression.");}
       
  7222 	 else {print_err_msg(locf(@3), locl(@3), "invalid expression after '**' in ST expression."); yyclearin;}
       
  7223 	 yyerrok;
       
  7224 	}
       
  7225 /* ERROR_CHECK_END */
       
  7226 ;
       
  7227 
       
  7228 
       
  7229 unary_expression:
       
  7230   non_negative_primary_expression
       
  7231 | '-' non_negative_primary_expression
       
  7232 	{$$ = new neg_expression_c($2, locloc(@$));}
       
  7233 | NOT primary_expression
       
  7234 	{$$ = new not_expression_c($2, locloc(@$));}
       
  7235 /* ERROR_CHECK_BEGIN */
       
  7236 | '-' error
       
  7237   {$$ = NULL;
       
  7238 	 if (is_current_syntax_token()) {print_err_msg(locl(@1), locf(@2), "no expression defined after '-' in ST expression.");}
       
  7239 	 else {print_err_msg(locf(@2), locl(@2), "invalid expression after '-' in ST expression."); yyclearin;}
       
  7240 	 yyerrok;
       
  7241 	}
       
  7242 | NOT error
       
  7243   {$$ = NULL;
       
  7244 	 if (is_current_syntax_token()) {print_err_msg(locl(@1), locf(@2), "no expression defined after 'NOT' in ST expression.");}
       
  7245 	 else {print_err_msg(locf(@2), locl(@2), "invalid expression after 'NOT' in ST expression."); yyclearin;}
       
  7246 	 yyerrok;
       
  7247 	}
       
  7248 /* ERROR_CHECK_END */
       
  7249 ;
       
  7250 
       
  7251 /* Not required...
       
  7252 unary_operator: '-' | 'NOT'
       
  7253 */
       
  7254 
       
  7255 
       
  7256 /* NOTE: using constant as a possible symbol for primary_expression
       
  7257  *       leads to a reduce/reduce conflict.
       
  7258  *
       
  7259  *       The text '-9' may be parsed as either a
       
  7260  *       expression<-primary_expression<-constant<-signed_integer
       
  7261  *       (i.e. the constant 9 negative)
       
  7262  *       OR
       
  7263  *       expression<-unary_expression<-constant<-integer
       
  7264  *       (i.e. the constant 9, preceded by a unary negation)
       
  7265  *
       
  7266  *       To remove the conflict, we only allow constants without
       
  7267  *       a preceding '-' to be used in primary_expression
       
  7268  *       (i.e. as a parameter to the unary negation operator)
       
  7269  */
       
  7270 /* NOTE: We use enumerated_value_without_identifier instead of enumerated_value
       
  7271  *       in order to remove a reduce/reduce conflict between reducing an
       
  7272  *       identifier to a variable or an enumerated_value.
       
  7273  *
       
  7274  *       This change follows the IEC specification. The specification seems to
       
  7275  *       imply (by introducing syntax that allows to unambiguosly reference an
       
  7276  *       enumerated value - enum_type#enum_value) that in case the same identifier is used
       
  7277  *       for a variable and an enumerated value, then the variable shall be
       
  7278  *       considered.
       
  7279  */
       
  7280 non_negative_primary_expression:
       
  7281   non_negative_constant
       
  7282 //| enumerated_value_without_identifier
       
  7283 | enumerated_value
       
  7284 | variable
       
  7285 | '(' expression ')'
       
  7286 	{$$ = $2;}
       
  7287 |  function_invocation
       
  7288 /* ERROR_CHECK_BEGIN */
       
  7289 | '(' expression error
       
  7290   {$$ = NULL; print_err_msg(locl(@2), locf(@3), "')' missing at the end of expression in ST expression."); yyerrok;}
       
  7291 /* ERROR_CHECK_END */
       
  7292 ;
       
  7293 
       
  7294 
       
  7295 primary_expression:
       
  7296   constant
       
  7297 //| enumerated_value_without_identifier
       
  7298 | enumerated_value
       
  7299 | variable
       
  7300 | '(' expression ')'
       
  7301 	{$$ = $2;}
       
  7302 |  function_invocation
       
  7303 /* ERROR_CHECK_BEGIN */
       
  7304 | '(' expression error
       
  7305   {$$ = NULL; print_err_msg(locl(@2), locf(@3), "')' missing at the end of expression in ST expression."); yyerrok;}
       
  7306 /* ERROR_CHECK_END */
       
  7307 ;
       
  7308 
       
  7309 
       
  7310 
       
  7311 /* intermediate helper symbol for primary_expression */
       
  7312 /* NOTE: function_name includes the standard function name 'NOT' !
       
  7313  *       This introduces a reduce/reduce conflict, as NOT(var)
       
  7314  *       may be parsed as either a function_invocation, or a
       
  7315  *       unary_expression.
       
  7316  *
       
  7317  *       I (Mario) have opted to remove the possible reduction
       
  7318  *       to function invocation, which means replacing the rule
       
  7319  *           function_name '(' param_assignment_list ')'
       
  7320  *       with
       
  7321  *           function_name_no_NOT_clashes '(' param_assignment_list ')'
       
  7322  *
       
  7323  *       Notice how the new rule does not include the situation where
       
  7324  *       the function NOT is called with more than one parameter, which
       
  7325  *       the original rule does include! Callinf the NOT function with more
       
  7326  *       than one argument is probably a semantic error anyway, so it
       
  7327  *       doesn't make much sense to take it into account.
       
  7328  *
       
  7329  *       Nevertheless, if we were to to it entirely correctly,
       
  7330  *       leaving the semantic checks for the next compiler stage,
       
  7331  *       this syntax parser would need to include such a possibility.
       
  7332  *
       
  7333  *       We will leave this out for now. No need to complicate the syntax
       
  7334  *       more than the specification does by contradicting itself, and
       
  7335  *       letting names clash!
       
  7336  */
       
  7337 function_invocation:
       
  7338 /*  function_name '(' [param_assignment_list] ')' */
       
  7339   function_name_no_NOT_clashes '(' param_assignment_formal_list ')'
       
  7340 	{$$ = new function_invocation_c($1, $3, NULL, locloc(@$));}
       
  7341 | function_name_no_NOT_clashes '(' param_assignment_nonformal_list ')'
       
  7342 	{$$ = new function_invocation_c($1, NULL, $3, locloc(@$));}
       
  7343 /* ERROR_CHECK_BEGIN */ 
       
  7344 | function_name_no_NOT_clashes param_assignment_formal_list ')'
       
  7345   {$$ = NULL; print_err_msg(locl(@1), locf(@2), "'(' missing after function name in ST expression."); yynerrs++;}
       
  7346 | function_name_no_NOT_clashes '(' ')'
       
  7347   {$$ = NULL; print_err_msg(locl(@2), locf(@3), "no parameter defined in function invocation of ST expression."); yynerrs++;}
       
  7348 | function_name_no_NOT_clashes '(' error ')'
       
  7349   {$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid parameter(s) defined in function invocation of ST expression."); yyerrok;}
       
  7350 | function_name_no_NOT_clashes '(' param_assignment_formal_list error
       
  7351   {$$ = NULL; print_err_msg(locl(@3), locf(@4), "')' missing at the end of function invocation in ST expression."); yyerrok;}
       
  7352 | function_name_no_NOT_clashes '(' param_assignment_nonformal_list error
       
  7353   {$$ = NULL; print_err_msg(locl(@3), locf(@4), "')' missing at the end of function invocation in ST expression."); yyerrok;}
       
  7354 /* ERROR_CHECK_END */
       
  7355 ;
       
  7356 
       
  7357 
       
  7358 /********************/
       
  7359 /* B 3.2 Statements */
       
  7360 /********************/
       
  7361 statement_list:
       
  7362   statement ';'
       
  7363 	{$$ = new statement_list_c(locloc(@$)); $$->add_element($1);}
       
  7364 | any_pragma
       
  7365 	{$$ = new statement_list_c(locloc(@$)); $$->add_element($1);}
       
  7366 | statement_list statement ';'
       
  7367 	{$$ = $1; $$->add_element($2);}
       
  7368 | statement_list any_pragma
       
  7369 	{$$ = $1; $$->add_element($2);}
       
  7370 /* ERROR_CHECK_BEGIN */
       
  7371 | statement error
       
  7372 	{$$ = new statement_list_c(locloc(@$)); print_err_msg(locl(@1), locf(@2), "';' missing at the end of statement in ST statement."); yyerrok;}
       
  7373 | statement_list statement error
       
  7374 	{$$ = $1; print_err_msg(locl(@2), locf(@3), "';' missing at the end of statement in ST statement."); yyerrok;}
       
  7375 | statement_list error ';'
       
  7376 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "invalid statement in ST statement."); yyerrok;}
       
  7377 | statement_list ';'
       
  7378 	{$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected ';' after statement in ST statement."); yynerrs++;}
       
  7379 /* ERROR_CHECK_END */
       
  7380 ;
       
  7381 
       
  7382 
       
  7383 statement:
       
  7384   assignment_statement
       
  7385 | subprogram_control_statement
       
  7386 | selection_statement
       
  7387 | iteration_statement
       
  7388 ;
       
  7389 
       
  7390 
       
  7391 /*********************************/
       
  7392 /* B 3.2.1 Assignment Statements */
       
  7393 /*********************************/
       
  7394 assignment_statement:
       
  7395   variable ASSIGN expression
       
  7396 	{$$ = new assignment_statement_c($1, $3, locloc(@$));}
       
  7397 /* ERROR_CHECK_BEGIN */
       
  7398 | error ASSIGN expression
       
  7399   {$$ = NULL; print_err_msg(locf(@1), locl(@1), "invalid variable before ':=' in ST assignment statement."); yyerrok;}
       
  7400 | variable ASSIGN error
       
  7401 	{$$ = NULL;
       
  7402 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined after ':=' in ST assignment statement.");}
       
  7403 	 else {print_err_msg(locf(@3), locl(@3), "invalid expression after ':=' in ST assignment statement."); yyclearin;}
       
  7404 	 yyerrok;
       
  7405 	}
       
  7406 /* ERROR_CHECK_END */
       
  7407 ;
       
  7408 
       
  7409 
       
  7410 
       
  7411 
       
  7412 /*****************************************/
       
  7413 /* B 3.2.2 Subprogram Control Statements */
       
  7414 /*****************************************/
       
  7415 subprogram_control_statement:
       
  7416   fb_invocation
       
  7417 | return_statement
       
  7418 ;
       
  7419 
       
  7420 return_statement:
       
  7421   RETURN	{$$ = new return_statement_c(locloc(@$));}
       
  7422 ;
       
  7423 
       
  7424 
       
  7425 
       
  7426 fb_invocation:
       
  7427   prev_declared_fb_name '(' ')'
       
  7428 	{$$ = new fb_invocation_c($1, NULL, NULL, locloc(@$));	}
       
  7429 | prev_declared_fb_name '(' param_assignment_formal_list ')'
       
  7430 	{$$ = new fb_invocation_c($1, $3, NULL, locloc(@$));}
       
  7431 | prev_declared_fb_name '(' param_assignment_nonformal_list ')'
       
  7432 	{$$ = new fb_invocation_c($1, NULL, $3, locloc(@$));}
       
  7433 /* ERROR_CHECK_BEGIN */
       
  7434 | prev_declared_fb_name ')'
       
  7435 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "'(' missing after function block name in ST statement."); yynerrs++;}
       
  7436 | prev_declared_fb_name param_assignment_formal_list ')'
       
  7437 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "'(' missing after function block name in ST statement."); yynerrs++;}
       
  7438 | prev_declared_fb_name '(' error ')'
       
  7439 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid parameter list in function block invocation in ST statement."); yyerrok;}
       
  7440 | prev_declared_fb_name '(' error
       
  7441 	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "')' missing after parameter list of function block invocation in ST statement."); yyerrok;}
       
  7442 | prev_declared_fb_name '(' param_assignment_formal_list error
       
  7443 	{$$ = NULL; print_err_msg(locl(@3), locf(@4), "')' missing after parameter list of function block invocation in ST statement."); yyerrok;}
       
  7444 | prev_declared_fb_name '(' param_assignment_nonformal_list error
       
  7445 	{$$ = NULL; print_err_msg(locl(@3), locf(@4), "')' missing after parameter list of function block invocation in ST statement."); yyerrok;}
       
  7446 /* ERROR_CHECK_END */
       
  7447 ;
       
  7448 
       
  7449 
       
  7450 /* helper symbol for
       
  7451  * - fb_invocation
       
  7452  * - function_invocation
       
  7453  */
       
  7454 param_assignment_formal_list:
       
  7455   param_assignment_formal
       
  7456 	{$$ = new param_assignment_list_c(locloc(@$)); $$->add_element($1);}
       
  7457 | param_assignment_formal_list ',' param_assignment_formal
       
  7458 	{$$ = $1; $$->add_element($3);}
       
  7459 /* ERROR_CHECK_BEGIN */
       
  7460 | param_assignment_formal_list ',' error
       
  7461   {$$ = $1;
       
  7462 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no parameter assignment defined in ST parameter assignment list.");}
       
  7463 	 else {print_err_msg(locf(@3), locl(@3), "invalid parameter assignment in ST parameter assignment list."); yyclearin;}
       
  7464 	 yyerrok;
       
  7465 	}
       
  7466 /* ERROR_CHECK_END */
       
  7467 ;
       
  7468 
       
  7469 /* helper symbol for
       
  7470  * - fb_invocation
       
  7471  * - function_invocation
       
  7472  */
       
  7473 param_assignment_nonformal_list:
       
  7474   param_assignment_nonformal
       
  7475 	{$$ = new param_assignment_list_c(locloc(@$)); $$->add_element($1);}
       
  7476 | param_assignment_nonformal_list ',' param_assignment_nonformal
       
  7477 	{$$ = $1; $$->add_element($3);}
       
  7478 /* ERROR_CHECK_BEGIN */
       
  7479 | param_assignment_nonformal_list ',' error
       
  7480   {$$ = $1;
       
  7481 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no parameter assignment defined in ST parameter assignment list.");}
       
  7482 	 else {print_err_msg(locf(@3), locl(@3), "invalid parameter assignment in ST parameter assignment list."); yyclearin;}
       
  7483 	 yyerrok;
       
  7484 	}
       
  7485 /* ERROR_CHECK_END */
       
  7486 ;
       
  7487 
       
  7488 
       
  7489 /* NOTE: According to the IEC 61131-3 standard, there are two possible
       
  7490  *       syntaxes for calling function blocks within ST.
       
  7491  *       The formal method has the form:
       
  7492  *        fb ( invar := x, inoutvar := var1, outvar => var2);
       
  7493  *       The non-formal method has the form:
       
  7494  *        fb (x, var1, var2);
       
  7495  *       In the text of IEC 61131-3 (where the semantics are defined),
       
  7496  *       it is obvious that mixing the two syntaxes is considered incorrect.
       
  7497  *       The following should therefore be incorrect: 
       
  7498  *        fb ( invar := x, var1, var2);
       
  7499  *       However, according to the syntax definition, as defined in IEC 61131-3,
       
  7500  *       mixing the formal and non-formal methods of invocation is allowed.
       
  7501  *       We have two alternatives:
       
  7502  *        (a) implement the syntax here in iec.y according to the standard,
       
  7503  *            and leave it to the semantic analyser stage to find this error
       
  7504  *        (b) or implement the syntax in iec.y correctly, not allowing 
       
  7505  *            the mixing of formal and non-formal invocation syntaxes.
       
  7506  *       Considering that this is a syntax issue, and not semantic issue,
       
  7507  *       I (Mario) have decided to go with alternative (a).
       
  7508  *       In other words, in iec.y we do not follow the syntax as defined in
       
  7509  *       Annex B of the IEC 61131-3 standard, but rather implement
       
  7510  *       the syntax also taking into account the textual part of the standard too.
       
  7511  */
       
  7512 /*
       
  7513 param_assignment:
       
  7514   variable_name ASSIGN expression 
       
  7515 */
       
  7516 param_assignment_nonformal:
       
  7517   expression
       
  7518 ;
       
  7519 
       
  7520 
       
  7521 param_assignment_formal:
       
  7522   any_identifier ASSIGN expression
       
  7523 	{$$ = new input_variable_param_assignment_c($1, $3, locloc(@$));}
       
  7524 | en_identifier ASSIGN expression
       
  7525 	{$$ = new input_variable_param_assignment_c($1, $3, locloc(@$));}
       
  7526 /*| variable_name SENDTO variable */
       
  7527 /*| any_identifier SENDTO variable */
       
  7528 | sendto_identifier SENDTO variable
       
  7529 	{$$ = new output_variable_param_assignment_c(NULL, $1, $3, locloc(@$));}
       
  7530 /* The following is not required, as the sendto_identifier_token returned by flex will 
       
  7531  * also include the 'ENO' identifier.
       
  7532  * The resulting abstract syntax tree is identical with or without this following rule,
       
  7533  * as both the eno_identifier and the sendto_identifier are stored as
       
  7534  * an identifier_c !!
       
  7535  *
       
  7536  * To understand why we must even explicitly consider the use of ENO here,  
       
  7537  * please read the comment above the definition of 'variable' in section B1.4 for details.
       
  7538  */
       
  7539 /*
       
  7540 | eno_identifier SENDTO variable
       
  7541 	{$$ = new output_variable_param_assignment_c(NULL, $1, $3, locloc(@$));}
       
  7542 */
       
  7543 /*| NOT variable_name SENDTO variable */
       
  7544 /*| NOT any_identifier SENDTO variable*/
       
  7545 | NOT sendto_identifier SENDTO variable
       
  7546 	{$$ = new output_variable_param_assignment_c(new not_paramassign_c(locloc(@$)), $2, $4, locloc(@$));}
       
  7547 /* The following is not required, as the sendto_identifier_token returned by flex will 
       
  7548  * also include the 'ENO' identifier.
       
  7549  * The resulting abstract syntax tree is identical with or without this following rule,
       
  7550  * as both the eno_identifier and the sendto_identifier are stored as
       
  7551  * an identifier_c !!
       
  7552  *
       
  7553  * To understand why we must even explicitly consider the use of ENO here,  
       
  7554  * please read the comment above the definition of 'variable' in section B1.4 for details.
       
  7555  */
       
  7556 /*
       
  7557 | NOT eno_identifier SENDTO variable
       
  7558 	{$$ = new output_variable_param_assignment_c(new not_paramassign_c(locloc(@$)), $2, $4, locloc(@$));}
       
  7559 */
       
  7560 /* ERROR_CHECK_BEGIN */
       
  7561 | any_identifier ASSIGN error
       
  7562   {$$ = NULL;
       
  7563 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined in ST formal parameter assignment.");}
       
  7564 	 else {print_err_msg(locf(@3), locl(@3), "invalid expression in ST formal parameter assignment."); yyclearin;}
       
  7565 	 yyerrok;
       
  7566 	}
       
  7567 | en_identifier ASSIGN error
       
  7568   {$$ = NULL;
       
  7569 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined in ST formal parameter assignment.");}
       
  7570 	 else {print_err_msg(locf(@3), locl(@3), "invalid expression in ST formal parameter assignment."); yyclearin;}
       
  7571 	 yyerrok;
       
  7572 	}
       
  7573 | sendto_identifier SENDTO error
       
  7574   {$$ = NULL;
       
  7575 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined in ST formal parameter out assignment.");}
       
  7576 	 else {print_err_msg(locf(@3), locl(@3), "invalid expression in ST formal parameter out assignment."); yyclearin;}
       
  7577 	 yyerrok;
       
  7578 	}
       
  7579 /*
       
  7580 | eno_identifier SENDTO error
       
  7581   {$$ = NULL;
       
  7582 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined in ST formal parameter out assignment.");}
       
  7583 	 else {print_err_msg(locf(@3), locl(@3), "invalid expression in ST formal parameter out assignment."); yyclearin;}
       
  7584 	 yyerrok;
       
  7585 	}
       
  7586 */
       
  7587 | NOT SENDTO variable
       
  7588   {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no parameter name defined in ST formal parameter out negated assignment."); yynerrs++;}
       
  7589 | NOT error SENDTO variable
       
  7590   {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid parameter name defined in ST formal parameter out negated assignment."); yyerrok;}
       
  7591 | NOT sendto_identifier SENDTO error
       
  7592   {$$ = NULL;
       
  7593 	 if (is_current_syntax_token()) {print_err_msg(locl(@3), locf(@4), "no expression defined in ST formal parameter out negated assignment.");}
       
  7594 	 else {print_err_msg(locf(@4), locl(@4), "invalid expression in ST formal parameter out negated assignment."); yyclearin;}
       
  7595 	 yyerrok;
       
  7596 	}
       
  7597 /*
       
  7598 | NOT eno_identifier SENDTO error
       
  7599   {$$ = NULL;
       
  7600 	 if (is_current_syntax_token()) {print_err_msg(locl(@3), locf(@4), "no expression defined in ST formal parameter out negated assignment.");}
       
  7601 	 else {print_err_msg(locf(@4), locl(@4), "invalid expression in ST formal parameter out negated assignment."); yyclearin;}
       
  7602 	 yyerrok;
       
  7603 	}
       
  7604 */
       
  7605 /* ERROR_CHECK_END */
       
  7606 ;
       
  7607 
       
  7608 
       
  7609 
       
  7610 
       
  7611 
       
  7612 /********************************/
       
  7613 /* B 3.2.3 Selection Statements */
       
  7614 /********************************/
       
  7615 selection_statement:
       
  7616   if_statement
       
  7617 | case_statement
       
  7618 ;
       
  7619 
       
  7620 
       
  7621 if_statement:
       
  7622   IF expression THEN statement_list elseif_statement_list END_IF
       
  7623 	{$$ = new if_statement_c($2, $4, $5, NULL, locloc(@$));}
       
  7624 | IF expression THEN statement_list elseif_statement_list ELSE statement_list END_IF
       
  7625 	{$$ = new if_statement_c($2, $4, $5, $7, locloc(@$));}
       
  7626 /* ERROR_CHECK_BEGIN */
       
  7627 | IF THEN statement_list elseif_statement_list END_IF
       
  7628   {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no test expression defined in ST 'IF' statement."); yynerrs++;}
       
  7629 | IF THEN statement_list elseif_statement_list ELSE statement_list END_IF
       
  7630   {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no test expression defined in ST 'IF' statement."); yynerrs++;}
       
  7631 | IF error THEN statement_list elseif_statement_list END_IF
       
  7632   {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid test expression defined for ST 'IF' statement."); yyerrok;}
       
  7633 | IF error THEN statement_list elseif_statement_list ELSE statement_list END_IF
       
  7634   {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid test expression defined for ST 'IF' statement."); yyerrok;}
       
  7635 | IF expression error statement_list elseif_statement_list END_IF
       
  7636   {$$ = NULL; print_err_msg(locf(@3), locl(@3), "expecting 'THEN' after test expression in ST 'IF' statement."); yyerrok;}
       
  7637 | IF expression error statement_list elseif_statement_list ELSE statement_list END_IF
       
  7638   {$$ = NULL; print_err_msg(locf(@3), locl(@3), "expecting 'THEN' after test expression in ST 'IF' statement."); yyerrok;}
       
  7639 | IF expression THEN elseif_statement_list END_IF
       
  7640   {$$ = NULL; print_err_msg(locl(@3), locf(@4), "no statement defined after 'THEN' in ST 'IF' statement."); yynerrs++;}
       
  7641 | IF expression THEN elseif_statement_list ELSE statement_list END_IF
       
  7642   {$$ = NULL; print_err_msg(locl(@3), locf(@4), "no statement defined after 'THEN' in ST 'IF' statement."); yynerrs++;}
       
  7643 | IF expression THEN statement_list elseif_statement_list ELSE END_IF
       
  7644   {$$ = NULL; print_err_msg(locl(@6), locf(@7), "no statement defined after 'ELSE' in ST 'IF' statement."); yynerrs++;}
       
  7645 | IF expression THEN statement_list elseif_statement_list ELSE error END_IF
       
  7646   {$$ = NULL; print_err_msg(locf(@7), locl(@7), "invalid statement defined after 'ELSE' in ST 'IF' statement."); yynerrs++; yyerrok;}
       
  7647 | IF expression error END_OF_INPUT
       
  7648   {$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed 'IF' statement in ST."); yyerrok;}
       
  7649 | IF expression THEN statement_list elseif_statement_list END_OF_INPUT
       
  7650   {$$ = NULL; print_err_msg(locf(@1), locl(@3), "unclosed 'IF' statement in ST."); yynerrs++;}
       
  7651 | IF expression THEN statement_list elseif_statement_list ELSE statement_list END_OF_INPUT
       
  7652   {$$ = NULL; print_err_msg(locf(@1), locl(@3), "unclosed 'IF' statement in ST."); yynerrs++;}
       
  7653 | IF error END_IF
       
  7654   {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in ST 'IF' statement."); yyerrok;}
       
  7655 /* ERROR_CHECK_END */
       
  7656 ;
       
  7657 
       
  7658 /* helper symbol for if_statement */
       
  7659 elseif_statement_list:
       
  7660   /* empty */
       
  7661 	{$$ = new elseif_statement_list_c(locloc(@$));}
       
  7662 | elseif_statement_list elseif_statement
       
  7663 	{$$ = $1; $$->add_element($2);}
       
  7664 ;
       
  7665 
       
  7666 /* helper symbol for elseif_statement_list */
       
  7667 elseif_statement:
       
  7668   ELSIF expression THEN statement_list
       
  7669 	{$$ = new elseif_statement_c($2, $4, locloc(@$));}
       
  7670 /* ERROR_CHECK_BEGIN */
       
  7671 | ELSIF THEN statement_list
       
  7672   {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no test expression defined for 'ELSEIF' statement in ST 'IF' statement."); yynerrs++;}
       
  7673 | ELSIF error THEN statement_list
       
  7674   {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid test expression defined for 'ELSEIF' statement in ST 'IF' statement."); yyerrok;}
       
  7675 | ELSIF expression error statement_list
       
  7676   {$$ = NULL; print_err_msg(locf(@3), locl(@3), "expecting 'THEN' after test expression in 'ELSEIF' statement of ST 'IF' statement."); yyerrok;}
       
  7677 | ELSIF expression THEN error
       
  7678   {$$ = NULL; print_err_msg(locf(@4), locl(@4), "invalid statement list in 'ELSEIF' statement of ST 'IF' statement."); yyerrok;}
       
  7679 /* ERROR_CHECK_END */
       
  7680 ;
       
  7681 
       
  7682 
       
  7683 case_statement:
       
  7684   CASE expression OF case_element_list END_CASE
       
  7685 	{$$ = new case_statement_c($2, $4, NULL, locloc(@$));}
       
  7686 | CASE expression OF case_element_list ELSE statement_list END_CASE
       
  7687 	{$$ = new case_statement_c($2, $4, $6, locloc(@$));}
       
  7688 /* ERROR_CHECK_BEGIN */
       
  7689 | CASE OF case_element_list END_CASE
       
  7690   {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no test expression defined in ST 'CASE' statement."); yynerrs++;}
       
  7691 | CASE OF case_element_list ELSE statement_list END_CASE
       
  7692   {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no test expression defined in ST 'CASE' statement."); yynerrs++;}
       
  7693 | CASE error OF case_element_list END_CASE
       
  7694   {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid test expression defined for ST 'CASE' statement."); yyerrok;}
       
  7695 | CASE error OF case_element_list ELSE statement_list END_CASE
       
  7696   {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid test expression defined for ST 'CASE' statement."); yyerrok;}
       
  7697 | CASE expression error case_element_list END_CASE
       
  7698   {$$ = NULL; print_err_msg(locf(@3), locl(@3), "expecting 'OF' after test expression in ST 'CASE' statement."); yyerrok;}
       
  7699 | CASE expression error case_element_list ELSE statement_list END_CASE
       
  7700   {$$ = NULL; print_err_msg(locf(@3), locl(@3), "expecting 'OF' after test expression in ST 'CASE' statement."); yyerrok;}
       
  7701 | CASE expression OF END_CASE
       
  7702   {$$ = NULL; print_err_msg(locl(@3), locf(@4), "no case element(s) defined after 'OF' in ST 'CASE' statement."); yynerrs++;}
       
  7703 | CASE expression OF ELSE statement_list END_CASE
       
  7704   {$$ = NULL; print_err_msg(locl(@3), locf(@4), "no case element(s) defined after 'OF' in ST 'CASE' statement."); yynerrs++;}
       
  7705 | CASE expression OF error END_CASE
       
  7706   {$$ = NULL; print_err_msg(locf(@4), locl(@4), "invalid case element(s) defined after 'OF' in ST 'CASE' statement."); yyerrok;}
       
  7707 | CASE expression OF error ELSE statement_list END_CASE
       
  7708   {$$ = NULL; print_err_msg(locf(@4), locl(@4), "invalid case element(s) defined after 'OF' in ST 'CASE' statement."); yyerrok;}
       
  7709 | CASE expression OF case_element_list ELSE END_CASE
       
  7710   {$$ = NULL; print_err_msg(locl(@5), locf(@6), "no statement defined after 'ELSE' in ST 'CASE' statement."); yynerrs++;}
       
  7711 | CASE expression OF case_element_list ELSE error END_CASE
       
  7712   {$$ = NULL; print_err_msg(locf(@6), locl(@6), "invalid statement defined after 'ELSE' in ST 'CASE' statement."); yyerrok;}
       
  7713 | CASE expression error END_OF_INPUT
       
  7714   {$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed 'CASE' statement in ST."); yyerrok;}
       
  7715 | CASE expression OF case_element_list END_OF_INPUT
       
  7716   {$$ = NULL; print_err_msg(locf(@1), locl(@3), "unclosed 'CASE' statement in ST."); yynerrs++;}
       
  7717 | CASE expression OF case_element_list ELSE statement_list END_OF_INPUT
       
  7718   {$$ = NULL; print_err_msg(locf(@1), locl(@3), "unclosed 'CASE' statement in ST."); yynerrs++;}
       
  7719 | CASE error END_CASE
       
  7720   {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in ST 'CASE' statement."); yyerrok;}
       
  7721 /* ERROR_CHECK_END */
       
  7722 ;
       
  7723 
       
  7724 
       
  7725 /* helper symbol for case_statement */
       
  7726 case_element_list:
       
  7727   case_element
       
  7728 	{$$ = new case_element_list_c(locloc(@$)); $$->add_element($1);}
       
  7729 | case_element_list case_element
       
  7730 	{$$ = $1; $$->add_element($2);}
       
  7731 ;
       
  7732 
       
  7733 
       
  7734 case_element:
       
  7735   case_list ':' statement_list
       
  7736 	{$$ = new case_element_c($1, $3, locloc(@$));}
       
  7737 /* ERROR_CHECK_BEGIN */
       
  7738 | case_list statement_list
       
  7739   {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing after case list in ST 'CASE' statement."); yynerrs++;}
       
  7740 | case_list ':' error
       
  7741   {$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid statement in case element of ST 'CASE' statement."); yyerrok;}
       
  7742 /* ERROR_CHECK_END */
       
  7743 ;
       
  7744 
       
  7745 
       
  7746 case_list:
       
  7747   case_list_element
       
  7748 	{$$ = new case_list_c(locloc(@$)); $$->add_element($1);}
       
  7749 | case_list ',' case_list_element
       
  7750 	{$$ = $1; $$->add_element($3);}
       
  7751 /* ERROR_CHECK_BEGIN */
       
  7752 | case_list ',' error
       
  7753   {$$ = $1;
       
  7754 	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no case defined in case list of ST parameter assignment list.");}
       
  7755 	 else {print_err_msg(locf(@3), locl(@3), "invalid case in case list of ST parameter assignment list."); yyclearin;}
       
  7756 	 yyerrok;
       
  7757 	}
       
  7758 /* ERROR_CHECK_END */
       
  7759 ;
       
  7760 
       
  7761 
       
  7762 case_list_element:
       
  7763   signed_integer
       
  7764 | subrange
       
  7765 | enumerated_value
       
  7766 ;
       
  7767 
       
  7768 
       
  7769 
       
  7770 
       
  7771 
       
  7772 /********************************/
       
  7773 /* B 3.2.4 Iteration Statements */
       
  7774 /********************************/
       
  7775 iteration_statement:
       
  7776   for_statement
       
  7777 | while_statement
       
  7778 | repeat_statement
       
  7779 | exit_statement
       
  7780 ;
       
  7781 
       
  7782 
       
  7783 for_statement:
       
  7784   FOR control_variable ASSIGN expression TO expression BY expression DO statement_list END_FOR
       
  7785 	{$$ = new for_statement_c($2, $4, $6, $8, $10, locloc(@$));}
       
  7786 | FOR control_variable ASSIGN expression TO expression DO statement_list END_FOR
       
  7787 	{$$ = new for_statement_c($2, $4, $6, NULL, $8, locloc(@$));}
       
  7788 /* ERROR_CHECK_BEGIN */
       
  7789 | FOR ASSIGN expression TO expression BY expression DO statement_list END_FOR
       
  7790   {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no control variable defined in ST 'FOR' statement."); yynerrs++;}
       
  7791 | FOR ASSIGN expression TO expression DO statement_list END_FOR
       
  7792   {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no control variable defined in ST 'FOR' statement."); yynerrs++;}
       
  7793 | FOR error ASSIGN expression TO expression BY expression DO statement_list END_FOR
       
  7794   {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid control variable defined for ST 'FOR' statement."); yyerrok;}
       
  7795 | FOR error ASSIGN expression TO expression DO statement_list END_FOR
       
  7796   {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid control variable defined for ST 'FOR' statement."); yyerrok;}
       
  7797 | FOR control_variable expression TO expression BY expression DO statement_list END_FOR
       
  7798   {$$ = NULL; print_err_msg(locl(@2), locf(@3), "':=' missing between control variable and start expression in ST 'FOR' statement."); yynerrs++;}
       
  7799 | FOR control_variable expression TO expression DO statement_list END_FOR
       
  7800   {$$ = NULL; print_err_msg(locl(@2), locf(@3), "':=' missing between control variable and start expression in ST 'FOR' statement."); yynerrs++;}
       
  7801 | FOR control_variable error expression TO expression BY expression DO statement_list END_FOR
       
  7802   {$$ = NULL; print_err_msg(locf(@3), locl(@3), "expecting ':=' between control variable and start expression in ST 'FOR' statement."); yyerrok;}
       
  7803 | FOR control_variable error expression TO expression DO statement_list END_FOR
       
  7804   {$$ = NULL; print_err_msg(locf(@3), locl(@3), "expecting ':=' between control variable and start expression in ST 'FOR' statement."); yyerrok;}
       
  7805 | FOR control_variable ASSIGN TO expression BY expression DO statement_list END_FOR
       
  7806   {$$ = NULL; print_err_msg(locl(@3), locf(@4), "no start expression defined in ST 'FOR' statement."); yynerrs++;}
       
  7807 | FOR control_variable ASSIGN TO expression DO statement_list END_FOR
       
  7808   {$$ = NULL; print_err_msg(locl(@3), locf(@4), "no start expression defined in ST 'FOR' statement."); yynerrs++;}
       
  7809 | FOR control_variable ASSIGN error TO expression BY expression DO statement_list END_FOR
       
  7810   {$$ = NULL; print_err_msg(locf(@4), locl(@4), "invalid start expression defined in ST 'FOR' statement."); yyerrok;}
       
  7811 | FOR control_variable ASSIGN error TO expression DO statement_list END_FOR
       
  7812   {$$ = NULL; print_err_msg(locf(@4), locl(@4), "invalid start expression in ST 'FOR' statement."); yyerrok;}
       
  7813 | FOR control_variable ASSIGN expression error expression BY expression DO statement_list END_FOR
       
  7814   {$$ = NULL; print_err_msg(locf(@5), locl(@5), "expecting 'TO' between start expression and end expression in ST 'FOR' statement."); yyerrok;}
       
  7815 | FOR control_variable ASSIGN expression error expression DO statement_list END_FOR
       
  7816   {$$ = NULL; print_err_msg(locf(@5), locl(@5), "expecting 'TO' between start expression and end expression in ST 'FOR' statement."); yyerrok;}
       
  7817 | FOR control_variable ASSIGN expression TO expression error expression DO statement_list END_FOR
       
  7818   {$$ = NULL; print_err_msg(locf(@7), locl(@7), "expecting 'BY' between end expression and step expression in ST 'FOR' statement."); yyerrok;}
       
  7819 | FOR control_variable ASSIGN expression TO expression BY expression error statement_list END_FOR
       
  7820   {$$ = NULL; print_err_msg(locf(@9), locl(@9), "expecting 'DO' after step expression in ST 'FOR' statement."); yyerrok;}
       
  7821 | FOR control_variable ASSIGN expression TO expression error statement_list END_FOR
       
  7822   {$$ = NULL; print_err_msg(locf(@7), locl(@7), "expecting 'DO' after end expression in ST 'FOR' statement."); yyerrok;}
       
  7823 | FOR control_variable ASSIGN expression TO expression BY expression DO END_FOR
       
  7824   {$$ = NULL; print_err_msg(locl(@9), locf(@10), "no statement(s) defined after 'DO' in ST 'FOR' statement."); yynerrs++;}
       
  7825 | FOR control_variable ASSIGN expression TO expression DO END_FOR
       
  7826   {$$ = NULL; print_err_msg(locl(@7), locf(@8), "no statement(s) defined after 'DO' in ST 'FOR' statement."); yynerrs++;}
       
  7827 | FOR control_variable ASSIGN expression TO expression BY expression DO error END_FOR
       
  7828   {$$ = NULL; print_err_msg(locf(@10), locl(@10), "invalid statement(s) defined after 'DO' in ST 'FOR' statement."); yyerrok;}
       
  7829 | FOR control_variable ASSIGN expression TO expression DO error END_FOR
       
  7830   {$$ = NULL; print_err_msg(locf(@8), locl(@8), "invalid statement(s) defined after 'DO' in ST 'FOR' statement."); yyerrok;}
       
  7831 | FOR control_variable error END_OF_INPUT
       
  7832   {$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed 'FOR' statement in ST."); yyerrok;}
       
  7833 | FOR control_variable ASSIGN expression error END_OF_INPUT
       
  7834   {$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed 'FOR' statement in ST."); yyerrok;}
       
  7835 | FOR control_variable ASSIGN expression TO expression DO statement_list END_OF_INPUT
       
  7836   {$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed 'FOR' statement in ST."); yynerrs++;}
       
  7837 | FOR control_variable ASSIGN expression TO expression BY expression error END_OF_INPUT
       
  7838   {$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed 'FOR' statement in ST."); yyerrok;}
       
  7839 | FOR control_variable ASSIGN expression TO expression BY expression DO statement_list END_OF_INPUT
       
  7840   {$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed 'FOR' statement in ST."); yynerrs++;}
       
  7841 | FOR error END_FOR
       
  7842   {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in ST 'FOR' statement."); yyerrok;}
       
  7843 /* ERROR_CHECK_END */
       
  7844 ;
       
  7845 
       
  7846 /* The spec has the syntax
       
  7847  * control_variable: identifier;
       
  7848  * but then defines the semantics of control_variable
       
  7849  * (Section 3.3.2.4) as being of an integer type
       
  7850  * (e.g., SINT, INT, or DINT).
       
  7851  *
       
  7852  * Obviously this presuposes that the control_variable
       
  7853  * must have been declared in some VAR .. END_VAR
       
  7854  * We must therefore change the syntax to read
       
  7855  * control_variable: prev_declared_variable_name;
       
  7856  * 
       
  7857  * If we don't, then the correct use of any previosuly declared 
       
  7858  * variable would result in an incorrect syntax error
       
  7859 */
       
  7860 control_variable: 
       
  7861   prev_declared_variable_name 
       
  7862 	{$$ = new symbolic_variable_c($1,locloc(@$));};
       
  7863 // control_variable: identifier {$$ = $1;};
       
  7864 
       
  7865 /* Integrated directly into for_statement */
       
  7866 /*
       
  7867 for_list:
       
  7868   expression TO expression [BY expression]
       
  7869 ;
       
  7870 */
       
  7871 
       
  7872 
       
  7873 while_statement:
       
  7874   WHILE expression DO statement_list END_WHILE
       
  7875 	{$$ = new while_statement_c($2, $4, locloc(@$));}
       
  7876 /* ERROR_CHECK_BEGIN */
       
  7877 | WHILE DO statement_list END_WHILE
       
  7878   {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no test expression defined in ST 'WHILE' statement."); yynerrs++;}
       
  7879 | WHILE error DO statement_list END_WHILE
       
  7880   {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid test expression defined for ST 'WHILE' statement."); yyerrok;}
       
  7881 | WHILE expression error statement_list END_WHILE
       
  7882   {$$ = NULL; print_err_msg(locf(@3), locl(@3), "expecting 'DO' after test expression in ST 'WHILE' statement."); yyerrok;}
       
  7883 | WHILE expression DO END_WHILE
       
  7884   {$$ = NULL; print_err_msg(locl(@3), locf(@4), "no statement(s) defined after 'DO' in ST 'WHILE' statement."); yynerrs++;}
       
  7885 | WHILE expression DO error END_WHILE
       
  7886   {$$ = NULL; print_err_msg(locf(@4), locl(@4), "invalid statement(s) defined after 'DO' in ST 'WHILE' statement."); yyerrok;}
       
  7887 | WHILE expression error END_OF_INPUT
       
  7888   {$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed 'WHILE' statement in ST."); yyerrok;}
       
  7889 | WHILE expression DO statement_list END_OF_INPUT
       
  7890   {$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed 'WHILE' statement in ST."); yynerrs++;}
       
  7891 | WHILE error END_WHILE
       
  7892   {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in ST 'WHILE' statement."); yyerrok;}
       
  7893 /* ERROR_CHECK_END */
       
  7894 ;
       
  7895 
       
  7896 
       
  7897 repeat_statement:
       
  7898   REPEAT statement_list UNTIL expression END_REPEAT
       
  7899 	{$$ = new repeat_statement_c($2, $4, locloc(@$));}
       
  7900 /* ERROR_CHECK_BEGIN */
       
  7901 | REPEAT UNTIL expression END_REPEAT
       
  7902   {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no statement(s) defined after 'REPEAT' in ST 'REPEAT' statement."); yynerrs++;}
       
  7903 | REPEAT error UNTIL expression END_REPEAT
       
  7904   {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid statement(s) defined after 'REPEAT' for ST 'REPEAT' statement."); yyerrok;}
       
  7905 | REPEAT statement_list UNTIL END_REPEAT
       
  7906   {$$ = NULL; print_err_msg(locl(@3), locf(@4), "no test expression defined after 'UNTIL' in ST 'REPEAT' statement.");}
       
  7907 | REPEAT statement_list UNTIL error END_REPEAT
       
  7908   {$$ = NULL; print_err_msg(locf(@4), locl(@4), "invalid test expression defined after 'UNTIL' in ST 'REPEAT' statement."); yyerrok;}
       
  7909 | REPEAT statement_list END_OF_INPUT
       
  7910   {$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed 'REPEAT' statement in ST."); yynerrs++;}
       
  7911 | REPEAT statement_list UNTIL expression error END_OF_INPUT
       
  7912   {$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed 'REPEAT' statement in ST."); yyerrok;}
       
  7913 | REPEAT error END_REPEAT
       
  7914   {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in ST 'REPEAT' statement."); yyerrok;}
       
  7915 /* ERROR_CHECK_END */
       
  7916 ;
       
  7917 
       
  7918 
       
  7919 exit_statement:
       
  7920   EXIT	{$$ = new exit_statement_c(locloc(@$));}
       
  7921 ;
       
  7922 
       
  7923 
       
  7924 
       
  7925 
       
  7926 
       
  7927 %%
       
  7928 
       
  7929 #include <stdio.h>	/* required for printf() */
       
  7930 #include <errno.h>
       
  7931 #include "../util/symtable.hh"
       
  7932 
       
  7933 /* variables defined in code generated by flex... */
       
  7934 extern FILE *yyin;
       
  7935 extern int yylineno;
       
  7936 extern tracking_t* current_tracking;
       
  7937 
       
  7938 
       
  7939 
       
  7940 
       
  7941 /*************************************************************************************************/
       
  7942 /* NOTE: These variables are really parameters we would like the stage2__ function to pass       */
       
  7943 /*       to the yyparse() function. However, the yyparse() function is created automatically     */
       
  7944 /*       by bison, so we cannot add parameters to this function. The only other                  */
       
  7945 /*       option is to use global variables! yuck!                                                */ 
       
  7946 /*************************************************************************************************/
       
  7947 
       
  7948 /* A global flag used to tell the parser if overloaded funtions should be allowed.
       
  7949  * The IEC 61131-3 standard allows overloaded funtions in the standard library,
       
  7950  * but disallows them in user code...
       
  7951  *
       
  7952  * In essence, a parameter we would like to pass to the yyparse() function but
       
  7953  * have to do it using a global variable, as the yyparse() prototype is fixed by bison.
       
  7954  */
       
  7955 bool allow_function_overloading = false;
       
  7956 
       
  7957 /* | [var1_list ','] variable_name '..' */
       
  7958 /* NOTE: This is an extension to the standard!!! */
       
  7959 /* In order to be able to handle extensible standard functions
       
  7960  * (i.e. standard functions that may have a variable number of
       
  7961  * input parameters, such as AND(word#33, word#44, word#55, word#66),
       
  7962  * we have extended the acceptable syntax to allow var_name '..'
       
  7963  * in an input variable declaration.
       
  7964  *
       
  7965  * This allows us to parse the declaration of standard
       
  7966  * extensible functions and load their interface definition
       
  7967  * into the abstract syntax tree just like we do to other 
       
  7968  * user defined functions.
       
  7969  * This has the advantage that we can later do semantic
       
  7970  * checking of calls to functions (be it a standard or user defined
       
  7971  * function) in (almost) exactly the same way.
       
  7972  *
       
  7973  * Of course, we have a flag that disables this syntax when parsing user
       
  7974  * written code, so we only allow this extra syntax while parsing the 
       
  7975  * 'header' file that declares all the standard IEC 61131-3 functions.
       
  7976  */
       
  7977 bool allow_extensible_function_parameters = false;
       
  7978 
       
  7979 /* A global flag used to tell the parser whether to include the full variable location
       
  7980  * when printing out error messages...
       
  7981  */
       
  7982 bool full_token_loc;
       
  7983 
       
  7984 /* A pointer to the root of the parsing tree that will be generated 
       
  7985  * by bison.
       
  7986  */
       
  7987 symbol_c *tree_root;
       
  7988 
       
  7989 
       
  7990 
       
  7991 /* The following function is called automatically by bison whenever it comes across
       
  7992  * an error. Unfortunately it calls this function before executing the code that handles
       
  7993  * the error itself, so we cannot print out the correct line numbers of the error location
       
  7994  * over here.
       
  7995  * Our solution is to store the current error message in a global variable, and have all
       
  7996  * error action handlers call the function print_err_msg() after setting the location
       
  7997  * (line number) variable correctly.
       
  7998  */
       
  7999 const char *current_error_msg;
       
  8000 void yyerror (const char *error_msg) {
       
  8001   current_error_msg = error_msg;
       
  8002 /* fprintf(stderr, "error %d: %s\n", yynerrs // global variable //, error_msg); */
       
  8003 /*  print_include_stack(); */
       
  8004 }
       
  8005 
       
  8006 
       
  8007 /* ERROR_CHECK_BEGIN */
       
  8008 bool is_current_syntax_token() {
       
  8009   switch (yychar) {
       
  8010     case ';':
       
  8011     case ',':
       
  8012     case ')':
       
  8013     case ']':
       
  8014     case '+':
       
  8015     case '*':
       
  8016     case '-':
       
  8017     case '/':
       
  8018     case '<':
       
  8019     case '>':
       
  8020     case '=':
       
  8021     case '&':
       
  8022     case OR:
       
  8023     case XOR:
       
  8024     case AND:
       
  8025     case AND2:
       
  8026     case OPER_NE:
       
  8027     case OPER_LE:
       
  8028     case OPER_GE:
       
  8029     case MOD:
       
  8030     case OPER_EXP:
       
  8031     case NOT:
       
  8032       return true;
       
  8033     default:
       
  8034      return false;
       
  8035   }
       
  8036 }
       
  8037 /* ERROR_CHECK_END */
       
  8038 
       
  8039 
       
  8040 void print_err_msg(int first_line,
       
  8041                    int first_column,
       
  8042                    const char *first_filename,
       
  8043                    long int first_order,
       
  8044                    int last_line,
       
  8045                    int last_column,
       
  8046                    const char *last_filename,
       
  8047                    long int last_order,
       
  8048                    const char *additional_error_msg) {
       
  8049 
       
  8050   const char *unknown_file = "<unknown_file>";
       
  8051   if (first_filename == NULL) first_filename = unknown_file;
       
  8052   if ( last_filename == NULL)  last_filename = unknown_file;
       
  8053 
       
  8054   if (full_token_loc) {
       
  8055     if (first_filename == last_filename)
       
  8056       fprintf(stderr, "%s:%d-%d..%d-%d: error : %s\n", first_filename, first_line, first_column, last_line, last_column, additional_error_msg);
       
  8057     else
       
  8058       fprintf(stderr, "%s:%d-%d..%s:%d-%d: error : %s\n", first_filename, first_line, first_column, last_filename, last_line, last_column, additional_error_msg);
       
  8059   } else {
       
  8060       fprintf(stderr, "%s:%d: error : %s\n", first_filename, first_line, additional_error_msg);
       
  8061   }
       
  8062   //fprintf(stderr, "error %d: %s\n", yynerrs /* a global variable */, additional_error_msg);
       
  8063   print_include_stack();
       
  8064   //fprintf(stderr, "%s(%d-%d): %s\n", current_filename, first_line, last_line, current_error_msg);
       
  8065 }
       
  8066 
       
  8067 
       
  8068 
       
  8069 /* If function overloading is on, we allow several functions with the same name.
       
  8070  *
       
  8071  * However, to support standard functions, we also allow functions named
       
  8072  *   AND, MOD, NOT, OR, XOR, ADD, ...
       
  8073  */
       
  8074 /*
       
  8075 identifier_c *token_2_identifier_c(char *value, ) {
       
  8076   identifier_c tmp = new identifier_c(value, locloc(@$));
       
  8077 	 if (!allow_function_overloading) {
       
  8078 	   fprintf(stderr, "Function overloading not allowed. Invalid identifier %s\n", ((token_c *)($$))->value);
       
  8079 	   ERROR;
       
  8080 	 }
       
  8081 	}
       
  8082 }
       
  8083 */
       
  8084 
       
  8085 /* convert between an il_operator to a function name */
       
  8086 /* This a kludge!
       
  8087  * It is required because our language requires more than one
       
  8088  * look ahead token, and bison only works with one!
       
  8089  */
       
  8090 #define op_2_str(op, str) {\
       
  8091   op ## _operator_c *ptr = dynamic_cast<op ## _operator_c *>(il_operator); \
       
  8092   if (ptr != NULL) name = str; \
       
  8093 }
       
  8094 
       
  8095 /* NOTE: this code is very ugly and un-eficient, but I (Mario) have many
       
  8096  *       more things to worry about right now, so just let it be...
       
  8097  */
       
  8098 symbol_c *il_operator_c_2_identifier_c(symbol_c *il_operator) {
       
  8099   const char *name = NULL;
       
  8100   identifier_c *res;
       
  8101 
       
  8102   op_2_str(NOT,   "NOT");
       
  8103 
       
  8104   op_2_str(AND,   "AND");
       
  8105   op_2_str(OR,    "OR");
       
  8106   op_2_str(XOR,   "XOR");
       
  8107   op_2_str(ADD,   "ADD");
       
  8108   op_2_str(SUB,   "SUB");
       
  8109   op_2_str(MUL,   "MUL");
       
  8110   op_2_str(DIV,   "DIV");
       
  8111   op_2_str(MOD,   "MOD");
       
  8112   op_2_str(GT,    "GT");
       
  8113   op_2_str(GE,    "GE");
       
  8114   op_2_str(EQ,    "EQ");
       
  8115   op_2_str(LT,    "LT");
       
  8116   op_2_str(LE,    "LE");
       
  8117   op_2_str(NE,    "NE");
       
  8118 
       
  8119   op_2_str(LD,    "LD");
       
  8120   op_2_str(LDN,   "LDN");
       
  8121   op_2_str(ST,    "ST");
       
  8122   op_2_str(STN,   "STN");
       
  8123 
       
  8124   op_2_str(S,     "S");
       
  8125   op_2_str(R,     "R");
       
  8126   op_2_str(S1,    "S1");
       
  8127   op_2_str(R1,    "R1");
       
  8128 
       
  8129   op_2_str(CLK,   "CLK");
       
  8130   op_2_str(CU,    "CU");
       
  8131   op_2_str(CD,    "CD");
       
  8132   op_2_str(PV,    "PV");
       
  8133   op_2_str(IN,    "IN");
       
  8134   op_2_str(PT,    "PT");
       
  8135 
       
  8136   op_2_str(ANDN,  "ANDN");
       
  8137   op_2_str(ORN,   "ORN");
       
  8138   op_2_str(XORN,  "XORN");
       
  8139 
       
  8140   op_2_str(ADD,   "ADD");
       
  8141   op_2_str(SUB,   "SUB");
       
  8142   op_2_str(MUL,   "MUL");
       
  8143   op_2_str(DIV,   "DIV");
       
  8144 
       
  8145   op_2_str(GT,    "GT");
       
  8146   op_2_str(GE,    "GE");
       
  8147   op_2_str(EQ,    "EQ");
       
  8148   op_2_str(LT,    "LT");
       
  8149   op_2_str(LE,    "LE");
       
  8150   op_2_str(NE,    "NE");
       
  8151 
       
  8152   op_2_str(CAL,   "CAL");
       
  8153   op_2_str(CALC,  "CALC");
       
  8154   op_2_str(CALCN, "CALCN");
       
  8155   op_2_str(RET,   "RET");
       
  8156   op_2_str(RETC,  "RETC");
       
  8157   op_2_str(RETCN, "RETCN");
       
  8158   op_2_str(JMP,   "JMP");
       
  8159   op_2_str(JMPC,  "JMPC");
       
  8160   op_2_str(JMPCN, "JMPCN");
       
  8161 
       
  8162   if (name == NULL)
       
  8163     ERROR;
       
  8164 
       
  8165   res = new identifier_c(strdup(name), 
       
  8166                          il_operator->first_line,
       
  8167                          il_operator->first_column,
       
  8168                          il_operator->first_file,
       
  8169                          il_operator->first_order,
       
  8170                          il_operator->last_line,
       
  8171                          il_operator->last_column,
       
  8172                          il_operator->last_file,
       
  8173                          il_operator->last_order
       
  8174                         );
       
  8175   free(il_operator);
       
  8176   return res;
       
  8177 }
       
  8178 
       
  8179 
       
  8180 #include "standard_function_names.c"
       
  8181 
       
  8182 const char *standard_function_block_names[] = {
       
  8183 // 2.5.2.3.1  Bistable elements
       
  8184 //   Table 34 - Standard bistable function blocks
       
  8185 "SR","RS",
       
  8186 // 2.5.2.3.2  Edge detection
       
  8187 //   Table 35 - Standard edge detection function blocks
       
  8188 "R_TRIG","F_TRIG",
       
  8189 // 2.5.2.3.3  Counters
       
  8190 //   Table 36 - Standard counter function blocks
       
  8191 "CTU","CTU_DINT","CTU_LINT","CTU_UDINT","CTU_ULINT",
       
  8192 "CTD","CTD_DINT","CTD_LINT","CTD_UDINT","CTD_ULINT",
       
  8193 "CTUD","CTUD_DINT","CTUD_LINT","CTUD_ULINT",
       
  8194 // 2.5.2.3.4  Timers
       
  8195 //   Table 37 - Standard timer function blocks
       
  8196 "TP","TON","TOF",
       
  8197 /* end of array marker! Do not remove! */
       
  8198 NULL
       
  8199 };
       
  8200 
       
  8201 
       
  8202 #define LIBFILE "ieclib.txt"
       
  8203 #define DEF_LIBFILENAME LIBDIRECTORY "/" LIBFILE
       
  8204 
       
  8205 extern const char *INCLUDE_DIRECTORIES[];
       
  8206 
       
  8207 
       
  8208 
       
  8209 int stage2__(const char *filename, 
       
  8210              const char *includedir,     /* Include directory, where included files will be searched for... */
       
  8211              symbol_c **tree_root_ref,
       
  8212              bool full_token_loc_        /* error messages specify full token location */
       
  8213             ) {
       
  8214 
       
  8215   FILE *in_file = NULL, *lib_file = NULL;
       
  8216   char *libfilename = NULL;
       
  8217 	
       
  8218   if((in_file = fopen(filename, "r")) == NULL) {
       
  8219     char *errmsg = strdup2("Error opening main file ", filename);
       
  8220     perror(errmsg);
       
  8221     free(errmsg);
       
  8222     return -1;
       
  8223   }
       
  8224 
       
  8225   if (includedir != NULL) {
       
  8226     INCLUDE_DIRECTORIES[0] = includedir;
       
  8227   }
       
  8228   if ((libfilename = strdup3(INCLUDE_DIRECTORIES[0], "/", LIBFILE)) == NULL) {
       
  8229     fprintf (stderr, "Out of memory. Bailing out!\n");
       
  8230     return -1;
       
  8231   }
       
  8232 
       
  8233   if((lib_file = fopen(libfilename, "r")) == NULL) {
       
  8234     char *errmsg = strdup2("Error opening library file ", libfilename);
       
  8235     perror(errmsg);
       
  8236     free(errmsg);
       
  8237   }
       
  8238 
       
  8239   if (lib_file == NULL) {
       
  8240     /* we give up... */
       
  8241     free(libfilename);
       
  8242     fclose(in_file);
       
  8243     return -1;
       
  8244   }
       
  8245 
       
  8246   /* first parse the standard library file... */
       
  8247   /*
       
  8248   #if YYDEBUG
       
  8249     yydebug = 1;
       
  8250   #endif
       
  8251   */
       
  8252   yyin = lib_file;
       
  8253   allow_function_overloading = true;
       
  8254   allow_extensible_function_parameters = true;
       
  8255   full_token_loc = full_token_loc_;
       
  8256   current_filename = libfilename;
       
  8257   current_tracking = GetNewTracking(yyin);
       
  8258   if (yyparse() != 0)
       
  8259       ERROR;
       
  8260 
       
  8261   if (yynerrs > 0) {
       
  8262     fprintf (stderr, "\nFound %d error(s) in %s. Bailing out!\n", yynerrs /* global variable */, libfilename);
       
  8263     ERROR;
       
  8264   }
       
  8265   free(libfilename);
       
  8266   fclose(lib_file);
       
  8267 
       
  8268   /* if by any chance the library is not complete, we
       
  8269    * now add the missing reserved keywords to the list!!!
       
  8270    */
       
  8271   for(int i = 0; standard_function_block_names[i] != NULL; i++)
       
  8272     if (library_element_symtable.find_value(standard_function_block_names[i]) ==
       
  8273         library_element_symtable.end_value())
       
  8274       library_element_symtable.insert(standard_function_block_names[i], standard_function_block_name_token);
       
  8275 
       
  8276 
       
  8277   /* now parse the input file... */
       
  8278   #if YYDEBUG
       
  8279     yydebug = 1;
       
  8280   #endif
       
  8281   yyin = in_file;
       
  8282   allow_function_overloading = false;
       
  8283   allow_extensible_function_parameters = false;
       
  8284   full_token_loc = full_token_loc_;
       
  8285   current_filename = filename;
       
  8286   current_tracking = GetNewTracking(yyin);
       
  8287   {int res;
       
  8288     if ((res = yyparse()) != 0) {
       
  8289       fprintf (stderr, "\nParsing failed because of too many consecutive syntax errors. Bailing out!\n");
       
  8290   		exit(EXIT_FAILURE);
       
  8291   	}
       
  8292   }
       
  8293 
       
  8294   if (yynerrs > 0) {
       
  8295     fprintf (stderr, "\nFound %d error(s). Bailing out!\n", yynerrs /* global variable */);
       
  8296     exit(EXIT_FAILURE);
       
  8297   }
       
  8298   
       
  8299   if (tree_root_ref != NULL)
       
  8300     *tree_root_ref = tree_root;
       
  8301 
       
  8302   fclose(in_file);
       
  8303   return 0;
       
  8304 }
       
  8305 
       
  8306 
       
  8307