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