--- a/stage1_2/iec.y Wed Sep 07 19:28:10 2011 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,8219 +0,0 @@
-/*
- * matiec - a compiler for the programming languages defined in IEC 61131-3
- *
- * Copyright (C) 2003-2011 Mario de Sousa (msousa@fe.up.pt)
- * Copyright (C) 2007-2011 Laurent Bessard and Edouard Tisserant
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- *
- * This code is made available on the understanding that it will not be
- * used in safety-critical situations without a full and competent review.
- */
-
-/*
- * An IEC 61131-3 compiler.
- *
- * Based on the
- * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10)
- *
- */
-
-/*
- * Stage 2
- * =======
- *
- * This file contains the syntax definition of the textual
- * languages IL and ST, as well as the textual version of SFC.
- * The syntax parser, comprising the 2nd stage of the overall
- * compiler, is generated by runing bison on this file.
- */
-
-
-
-
-/**********************************************************************/
-/**********************************************************************/
-/**********************************************************************/
-/**********************************************************************/
-/******* *******/
-/******* The following syntax does not have any conflicts. *******/
-/******* *******/
-/******* P L E A S E K E E P I T T H A T W A Y ! *******/
-/******* =================================================== *******/
-/******* *******/
-/**********************************************************************/
-/**********************************************************************/
-/**********************************************************************/
-/**********************************************************************/
-
-
-
-
-%{
-#include <string.h> /* required for strdup() */
-
-
-/* declare the token parser generated by flex... */
-int yylex(void);
-
-/* declare the error handler defined at the end of this file */
-void yyerror (const char *error_msg);
-
-/* produce a more verbose parsing error message */
-#define YYERROR_VERBOSE
-
-/* Include debuging code.
- * Printing of debug info must then be activated by setting
- * the variable yydebug to 1.
- */
-#define YYDEBUG 0
-
-
-/* file with declaration of absyntax classes... */
-#include "../absyntax/absyntax.hh"
-
-/* file with declaration of token constants. Generated by bison! */
-#include "iec.y.hh"
-
-/* The interface through which bison and flex interact. */
-#include "stage1_2_priv.hh"
-
-
-#include "../absyntax_utils/add_en_eno_param_decl.hh" /* required for add_en_eno_param_decl_c */
-
-/* an ugly hack!!
- * We will probably not need it when we decide
- * to cut down the abstract syntax down to size.
- * We keep it as it is until we get to write
- * stages 3 and 4 of the compiler. Who knows,
- * we might just find out that we really do need
- * the abstract syntax tree to stay as it is
- * afterall!
- */
-/* for each element <elem> in list_c * <list>
- * execute the code <code>
- */
-#define FOR_EACH_ELEMENT(elem, list, code) { \
- symbol_c *elem; \
- for(int i = 0; i < list->n; i++) { \
- elem = list->elements[i]; \
- code; \
- } \
-}
-
-
-
-/* Macros used to pass the line and column locations when
- * creating a new object for the abstract syntax tree.
- */
-#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
-#define locf(foo) foo.first_line, foo.first_column, foo.first_file, foo.first_order
-#define locl(foo) foo.last_line, foo.last_column, foo.last_file, foo.last_order
-
-/* Redefine the default action to take for each rule, so that the filenames are correctly processed... */
-# define YYLLOC_DEFAULT(Current, Rhs, N) \
- do \
- if (N) \
- { \
- (Current).first_line = YYRHSLOC(Rhs, 1).first_line; \
- (Current).first_column = YYRHSLOC(Rhs, 1).first_column; \
- (Current).first_file = YYRHSLOC(Rhs, 1).first_file; \
- (Current).first_order = YYRHSLOC(Rhs, 1).first_order; \
- (Current).last_line = YYRHSLOC(Rhs, N).last_line; \
- (Current).last_column = YYRHSLOC(Rhs, N).last_column; \
- (Current).last_file = YYRHSLOC(Rhs, 1).last_file; \
- (Current).last_order = YYRHSLOC(Rhs, 1).last_order; \
- } \
- else \
- { \
- (Current).first_line = (Current).last_line = \
- YYRHSLOC(Rhs, 0).last_line; \
- (Current).first_column = (Current).last_column = \
- YYRHSLOC(Rhs, 0).last_column; \
- (Current).first_file = (Current).last_file = \
- YYRHSLOC(Rhs, 0).last_file; \
- (Current).first_order = (Current).last_order = \
- YYRHSLOC(Rhs, 0).last_order; \
- } \
- while (0)
-
-
-/* A macro for printing out internal parser errors... */
-#define ERROR error_exit(__FILE__,__LINE__)
-/* function defined in main.cc */
-extern void error_exit(const char *file_name, int line_no);
-
-
-
-/*************************/
-/* global variables... */
-/*************************/
-/* NOTE: For some strange reason bison ver 2.3 is including these declarations
- * in the iec.y.hh file, which is in turn included by flex.
- * We cannot therefore define any variables over here, but merely declare
- * their existance (otherwise we get errors when linking the code, since we
- * would get a new variable defined each time iec.y.hh is included!).
- * Even though the variables are declared 'extern' over here, they will in
- * fact be defined towards the end of this same file (i.e. in the prologue)
- */
-
-
-/* NOTE: These variable are really parameters we would like the stage2__ function to pass
- * to the yyparse() function. However, the yyparse() function is created automatically
- * by bison, so we cannot add parameters to this function. The only other
- * option is to use global variables! yuck!
- */
-
-/* A global flag used to tell the parser if overloaded funtions should be allowed.
- * The IEC 61131-3 standard allows overloaded funtions in the standard library,
- * but disallows them in user code...
- */
-extern bool allow_function_overloading;
-
-/* A global flag used to tell the parser whether to include the full variable location
- * when printing out error messages...
- */
-extern bool full_token_loc;
-
-/* A pointer to the root of the parsing tree that will be generated
- * by bison.
- */
-extern symbol_c *tree_root;
-
-
-
-/************************/
-/* forward declarations */
-/************************/
-/* The functions declared here are defined at the end of this file... */
-
-/* Convert an il_operator_c into an identifier_c */
-symbol_c *il_operator_c_2_identifier_c(symbol_c *il_operator);
-
-/* return if current token is a syntax element */
-/* ERROR_CHECK_BEGIN */
-bool is_current_syntax_token();
-/* ERROR_CHECK_END */
-
-/* print an error message */
-void print_err_msg(int first_line,
- int first_column,
- const char *first_filename,
- long int first_order,
- int last_line,
- int last_column,
- const char *last_filename,
- long int last_order,
- const char *additional_error_msg);
-%}
-
-
-
-
-// %glr-parser
-// %expect-rr 1
-
-
-/* The following definitions need to be inside a '%code requires'
- * so that they are also included in the header files. If this were not the case,
- * YYLTYPE would be delcared as something in the iec.cc file, and another thing
- * (actually the default value of YYLTYPE) in the iec.y.hh heder file.
- */
-%code requires {
-/* define a new data type to store the locations, so we can also store
- * the filename in which the token is expressed.
- */
-/* NOTE: since this code will be placed in the iec.y.hh header file,
- * as well as the iec.cc file that also includes the iec.y.hh header file,
- * declaring the typedef struct yyltype__local here would result in a
- * compilation error when compiling iec.cc, as this struct would be
- * declared twice.
- * We therefore use the #if !defined YYLTYPE ...
- * to make sure only the first declaration is parsed by the C++ compiler.
- *
- * At first glance it seems that what we really should do is delcare the
- * YYLTYPE directly as an anonymous struct, thus:
- * #define YYLTYPE struct{ ...}
- * however, this also results in compilation errors.
- *
- * I (Mario) think this is kind of a hack. If you know how to
- * do this re-declaration of YYLTYPE properly, please let me know!
- */
-#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
- typedef struct {
- int first_line;
- int first_column;
- const char *first_file;
- long int first_order;
- int last_line;
- int last_column;
- const char *last_file;
- long int last_order;
- } yyltype__local;
- #define YYLTYPE yyltype__local
-#endif
-}
-
-
-
-%union {
- symbol_c *leaf;
- list_c *list;
- char *ID; /* token value */
-}
-
-/*
- TODO: DO we need to define a destructor do free
- memory when recovering from errors, or do the
- class destructors already handle this?
- Following is example on how to define
- detructors, using the syntax:
- %destructor { CODE } SYMBOLS
-%union
- {
- char *string;
- }
- %token <string> STRING
- %type <string> string
- %destructor { free ($$); } STRING string
-*/
-
-
-
-
-/*************************************/
-/* Prelimenary helpful constructs... */
-/*************************************/
-/* A token used to identify the very end of the input file
- * after all includes have already been processed.
- *
- * Flex automatically returns the token with value 0
- * at the end of the file. We therefore specify here
- * a token with that exact same value here, so we can use it
- * to detect the very end of the input files.
- */
-%token END_OF_INPUT 0
-
-/* A bogus token that, in principle, flex MUST NEVER generate */
-/* USE 1:
- * ======
- * This token is currently also being used as the default
- * initialisation value of the token_id member in
- * the symbol_c base class.
- *
- * USE 2
- * =====
- * This token may also be used in the future to remove
- * mysterious reduce/reduce conflicts due to the fact
- * that our grammar may not be LALR(1) but merely LR(1).
- * This means that bison cannot handle it without some
- * caoxing from ourselves. We will then need this token
- * to do the coaxing...
- */
-%token BOGUS_TOKEN_ID
-
-%type <leaf> start
-
-%type <leaf> any_identifier
-
-%token <ID> prev_declared_variable_name_token
-%token <ID> prev_declared_direct_variable_token
-%token <ID> prev_declared_fb_name_token
-%type <leaf> prev_declared_variable_name
-%type <leaf> prev_declared_direct_variable
-%type <leaf> prev_declared_fb_name
-
-%token <ID> prev_declared_simple_type_name_token
-%token <ID> prev_declared_subrange_type_name_token
-%token <ID> prev_declared_enumerated_type_name_token
-%token <ID> prev_declared_array_type_name_token
-%token <ID> prev_declared_structure_type_name_token
-%token <ID> prev_declared_string_type_name_token
-
-%type <leaf> prev_declared_simple_type_name
-%type <leaf> prev_declared_subrange_type_name
-%type <leaf> prev_declared_enumerated_type_name
-%type <leaf> prev_declared_array_type_name
-%type <leaf> prev_declared_structure_type_name
-%type <leaf> prev_declared_string_type_name
-
-%token <ID> prev_declared_derived_function_name_token
-%token <ID> prev_declared_derived_function_block_name_token
-%token <ID> prev_declared_program_type_name_token
-%type <leaf> prev_declared_derived_function_name
-%type <leaf> prev_declared_derived_function_block_name
-%type <leaf> prev_declared_program_type_name
-
-
-
-
-/**********************************************************************************/
-/* B XXX - Things that are missing from the standard, but should have been there! */
-/**********************************************************************************/
-
-/* Pragmas that our compiler will accept.
- * See the comment in iec.flex for why these pragmas exist.
- */
-%token disable_code_generation_pragma_token
-%token enable_code_generation_pragma_token
-%type <leaf> disable_code_generation_pragma
-%type <leaf> enable_code_generation_pragma
-
-
-/* All other pragmas that we do not support... */
-/* In most stage 4, the text inside the pragmas will simply be copied to the output file.
- * This allows us to insert C code (if using stage 4 generating C code)
- * inside/interningled with the IEC 61131-3 code!
- */
-%token <ID> pragma_token
-%type <leaf> pragma
-
-/* The joining of all previous pragmas, i.e. any possible pragma */
-%type <leaf> any_pragma
-
-
-/* Where do these tokens belong?? They are missing from the standard! */
-/* NOTE: There are other tokens related to these 'EN' ENO', that are also
- * missing from the standard. However, their location in the annex B is
- * relatively obvious, so they have been inserted in what seems to us their
- * correct place in order to ease understanding of the parser...
- *
- * please read the comment above the definition of 'variable' in section B1.4 for details.
- */
-%token EN
-%token ENO
-%type <leaf> en_identifier
-%type <leaf> eno_identifier
-
-
-
-
-/***************************/
-/* B 0 - Programming Model */
-/***************************/
-%type <list> library
-%type <leaf> library_element_declaration
-
-
-/*******************************************/
-/* B 1.1 - Letters, digits and identifiers */
-/*******************************************/
-/* Done totally within flex...
- letter
- digit
- octal_digit
- hex_digit
-*/
-%token <ID> identifier_token
-%type <leaf> identifier
-
-/*********************/
-/* B 1.2 - Constants */
-/*********************/
-%type <leaf> constant
-%type <leaf> non_negative_constant
-
-/******************************/
-/* B 1.2.1 - Numeric Literals */
-/******************************/
-/* Done totally within flex...
- bit
-*/
-%type <leaf> numeric_literal
-%type <leaf> integer_literal
-%type <leaf> signed_integer
-%token <ID> integer_token
-%type <leaf> integer
-%token <ID> binary_integer_token
-%type <leaf> binary_integer
-%token <ID> octal_integer_token
-%type <leaf> octal_integer
-%token <ID> hex_integer_token
-%type <leaf> hex_integer
-%token <ID> real_token
-%type <leaf> real
-%type <leaf> signed_real
-%type <leaf> real_literal
-// %type <leaf> exponent
-%type <leaf> bit_string_literal
-%type <leaf> boolean_literal
-
-%token safeboolean_true_literal_token
-%token safeboolean_false_literal_token
-%token boolean_true_literal_token
-%token boolean_false_literal_token
-
-%token FALSE
-%token TRUE
-
-
-/*******************************/
-/* B 1.2.2 - Character Strings */
-/*******************************/
-%token <ID> single_byte_character_string_token
-%token <ID> double_byte_character_string_token
-
-%type <leaf> character_string
-%type <leaf> single_byte_character_string
-%type <leaf> double_byte_character_string
-
-
-/***************************/
-/* B 1.2.3 - Time Literals */
-/***************************/
-%type <leaf> time_literal
-
-
-/************************/
-/* B 1.2.3.1 - Duration */
-/************************/
-%type <leaf> duration
-%type <leaf> interval
-%type <leaf> days
-%type <leaf> fixed_point
-%type <leaf> hours
-%type <leaf> minutes
-%type <leaf> seconds
-%type <leaf> milliseconds
-
-%type <leaf> integer_d
-%type <leaf> integer_h
-%type <leaf> integer_m
-%type <leaf> integer_s
-%type <leaf> integer_ms
-%type <leaf> fixed_point_d
-%type <leaf> fixed_point_h
-%type <leaf> fixed_point_m
-%type <leaf> fixed_point_s
-%type <leaf> fixed_point_ms
-
-%token <ID> fixed_point_token
-%token <ID> fixed_point_d_token
-%token <ID> integer_d_token
-%token <ID> fixed_point_h_token
-%token <ID> integer_h_token
-%token <ID> fixed_point_m_token
-%token <ID> integer_m_token
-%token <ID> fixed_point_s_token
-%token <ID> integer_s_token
-%token <ID> fixed_point_ms_token
-%token <ID> integer_ms_token
-
-// %token TIME
-%token T_SHARP
-
-
-/************************************/
-/* B 1.2.3.2 - Time of day and Date */
-/************************************/
-%type <leaf> time_of_day
-%type <leaf> daytime
-%type <leaf> day_hour
-%type <leaf> day_minute
-%type <leaf> day_second
-%type <leaf> date
-%type <leaf> date_literal
-%type <leaf> year
-%type <leaf> month
-%type <leaf> day
-%type <leaf> date_and_time
-
-// %token TIME_OF_DAY
-// %token DATE
-%token D_SHARP
-// %token DATE_AND_TIME
-
-
-/**********************/
-/* B 1.3 - Data Types */
-/**********************/
-/* Strangely, the following symbol does seem to be required! */
-// %type <leaf> data_type_name
-%type <leaf> non_generic_type_name
-
-
-/***********************************/
-/* B 1.3.1 - Elementary Data Types */
-/***********************************/
-/* NOTES:
- *
- * - To make the definition of bit_string_literal more
- * concise, it is useful to use an extra non-terminal
- * symbol (i.e. a grouping or construct) that groups the
- * following elements (BYTE, WORD, DWORD, LWORD).
- * Note that the definition of bit_string_type_name
- * (according to the spec) includes the above elements
- * and an extra BOOL.
- * We could use an extra construct with the first four
- * elements to be used solely in the definition of
- * bit_string_literal, but with the objective of not
- * having to replicate the actions (if we ever need
- * to change them, they would need to be changed in both
- * bit_string_type_name and the extra grouping), we
- * have re-defined bit_string_type_name as only including
- * the first four elements.
- * In order to have our parser implement the specification
- * correctly we have augmented every occurence of
- * bit_string_type_name in other rules with the BOOL
- * token. Since bit_string_type_name only appears in
- * the rule for elementary_type_name, this does not
- * seem to be a big concession to make!
- *
- * - We have added a helper symbol to concentrate the
- * instantiation of STRING and WSTRING into a single
- * location (elementary_string_type_name).
- * These two elements show up in several other rules,
- * but we want to create the equivalent abstract syntax
- * in a single location of this file, in order to make
- * possible future changes easier to edit...
- */
-%type <leaf> elementary_type_name
-%type <leaf> numeric_type_name
-%type <leaf> integer_type_name
-%type <leaf> signed_integer_type_name
-%type <leaf> unsigned_integer_type_name
-%type <leaf> real_type_name
-%type <leaf> date_type_name
-%type <leaf> bit_string_type_name
-/* helper symbol to concentrate the instantiation
- * of STRING and WSTRING into a single location
- */
-%type <leaf> elementary_string_type_name
-
-%token BYTE
-%token WORD
-%token DWORD
-%token LWORD
-
-%token LREAL
-%token REAL
-
-%token SINT
-%token INT
-%token DINT
-%token LINT
-
-%token USINT
-%token UINT
-%token UDINT
-%token ULINT
-
-%token WSTRING
-%token STRING
-%token BOOL
-
-%token TIME
-%token DATE
-%token DATE_AND_TIME
-%token DT
-%token TIME_OF_DAY
-%token TOD
-
-/******************************************************/
-/* Symbols defined in */
-/* "Safety Software Technical Specification, */
-/* Part 1: Concepts and Function Blocks, */
-/* Version 1.0 – Official Release" */
-/* by PLCopen - Technical Committee 5 - 2006-01-31 */
-/******************************************************/
-
-%token SAFEBYTE
-%token SAFEWORD
-%token SAFEDWORD
-%token SAFELWORD
-
-%token SAFELREAL
-%token SAFEREAL
-
-%token SAFESINT
-%token SAFEINT
-%token SAFEDINT
-%token SAFELINT
-
-%token SAFEUSINT
-%token SAFEUINT
-%token SAFEUDINT
-%token SAFEULINT
-
-%token SAFEWSTRING
-%token SAFESTRING
-%token SAFEBOOL
-
-%token SAFETIME
-%token SAFEDATE
-%token SAFEDATE_AND_TIME
-%token SAFEDT
-%token SAFETIME_OF_DAY
-%token SAFETOD
-
-/********************************/
-/* B 1.3.2 - Generic data types */
-/********************************/
-/* Strangely, the following symbol does seem to be required! */
-// %type <leaf> generic_type_name
-
-/* The following tokens do not seem to be used either
- * but we declare them so they become reserved words...
- */
-%token ANY
-%token ANY_DERIVED
-%token ANY_ELEMENTARY
-%token ANY_MAGNITUDE
-%token ANY_NUM
-%token ANY_REAL
-%token ANY_INT
-%token ANY_BIT
-%token ANY_STRING
-%token ANY_DATE
-
-
-/********************************/
-/* B 1.3.3 - Derived data types */
-/********************************/
-%type <leaf> derived_type_name
-%type <leaf> single_element_type_name
-// %type <leaf> simple_type_name
-// %type <leaf> subrange_type_name
-// %type <leaf> enumerated_type_name
-// %type <leaf> array_type_name
-// %type <leaf> structure_type_name
-
-%type <leaf> data_type_declaration
-/* helper symbol for data_type_declaration */
-%type <list> type_declaration_list
-%type <leaf> type_declaration
-%type <leaf> single_element_type_declaration
-
-%type <leaf> simple_type_declaration
-%type <leaf> simple_spec_init
-%type <leaf> simple_specification
-
-%type <leaf> subrange_type_declaration
-%type <leaf> subrange_spec_init
-%type <leaf> subrange_specification
-%type <leaf> subrange
-
-%type <leaf> enumerated_type_declaration
-%type <leaf> enumerated_spec_init
-%type <leaf> enumerated_specification
-/* helper symbol for enumerated_value */
-%type <list> enumerated_value_list
-%type <leaf> enumerated_value
-//%type <leaf> enumerated_value_without_identifier
-
-%type <leaf> array_type_declaration
-%type <leaf> array_spec_init
-%type <leaf> array_specification
-/* helper symbol for array_specification */
-%type <list> array_subrange_list
-%type <leaf> array_initialization
-/* helper symbol for array_initialization */
-%type <list> array_initial_elements_list
-%type <leaf> array_initial_elements
-%type <leaf> array_initial_element
-
-%type <leaf> structure_type_declaration
-%type <leaf> structure_specification
-%type <leaf> initialized_structure
-%type <leaf> structure_declaration
-/* helper symbol for structure_declaration */
-%type <list> structure_element_declaration_list
-%type <leaf> structure_element_declaration
-%type <leaf> structure_element_name
-%type <leaf> structure_initialization
-/* helper symbol for structure_initialization */
-%type <list> structure_element_initialization_list
-%type <leaf> structure_element_initialization
-
-//%type <leaf> string_type_name
-%type <leaf> string_type_declaration
-/* helper symbol for string_type_declaration */
-%type <leaf> string_type_declaration_size
-/* helper symbol for string_type_declaration */
-%type <leaf> string_type_declaration_init
-
-%token ASSIGN
-%token DOTDOT /* ".." */
-%token TYPE
-%token END_TYPE
-%token ARRAY
-%token OF
-%token STRUCT
-%token END_STRUCT
-
-
-
-/*********************/
-/* B 1.4 - Variables */
-/*********************/
-%type <leaf> variable
-%type <leaf> symbolic_variable
-/* helper symbol for prog_cnxn */
-%type <leaf> any_symbolic_variable
-%type <leaf> variable_name
-
-
-
-
-/********************************************/
-/* B.1.4.1 Directly Represented Variables */
-/********************************************/
-/* Done totally within flex...
- location_prefix
- size_prefix
-*/
-%token <ID> direct_variable_token
-//%type <leaf> direct_variable
-
-
-/*************************************/
-/* B.1.4.2 Multi-element Variables */
-/*************************************/
-%type <leaf> multi_element_variable
-/* helper symbol for any_symbolic_variable */
-%type <leaf> any_multi_element_variable
-%type <leaf> array_variable
-/* helper symbol for any_symbolic_variable */
-%type <leaf> any_array_variable
-%type <leaf> subscripted_variable
-/* helper symbol for any_symbolic_variable */
-%type <leaf> any_subscripted_variable
-%type <list> subscript_list
-%type <leaf> subscript
-%type <leaf> structured_variable
-/* helper symbol for any_symbolic_variable */
-%type <leaf> any_structured_variable
-%type <leaf> record_variable
-/* helper symbol for any_symbolic_variable */
-%type <leaf> any_record_variable
-%type <leaf> field_selector
-
-
-/******************************************/
-/* B 1.4.3 - Declaration & Initialisation */
-/******************************************/
-%type <leaf> input_declarations
-/* helper symbol for input_declarations */
-%type <list> input_declaration_list
-%type <leaf> input_declaration
-%type <leaf> edge_declaration
-/* en_param_declaration is not in the standard, but should be! */
-%type <leaf> en_param_declaration
-%type <leaf> var_init_decl
-%type <leaf> var1_init_decl
-%type <list> var1_list
-%type <leaf> array_var_init_decl
-%type <leaf> structured_var_init_decl
-%type <leaf> fb_name_decl
-/* helper symbol for fb_name_decl */
-%type <list> fb_name_list_with_colon
-/* helper symbol for fb_name_list_with_colon */
-%type <list> var1_list_with_colon
-// %type <list> fb_name_list
-// %type <leaf> fb_name
-%type <leaf> output_declarations
-%type <leaf> var_output_init_decl
-%type <list> var_output_init_decl_list
-/* eno_param_declaration is not in the standard, but should be! */
-%type <leaf> eno_param_declaration
-%type <leaf> input_output_declarations
-/* helper symbol for input_output_declarations */
-%type <list> var_declaration_list
-%type <leaf> var_declaration
-%type <leaf> temp_var_decl
-%type <leaf> var1_declaration
-%type <leaf> array_var_declaration
-%type <leaf> structured_var_declaration
-%type <leaf> var_declarations
-%type <leaf> retentive_var_declarations
-%type <leaf> located_var_declarations
-/* helper symbol for located_var_declarations */
-%type <list> located_var_decl_list
-%type <leaf> located_var_decl
-%type <leaf> external_var_declarations
-/* helper symbol for external_var_declarations */
-%type <list> external_declaration_list
-%type <leaf> external_declaration
-%type <leaf> global_var_name
-%type <leaf> global_var_declarations
-/* helper symbol for global_var_declarations */
-%type <list> global_var_decl_list
-%type <leaf> global_var_decl
-%type <leaf> global_var_spec
-%type <leaf> located_var_spec_init
-%type <leaf> location
-%type <list> global_var_list
-%type <leaf> string_var_declaration
-%type <leaf> single_byte_string_var_declaration
-%type <leaf> single_byte_string_spec
-%type <leaf> double_byte_string_var_declaration
-%type <leaf> double_byte_string_spec
-%type <leaf> incompl_located_var_declarations
-/* helper symbol for incompl_located_var_declarations */
-%type <list> incompl_located_var_decl_list
-%type <leaf> incompl_located_var_decl
-%type <leaf> incompl_location
-%type <leaf> var_spec
-/* helper symbol for var_spec */
-%type <leaf> string_spec
-/* intermediate helper symbol for:
- * - non_retentive_var_decls
- * - var_declarations
- */
-%type <list> var_init_decl_list
-
-%token <ID> incompl_location_token
-
-%token VAR_INPUT
-%token VAR_OUTPUT
-%token VAR_IN_OUT
-%token VAR_EXTERNAL
-%token VAR_GLOBAL
-%token END_VAR
-%token RETAIN
-%token NON_RETAIN
-%token R_EDGE
-%token F_EDGE
-%token AT
-
-
-/***********************/
-/* B 1.5.1 - Functions */
-/***********************/
-// %type <leaf> function_name
-/* helper symbol for IL language */
-%type <leaf> function_name_no_clashes
-%type <leaf> function_name_simpleop_clashes
-//%type <leaf> function_name_expression_clashes
-/* helper symbols for ST language */
-//%type <leaf> function_name_NOT_clashes
-%type <leaf> function_name_no_NOT_clashes
-
-//%type <leaf> standard_function_name
-/* helper symbols for IL language */
-%type <leaf> standard_function_name_no_clashes
-%type <leaf> standard_function_name_simpleop_clashes
-%type <leaf> standard_function_name_expression_clashes
-/* helper symbols for ST language */
-%type <leaf> standard_function_name_NOT_clashes
-%type <leaf> standard_function_name_no_NOT_clashes
-
-%type <leaf> derived_function_name
-%type <leaf> function_declaration
-/* helper symbol for function_declaration */
-%type <leaf> function_name_declaration
-%type <leaf> io_var_declarations
-%type <leaf> function_var_decls
-%type <leaf> function_body
-%type <leaf> var2_init_decl
-/* intermediate helper symbol for function_declaration */
-%type <list> io_OR_function_var_declarations_list
-/* intermediate helper symbol for function_var_decls */
-%type <list> var2_init_decl_list
-
-%token <ID> standard_function_name_token
-
-%token FUNCTION
-%token END_FUNCTION
-%token CONSTANT
-
-
-/*****************************/
-/* B 1.5.2 - Function Blocks */
-/*****************************/
-%type <leaf> function_block_type_name
-%type <leaf> standard_function_block_name
-%type <leaf> derived_function_block_name
-%type <leaf> function_block_declaration
-%type <leaf> other_var_declarations
-%type <leaf> temp_var_decls
-%type <leaf> non_retentive_var_decls
-%type <leaf> function_block_body
-/* intermediate helper symbol for function_declaration */
-%type <list> io_OR_other_var_declarations_list
-/* intermediate helper symbol for temp_var_decls */
-%type <list> temp_var_decls_list
-
-%token <ID> standard_function_block_name_token
-
-%token FUNCTION_BLOCK
-%token END_FUNCTION_BLOCK
-%token VAR_TEMP
-// %token END_VAR
-%token VAR
-// %token NON_RETAIN
-// %token END_VAR
-
-
-/**********************/
-/* B 1.5.3 - Programs */
-/**********************/
-%type <leaf> program_type_name
-%type <leaf> program_declaration
-/* helper symbol for program_declaration */
-%type <list> program_var_declarations_list
-
-%token PROGRAM
-%token END_PROGRAM
-
-
-/********************************************/
-/* B 1.6 Sequential Function Chart elements */
-/********************************************/
-
-%type <list> sequential_function_chart
-%type <list> sfc_network
-%type <leaf> initial_step
-%type <leaf> step
-%type <list> action_association_list
-%type <leaf> step_name
-%type <leaf> action_association
-/* helper symbol for action_association */
-%type <list> indicator_name_list
-%type <leaf> action_name
-%type <leaf> action_qualifier
-%type <leaf> qualifier
-%type <leaf> timed_qualifier
-%type <leaf> action_time
-%type <leaf> indicator_name
-%type <leaf> transition
-%type <leaf> steps
-%type <list> step_name_list
-%type <leaf> transition_priority
-%type <leaf> transition_condition
-%type <leaf> action
-%type <leaf> action_body
-%type <leaf> transition_name
-
-
-// %token ASSIGN
-%token ACTION
-%token END_ACTION
-
-%token TRANSITION
-%token END_TRANSITION
-%token FROM
-%token TO
-%token PRIORITY
-
-%token INITIAL_STEP
-%token STEP
-%token END_STEP
-
-%token L
-%token D
-%token SD
-%token DS
-%token SL
-
-%token N
-%token P
-/* NOTE: the following two clash with the R and S IL operators.
- * It will have to be handled when we include parsing of SFC...
- */
-/*
-%token R
-%token S
-*/
-
-
-/********************************/
-/* B 1.7 Configuration elements */
-/********************************/
-%type <leaf> configuration_name
-%type <leaf> resource_type_name
-%type <leaf> configuration_declaration
-// helper symbol for
-// - configuration_declaration
-// - resource_declaration
-//
-%type <leaf> optional_global_var_declarations
-// helper symbol for configuration_declaration
-%type <leaf> optional_access_declarations
-// helper symbol for configuration_declaration
-%type <leaf> optional_instance_specific_initializations
-// helper symbol for configuration_declaration
-%type <list> resource_declaration_list
-%type <leaf> resource_declaration
-%type <leaf> single_resource_declaration
-// helper symbol for single_resource_declaration
-%type <list> task_configuration_list
-// helper symbol for single_resource_declaration
-%type <list> program_configuration_list
-%type <leaf> resource_name
-// %type <leaf> access_declarations
-// helper symbol for access_declarations
-// %type <leaf> access_declaration_list
-// %type <leaf> access_declaration
-// %type <leaf> access_path
-// helper symbol for access_path
-%type <list> any_fb_name_list
-%type <leaf> global_var_reference
-// %type <leaf> access_name
-%type <leaf> program_output_reference
-%type <leaf> program_name
-// %type <leaf> direction
-%type <leaf> task_configuration
-%type <leaf> task_name
-%type <leaf> task_initialization
-// 3 helper symbols for task_initialization
-%type <leaf> task_initialization_single
-%type <leaf> task_initialization_interval
-%type <leaf> task_initialization_priority
-
-%type <leaf> data_source
-%type <leaf> program_configuration
-// helper symbol for program_configuration
-%type <leaf> optional_task_name
-// helper symbol for program_configuration
-%type <leaf> optional_prog_conf_elements
-%type <list> prog_conf_elements
-%type <leaf> prog_conf_element
-%type <leaf> fb_task
-%type <leaf> prog_cnxn
-%type <leaf> prog_data_source
-%type <leaf> data_sink
-%type <leaf> instance_specific_initializations
-// helper symbol for instance_specific_initializations
-%type <list> instance_specific_init_list
-%type <leaf> instance_specific_init
-// helper symbol for instance_specific_init
-%type <leaf> fb_initialization
-
-%type <leaf> prev_declared_global_var_name
-%token <ID> prev_declared_global_var_name_token
-
-%type <leaf> prev_declared_program_name
-%token <ID> prev_declared_program_name_token
-
-%type <leaf> prev_declared_resource_name
-%token <ID> prev_declared_resource_name_token
-
-%token <ID> prev_declared_configuration_name_token
-
-// %type <leaf> prev_declared_task_name
-// %token <ID> prev_declared_task_name_token
-
-%token CONFIGURATION
-%token END_CONFIGURATION
-%token TASK
-%token RESOURCE
-%token ON
-%token END_RESOURCE
-%token VAR_CONFIG
-%token VAR_ACCESS
-// %token END_VAR
-%token WITH
-// %token PROGRAM
-// %token RETAIN
-// %token NON_RETAIN
-// %token PRIORITY
-%token SINGLE
-%token INTERVAL
-%token READ_WRITE
-%token READ_ONLY
-
-
-/***********************************/
-/* B 2.1 Instructions and Operands */
-/***********************************/
-%type <list> instruction_list
-%type <leaf> il_instruction
-%type <leaf> il_incomplete_instruction
-%type <leaf> label
-%type <leaf> il_simple_operation
-// helper symbol for il_simple_operation
-//%type <tmp_symbol> il_simple_operator_clash_il_operand
-%type <leaf> il_expression
-%type <leaf> il_jump_operation
-%type <leaf> il_fb_call
-%type <leaf> il_formal_funct_call
-// helper symbol for il_formal_funct_call
-%type <leaf> il_expr_operator_clash_eol_list
-%type <leaf> il_operand
-%type <list> il_operand_list
-// helper symbol for il_simple_operation
-%type <list> il_operand_list2
-%type <list> simple_instr_list
-%type <leaf> il_simple_instruction
-%type <list> il_param_list
-%type <list> il_param_instruction_list
-%type <leaf> il_param_instruction
-%type <leaf> il_param_last_instruction
-%type <leaf> il_param_assignment
-%type <leaf> il_param_out_assignment
-
-%token EOL
-
-
-/*******************/
-/* B 2.2 Operators */
-/*******************/
-%token <ID> sendto_identifier_token
-%type <leaf> sendto_identifier
-
-%type <leaf> LD_operator
-%type <leaf> LDN_operator
-%type <leaf> ST_operator
-%type <leaf> STN_operator
-%type <leaf> NOT_operator
-%type <leaf> S_operator
-%type <leaf> R_operator
-%type <leaf> S1_operator
-%type <leaf> R1_operator
-%type <leaf> CLK_operator
-%type <leaf> CU_operator
-%type <leaf> CD_operator
-%type <leaf> PV_operator
-%type <leaf> IN_operator
-%type <leaf> PT_operator
-%type <leaf> AND_operator
-%type <leaf> AND2_operator
-%type <leaf> OR_operator
-%type <leaf> XOR_operator
-%type <leaf> ANDN_operator
-%type <leaf> ANDN2_operator
-%type <leaf> ORN_operator
-%type <leaf> XORN_operator
-%type <leaf> ADD_operator
-%type <leaf> SUB_operator
-%type <leaf> MUL_operator
-%type <leaf> DIV_operator
-%type <leaf> MOD_operator
-%type <leaf> GT_operator
-%type <leaf> GE_operator
-%type <leaf> EQ_operator
-%type <leaf> LT_operator
-%type <leaf> LE_operator
-%type <leaf> NE_operator
-%type <leaf> CAL_operator
-%type <leaf> CALC_operator
-%type <leaf> CALCN_operator
-%type <leaf> RET_operator
-%type <leaf> RETC_operator
-%type <leaf> RETCN_operator
-%type <leaf> JMP_operator
-%type <leaf> JMPC_operator
-%type <leaf> JMPCN_operator
-
-%type <leaf> il_simple_operator
-%type <leaf> il_simple_operator_clash
-%type <leaf> il_simple_operator_clash1
-%type <leaf> il_simple_operator_clash2
-%type <leaf> il_simple_operator_noclash
-
-//%type <leaf> il_expr_operator
-%type <leaf> il_expr_operator_clash
-%type <leaf> il_expr_operator_noclash
-
-%type <leaf> il_assign_operator
-%type <leaf> il_assign_out_operator
-%type <leaf> il_call_operator
-%type <leaf> il_return_operator
-%type <leaf> il_jump_operator
-
-
-%token LD
-%token LDN
-%token ST
-%token STN
-%token NOT
-%token S
-%token R
-%token S1
-%token R1
-%token CLK
-%token CU
-%token CD
-%token PV
-%token IN
-%token PT
-%token AND
-%token AND2 /* character '&' in the source code*/
-%token OR
-%token XOR
-%token ANDN
-%token ANDN2 /* characters '&N' in the source code */
-%token ORN
-%token XORN
-%token ADD
-%token SUB
-%token MUL
-%token DIV
-%token MOD
-%token GT
-%token GE
-%token EQ
-%token LT
-%token LE
-%token NE
-%token CAL
-%token CALC
-%token CALCN
-%token RET
-%token RETC
-%token RETCN
-%token JMP
-%token JMPC
-%token JMPCN
-
-%token SENDTO /* "=>" */
-
-
-/***********************/
-/* B 3.1 - Expressions */
-/***********************/
-/* NOTE:
- *
- * - unary_operator, multiply_operator,
- * add_operator and comparison_operator
- * are not required. Their values are integrated
- * directly into other rules...
- */
-%type <leaf> expression
-%type <leaf> xor_expression
-%type <leaf> and_expression
-%type <leaf> comparison
-%type <leaf> equ_expression
-// %type <leaf> comparison_operator
-%type <leaf> add_expression
-// %type <leaf> add_operator
-%type <leaf> term
-// %type <leaf> multiply_operator
-%type <leaf> power_expression
-%type <leaf> unary_expression
-// %type <leaf> unary_operator
-%type <leaf> primary_expression
-%type <leaf> non_negative_primary_expression
-/* intermediate helper symbol for primary_expression */
-%type <leaf> function_invocation
-
-// %token AND
-// %token XOR
-// %token OR
-// %token MOD
-// %token NOT
-%token OPER_NE
-%token OPER_GE
-%token OPER_LE
-%token OPER_EXP
-
-
-/********************/
-/* B 3.2 Statements */
-/********************/
-%type <list> statement_list
-%type <leaf> statement
-
-
-
-/*********************************/
-/* B 3.2.1 Assignment Statements */
-/*********************************/
-%type <leaf> assignment_statement
-// %token ASSIGN /* ":=" */
-
-
-/*****************************************/
-/* B 3.2.2 Subprogram Control Statements */
-/*****************************************/
-%type <leaf> subprogram_control_statement
-%type <leaf> return_statement
-%type <leaf> fb_invocation
-// %type <leaf> param_assignment
-%type <leaf> param_assignment_formal
-%type <leaf> param_assignment_nonformal
-/* helper symbols for fb_invocation */
-%type <list> param_assignment_formal_list
-%type <list> param_assignment_nonformal_list
-
-// %token ASSIGN
-// %token SENDTO /* "=>" */
-%token RETURN
-
-
-/********************************/
-/* B 3.2.3 Selection Statements */
-/********************************/
-%type <leaf> selection_statement
-%type <leaf> if_statement
-%type <leaf> case_statement
-%type <leaf> case_element
-%type <list> case_list
-%type <leaf> case_list_element
-/* helper symbol for if_statement */
-%type <list> elseif_statement_list
-/* helper symbol for elseif_statement_list */
-%type <leaf> elseif_statement
-/* helper symbol for case_statement */
-%type <list> case_element_list
-
-%token IF
-%token THEN
-%token ELSIF
-%token ELSE
-%token END_IF
-
-%token CASE
-// %token OF
-// %token ELSE
-%token END_CASE
-
-
-
-/********************************/
-/* B 3.2.4 Iteration Statements */
-/********************************/
-%type <leaf> iteration_statement
-%type <leaf> for_statement
-%type <leaf> control_variable
-%type <leaf> while_statement
-%type <leaf> repeat_statement
-%type <leaf> exit_statement
-/* Integrated directly into for_statement */
-// %type <leaf> for_list
-
-%token FOR
-// %token ASSIGN
-// %token TO
-%token BY
-%token DO
-%token END_FOR
-
-%token WHILE
-// %token DO
-%token END_WHILE
-
-%token REPEAT
-%token UNTIL
-%token END_REPEAT
-
-%token EXIT
-
-
-%%
-
-
-
-
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-/********************************************************/
-
-
-start:
- library {$$ = $1;}
-;
-
-
-/**********************************************************************************/
-/* B XXX - Things that are missing from the standard, but should have been there! */
-/**********************************************************************************/
-
-
-/* the pragmas... */
-
-
-disable_code_generation_pragma:
- disable_code_generation_pragma_token {$$ = new disable_code_generation_pragma_c(locloc(@$));}
-
-enable_code_generation_pragma:
- enable_code_generation_pragma_token {$$ = new enable_code_generation_pragma_c(locloc(@$));}
-
-pragma:
- pragma_token {$$ = new pragma_c($1, locloc(@$));}
-
-any_pragma:
- disable_code_generation_pragma
-| enable_code_generation_pragma
-| pragma
-;
-
-
-/* EN/ENO */
-/* Tese tokens are essentially used as variable names, so we handle them
- * similarly to these...
- */
-en_identifier:
- EN {$$ = new identifier_c("EN", locloc(@$));}
-;
-
-eno_identifier:
- ENO {$$ = new identifier_c("ENO", locloc(@$));}
-;
-
-
-
-/*************************************/
-/* Prelimenary helpful constructs... */
-/*************************************/
-
-/* NOTE:
- * short version:
- * identifier is used for previously undeclared identifiers
- * any_identifier is used when any identifier, previously
- * declared or not, is required in the syntax.
- *
- * long version:
- * When flex comes across an identifier, it first
- * searches through the currently declared variables,
- * functions, types, etc... to determine if it has
- * been previously declared.
- * Only if the identifier has not yet been declared
- * will it return an identifier_token (later turned into
- * an identifier symbol by the bison generated syntax parser).
- *
- * Some constructs in the syntax, such as when calling
- * a function 'F(var1 := 1; var2 := 2);', will accept _any_
- * identifier in 'var1', even if it has been previously
- * declared in the current scope, since var1 belongs to
- * another scope (the variables declared in function F).
- *
- * For the above reason, we need to define the symbol
- * any_identifier. All the symbols that may become an
- * any_identifier are expected to be stored in the
- * abstract syntax as a identifier_c
- */
-/* NOTE:
- * Type names, function names, function block type names and
- * program type names are considerd keywords once they are defined,
- * so may no longer be used for variable names!
- * BUT the spec is confusing on this issue, as it is not clear when
- * a function name should be considered as defined. If it is to be
- * considered defined only from the location from where it is declared
- * and onwards, it means that before it is declared its name may be
- * used for variable names!
- * This means that we must allow names previously used for functions
- * (et. al.) to also constitue an any_identifier!
- */
-any_identifier:
- identifier
-| prev_declared_fb_name
-| prev_declared_variable_name
-/**/
-| prev_declared_enumerated_type_name
-| prev_declared_simple_type_name
-| prev_declared_subrange_type_name
-| prev_declared_array_type_name
-| prev_declared_structure_type_name
-| prev_declared_string_type_name
-| prev_declared_derived_function_name
-| prev_declared_derived_function_block_name
-| prev_declared_program_type_name
-/**/
-| prev_declared_resource_name
-| prev_declared_program_name
-| prev_declared_global_var_name
-;
-
-
-prev_declared_variable_name: prev_declared_variable_name_token {$$ = new identifier_c($1, locloc(@$));};
-prev_declared_fb_name: prev_declared_fb_name_token {$$ = new identifier_c($1, locloc(@$));};
-
-prev_declared_simple_type_name: prev_declared_simple_type_name_token {$$ = new identifier_c($1, locloc(@$));};
-prev_declared_subrange_type_name: prev_declared_subrange_type_name_token {$$ = new identifier_c($1, locloc(@$));};
-prev_declared_enumerated_type_name: prev_declared_enumerated_type_name_token {$$ = new identifier_c($1, locloc(@$));};
-prev_declared_array_type_name: prev_declared_array_type_name_token {$$ = new identifier_c($1, locloc(@$));};
-prev_declared_structure_type_name: prev_declared_structure_type_name_token {$$ = new identifier_c($1, locloc(@$));};
-prev_declared_string_type_name: prev_declared_string_type_name_token {$$ = new identifier_c($1, locloc(@$));};
-
-prev_declared_derived_function_name: prev_declared_derived_function_name_token {$$ = new identifier_c($1, locloc(@$));};
-prev_declared_derived_function_block_name: prev_declared_derived_function_block_name_token {$$ = new identifier_c($1, locloc(@$));};
-prev_declared_program_type_name: prev_declared_program_type_name_token {$$ = new identifier_c($1, locloc(@$));};
-
-
-
-/***************************/
-/* B 0 - Programming Model */
-/***************************/
-library:
- /* empty */
- {if (tree_root == NULL)
- tree_root = new library_c();
- $$ = (list_c *)tree_root;
- }
-| library library_element_declaration
- {$$ = $1; $$->add_element($2);}
-| library any_pragma
- {$$ = $1; $$->add_element($2);}
-/* ERROR_CHECK_BEGIN */
-| library error library_element_declaration
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "unknown syntax error."); yyerrok;}
-| library error END_OF_INPUT
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "unknown syntax error."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-library_element_declaration:
- data_type_declaration
-| function_declaration
-| function_block_declaration
-| program_declaration
-| configuration_declaration
-;
-
-
-
-/*******************************************/
-/* B 1.1 - Letters, digits and identifiers */
-/*******************************************/
-/* NOTE: the spec defines identifier as:
- * identifier ::= (letter|('_' (letter|digit))) {['_'] (letter|digit)}
- * In essence, any sequence of letters or digits, starting with a letter
- * or '_'.
- *
- * On section 2.1.3 (pg 26) , the spec states
- * "The keywords listed in annex C shall not be used for any other purpose,
- * e.g., variable names or extensions as defined in 1.5.1."
- * (NOTE: the spec itself does not follow this rule, as it defines standard
- * functions with names identidal to keywords, e.g. 'MOD', 'NOT' !!. This is
- * another issue altogether, and is worked around somewhere else...)
- *
- * This means that we must re-define indentifier so as to exclude
- * any keywords defined in annex C.
- *
- * Note also that the list includes
- * - Data type names
- * - Function names
- * - Function Block names
- * This means that any named used for a function name, data type name
- * or function block name, essentially becomes a keyword, and may therefore
- * no longer be re-used for any other use! (see NOTE 2)
- *
- * In our case, excluding the keywords is achieved in the lexical parser,
- * by two mechanisms:
- * (1) giving higher priority to the keywords (tokens) than to identifiers,
- * so when the lexical parser finds a keyword it will be parsed as a
- * token before being parsed as an identifier.
- * (2) when an identifier is found that is not a keyword, the lexical parser
- * then looks in the global symbol table, and will not return an identifier
- * if the name has been previously used as a data type name, function name,
- * or function block name! (In these cases it will return a
- * prev_declared_function_name_token, etc...).
- *
- * Unfortunately, the language (especially IL) uses tokens that are
- * not defined as keywords in the spec (e.g. 'IN', 'R1', 'S1', 'PT', etc...)!
- * This means that it is valid to name a function 'IN', a variable 'PT', etc...
- * In order to solve this potential ambiguity, flex only parses the above
- * identifiers as keywords / tokens if we are currently parsing IL code.
- * When parsing all code other than IL code, the above identifiers are treated
- * just like any other identifier.
- *
- *
- *
- *
- * NOTE 2:
- * I (Mario) find it strange that the writers of the spec really want
- * names previously used for function names, data type names or function
- * block names, to become full fledged keywords. I understand that they
- * do not want these names being used as variable names, but how about
- * enumeration values? How about structure element names?
- * If we interpret the spec literally, these would not be accepted,
- * which would probably burden the programmer quite a bit, in making sure
- * all these name don't clash!
- *
- *
- *
- * NOTE 3: The keywords, as specified in Annex C are...
- *
- * - Data type names
- * - Function names
- * - Function Block names
- * - ACTION...END_ACTION
- * - ARRAY...OF
- * - AT
- * - CASE...OF...ELSE...END_CASE
- * - CONFIGURATION...END_CONFIGURATION
- * - CONSTANT
- * - EN, ENO
- * - EXIT
- * - FALSE
- * - F_EDGE
- * - FOR...TO...BY...DO...END_FOR
- * - FUNCTION...END_FUNCTION
- * - FUNCTION_BLOCK...END_FUNCTION_BLOCK
- * - IF...THEN...ELSIF...ELSE...END_IF
- * - INITIAL_STEP...END_STEP
- * - NOT, MOD, AND, XOR, OR
- * - PROGRAM...WITH...
- * - PROGRAM...END_PROGRAM
- * - R_EDGE
- * - READ_ONLY, READ_WRITE
- * - REPEAT...UNTIL...END_REPEAT
- * - RESOURCE...ON...END_RESOURCE
- * - RETAIN, NON_RETAIN
- * - RETURN
- * - STEP...END_STEP
- * - STRUCT...END_STRUCT
- * - TASK
- * - TRANSITION...FROM...TO...END_TRANSITION
- * - TRUE
- * - TYPE...END_TYPE
- * - VAR...END_VAR
- * - VAR_INPUT...END_VAR
- * - VAR_OUTPUT...END_VAR
- * - VAR_IN_OUT...END_VAR
- * - VAR_TEMP...END_VAR
- * - VAR_EXTERNAL...END_VAR
- * - VAR_ACCESS...END_VAR
- * - VAR_CONFIG...END_VAR
- * - VAR_GLOBAL...END_VAR
- * - WHILE...DO...END_WHILE
- * - WITH
- */
-
-identifier:
- identifier_token {$$ = new identifier_c($1, locloc(@$));}
-;
-
-
-
-/*********************/
-/* B 1.2 - Constants */
-/*********************/
-constant:
- numeric_literal
-| character_string
-| time_literal
-| bit_string_literal
-| boolean_literal
-/* NOTE: in order to remove reduce/reduce conflicts,
- * [between -9.5 being parsed as
- * (i) a signed real,
- * (ii) or as a real preceded by the '-' operator
- * ]
- * we need to define a variant of the constant construct
- * where any constant is never preceded by the '-' character.
- * In order to do this, we have borugh the signed_real
- * directly into the definition of the constant construct
- * (so we can define another non_negative_constant
- * construct that does not include it!)
- */
-| signed_real
-/* NOTE: in order to remove reduce/reduce conflicts,
- * unsigned_integer, signed_integer, binary_integer, octal_integer
- * and hex_integer have been integrated directly into
- * the constants construct, instead of belonging to
- * both the bit_string_literal or integer_literal
- * construct.
- */
-/* NOTE: unsigned_integer, although used in some
- * rules, is not defined in the spec!
- * We therefore replaced unsigned_integer as integer
- */
-/*| integer {} */ /* i.e. an unsigned_integer */ /* NOTE: already included as a signed integer! */
-| signed_integer
-| binary_integer
-| octal_integer
-| hex_integer
-;
-
-
-/* NOTE: in order to remove reduce/reduce conflicts,
- * [between -9.5 being parsed as
- * (i) a signed real,
- * (ii) or as a real preceded by the '-' operator
- * ]
- * we need to define a variant of the constant construct
- * where any constant is never preceded by the '-' character.
- * In order to do this, we have borugh the signed_real
- * directly into the definition of the constant construct
- * (so we can define another non_negative_constant
- * construct that does not include it!)
- */
-non_negative_constant:
- numeric_literal
-| character_string
-| time_literal
-| bit_string_literal
-| boolean_literal
-/* NOTE: in order to remove reduce/reduce conflicts,
- * [between -9.5 being parsed as
- * (i) a signed real,
- * (ii) or as a real preceded by the '-' operator
- * ]
- * we need to define a variant of the constant construct
- * where any constant is never preceded by the '-' character.
- * In order to do this, we have borugh the signed_real
- * directly into the definition of the constant construct
- * (so we can define another non_negative_constant
- * construct that does not include it!)
- */
-/* | signed_real */
-| real /* an unsigned real */
-/* NOTE: in order to remove reduce/reduce conflicts,
- * unsigned_integer, signed_integer, binary_integer, octal_integer
- * and hex_integer have been integrated directly into
- * the constants construct, instead of belonging to
- * both the bit_string_literal or integer_literal
- * construct.
- */
-/* NOTE: unsigned_integer, although used in some
- * rules, is not defined in the spec!
- * We therefore replaced unsigned_integer as integer
- */
-| integer /* i.e. an unsigned_integer */
-/* | signed_integer */
-| binary_integer
-| octal_integer
-| hex_integer
-;
-
-
-/******************************/
-/* B 1.2.1 - Numeric Literals */
-/******************************/
-/* NOTES:
- *
- * - integer is parsed by flex, but signed_integer
- * is parsed by bison. Flex cannot parse a signed
- * integer correctly! For example: '123+456'
- * would be parsed by flex as an {integer} {signed_integer}
- * instead of {integer} '+' {integer}
- *
- * - Neither flex nor bison can parse a real_literal
- * completely (and correctly).
- * Note that we cannot use the definition of real in bison as
- * real: signed_integer '.' integer [exponent]
- * exponent: {'E'|'e'} ['+'|'-'] integer
- * because 123e45 would be parsed by flex as
- * integer (123) identifier (e45).
- * I.e., flex never hands over an 'e' directly to
- * bison, but rather interprets it as an identifier.
- * I guess we could jump through hoops and get it
- * working in bison, but the following alternative
- * seems more straight forward...
- *
- * We therefore had to break up the definition of
- * real_literal in discrete parts:
- * real_literal: [real_type_name '#'] singned_real
- * signed_real: ['+'|'-'] real
- * Flex handles real, while bison handles signed_real
- * and real_literal.
- *
- * - According to the spec, integer '.' integer
- * may be reduced to either a real or a fixed_point.
- * It is nevertheless possible to figure out from the
- * context which of the two rules should be used in
- * the reduction.
- * Unfortunately, due to the issue described above
- * regarding the exponent of a real, the syntax
- * integer '.' integer
- * must be parsed by flex as a single token (i.e.
- * fixed_point_token). This means we must add fixed_point
- * to the definition of real!
- *
- * - The syntax also uses a construct
- * fixed_point: integer ['.' integer]
- * Notice that real is not defined based on fixed point,
- * but rather off integer thus:
- * real: integer '.' integer [exponent]
- * This means that a real may not be composed of a single
- * integer, unlike the construct fixed_point!
- * This also means that a
- * integer '.' integer
- * could be reduced to either a real or a fixed_point
- * construct. It is probably possible to decide by looking
- * at the context, BUT:
- * Unfortunatley, due to the reasons explained way above,
- * a real (with an exponent) has to be handled by flex as a
- * whole. This means that we cannot leave to bison (the syntax
- * parser) the decision of how to reduce an
- * integer '.' integer
- * (either to real or to fixed_point)
- * The decision on how to reduce it would need to be done by
- * ther lexical analyser (i.e. flex). But flex cannot do this
- * sort of thing.
- * The solution I (Mario) adopted is to have flex return
- * a real_token on (notice that exponent is no longer optional)
- * integer '.' integer exponent
- * and to return a fixed_point_token when it finds
- * integer '.' integer
- * We now redefine real and fixed_point to be
- * fixed_point: fixed_point_token | integer
- * real: real_token | fixed_point_token
- */
-real:
- real_token {$$ = new real_c($1, locloc(@$));}
-| fixed_point_token {$$ = new real_c($1, locloc(@$));}
-;
-
-integer: integer_token {$$ = new integer_c($1, locloc(@$));};
-binary_integer: binary_integer_token {$$ = new binary_integer_c($1, locloc(@$));};
-octal_integer: octal_integer_token {$$ = new octal_integer_c($1, locloc(@$));};
-hex_integer: hex_integer_token {$$ = new hex_integer_c($1, locloc(@$));};
-
-numeric_literal:
- integer_literal
-| real_literal
-;
-
-
-integer_literal:
- integer_type_name '#' signed_integer
- {$$ = new integer_literal_c($1, $3, locf(@1), locl(@3));}
-| integer_type_name '#' binary_integer
- {$$ = new integer_literal_c($1, $3, locf(@1), locl(@3));}
-| integer_type_name '#' octal_integer
- {$$ = new integer_literal_c($1, $3, locf(@1), locl(@3));}
-| integer_type_name '#' hex_integer
- {$$ = new integer_literal_c($1, $3, locf(@1), locl(@3));}
-/* NOTE: see note in the definition of constant for reason
- * why signed_integer, binary_integer, octal_integer
- * and hex_integer are missing here!
- */
-/* ERROR_CHECK_BEGIN */
-| integer_type_name signed_integer
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "'#' missing between integer type name and value in integer literal."); yynerrs++;}
-| integer_type_name binary_integer
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "'#' missing between integer type name and value in integer literal."); yynerrs++;}
-| integer_type_name octal_integer
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "'#' missing between integer type name and value in integer literal."); yynerrs++;}
-| integer_type_name hex_integer
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "'#' missing between integer type name and value in integer literal."); yynerrs++;}
-| integer_type_name '#' error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no value defined for integer literal.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid value for integer literal."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-signed_integer:
- integer
-| '+' integer {$$ = $2;}
-| '-' integer {$$ = new neg_integer_c($2, locloc(@$));}
-;
-
-
-real_literal:
-/* NOTE: see note in the definition of constant for reason
- * why signed_real is missing here!
- */
-/* signed_real */
- real_type_name '#' signed_real
- {$$ = new real_literal_c($1, $3, locf(@1), locl(@3));}
-/* ERROR_CHECK_BEGIN */
-| real_type_name signed_real
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "'#' missing between real type name and value in real literal."); yynerrs++;}
-| real_type_name '#' error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no value defined for real literal.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid value for real literal."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-signed_real:
- real
-| '+' real {$$ = $2;}
-| '-' real {$$ = new neg_real_c($2, locloc(@2));}
-;
-
-
-
-bit_string_literal:
- bit_string_type_name '#' integer /* i.e. unsigned_integer */
- {$$ = new bit_string_literal_c($1, $3, locf(@1), locl(@3));}
-| bit_string_type_name '#' binary_integer
- {$$ = new bit_string_literal_c($1, $3, locf(@1), locl(@3));}
-| bit_string_type_name '#' octal_integer
- {$$ = new bit_string_literal_c($1, $3, locf(@1), locl(@3));}
-| bit_string_type_name '#' hex_integer
- {$$ = new bit_string_literal_c($1, $3, locf(@1), locl(@3));}
-/* NOTE: see note in the definition of constant for reason
- * why unsigned_integer, binary_integer, octal_integer
- * and hex_integer are missing here!
- */
-/* NOTE: see note under the B 1.2.1 section of token
- * and grouping type definition for reason why the use of
- * bit_string_type_name, although seemingly incorrect, is
- * really correct here!
- */
-/* ERROR_CHECK_BEGIN */
-| bit_string_type_name integer
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "'#' missing between bit string type name and value in bit string literal."); yynerrs++;}
-| bit_string_type_name binary_integer
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "'#' missing between bit string type name and value in bit string literal."); yynerrs++;}
-| bit_string_type_name octal_integer
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "'#' missing between bit string type name and value in bit string literal."); yynerrs++;}
-| bit_string_type_name hex_integer
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "'#' missing between bit string type name and value in bit string literal."); yynerrs++;}
-| bit_string_type_name '#' error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no value defined for bit string literal.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid value for bit string literal."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-boolean_literal:
- boolean_true_literal_token
- {$$ = new boolean_literal_c(new bool_type_name_c(locloc(@$)),
- new boolean_true_c(locloc(@$)),
- locloc(@$));
- }
-| boolean_false_literal_token
- {$$ = new boolean_literal_c(new bool_type_name_c(locloc(@$)),
- new boolean_false_c(locloc(@$)),
- locloc(@$));
- }
-| safeboolean_true_literal_token
- {$$ = new boolean_literal_c(new safebool_type_name_c(locloc(@$)),
- new boolean_true_c(locloc(@$)),
- locloc(@$));
- }
-| safeboolean_false_literal_token
- {$$ = new boolean_literal_c(new safebool_type_name_c(locloc(@$)),
- new boolean_false_c(locloc(@$)),
- locloc(@$));
- }
-| FALSE
- {$$ = new boolean_literal_c(NULL,
- new boolean_false_c(locloc(@$)),
- locloc(@$));
- }
-| TRUE
- {$$ = new boolean_literal_c(NULL,
- new boolean_true_c(locloc(@$)),
- locloc(@$));
- }
-/*
-| BOOL '#' '1' {}
-| BOOL '#' '0' {}
-*/
-/* NOTE: the rules
- * BOOL '#' '1'
- * and
- * BOOL '#' '0'
- * do not work as expected...
- * Consider that we are using 'BOOL' and '#' as tokens
- * that flex hands over to bison (yacc). Because flex would
- * then parse the single '1' or '0' as an integer,
- * the rule in bison would have to be
- * BOOL '#' integer, followed by verifying of the
- * integer has the correct value!
- *
- * We therefore have flex return TRUE whenever it
- * comes across 'TRUE' or 'BOOL#1', and FALSE whenever
- * it comes across 'FALSE' or 'BOOL#0'.
- * Note that this means that flex will parse "BOOL#01"
- * as FALSE followed by an integer ('1').
- * Bison should detect this as an error, so we should
- * be OK.
- *
- * Another option would be to change the rules to accept
- * BOOL '#' integer
- * but then check whether the integer has a correct
- * value! At the moment I feel that the first option
- * is more straight forward.
- */
-;
-
-
-
-/*******************************/
-/* B 1.2.2 - Character Strings */
-/*******************************/
-/* Transform the tokens given us by flex into leafs */
-single_byte_character_string: single_byte_character_string_token
- {$$ = new single_byte_character_string_c($1, locloc(@$));};
-
-double_byte_character_string: double_byte_character_string_token
- {$$ = new double_byte_character_string_c($1, locloc(@$));};
-
-
-character_string:
- single_byte_character_string
-| double_byte_character_string
-;
-
-
-
-
-
-/***************************/
-/* B 1.2.3 - Time Literals */
-/***************************/
-time_literal:
- time_of_day
-| date
-| date_and_time
-| duration
-;
-
-
-/************************/
-/* B 1.2.3.1 - Duration */
-/************************/
-duration:
-/* (T | TIME) '#' ['-'] interval */
-/* NOTE: since TIME is also a data type, it is a keyword
- * and may therefore be handled by a token.
- *
- * Unfortunately T is not a data type, and therefore
- * not a keyword. This means that we may have variables named T!
- * Flex cannot return the token TIME when it comes across a single T!
- *
- * We therefore have flex returning the token T_SHARP
- * when it comes across 'T#'
- */
- TIME '#' interval
- {$$ = new duration_c(new time_type_name_c(locloc(@1)), NULL, $3, locloc(@$));}
-| TIME '#' '-' interval
- {$$ = new duration_c(new time_type_name_c(locloc(@1)), new neg_time_c(locloc(@$)), $4, locloc(@$));}
-| T_SHARP interval
- {$$ = new duration_c(new time_type_name_c(locloc(@1)), NULL, $2, locloc(@$));}
-| T_SHARP '-' interval
- {$$ = new duration_c(new time_type_name_c(locloc(@1)), new neg_time_c(locloc(@$)), $3, locloc(@$));}
-| SAFETIME '#' interval
- {$$ = new duration_c(new safetime_type_name_c(locloc(@1)), NULL, $3, locloc(@$));}
-| SAFETIME '#' '-' interval
- {$$ = new duration_c(new safetime_type_name_c(locloc(@1)), new neg_time_c(locloc(@$)), $4, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| TIME interval
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "'#' missing between 'TIME' and interval in duration."); yynerrs++;}
-| TIME '-' interval
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "'#' missing between 'TIME' and interval in duration."); yynerrs++;}
-| TIME '#' error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no value defined for duration.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid value for duration."); yyclearin;}
- yyerrok;
- }
-| T_SHARP error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@1), locf(@2), "no value defined for duration.");}
- else {print_err_msg(locf(@2), locl(@2), "invalid value for duration."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-interval:
- days
-| hours
-| minutes
-| seconds
-| milliseconds
-;
-
-integer_d: integer_d_token {$$ = new integer_c($1, locloc(@$));};
-integer_h: integer_h_token {$$ = new integer_c($1, locloc(@$));};
-integer_m: integer_m_token {$$ = new integer_c($1, locloc(@$));};
-integer_s: integer_s_token {$$ = new integer_c($1, locloc(@$));};
-integer_ms: integer_ms_token {$$ = new integer_c($1, locloc(@$));};
-
-fixed_point_d:
- fixed_point_d_token
- {$$ = new fixed_point_c($1, locloc(@$));}
-| integer_d
-;
-
-fixed_point_h:
- fixed_point_h_token
- {$$ = new fixed_point_c($1, locloc(@$));}
-| integer_h
-;
-
-fixed_point_m:
- fixed_point_m_token
- {$$ = new fixed_point_c($1, locloc(@$));}
-| integer_m
-;
-
-fixed_point_s:
- fixed_point_s_token
- {$$ = new fixed_point_c($1, locloc(@$));}
-| integer_s
-;
-
-fixed_point_ms:
- fixed_point_ms_token
- {$$ = new fixed_point_c($1, locloc(@$));}
-| integer_ms
-;
-
-
-fixed_point:
- fixed_point_token
- {$$ = new fixed_point_c($1, locloc(@$));}
-| integer
-;
-
-
-days:
-/* fixed_point ('d') */
- fixed_point_d
- {$$ = new days_c($1, NULL, locloc(@$));}
-/*| integer ('d') ['_'] hours */
-| integer_d hours
- {$$ = new days_c($1, $2, locloc(@$));}
-| integer_d '_' hours
- {$$ = new days_c($1, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| integer_d '_' error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no value defined for hours in duration.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid value for hours in duration."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-hours:
-/* fixed_point ('h') */
- fixed_point_h
- {$$ = new hours_c($1, NULL, locloc(@$));}
-/*| integer ('h') ['_'] minutes */
-| integer_h minutes
- {$$ = new hours_c($1, $2, locloc(@$));}
-| integer_h '_' minutes
- {$$ = new hours_c($1, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| integer_h '_' error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no value defined for minutes in duration.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid value for minutes in duration."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-
-;
-
-minutes:
-/* fixed_point ('m') */
- fixed_point_m
- {$$ = new minutes_c($1, NULL, locloc(@$));}
-/*| integer ('m') ['_'] seconds */
-| integer_m seconds
- {$$ = new minutes_c($1, $2, locloc(@$));}
-| integer_m '_' seconds
- {$$ = new minutes_c($1, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| integer_m '_' error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no value defined for seconds in duration.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid value for seconds in duration."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-seconds:
-/* fixed_point ('s') */
- fixed_point_s
- {$$ = new seconds_c($1, NULL, locloc(@$));}
-/*| integer ('s') ['_'] milliseconds */
-| integer_s milliseconds
- {$$ = new seconds_c($1, $2, locloc(@$));}
-| integer_s '_' milliseconds
- {$$ = new seconds_c($1, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| integer_s '_' error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no value defined for milliseconds in duration.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid value for milliseconds in duration."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-milliseconds:
-/* fixed_point ('ms') */
- fixed_point_ms
- {$$ = new milliseconds_c($1, locloc(@$));}
-;
-
-
-
-/************************************/
-/* B 1.2.3.2 - Time of day and Date */
-/************************************/
-time_of_day:
- TIME_OF_DAY '#' daytime
- {$$ = new time_of_day_c(new tod_type_name_c(locloc(@1)), $3, locloc(@$));}
-| SAFETIME_OF_DAY '#' daytime
- {$$ = new time_of_day_c(new safetod_type_name_c(locloc(@1)), $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| TIME_OF_DAY daytime
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "'#' missing between 'TIME_OF_DAY' and daytime in time of day."); yynerrs++;}
-| TIME_OF_DAY '#' error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no value defined for time of day.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid value for time of day."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-daytime:
- day_hour ':' day_minute ':' day_second
- {$$ = new daytime_c($1, $3, $5, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| ':' day_minute ':' day_second
- {$$ = NULL; print_err_msg(locf(@1), locl(@4), "no value defined for hours in daytime."); yynerrs++;}
-| error ':' day_minute ':' day_second
- {$$ = NULL; print_err_msg(locf(@1), locl(@1), "invalid value defined for hours in daytime."); yyerrok;}
-| day_hour day_minute ':' day_second
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between hours and minutes in daytime."); yynerrs++;}
-| day_hour ':' ':' day_second
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "no value defined for minutes in daytime."); yynerrs++;}
-| day_hour ':' error ':' day_second
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid value defined for minutes in daytime."); yyerrok;}
-| day_hour ':' day_minute day_second
- {$$ = NULL; print_err_msg(locl(@3), locf(@4), "':' missing between minutes and seconds in daytime."); yynerrs++;}
-| day_hour ':' day_minute ':' error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@4), locf(@5), "no value defined for seconds in daytime.");}
- else {print_err_msg(locf(@5), locl(@5), "invalid value for seconds in daytime."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-day_hour: integer;
-day_minute: integer;
-day_second: fixed_point;
-
-
-date:
- DATE '#' date_literal
- {$$ = new date_c(new date_type_name_c(locloc(@1)), $3, locloc(@$));}
-| D_SHARP date_literal
- {$$ = new date_c(new date_type_name_c(locloc(@1)), $2, locloc(@$));}
-| SAFEDATE '#' date_literal
- {$$ = new date_c(new safedate_type_name_c(locloc(@1)), $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| DATE date_literal
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "'#' missing between 'DATE' and date literal in date."); yynerrs++;}
-| DATE '#' error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no value defined for date.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid value for date."); yyclearin;}
- yyerrok;
- }
-| D_SHARP error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@1), locf(@2), "no value defined for date.");}
- else {print_err_msg(locf(@2), locl(@2), "invalid value for date."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-date_literal:
- year '-' month '-' day
- {$$ = new date_literal_c($1, $3, $5, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| '-' month '-' day
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no value defined for year in date literal."); yynerrs++;}
-| year month '-' day
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "'-' missing between year and month in date literal."); yynerrs++;}
-| year '-' '-' day
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "no value defined for month in date literal."); yynerrs++;}
-| year '-' error '-' day
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid value defined for month in date literal."); yyerrok;}
-| year '-' month day
- {$$ = NULL; print_err_msg(locl(@3), locf(@4), "'-' missing between month and day in date literal."); yynerrs++;}
-| year '-' month '-' error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@4), locf(@5), "no value defined for day in date literal.");}
- else {print_err_msg(locf(@5), locl(@5), "invalid value for day in date literal."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-year: integer;
-month: integer;
-day: integer;
-
-
-date_and_time:
- DATE_AND_TIME '#' date_literal '-' daytime
- {$$ = new date_and_time_c(new dt_type_name_c(locloc(@1)), $3, $5, locloc(@$));}
-| SAFEDATE_AND_TIME '#' date_literal '-' daytime
- {$$ = new date_and_time_c(new safedt_type_name_c(locloc(@1)), $3, $5, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| DATE_AND_TIME date_literal '-' daytime
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "'#' missing between 'DATE_AND_TIME' and date literal in date and time."); yynerrs++;}
-| DATE_AND_TIME '#' '-' daytime
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "no value defined for date literal in date and time."); yynerrs++;}
-| DATE_AND_TIME '#' error '-' daytime
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid value for date literal in date and time."); yyerrok;}
-| DATE_AND_TIME '#' date_literal daytime
- {$$ = NULL; print_err_msg(locl(@3), locf(@4), "'-' missing between date literal and daytime in date and time."); yynerrs++;}
-| DATE_AND_TIME '#' date_literal '-' error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@4), locf(@5), "no value defined for daytime in date and time.");}
- else {print_err_msg(locf(@5), locl(@5), "invalid value for daytime in date and time."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-
-
-
-
-/**********************/
-/* B 1.3 - Data Types */
-/**********************/
-/* Strangely, the following symbol does seem to be required! */
-/*
-data_type_name:
- non_generic_type_name
-| generic_type_name
-;
-*/
-
-non_generic_type_name:
- elementary_type_name
-| derived_type_name
-;
-
-
-
-/***********************************/
-/* B 1.3.1 - Elementary Data Types */
-/***********************************/
- /******************************************************/
- /* SAFExxxx Symbols defined in */
- /* "Safety Software Technical Specification, */
- /* Part 1: Concepts and Function Blocks, */
- /* Version 1.0 – Official Release" */
- /* by PLCopen - Technical Committee 5 - 2006-01-31 */
- /******************************************************/
-
-elementary_type_name:
- numeric_type_name
-| date_type_name
-| bit_string_type_name
-| elementary_string_type_name
-| TIME {$$ = new time_type_name_c(locloc(@$));}
-| BOOL {$$ = new bool_type_name_c(locloc(@$));}
-/* NOTE: see note under the B 1.2.1 section of token
- * and grouping type definition for reason why BOOL
- * was added to this definition.
- */
-| SAFETIME {$$ = new safetime_type_name_c(locloc(@$));}
-| SAFEBOOL {$$ = new safebool_type_name_c(locloc(@$));}
-;
-
-numeric_type_name:
- integer_type_name
-| real_type_name
-;
-
-integer_type_name:
- signed_integer_type_name
-| unsigned_integer_type_name
-;
-
-signed_integer_type_name:
- SINT {$$ = new sint_type_name_c(locloc(@$));}
-| INT {$$ = new int_type_name_c(locloc(@$));}
-| DINT {$$ = new dint_type_name_c(locloc(@$));}
-| LINT {$$ = new lint_type_name_c(locloc(@$));}
-| SAFESINT {$$ = new safesint_type_name_c(locloc(@$));}
-| SAFEINT {$$ = new safeint_type_name_c(locloc(@$));}
-| SAFEDINT {$$ = new safedint_type_name_c(locloc(@$));}
-| SAFELINT {$$ = new safelint_type_name_c(locloc(@$));}
-;
-
-unsigned_integer_type_name:
- USINT {$$ = new usint_type_name_c(locloc(@$));}
-| UINT {$$ = new uint_type_name_c(locloc(@$));}
-| UDINT {$$ = new udint_type_name_c(locloc(@$));}
-| ULINT {$$ = new ulint_type_name_c(locloc(@$));}
-| SAFEUSINT {$$ = new safeusint_type_name_c(locloc(@$));}
-| SAFEUINT {$$ = new safeuint_type_name_c(locloc(@$));}
-| SAFEUDINT {$$ = new safeudint_type_name_c(locloc(@$));}
-| SAFEULINT {$$ = new safeulint_type_name_c(locloc(@$));}
-;
-
-real_type_name:
- REAL {$$ = new real_type_name_c(locloc(@$));}
-| LREAL {$$ = new lreal_type_name_c(locloc(@$));}
-| SAFEREAL {$$ = new safereal_type_name_c(locloc(@$));}
-| SAFELREAL {$$ = new safelreal_type_name_c(locloc(@$));}
-;
-
-date_type_name:
- DATE {$$ = new date_type_name_c(locloc(@$));}
-| TIME_OF_DAY {$$ = new tod_type_name_c(locloc(@$));}
-| TOD {$$ = new tod_type_name_c(locloc(@$));}
-| DATE_AND_TIME {$$ = new dt_type_name_c(locloc(@$));}
-| DT {$$ = new dt_type_name_c(locloc(@$));}
-| SAFEDATE {$$ = new safedate_type_name_c(locloc(@$));}
-| SAFETIME_OF_DAY {$$ = new safetod_type_name_c(locloc(@$));}
-| SAFETOD {$$ = new safetod_type_name_c(locloc(@$));}
-| SAFEDATE_AND_TIME {$$ = new safedt_type_name_c(locloc(@$));}
-| SAFEDT {$$ = new safedt_type_name_c(locloc(@$));}
-;
-
-
-bit_string_type_name:
- BYTE {$$ = new byte_type_name_c(locloc(@$));}
-| WORD {$$ = new word_type_name_c(locloc(@$));}
-| DWORD {$$ = new dword_type_name_c(locloc(@$));}
-| LWORD {$$ = new lword_type_name_c(locloc(@$));}
-| SAFEBYTE {$$ = new safebyte_type_name_c(locloc(@$));}
-| SAFEWORD {$$ = new safeword_type_name_c(locloc(@$));}
-| SAFEDWORD {$$ = new safedword_type_name_c(locloc(@$));}
-| SAFELWORD {$$ = new safelword_type_name_c(locloc(@$));}
-/* NOTE: see note under the B 1.2.1 section of token
- * and grouping type definition for reason why the BOOL
- * was omitted from this definition.
- */
-;
-
-
-/* Helper symbol to concentrate the instantiation
- * of STRING and WSTRING into a single location.
- *
- * These two elements show up in several other rules,
- * but we want to create the equivalent abstract syntax
- * in a single location of this file, in order to make
- * possible future changes easier to edit...
- */
-elementary_string_type_name:
- STRING {$$ = new string_type_name_c(locloc(@$));}
-| WSTRING {$$ = new wstring_type_name_c(locloc(@$));}
-| SAFESTRING {$$ = new safestring_type_name_c(locloc(@$));}
-| SAFEWSTRING {$$ = new safewstring_type_name_c(locloc(@$));}
-;
-
-
-
-/********************************/
-/* B 1.3.2 - Generic data types */
-/********************************/
-/* Strangely, the following symbol does not seem to be required! */
-/*
-generic_type_name:
- ANY
-| ANY_DERIVED
-| ANY_ELEMENTARY
-| ANY_MAGNITUDE
-| ANY_NUM
-| ANY_REAL
-| ANY_INT
-| ANY_BIT
-| ANY_STRING
-| ANY_DATE
-;
-*/
-
-
-/********************************/
-/* B 1.3.3 - Derived data types */
-/********************************/
-
-derived_type_name:
- single_element_type_name
-| prev_declared_array_type_name
-| prev_declared_structure_type_name
-| prev_declared_string_type_name
-;
-
-single_element_type_name:
- prev_declared_simple_type_name
-/* Include the following if arrays of function blocks are to be allowed!
- * Since the standard does not allow them,
- * we leave it commented out for the time being...
- */
-//| prev_declared_derived_function_block_name
-| prev_declared_subrange_type_name
-| prev_declared_enumerated_type_name
-;
-
-/* NOTE: in order to remove a reduce/reduce conflict,
- * all occurences of simple_type_name, etc...
- * have been replaced with identifier!
- */
-/*
-simple_type_name: identifier;
-subrange_type_name: identifier;
-enumerated_type_name: identifier;
-array_type_name: identifier;
-structure_type_name: identifier;
-*/
-
-data_type_declaration:
- TYPE type_declaration_list END_TYPE
- {$$ = new data_type_declaration_c($2, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| TYPE END_TYPE
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no data type declared in data type(s) declaration."); yynerrs++;}
-| TYPE error type_declaration_list END_TYPE
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unexpected token after 'TYPE' in data type(s) declaration."); yyerrok;}
-| TYPE type_declaration_list error END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed data type(s) declaration."); yyerrok;}
-| TYPE error END_TYPE
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in data type(s) declaration."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-/* helper symbol for data_type_declaration */
-type_declaration_list:
- type_declaration ';'
- {$$ = new type_declaration_list_c(locloc(@$)); $$->add_element($1);}
-| type_declaration_list type_declaration ';'
- {$$ = $1; $$->add_element($2);}
-/* ERROR_CHECK_BEGIN */
-| error ';'
- {$$ = new type_declaration_list_c(locloc(@$)); print_err_msg(locf(@1), locl(@1), "invalid data type declaration."); yyerrok;}
-| type_declaration error
- {$$ = new type_declaration_list_c(locloc(@$)); print_err_msg(locl(@1), locf(@2), "';' missing at end of data type declaration."); yyerrok;}
-| type_declaration_list type_declaration error
- {$$ = $1; print_err_msg(locl(@2), locf(@3), "';' missing at end of data type declaration."); yyerrok;}
-| type_declaration_list error ';'
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "invalid data type declaration."); yyerrok;}
-| type_declaration_list ';'
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected ';' after data type declaration."); yynerrs++;}
-/* ERROR_CHECK_END */
-;
-
-type_declaration:
- single_element_type_declaration
-| array_type_declaration
-| structure_type_declaration
-| string_type_declaration
-;
-
-single_element_type_declaration:
- simple_type_declaration
-| subrange_type_declaration
-| enumerated_type_declaration
-;
-
-simple_type_declaration:
-/* simple_type_name ':' simple_spec_init */
- identifier ':' simple_spec_init
- {$$ = new simple_type_declaration_c($1, $3, locloc(@$));
- library_element_symtable.insert($1, prev_declared_simple_type_name_token);
- }
-/* ERROR_CHECK_BEGIN */
-| error ':' simple_spec_init
- {$$ = NULL; print_err_msg(locf(@1), locl(@1), "invalid name defined for data type declaration.");yyerrok;}
-| identifier simple_spec_init
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between data type name and specification in simple type declaration."); yynerrs++;}
-| identifier ':' error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no specification defined in data type declaration.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid specification in data type declaration."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-simple_spec_init:
- simple_specification
- /* The following commented line was changed to the
- * next two lines so that we wouldn't
- * have the first element of a simple_spec_init_c()
- * pointing to another simple_spec_init_c!
- */
-/*
-| simple_specification ASSIGN constant
- {$$ = new simple_spec_init_c($1, $3);}
-*/
-| elementary_type_name ASSIGN constant
- {$$ = new simple_spec_init_c($1, $3, locloc(@$));}
-| prev_declared_simple_type_name ASSIGN constant
- {$$ = new simple_spec_init_c($1, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| elementary_type_name constant
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':=' missing in specification with initialization."); yynerrs++;}
-| prev_declared_simple_type_name constant
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':=' missing in specification with initialization."); yynerrs++;}
-| elementary_type_name ASSIGN error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no initial value defined in specification with initialization.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid initial value in specification with initialization."); yyclearin;}
- yyerrok;
- }
-| prev_declared_simple_type_name ASSIGN error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no initial value defined in specification with initialization.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid initial value in specification with initialization."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-/* When converting to C/C++, we need to know whether
- * the elementary_type_name is being used in a variable
- * declaration or elsewhere (ex. declaration of a derived
- * type), so the abstract syntax has the elementary_type_name
- * wrapped inside a simple_spec_init_c.
- * The exact same thing occurs with prev_declared_simple_type_name.
- *
- * This is why in the definition of simple_spec_init,
- * simple_specification was brocken up into its
- * constituent components...
- */
-simple_specification:
-// elementary_type_name | simple_type_name
- elementary_type_name
- {$$ = new simple_spec_init_c($1, NULL, locloc(@$));}
-| prev_declared_simple_type_name
- {$$ = new simple_spec_init_c($1, NULL, locloc(@$));}
-;
-
-
-subrange_type_declaration:
-/* subrange_type_name ':' subrange_spec_init */
- identifier ':' subrange_spec_init
- {$$ = new subrange_type_declaration_c($1, $3, locloc(@$));
- library_element_symtable.insert($1, prev_declared_subrange_type_name_token);
- }
-/* ERROR_CHECK_BEGIN */
-| error ':' subrange_spec_init
- {$$ = NULL; print_err_msg(locf(@1), locl(@1), "invalid name defined for subrange type declaration."); yyerrok;}
-| identifier subrange_spec_init
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between data type name and specification in subrange type declaration."); yynerrs++;}
-/* ERROR_CHECK_END */
-;
-
-subrange_spec_init:
- subrange_specification
- {$$ = new subrange_spec_init_c($1, NULL, locloc(@$));}
-| subrange_specification ASSIGN signed_integer
- {$$ = new subrange_spec_init_c($1, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| subrange_specification signed_integer
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':=' missing in subrange specification with initialization."); yynerrs++;}
-| subrange_specification ASSIGN error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no initial value defined in subrange specification with initialization.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid initial value in subrange specification with initialization."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-subrange_specification:
- integer_type_name '(' subrange ')'
- {$$ = new subrange_specification_c($1, $3, locloc(@$));}
-| prev_declared_subrange_type_name
- {$$ = new subrange_specification_c($1, NULL, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| integer_type_name '(' ')'
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "no subrange defined in subrange specification."); yynerrs++;}
-| integer_type_name '(' error ')'
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid subrange defined in subrange specification."); yyerrok;}
-| integer_type_name '(' subrange error
- {$$ = NULL; print_err_msg(locl(@3), locf(@4), "')' missing after subrange defined in subrange specification."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-subrange:
- signed_integer DOTDOT signed_integer
- {$$ = new subrange_c($1, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| signed_integer signed_integer
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "'..' missing between bounds in subrange definition."); yynerrs++;}
-| signed_integer DOTDOT error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no value defined for upper bound in subrange definition.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid value for upper bound in subrange definition."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-enumerated_type_declaration:
-/* enumerated_type_name ':' enumerated_spec_init */
- identifier ':' enumerated_spec_init
- {$$ = new enumerated_type_declaration_c($1, $3, locloc(@$));
- library_element_symtable.insert($1, prev_declared_enumerated_type_name_token);
- }
-/* ERROR_CHECK_BEGIN */
-| error ':' enumerated_spec_init
- {$$ = NULL; print_err_msg(locf(@1), locl(@1), "invalid name defined for enumerated type declaration."); yyerrok;}
-| identifier enumerated_spec_init
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between data type name and specification in enumerated type declaration."); yynerrs++;}
-/* ERROR_CHECK_END */
-;
-
-
-enumerated_spec_init:
- enumerated_specification
- {$$ = new enumerated_spec_init_c($1, NULL, locloc(@$));}
-| enumerated_specification ASSIGN enumerated_value
- {$$ = new enumerated_spec_init_c($1, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| enumerated_specification enumerated_value
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':=' missing in enumerated specification with initialization."); yynerrs++;}
-| enumerated_specification ASSIGN error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no value defined in enumerated specification with initialization.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid value in enumerated specification with initialization."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-enumerated_specification:
- '(' enumerated_value_list ')'
- {$$ = $2;}
-| prev_declared_enumerated_type_name
-/* ERROR_CHECK_BEGIN */
-| '(' ')'
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no enumerated value list defined in enumerated specification."); yynerrs++;}
-| '(' error ')'
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid enumerated value list defined in enumerated specification.");yyerrok;}
-| '(' enumerated_value_list error
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "')' missing at the end of enumerated specification."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-/* helper symbol for enumerated_specification */
-enumerated_value_list:
- enumerated_value
- {$$ = new enumerated_value_list_c(locloc(@$)); $$->add_element($1);}
-| enumerated_value_list ',' enumerated_value
- {$$ = $1; $$->add_element($3);}
-/* ERROR_CHECK_BEGIN */
-| enumerated_value_list enumerated_value
- {$$ = $1; print_err_msg(locl(@1), locf(@2), "',' missing in enumerated value list.");}
-| enumerated_value_list ',' error
- {$$ = $1;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no value defined in enumerated value list.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid value in enumerated value list."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-enumerated_value:
- identifier
- {$$ = new enumerated_value_c(NULL, $1, locloc(@$));}
-| prev_declared_enumerated_type_name '#' any_identifier
- {$$ = new enumerated_value_c($1, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| prev_declared_enumerated_type_name any_identifier
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "'#' missing between enumerated type name and value in enumerated literal."); yynerrs++;}
-| prev_declared_enumerated_type_name '#' error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no value defined for enumerated literal.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid value for enumerated literal."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-/*
-enumerated_value_without_identifier:
- prev_declared_enumerated_type_name '#' any_identifier
- {$$ = new enumerated_value_c($1, $3, locloc(@$));}
-;
-*/
-
-
-array_type_declaration:
-/* array_type_name ':' array_spec_init */
- identifier ':' array_spec_init
- {$$ = new array_type_declaration_c($1, $3, locloc(@$));
- library_element_symtable.insert($1, prev_declared_array_type_name_token);
- }
-/* ERROR_CHECK_BEGIN */
-| identifier array_spec_init
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between data type name and specification in array type declaration."); yynerrs++;}
-/* ERROR_CHECK_END */
-;
-
-array_spec_init:
- array_specification
- {$$ = new array_spec_init_c($1, NULL, locloc(@$));}
-| array_specification ASSIGN array_initialization
- {$$ = new array_spec_init_c($1, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| array_specification array_initialization
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':=' missing in array specification with initialization."); yynerrs++;}
-| array_specification ASSIGN error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no initial value defined in array specification with initialization.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid initial value in array specification with initialization."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-array_specification:
- prev_declared_array_type_name
-| ARRAY '[' array_subrange_list ']' OF non_generic_type_name
- {$$ = new array_specification_c($3, $6, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| ARRAY array_subrange_list ']' OF non_generic_type_name
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "'[' missing before subrange list in array specification."); yynerrs++;}
-| ARRAY '[' ']' OF non_generic_type_name
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "no subrange list defined in array specification."); yynerrs++;}
-| ARRAY '[' error ']' OF non_generic_type_name
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid subrange list defined in array specification."); yyerrok;}
-| ARRAY OF non_generic_type_name
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no subrange list defined in array specification."); yynerrs++;}
-| ARRAY error OF non_generic_type_name
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid subrange list defined in array specification."); yyerrok;}
-| ARRAY '[' array_subrange_list OF non_generic_type_name
- {$$ = NULL; print_err_msg(locl(@3), locf(@4), "']' missing after subrange list in array specification."); yynerrs++;}
-| ARRAY '[' array_subrange_list ']' non_generic_type_name
- {$$ = NULL; print_err_msg(locl(@4), locf(@5), "'OF' missing between subrange list and item type name in array specification."); yynerrs++;}
-| ARRAY '[' array_subrange_list ']' OF error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no item data type defined in array specification.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid item data type in array specification."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-/* helper symbol for array_specification */
-array_subrange_list:
- subrange
- {$$ = new array_subrange_list_c(locloc(@$)); $$->add_element($1);}
-| array_subrange_list ',' subrange
- {$$ = $1; $$->add_element($3);}
-/* ERROR_CHECK_BEGIN */
-| array_subrange_list subrange
- {$$ = $1; print_err_msg(locl(@1), locf(@2), "',' missing in subrange list."); yynerrs++;}
-| array_subrange_list ',' error
- {$$ = $1;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no subrange defined in subrange list.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid subrange in subrange list."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-array_initialization:
- '[' array_initial_elements_list ']'
- {$$ = $2;}
-/* ERROR_CHECK_BEGIN */
-| '[' ']'
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no initial values list defined in array initialization."); yynerrs++;}
-| '[' error ']'
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid initial values list defined in array initialization."); yyerrok;}
-| '[' array_initial_elements_list error
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "']' missing at the end of array initialization."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-/* helper symbol for array_initialization */
-array_initial_elements_list:
- array_initial_elements
- {$$ = new array_initial_elements_list_c(locloc(@$)); $$->add_element($1);}
-| array_initial_elements_list ',' array_initial_elements
- {$$ = $1; $$->add_element($3);}
-/* ERROR_CHECK_BEGIN
-| array_initial_elements_list ',' error
- {$$ = $1;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no array initial value in array initial values list.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid array initial value in array initial values list."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-array_initial_elements:
- array_initial_element
-| integer '(' ')'
-| integer '(' array_initial_element ')'
- {$$ = new array_initial_elements_c($1, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| integer '(' error ')'
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid array initial value in array initial values list."); yyerrok;}
-| integer '(' array_initial_element error
- {$$ = NULL; print_err_msg(locl(@3), locf(@4), "')' missing at the end of array initial value in array initial values list."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-array_initial_element:
- constant
-| enumerated_value
-| structure_initialization
-| array_initialization
-;
-
-
-
-structure_type_declaration:
-/* structure_type_name ':' structure_specification */
- identifier ':' structure_specification
- {$$ = new structure_type_declaration_c($1, $3, locloc(@$));
- library_element_symtable.insert($1, prev_declared_structure_type_name_token);
- }
-/* ERROR_CHECK_BEGIN */
-| identifier structure_specification
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between data type name and specification in structure type declaration."); yynerrs++;}
-/* ERROR_CHECK_END */
-;
-
-
-structure_specification:
- structure_declaration
-| initialized_structure
-;
-
-
-initialized_structure:
- prev_declared_structure_type_name
- {$$ = new initialized_structure_c($1, NULL, locloc(@$));}
-| prev_declared_structure_type_name ASSIGN structure_initialization
- {$$ = new initialized_structure_c($1, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| prev_declared_structure_type_name structure_initialization
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':=' missing in structure specification with initialization."); yynerrs++;}
-| prev_declared_structure_type_name ASSIGN error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no value defined in structure specification with initialization.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid value in structure specification with initialization."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-structure_declaration:
- STRUCT structure_element_declaration_list END_STRUCT
- {$$ = $2;}
-/* ERROR_CHECK_BEGIN */
-| STRUCT END_STRUCT
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no structure element declared in structure type declaration."); yynerrs++;}
-| STRUCT error structure_element_declaration_list END_STRUCT
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unexpected token after 'STRUCT' in structure type declaration."); yyerrok;}
-| STRUCT structure_element_declaration_list error END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed structure type declaration."); yyerrok;}
-| STRUCT error END_STRUCT
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in structure type declaration."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-/* helper symbol for structure_declaration */
-structure_element_declaration_list:
- structure_element_declaration ';'
- {$$ = new structure_element_declaration_list_c(locloc(@$)); $$->add_element($1);}
-| structure_element_declaration_list structure_element_declaration ';'
- {$$ = $1; $$->add_element($2);}
-/* ERROR_CHECK_BEGIN */
-| error ';'
- {$$ = new structure_element_declaration_list_c(locloc(@$)); print_err_msg(locf(@1), locl(@1), "invalid structure element declaration."); yyerrok;}
-| structure_element_declaration error
- {$$ = new structure_element_declaration_list_c(locloc(@$)); print_err_msg(locl(@1), locf(@2), "';' missing at end of structure element declaration."); yyerrok;}
-| structure_element_declaration_list structure_element_declaration error
- {$$ = $1; print_err_msg(locl(@2), locf(@3), "';' missing at end of structure element declaration."); yyerrok;}
-| structure_element_declaration_list error ';'
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "invalid structure element declaration."); yyerrok;}
-| structure_element_declaration_list ';'
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected ';' after structure element declaration."); yynerrs++;}
-/* ERROR_CHECK_END */
-;
-
-
-structure_element_declaration:
- structure_element_name ':' simple_spec_init
- {$$ = new structure_element_declaration_c($1, $3, locloc(@$));}
-| structure_element_name ':' subrange_spec_init
- {$$ = new structure_element_declaration_c($1, $3, locloc(@$));}
-| structure_element_name ':' enumerated_spec_init
- {$$ = new structure_element_declaration_c($1, $3, locloc(@$));}
-| structure_element_name ':' array_spec_init
- {$$ = new structure_element_declaration_c($1, $3, locloc(@$));}
-| structure_element_name ':' initialized_structure
- {$$ = new structure_element_declaration_c($1, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| structure_element_name simple_spec_init
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between structure element name and simple specification."); yynerrs++;}
-| structure_element_name subrange_spec_init
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between structure element name and subrange specification."); yynerrs++;}
-| structure_element_name enumerated_spec_init
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between structure element name and enumerated specification."); yynerrs++;}
-| structure_element_name array_spec_init
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between structure element name and array specification."); yynerrs++;}
-| structure_element_name initialized_structure
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between structure element name and structure specification."); yynerrs++;}
-| structure_element_name ':' error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no specification defined in structure element declaration.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid specification in structure element declaration."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-structure_element_name: any_identifier;
-
-
-structure_initialization:
- '(' structure_element_initialization_list ')'
- {$$ = $2;}
-/* ERROR_CHECK_BEGIN */
-| '(' error ')'
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid structure element initialization list in structure initialization."); yyerrok;}
-| '(' structure_element_initialization_list error
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "expecting ')' at the end of structure element initialization list in structure initialization."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-/* helper symbol for structure_initialization */
-structure_element_initialization_list:
- structure_element_initialization
- {$$ = new structure_element_initialization_list_c(locloc(@$)); $$->add_element($1);}
-| structure_element_initialization_list ',' structure_element_initialization
- {$$ = $1; $$->add_element($3);}
-/* ERROR_CHECK_BEGIN
-| structure_element_initialization_list structure_element_initialization
- {$$ = $1; print_err_msg(locl(@1), locf(@2), "',' missing in structure element initialization list in structure initialization."); yynerrs++;}
-| structure_element_initialization_list ',' error
- {$$ = $1;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no structure element initialization defined in structure initialization.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid structure element initialization in structure initialization."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-structure_element_initialization:
- structure_element_name ASSIGN constant
- {$$ = new structure_element_initialization_c($1, $3, locloc(@$));}
-| structure_element_name ASSIGN enumerated_value
- {$$ = new structure_element_initialization_c($1, $3, locloc(@$));}
-| structure_element_name ASSIGN array_initialization
- {$$ = new structure_element_initialization_c($1, $3, locloc(@$));}
-| structure_element_name ASSIGN structure_initialization
- {$$ = new structure_element_initialization_c($1, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| structure_element_name constant
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':=' missing in structure element initialization."); yynerrs++;}
-| structure_element_name enumerated_value
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':=' missing in enumerated structure element initialization."); yynerrs++;}
-| structure_element_name array_initialization
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':=' missing in array structure element initialization."); yynerrs++;}
-| structure_element_name structure_initialization
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':=' missing in structured structure element initialization."); yynerrs++;}
-| structure_element_name ASSIGN error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no initial value defined in structured structure element initialization.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid initial value in structured structure element initialization."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-/* NOTE: in order to remove a reduce/reduce conflict,
- * all occurences of string_type_name
- * have been replaced with identifier!
- */
-/*
-string_type_name: identifier;
-*/
-
-string_type_declaration:
-/* string_type_name ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init */
- identifier ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init
- {$$ = new string_type_declaration_c($1, $3, $4, $5, locloc(@$));
- library_element_symtable.insert($1, prev_declared_string_type_name_token);
- }
-;
-
-
-/* helper symbol for string_type_declaration */
-string_type_declaration_size:
- '[' integer ']'
- {$$ = $2;}
-/* REMOVED !! */
-//| /* empty */
-// {$$ = NULL;}
-;
-/* The syntax contains a reduce/reduce conflict.
- * The optional '[' <size> ']'
- * has been changed to become mandatory to remove the conflict.
- *
- * The conflict arises because
- * new_str_type : STRING := "hello!"
- * may be reduced to a string_type_declaration OR
- * a simple_type_declaration.
- *
- * Our change forces it to be reduced to a
- * simple_type_declaration!
- * We chose this option because changing the definition
- * of simple_spec_init would force us to change all the other
- * rules in which it appears. The change we made has no
- * side-effects!
- */
-
-/* helper symbol for string_type_declaration */
-string_type_declaration_init:
- /* empty */
- {$$ = NULL;}
-| ASSIGN character_string
- {$$ = $2;}
-;
-
-
-
-/*********************/
-/* B 1.4 - Variables */
-/*********************/
-/* NOTE: The standard is erroneous in it's definition of 'variable' because:
- * - The standard considers 'ENO' as a keyword...
- * - ...=> which means that it may never be parsed as an 'identifier'...
- * - ...=> and therefore may never be used as the name of a variable inside an expression.
- * - However, a function/FB must be able to assign the ENO parameter
- * it's value, doing it in an assignment statement, and therefore using the 'ENO'
- * character sequence as an identifier!
- * The obvious solution is to also allow the ENO keyword to be
- * used as the name of a variable. Note that this variable may be used
- * even though it is not explicitly declared as a function/FB variable,
- * as the standard requires us to define it implicitly in this case!
- * There are three ways of achieving this:
- * (i) simply not define EN and ENO as keywords in flex (lexical analyser)
- * and let them be considered 'identifiers'. Aditionally, add some code
- * so that if they are not explicitly declared, we add them automatically to
- * the declaration of each Functions and FB, where they would then be parsed
- * as a previously_declared_variable.
- * This approach has the advantage the EN and ENO would automatically be valid
- * in every location where it needs to be valid, namely in the explicit declaration
- * of these same variables, or when they are used within expressions.
- * However, this approach has the drawback that
- * EN and ENO could then also be used anywhere a standard identifier is allowed,
- * including in the naming of Functions, FBs, Programs, Configurations, Resources,
- * SFC Actions, SFC Steps, etc...
- * This would mean that we would then have to add a lexical analysis check
- * within the bison code (syntax analyser) to all the above constructs to make sure
- * that the identifier being used is not EN or ENO.
- * (ii) The other approach is to define EN and ENO as keywords / tokens in flex
- * (lexical analyser) and then change the syntax in bison to acomodate
- * these tokens wherever they could correctly appear.
- * This has the drawback that we need to do some changes to the synax defintion.
- * (iii) Yet a another option is to mix the above two methods.
- * Define EN and ENO as tokens in flex, but change (only) the syntax for
- * variable declaration to allow these tokens to also be used in declaring variables.
- * From this point onwards these tokens are then considered a previously_declared_variable,
- * since flex will first check for this before even checking for tokens.
- *
- * I (Mario) cuurretnly (2011) believe the cleanest method of achieving this goal
- * is to use option (iii)
- * However, considering that:
- * - I have already previously implemented option (ii);
- * - option (iii) requires that flex parse the previously_declared_variable
- * before parsing any token. We already support this (remeber that this is
- * used mainly to allow some IL operators as well as PRIORITY, etc. tokens
- * to be used as identifiers, since the standard does not define them as keywords),
- * but this part of the code in flex is often commented out as usually people do not expect
- * us to follow the standard in the strict sense, but rather consider those
- * tokens as keywords;
- * considering the above, we currently carry on using option (ii).
- */
-variable:
- symbolic_variable
-| prev_declared_direct_variable
-| eno_identifier
- {$$ = new symbolic_variable_c($1, locloc(@$));}
-;
-
-
-symbolic_variable:
-/* NOTE: To be entirely correct, variable_name must be replacemed by
- * prev_declared_variable_name | prev_declared_fb_name | prev_declared_global_var_name
- */
- prev_declared_fb_name
- {$$ = new symbolic_variable_c($1, locloc(@$));}
-| prev_declared_global_var_name
- {$$ = new symbolic_variable_c($1, locloc(@$));}
-| prev_declared_variable_name
- {$$ = new symbolic_variable_c($1, locloc(@$));}
-| multi_element_variable
-/*
-| identifier
- {$$ = new symbolic_variable_c($1, locloc(@$));}
-*/
-;
-
-
-/* NOTE: in section B 1.7, when configuring a program, symbolic_variable
- * is used. Nevertheless, during the parsing of a configuration,
- * the variables in question are out of scope, so we should
- * be allowing any_identifier instead of prev_declared_variable_name!
- *
- * We therefore need a new any_symbolic_variable construct that
- * allows the use of any_identifier instead of previously declared
- * variables, function blocks, etc...
- */
-any_symbolic_variable:
-// variable_name -> replaced by any_identifier
- any_identifier
- {$$ = new symbolic_variable_c($1, locloc(@$));}
-| any_multi_element_variable
-;
-
-
-/* for yet undeclared variable names ! */
-variable_name: identifier;
-
-
-
-
-
-/********************************************/
-/* B.1.4.1 Directly Represented Variables */
-/********************************************/
-prev_declared_direct_variable: prev_declared_direct_variable_token {$$ = new direct_variable_c($1, locloc(@$));};
-
-
-
-
-/*************************************/
-/* B.1.4.2 Multi-element Variables */
-/*************************************/
-multi_element_variable:
- array_variable
-| structured_variable
-;
-
-/* please see note above any_symbolic_variable */
-any_multi_element_variable:
- any_array_variable
-| any_structured_variable
-;
-
-
-array_variable:
- subscripted_variable '[' subscript_list ']'
- {$$ = new array_variable_c($1, $3, locloc(@$));}
-;
-
-/* please see note above any_symbolic_variable */
-any_array_variable:
- any_subscripted_variable '[' subscript_list ']'
- {$$ = new array_variable_c($1, $3, locloc(@$));}
-;
-
-
-subscripted_variable:
- symbolic_variable
-;
-
-
-/* please see note above any_symbolic_variable */
-any_subscripted_variable:
- any_symbolic_variable
-;
-
-
-subscript_list:
- subscript
- {$$ = new subscript_list_c(locloc(@$)); $$->add_element($1);}
-| subscript_list ',' subscript
- {$$ = $1; $$->add_element($3);}
-;
-
-
-subscript: expression;
-
-
-structured_variable:
- record_variable '.' field_selector
- {$$ = new structured_variable_c($1, $3, locloc(@$));}
-;
-
-
-/* please see note above any_symbolic_variable */
-any_structured_variable:
- any_record_variable '.' field_selector
- {$$ = new structured_variable_c($1, $3, locloc(@$));}
-;
-
-
-
-record_variable:
- symbolic_variable
-;
-
-
-/* please see note above any_symbolic_variable */
-any_record_variable:
- any_symbolic_variable
-;
-
-
-field_selector:
- any_identifier
-| eno_identifier
-;
-
-
-
-
-
-
-/******************************************/
-/* B 1.4.3 - Declaration & Initialisation */
-/******************************************/
-input_declarations:
- VAR_INPUT input_declaration_list END_VAR
- {$$ = new input_declarations_c(NULL, $2, new explicit_definition_c(), locloc(@$));}
-| VAR_INPUT RETAIN input_declaration_list END_VAR
- {$$ = new input_declarations_c(new retain_option_c(locloc(@2)), $3, new explicit_definition_c(), locloc(@$));}
-| VAR_INPUT NON_RETAIN input_declaration_list END_VAR
- {$$ = new input_declarations_c(new non_retain_option_c(locloc(@2)), $3, new explicit_definition_c(), locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| VAR_INPUT END_VAR
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no variable declared in input variable(s) declaration."); yynerrs++;}
-| VAR_INPUT RETAIN END_VAR
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable declared in retentive input variable(s) declaration."); yynerrs++;}
-| VAR_INPUT NON_RETAIN END_VAR
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable declared in non-retentive input variable(s) declaration."); yynerrs++;}
-| VAR_INPUT error input_declaration_list END_VAR
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unexpected token after 'VAR_INPUT' in input variable(s) declaration."); yyerrok;}
-| VAR_INPUT RETAIN error input_declaration_list END_VAR
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "unexpected token after 'RETAIN' in retentive input variable(s) declaration."); yyerrok;}
-| VAR_INPUT NON_RETAIN error input_declaration_list END_VAR
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "unexpected token after 'NON_RETAIN' in non-retentive input variable(s) declaration."); yyerrok;}
-| VAR_INPUT input_declaration_list error END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed input variable(s) declaration."); yyerrok;}
-| VAR_INPUT RETAIN input_declaration_list error END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed retentive input variable(s) declaration."); yyerrok;}
-| VAR_INPUT NON_RETAIN input_declaration_list error END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed non-retentive input variable(s) declaration."); yyerrok;}
-| VAR_INPUT error END_VAR
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in input variable(s) declaration."); yyerrok;}
-| VAR_INPUT RETAIN error END_VAR
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "unknown error in retentive input variable(s) declaration."); yyerrok;}
-| VAR_INPUT NON_RETAIN error END_VAR
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "unknown error in non-retentive input variable(s) declaration."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-/* helper symbol for input_declarations */
-input_declaration_list:
- input_declaration ';'
- {$$ = new input_declaration_list_c(locloc(@$)); $$->add_element($1);}
-| input_declaration_list input_declaration ';'
- {$$ = $1; $$->add_element($2);}
-/* ERROR_CHECK_BEGIN */
-| error ';'
- {$$ = new input_declaration_list_c(locloc(@$)); print_err_msg(locf(@1), locl(@1), "invalid input variable(s) declaration."); yyerrok;}
-| input_declaration error
- {$$ = new input_declaration_list_c(locloc(@$)); print_err_msg(locl(@1), locf(@2), "';' missing at end of input variable(s) declaration."); yyerrok;}
-| input_declaration_list input_declaration error
- {$$ = $1; print_err_msg(locl(@2), locf(@3), "';' missing at end of input variable(s) declaration."); yyerrok;}
-| input_declaration_list error ';'
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "invalid input variable(s) declaration."); yyerrok;}
-| input_declaration_list ';'
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected ';' after input variable(s) declaration."); yynerrs++;}
-/* ERROR_CHECK_END */
-;
-
-
-/* NOTE: The formal definition of 'input_declaration' as defined in the standard is erroneous,
- * as it does not allow a user defined 'EN' input parameter. However,
- * The semantic description of the languages clearly states that this is allowed.
- * We have added the 'en_param_declaration' clause to cover for this.
- */
-input_declaration:
- var_init_decl
-| edge_declaration
-| en_param_declaration
-;
-
-
-edge_declaration:
- var1_list ':' BOOL R_EDGE
- {$$ = new edge_declaration_c(new raising_edge_option_c(locloc(@3)), $1, locloc(@$));}
-| var1_list ':' BOOL F_EDGE
- {$$ = new edge_declaration_c(new falling_edge_option_c(locloc(@3)), $1, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| var1_list BOOL R_EDGE
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and specification in edge declaration."); yynerrs++;}
-| var1_list BOOL F_EDGE
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and specification in edge declaration."); yynerrs++;}
-| var1_list ':' BOOL R_EDGE F_EDGE
- {$$ = 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++;}
-| var1_list ':' BOOL F_EDGE R_EDGE
- {$$ = 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++;}
-| var1_list ':' R_EDGE
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "'BOOL' missing in edge declaration."); yynerrs++;}
-| var1_list ':' F_EDGE
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "'BOOL' missing in edge declaration."); yynerrs++;}
-/* ERROR_CHECK_END */
-;
-
-
-/* NOTE: The formal definition of the standard is erroneous, as it simply does not
- * consider the EN and ENO keywords!
- * The semantic description of the languages clearly states that these may be
- * used in several ways. One of them is to declare an EN input parameter.
- * We have added the 'en_param_declaration' clause to cover for this.
- *
- * Please read the comment above the definition of 'variable' in section B1.4 for details.
- */
-en_param_declaration:
- en_identifier ':' BOOL ASSIGN boolean_literal
- {$$ = new en_param_declaration_c($1, new bool_type_name_c(locloc(@$)), $5, new explicit_definition_c(), locloc(@$));}
-| en_identifier ':' BOOL ASSIGN integer
- {$$ = new en_param_declaration_c($1, new bool_type_name_c(locloc(@$)), $5, new explicit_definition_c(), locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| en_identifier BOOL ASSIGN boolean_literal
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and specification in EN declaration."); yynerrs++;}
-| en_identifier BOOL ASSIGN integer
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and specification in EN declaration."); yynerrs++;}
-| en_identifier ':' ASSIGN boolean_literal
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "'BOOL' missing in EN declaration."); yynerrs++;}
-| en_identifier ':' ASSIGN integer
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "'BOOL' missing in EN declaration."); yynerrs++;}
-| en_identifier ':' BOOL ASSIGN error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no specification defined in EN declaration.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid specification in EN declaration."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-var_init_decl:
- var1_init_decl
-| array_var_init_decl
-| structured_var_init_decl
-| fb_name_decl
-| string_var_declaration
-;
-
-
-
-
-var1_init_decl:
- var1_list ':' simple_spec_init
- {$$ = new var1_init_decl_c($1, $3, locloc(@$));}
-| var1_list ':' subrange_spec_init
- {$$ = new var1_init_decl_c($1, $3, locloc(@$));}
-| var1_list ':' enumerated_spec_init
- {$$ = new var1_init_decl_c($1, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| var1_list simple_spec_init
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and simple specification."); yynerrs++;}
-| var1_list subrange_spec_init
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and subrange specification."); yynerrs++;}
-| var1_list enumerated_spec_init
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and enumerated specification."); yynerrs++;}
-| var1_list ':' error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no specification defined in variable declaration.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid specification in variable declaration."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-var1_list:
- variable_name
- {$$ = new var1_list_c(locloc(@$)); $$->add_element($1);
- variable_name_symtable.insert($1, prev_declared_variable_name_token);
- }
- | var1_list ',' variable_name
- {$$ = $1; $$->add_element($3);
- variable_name_symtable.insert($3, prev_declared_variable_name_token);
- }
-/* ERROR_CHECK_BEGIN */
-| var1_list variable_name
- {$$ = $1; print_err_msg(locl(@1), locf(@2), "',' missing in variable list."); yynerrs++;}
-| var1_list ',' error
- {$$ = $1;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no variable name defined in variable declaration.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid variable name in variable declaration."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-
-array_var_init_decl:
- var1_list ':' array_spec_init
- {$$ = new array_var_init_decl_c($1, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| var1_list array_spec_init
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and array specification."); yynerrs++;}
-/* ERROR_CHECK_END */
-;
-
-
-structured_var_init_decl:
- var1_list ':' initialized_structure
- {$$ = new structured_var_init_decl_c($1, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| var1_list initialized_structure
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and structured specification."); yynerrs++;}
-/* ERROR_CHECK_END */
-;
-
-
-/* NOTE: see notes above fb_name_list and var1_list
- * for reason why ':' was removed from this rule!
- * In essence, to remove a shift/reduce conflict,
- * the ':' was moved to var1_list and fb_name_list!
- */
-fb_name_decl:
-/* fb_name_list ':' function_block_type_name */
- fb_name_list_with_colon function_block_type_name
- {$$ = new fb_name_decl_c($1, $2, NULL, locloc(@$));}
-/*| fb_name_list ':' function_block_type_name ASSIGN structure_initialization */
-| fb_name_list_with_colon function_block_type_name ASSIGN structure_initialization
- {$$ = new fb_name_decl_c($1, $2, $4, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| fb_name_list_with_colon ASSIGN structure_initialization
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no function block type name defined in function block declaration with initialization."); yynerrs++;}
-| fb_name_list_with_colon function_block_type_name structure_initialization
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "':=' missing in function block declaration with initialization."); yynerrs++;}
-| fb_name_list_with_colon function_block_type_name ASSIGN error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@3), locf(@4), "no initialization defined in function block declaration.");}
- else {print_err_msg(locf(@4), locl(@4), "invalid initialization in function block declaration."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-
-/* NOTE: In order to remove a reduce/reduce conflict between
- * var1_list and fb_name_list, which are identical to each
- * other, fb_name_list has been redefined to be a var1_list.
- *
- * In order to remove a further shift/reduce conflict, var1_list
- * is imediately transfomred into var1_list_with_colon
- * (i.e. it includes the ':' following the list), which
- * means that fb_name_list is built from a
- * var1_list_with_colon after all!
- */
-/*
-fb_name_list:
- (* fb_name *)
- identifier
- {$$ = new fb_name_list_c($1);
- variable_name_symtable.insert($1, prev_declared_fb_name_token);
- }
-(* | fb_name_list ',' fb_name *)
-| fb_name_list ',' identifier
- {$$ = $1; $$->add_element($3);
- variable_name_symtable.insert($3, prev_declared_fb_name_token);
- }
-;
-*/
-
-fb_name_list_with_colon:
- var1_list_with_colon
- {$$ = new fb_name_list_c(locloc(@$));
- /* fill up the new fb_name_list_c object with the references
- * contained in the var1_list_c object.
- */
- FOR_EACH_ELEMENT(elem, $1, {$$->add_element(elem);});
- delete $1;
- /* change the tokens associated with the symbols stored in
- * the variable name symbol table from prev_declared_variable_name_token
- * to prev_declared_fb_name_token
- */
- FOR_EACH_ELEMENT(elem, $$, {variable_name_symtable.set(elem, prev_declared_fb_name_token);});
- }
-;
-
-/* helper symbol for fb_name_list_with_colon */
-var1_list_with_colon:
- var1_list ':'
-;
-
-
-// fb_name: identifier;
-
-
-
-output_declarations:
- VAR_OUTPUT var_output_init_decl_list END_VAR
- {$$ = new output_declarations_c(NULL, $2, new explicit_definition_c(), locloc(@$));}
-| VAR_OUTPUT RETAIN var_output_init_decl_list END_VAR
- {$$ = new output_declarations_c(new retain_option_c(locloc(@2)), $3, new explicit_definition_c(), locloc(@$));}
-| VAR_OUTPUT NON_RETAIN var_output_init_decl_list END_VAR
- {$$ = new output_declarations_c(new non_retain_option_c(locloc(@2)), $3, new explicit_definition_c(), locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| VAR_OUTPUT END_VAR
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no variable declared in output variable(s) declaration."); yynerrs++;}
-| VAR_OUTPUT RETAIN END_VAR
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable declared in retentive output variable(s) declaration."); yynerrs++;}
-| VAR_OUTPUT NON_RETAIN END_VAR
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable declared in non-retentive output variable(s) declaration."); yynerrs++;}
-| VAR_OUTPUT error var_output_init_decl_list END_VAR
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unexpected token after 'VAR_OUPUT' in output variable(s) declaration."); yyerrok;}
-| VAR_OUTPUT RETAIN error var_output_init_decl_list END_VAR
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "unexpected token after 'RETAIN' in retentive output variable(s) declaration."); yyerrok;}
-| VAR_OUTPUT NON_RETAIN error var_output_init_decl_list END_VAR
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "unexpected token after 'NON_RETAIN' in non-retentive output variable(s) declaration."); yyerrok;}
-| VAR_OUTPUT var_output_init_decl_list error END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed output variable(s) declaration."); yyerrok;}
-| VAR_OUTPUT RETAIN var_output_init_decl_list error END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed retentive output variable(s) declaration."); yyerrok;}
-| VAR_OUTPUT NON_RETAIN var_output_init_decl_list error END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed non-retentive output variable(s) declaration."); yyerrok;}
-| VAR_OUTPUT error END_VAR
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in output variable(s) declaration."); yyerrok;}
-| VAR_OUTPUT RETAIN error END_VAR
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "unknown error in retentive output variable(s) declaration."); yyerrok;}
-| VAR_OUTPUT NON_RETAIN error END_VAR
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "unknown error in non-retentive output variable(s) declaration."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-/* NOTE: The formal definition of 'var_output_init_decl' as defined in the standard is erroneous,
- * as it does not allow a user defined 'ENO' output parameter. However,
- * The semantic description of the languages clearly states that this is allowed.
- * We have added the 'eno_param_declaration' clause to cover for this.
- *
- * Please read the comment above the definition of 'variable' in section B1.4 for details.
- */
-var_output_init_decl:
- var_init_decl
-| eno_param_declaration
-;
-
-var_output_init_decl_list:
- var_output_init_decl ';'
- {$$ = new var_init_decl_list_c(locloc(@$)); $$->add_element($1);}
-| var_output_init_decl_list var_output_init_decl ';'
- {$$ = $1; $$->add_element($2);}
-/* ERROR_CHECK_BEGIN */
-| var_output_init_decl_list var_output_init_decl error
- {$$ = $1; print_err_msg(locl(@2), locf(@3), "';' missing at end of variable(s) declaration."); yyerrok;}
-| var_output_init_decl_list error ';'
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "invalid variable(s) declaration."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-/* NOTE: The formal definition of the standard is erroneous, as it simply does not
- * consider the EN and ENO keywords!
- * The semantic description of the languages clearly states that these may be
- * used in several ways. One of them is to declare an ENO output parameter.
- * We have added the 'eno_param_declaration' clause to cover for this.
- *
- * Please read the comment above the definition of 'variable' in section B1.4 for details.
- */
-eno_param_declaration:
- eno_identifier ':' BOOL
- /* NOTE We do _NOT_ include this variable in the previously_declared_variable symbol table!
- * Please read the comment above the definition of 'variable' for the reason for this.
- */
- {$$ = new eno_param_declaration_c($1, new bool_type_name_c(locloc(@$)), new explicit_definition_c(), locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| eno_identifier BOOL
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and specification in ENO declaration."); yynerrs++;}
-| eno_identifier ':' error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no specification defined in ENO declaration.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid specification in ENO declaration."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-input_output_declarations:
- VAR_IN_OUT var_declaration_list END_VAR
- {$$ = new input_output_declarations_c($2, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| VAR_IN_OUT END_VAR
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no variable declared in in_out variable(s) declaration."); yynerrs++;}
-| VAR_IN_OUT error var_declaration_list END_VAR
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unexpected token after 'VAR_IN_OUT' in in_out variable(s) declaration."); yyerrok;}
-| VAR_IN_OUT var_declaration_list error END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed in_out variable(s) declaration."); yyerrok;}
-| VAR_IN_OUT error END_VAR
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in in_out variable(s) declaration."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-
-/* helper symbol for input_output_declarations */
-var_declaration_list:
- var_declaration ';'
- {$$ = new var_declaration_list_c(locloc(@$)); $$->add_element($1);}
-| var_declaration_list var_declaration ';'
- {$$ = $1; $$->add_element($2);}
-/* ERROR_CHECK_BEGIN */
-| error ';'
- {$$ = new var_declaration_list_c(locloc(@$)); print_err_msg(locf(@1), locl(@1), "invalid variable(s) declaration."); yyerrok;}
-| var_declaration error
- {$$ = new var_declaration_list_c(locloc(@$)); print_err_msg(locl(@1), locf(@2), "';' missing at end of variable(s) declaration."); yyerrok;}
-| var_declaration_list var_declaration error
- {$$ = $1; print_err_msg(locl(@2), locf(@3), "';' missing at end of variable(s) declaration."); yyerrok;}
-| var_declaration_list error ';'
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "invalid variable(s) declaration."); yyerrok;}
-| var_declaration_list ';'
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected ';' after variable(s) declaration."); yynerrs++;}
-/* ERROR_CHECK_END */
-;
-
-
-var_declaration:
- temp_var_decl
-| fb_name_decl
-;
-
-
-temp_var_decl:
- var1_declaration
-| array_var_declaration
-| structured_var_declaration
-| string_var_declaration
-;
-
-var1_declaration:
- var1_list ':' simple_specification
- {$$ = new var1_init_decl_c($1, $3, locloc(@$));}
-| var1_list ':' subrange_specification
- {$$ = new var1_init_decl_c($1, $3, locloc(@$));}
-| var1_list ':' enumerated_specification
- {$$ = new var1_init_decl_c($1, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| var1_list simple_specification
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and simple specification."); yynerrs++;}
-| var1_list subrange_specification
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and subrange specification."); yynerrs++;}
-| var1_list enumerated_specification
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and enumerated specification."); yynerrs++;}
-/* ERROR_CHECK_END */
-;
-
-
-
-array_var_declaration:
- var1_list ':' array_specification
- {$$ = new array_var_declaration_c($1, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| var1_list array_specification
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and array specification."); yynerrs++;}
-/* ERROR_CHECK_END */
-;
-
-structured_var_declaration:
- var1_list ':' prev_declared_structure_type_name
- {$$ = new structured_var_declaration_c($1, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| var1_list prev_declared_structure_type_name
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and structured specification."); yynerrs++;}
-/* ERROR_CHECK_END */
-;
-
-
-var_declarations:
- VAR var_init_decl_list END_VAR
- {$$ = new var_declarations_c(NULL, $2, locloc(@$));}
-| VAR CONSTANT var_init_decl_list END_VAR
- {$$ = new var_declarations_c(new constant_option_c(locloc(@2)), $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| VAR END_VAR
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no variable declared in variable(s) declaration."); yynerrs++;}
-| VAR CONSTANT END_VAR
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable declared in constant variable(s) declaration."); yynerrs++;}
-| VAR error var_init_decl_list END_VAR
- {$$ = NULL; print_err_msg(locl(@1), locf(@3), "unexpected token after 'VAR' in variable(s) declaration."); yyerrok;}
-| VAR CONSTANT error var_init_decl_list END_VAR
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "unexpected token after 'CONSTANT' in constant variable(s) declaration."); yyerrok;}
-| VAR var_init_decl_list error END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed variable(s) declaration."); yyerrok;}
-| VAR CONSTANT var_init_decl_list error END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed constant variable(s) declaration."); yyerrok;}
-| VAR error END_VAR
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in variable(s) declaration."); yyerrok;}
-| VAR CONSTANT error END_VAR
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "unknown error in constant variable(s) declaration."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-retentive_var_declarations:
- VAR RETAIN var_init_decl_list END_VAR
- {$$ = new retentive_var_declarations_c($3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| VAR RETAIN END_VAR
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable declared in retentive variable(s) declaration."); yynerrs++;}
-| VAR RETAIN error var_init_decl_list END_VAR
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "unexpected token after 'RETAIN' in retentive variable(s) declaration."); yyerrok;}
-| VAR RETAIN var_init_decl_list error END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed retentive variable(s) declaration."); yyerrok;}
-| VAR RETAIN error END_VAR
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "unknown error in retentive variable(s) declaration."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-located_var_declarations:
- VAR located_var_decl_list END_VAR
- {$$ = new located_var_declarations_c(NULL, $2, locloc(@$));}
-| VAR CONSTANT located_var_decl_list END_VAR
- {$$ = new located_var_declarations_c(new constant_option_c(locloc(@2)), $3, locloc(@$));}
-| VAR RETAIN located_var_decl_list END_VAR
- {$$ = new located_var_declarations_c(new retain_option_c(locloc(@2)), $3, locloc(@$));}
-| VAR NON_RETAIN located_var_decl_list END_VAR
- {$$ = new located_var_declarations_c(new non_retain_option_c(locloc(@2)), $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| VAR NON_RETAIN END_VAR
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable declared in non-retentive located variable(s) declaration."); yynerrs++;}
-| VAR error located_var_decl_list END_VAR
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unexpected token after 'VAR' in located variable(s) declaration."); yyerrok;}
-| VAR CONSTANT error located_var_decl_list END_VAR
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "unexpected token after 'CONSTANT' in constant located variable(s) declaration."); yyerrok;}
-| VAR RETAIN error located_var_decl_list END_VAR
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "unexpected token after 'RETAIN' in retentive located variable(s) declaration."); yyerrok;}
-| VAR NON_RETAIN error located_var_decl_list END_VAR
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "unexpected token after 'NON_RETAIN' in non-retentive located variable(s) declaration."); yyerrok;}
-| VAR located_var_decl_list error END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed located variable(s) declaration."); yyerrok;}
-| VAR CONSTANT located_var_decl_list error END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed constant located variable(s) declaration."); yyerrok;}
-| VAR RETAIN located_var_decl_list error END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed retentive located variable(s) declaration."); yyerrok;}
-| VAR NON_RETAIN located_var_decl_list error END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed non-retentive located variable(s) declaration."); yyerrok;}
-| VAR NON_RETAIN error END_VAR
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "unknown error in non retentive variable(s) declaration."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-/* helper symbol for located_var_declarations */
-located_var_decl_list:
- located_var_decl ';'
- {$$ = new located_var_decl_list_c(locloc(@$)); $$->add_element($1);}
-| located_var_decl_list located_var_decl ';'
- {$$ = $1; $$->add_element($2);}
-/* ERROR_CHECK_BEGIN */
-| error ';'
- {$$ = new located_var_decl_list_c(locloc(@$)); print_err_msg(locf(@1), locl(@1), "invalid located variable declaration."); yyerrok;}
-| located_var_decl error
- {$$ = new located_var_decl_list_c(locloc(@$)); print_err_msg(locl(@1), locf(@2), "';' missing at end of located variable declaration."); yyerrok;}
-| located_var_decl_list located_var_decl error
- {$$ = $1; print_err_msg(locl(@2), locf(@3), "';' missing at end of located variable declaration."); yyerrok;}
-| located_var_decl_list error ';'
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "invalid located variable declaration."); yyerrok;}
-| located_var_decl_list ';'
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected ';' after located variable declaration."); yynerrs++;}
-/* ERROR_CHECK_END */
-;
-
-
-located_var_decl:
- variable_name location ':' located_var_spec_init
- {$$ = new located_var_decl_c($1, $2, $4, locloc(@$));
- variable_name_symtable.insert($1, prev_declared_variable_name_token);
- }
-| location ':' located_var_spec_init
- {$$ = new located_var_decl_c(NULL, $1, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| variable_name location located_var_spec_init
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between located variable location and specification."); yynerrs++;}
-| location located_var_spec_init
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between located variable location and specification."); yynerrs++;}
-| variable_name location ':' error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no specification defined in located variable declaration.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid specification in located variable declaration."); yyclearin;}
- yyerrok;
- }
-| location ':' error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no specification defined in located variable declaration.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid specification in located variable declaration."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-
-
-external_var_declarations:
- VAR_EXTERNAL external_declaration_list END_VAR
- {$$ = new external_var_declarations_c(NULL, $2, locloc(@$));}
-| VAR_EXTERNAL CONSTANT external_declaration_list END_VAR
- {$$ = new external_var_declarations_c(new constant_option_c(locloc(@2)), $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| VAR_EXTERNAL END_VAR
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no variable declared in external variable(s) declaration."); yynerrs++;}
-| VAR_EXTERNAL CONSTANT END_VAR
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable declared in constant external variable(s) declaration."); yynerrs++;}
-| VAR_EXTERNAL error external_declaration_list END_VAR
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unexpected token after 'VAR_EXTERNAL' in external variable(s) declaration."); yyerrok;}
-| VAR_EXTERNAL CONSTANT error external_declaration_list END_VAR
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "unexpected token after 'CONSTANT' in constant external variable(s) declaration."); yyerrok;}
-| VAR_EXTERNAL external_declaration_list error END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed external variable(s) declaration."); yyerrok;}
-| VAR_EXTERNAL CONSTANT external_declaration_list error END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed constant external variable(s) declaration."); yyerrok;}
-| VAR_EXTERNAL error END_VAR
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in external variable(s) declaration."); yyerrok;}
-| VAR_EXTERNAL CONSTANT error END_VAR
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "unknown error in constant external variable(s) declaration."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-/* helper symbol for external_var_declarations */
-external_declaration_list:
- external_declaration ';'
- {$$ = new external_declaration_list_c(locloc(@$)); $$->add_element($1);}
-| external_declaration_list external_declaration ';'
- {$$ = $1; $$->add_element($2);}
-/* ERROR_CHECK_BEGIN */
-| error ';'
- {$$ = new external_declaration_list_c(locloc(@$)); print_err_msg(locf(@1), locl(@1), "invalid external variable declaration."); yyerrok;}
-| external_declaration error
- {$$ = new external_declaration_list_c(locloc(@$)); print_err_msg(locl(@1), locf(@2), "';' missing at end of external variable declaration."); yyerrok;}
-| external_declaration_list external_declaration error
- {$$ = $1; print_err_msg(locl(@2), locf(@3), "';' missing at end of external variable declaration."); yyerrok;}
-| external_declaration_list error ';'
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "invalid external variable declaration."); yyerrok;}
-| external_declaration_list ';'
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected ';' after external variable declaration."); yynerrs++;}
-/* ERROR_CHECK_END */
-;
-
-
-external_declaration:
- global_var_name ':' simple_specification
- {$$ = new external_declaration_c($1, $3, locloc(@$));
- variable_name_symtable.insert($1, prev_declared_variable_name_token);
- }
-| global_var_name ':' subrange_specification
- {$$ = new external_declaration_c($1, $3, locloc(@$));
- variable_name_symtable.insert($1, prev_declared_variable_name_token);
- }
-| global_var_name ':' enumerated_specification
- {$$ = new external_declaration_c($1, $3, locloc(@$));
- variable_name_symtable.insert($1, prev_declared_variable_name_token);
- }
-| global_var_name ':' array_specification
- {$$ = new external_declaration_c($1, $3, locloc(@$));
- variable_name_symtable.insert($1, prev_declared_variable_name_token);
- }
-| global_var_name ':' prev_declared_structure_type_name
- {$$ = new external_declaration_c($1, $3, locloc(@$));
- variable_name_symtable.insert($1, prev_declared_variable_name_token);
- }
-| global_var_name ':' function_block_type_name
- {$$ = new external_declaration_c($1, $3, locloc(@$));
- variable_name_symtable.insert($1, prev_declared_fb_name_token);
- }
-/* ERROR_CHECK_BEGIN */
-| global_var_name simple_specification
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between external variable name and simple specification."); yynerrs++;}
-| global_var_name subrange_specification
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between external variable name and subrange specification."); yynerrs++;}
-| global_var_name enumerated_specification
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between external variable name and enumerated specification."); yynerrs++;}
-| global_var_name array_specification
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between external variable name and array specification."); yynerrs++;}
-| global_var_name prev_declared_structure_type_name
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between external variable name and structured specification."); yynerrs++;}
-| global_var_name function_block_type_name
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between external variable name and function block type specification."); yynerrs++;}
-| global_var_name ':' error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no specification defined in external variable declaration.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid specification in external variable declaration."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-global_var_name: identifier;
-
-
-global_var_declarations:
- VAR_GLOBAL global_var_decl_list END_VAR
- {$$ = new global_var_declarations_c(NULL, $2, locloc(@$));}
-| VAR_GLOBAL CONSTANT global_var_decl_list END_VAR
- {$$ = new global_var_declarations_c(new constant_option_c(locloc(@2)), $3, locloc(@$));}
-| VAR_GLOBAL RETAIN global_var_decl_list END_VAR
- {$$ = new global_var_declarations_c(new retain_option_c(locloc(@2)), $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| VAR_GLOBAL END_VAR
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no variable declared in global variable(s) declaration."); yynerrs++;}
-| VAR_GLOBAL CONSTANT END_VAR
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable declared in constant global variable(s) declaration."); yynerrs++;}
-| VAR_GLOBAL RETAIN END_VAR
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable declared in retentive global variable(s) declaration."); yynerrs++;}
-| VAR_GLOBAL error global_var_decl_list END_VAR
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unexpected token after 'VAR_GLOBAL' in global variable(s) declaration."); yyerrok;}
-| VAR_GLOBAL CONSTANT error global_var_decl_list END_VAR
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "unexpected token after 'CONSTANT' in constant global variable(s) declaration."); yyerrok;}
-| VAR_GLOBAL RETAIN error global_var_decl_list END_VAR
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "unexpected token after 'RETAIN' in retentive global variable(s) declaration."); yyerrok;}
-| VAR_GLOBAL global_var_decl_list error END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed global variable(s) declaration."); yyerrok;}
-| VAR_GLOBAL CONSTANT global_var_decl_list error END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed constant global variable(s) declaration."); yyerrok;}
-| VAR_GLOBAL RETAIN global_var_decl_list error END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed retentive global variable(s) declaration."); yyerrok;}
-| VAR_GLOBAL error END_VAR
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in global variable(s) declaration."); yyerrok;}
-| VAR_GLOBAL CONSTANT error END_VAR
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "unknown error in constant global variable(s) declaration."); yyerrok;}
-| VAR_GLOBAL RETAIN error END_VAR
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "unknown error in constant global variable(s) declaration."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-/* helper symbol for global_var_declarations */
-global_var_decl_list:
- global_var_decl ';'
- {$$ = new global_var_decl_list_c(locloc(@$)); $$->add_element($1);}
-| global_var_decl_list global_var_decl ';'
- {$$ = $1; $$->add_element($2);}
-/* ERROR_CHECK_BEGIN */
-| error ';'
- {$$ = new global_var_decl_list_c(locloc(@$)); print_err_msg(locf(@1), locl(@1), "invalid global variable(s) declaration."); yyerrok;}
-| global_var_decl error
- {$$ = new global_var_decl_list_c(locloc(@$)); print_err_msg(locl(@1), locf(@2), "';' missing at end of global variable(s) declaration."); yyerrok;}
-| global_var_decl_list global_var_decl error
- {$$ = $1; print_err_msg(locl(@1), locf(@2), "';' missing at end of global variable(s) declaration."); yyerrok;}
-| global_var_decl_list error ';'
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "invalid global variable(s) declaration."); yyerrok;}
-| global_var_decl_list ';'
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected ';' after global variable(s) declaration."); yynerrs++;}
-/* ERROR_CHECK_END */
-;
-
-
-global_var_decl:
-/* NOTE : This possibility defined in standard has no sense and generate a conflict (disabled)
- global_var_spec ':'
- {$$ = new global_var_decl_c($1, NULL, locloc(@$));}
-*/
- global_var_spec ':' located_var_spec_init
- {$$ = new global_var_decl_c($1, $3, locloc(@$));}
-| global_var_spec ':' function_block_type_name
- {$$ = new global_var_decl_c($1, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| global_var_list located_var_spec_init
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between global variable list and type specification."); yynerrs++;}
-| global_var_name location located_var_spec_init
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between global variable specification and type specification."); yynerrs++;}
-| global_var_spec function_block_type_name
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between global variable specification and function block type specification."); yynerrs++;}
-| global_var_spec ':' error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no specification defined in global variable declaration.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid specification in global variable declaration."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-global_var_spec:
- global_var_list {$$ = $1;}
-| location
- {$$ = new global_var_spec_c(NULL, $1, locloc(@$));}
-| global_var_name location
- {$$ = new global_var_spec_c($1, $2, locloc(@$));
- variable_name_symtable.insert($1, prev_declared_global_var_name_token);
- }
-;
-
-
-located_var_spec_init:
- simple_spec_init
-| subrange_spec_init
-| enumerated_spec_init
-| array_spec_init
-| initialized_structure
-| single_byte_string_spec
-| double_byte_string_spec
-;
-
-
-location:
- AT direct_variable_token
- {$$ = new location_c(new direct_variable_c($2, locloc(@$)), locloc(@$));
- direct_variable_symtable.insert($2, prev_declared_direct_variable_token);
- }
-/* ERROR_CHECK_BEGIN */
-| AT error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@1), locf(@2), "no location defined in location declaration.");}
- else {print_err_msg(locf(@2), locl(@2), "invalid location in global location declaration."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-
-global_var_list:
- global_var_name
- {$$ = new global_var_list_c(locloc(@$)); $$->add_element($1);
- variable_name_symtable.insert($1, prev_declared_global_var_name_token);
- }
-| global_var_list ',' global_var_name
- {$$ = $1; $$->add_element($3);
- variable_name_symtable.insert($3, prev_declared_global_var_name_token);
- }
-/* ERROR_CHECK_BEGIN */
-| global_var_list global_var_name
- {$$ = new global_var_list_c(locloc(@$)); print_err_msg(locl(@1), locf(@2), "',' missing in global variable list."); yynerrs++;}
-| global_var_list ',' error
- {$$ = $1;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no variable name defined in global variable declaration.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid variable name in global variable declaration."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-
-string_var_declaration:
- single_byte_string_var_declaration
-| double_byte_string_var_declaration
-;
-
-single_byte_string_var_declaration:
- var1_list ':' single_byte_string_spec
- {$$ = new single_byte_string_var_declaration_c($1, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| var1_list single_byte_string_spec
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and string type specification."); yynerrs++;}
-/* ERROR_CHECK_END */
-;
-
-/* NOTE: The constructs
- *
- * [W]STRING
- * and
- * [W]STRING ASSIGN single_byte_character_string
- *
- * were removed as they are already contained
- * within a other constructs.
- *
- * single_byte_string_spec is used in:
- * - single_byte_string_var_declaration ->
- * -> string_var_declaration ---> var_init_decl
- * |--> temp_var_decl
- * |--> var2_init_decl
- * - located_var_spec_init
- *
- * STRING [ASSIGN string_constant] -> elementary_string_type_name ->
- * -> simple_spec -> simple_specification -> simple_spec_init ->
- * -> located_var_spec_init
- *
- * STRING [ASSIGN string_constant] -> elementary_string_type_name ->
- * -> simple_spec -> simple_specification -> simple_spec_init ->
- * -> var1_init_decl -> var_init_decl
- *
- * STRING [ASSIGN string_constant] -> elementary_string_type_name ->
- * -> simple_spec -> simple_specification -> simple_spec_init ->
- * -> var1_init_decl -> var2_init_decl
- *
- * STRING [ASSIGN string_constant] -> elementary_string_type_name ->
- * -> simple_spec -> simple_specification ->
- * -> var1_declaration -> temp_var_decl
- */
-single_byte_string_spec:
-/* STRING
- {$$ = new single_byte_string_spec_c(NULL, NULL);}
-*/
- STRING '[' integer ']'
- {$$ = new single_byte_string_spec_c($3, NULL, locloc(@$));}
-/*
-| STRING ASSIGN single_byte_character_string
- {$$ = new single_byte_string_spec_c(NULL, $3, locloc(@$));}
-*/
-| STRING '[' integer ']' ASSIGN single_byte_character_string
- {$$ = new single_byte_string_spec_c($3, $6, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| STRING '[' error ']'
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid length value for limited string type specification."); yyerrok;}
-| STRING '[' error ']' ASSIGN single_byte_character_string
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid length value for limited string type specification."); yyerrok;}
-| STRING '[' ']'
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "missing length value for limited string type specification."); yynerrs++;}
-| STRING '[' ']' ASSIGN single_byte_character_string
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "missing length value for limited string type specification."); yynerrs++;}
-| STRING '[' integer error
- {$$ = NULL; print_err_msg(locl(@3), locf(@4), "expecting ']' after length definition for limited string type specification."); yyerrok;}
-| STRING '[' integer ']' single_byte_character_string
- {$$ = NULL; print_err_msg(locl(@4), locf(@5), "':=' missing before limited string type initialization."); yynerrs++;}
-| STRING '[' integer ']' ASSIGN error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@5), locf(@6), "no initial value defined in limited string type initialization.");}
- else {print_err_msg(locf(@6), locl(@6), "invalid initial value in limited string type initialization."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-double_byte_string_var_declaration:
- var1_list ':' double_byte_string_spec
- {$$ = new double_byte_string_var_declaration_c($1, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| var1_list double_byte_string_spec
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and double byte string type specification."); yynerrs++;}
-/* ERROR_CHECK_END */
-;
-
-double_byte_string_spec:
-/* WSTRING
- {$$ = new double_byte_string_spec_c(NULL, NULL, locloc(@$));}
-*/
- WSTRING '[' integer ']'
- {$$ = new double_byte_string_spec_c($3, NULL, locloc(@$));}
-/*
-| WSTRING ASSIGN double_byte_character_string
- {$$ = new double_byte_string_spec_c(NULL, $3, locloc(@$));}
-*/
-| WSTRING '[' integer ']' ASSIGN double_byte_character_string
- {$$ = new double_byte_string_spec_c($3, $6, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| WSTRING '[' error ']'
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid length value for limited double byte string type specification."); yyerrok;}
-| WSTRING '[' error ']' ASSIGN single_byte_character_string
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid length value for limited double byte string type specification."); yyerrok;}
-| WSTRING '[' ']'
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "missing length value for limited double byte string type specification."); yynerrs++;}
-| WSTRING '[' ']' ASSIGN single_byte_character_string
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "missing length value for limited double byte string type specification."); yynerrs++;}
-| WSTRING '[' integer error
- {$$ = NULL; print_err_msg(locl(@3), locf(@4), "expecting ']' after length definition for limited double byte string type specification."); yyerrok;}
-| WSTRING '[' integer ']' single_byte_character_string
- {$$ = NULL; print_err_msg(locl(@4), locf(@5), "':=' missing before limited double byte string type initialization."); yynerrs++;}
-| WSTRING '[' integer ']' ASSIGN error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@5), locf(@6), "no initial value defined double byte in limited string type initialization.");}
- else {print_err_msg(locf(@6), locl(@6), "invalid initial value in limited double byte string type initialization."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-
-incompl_located_var_declarations:
- VAR incompl_located_var_decl_list END_VAR
- {$$ = new incompl_located_var_declarations_c(NULL, $2, locloc(@$));}
-| VAR RETAIN incompl_located_var_decl_list END_VAR
- {$$ = new incompl_located_var_declarations_c(new retain_option_c(locloc(@2)), $3, locloc(@$));}
-| VAR NON_RETAIN incompl_located_var_decl_list END_VAR
- {$$ = new incompl_located_var_declarations_c(new non_retain_option_c(locloc(@2)), $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| VAR incompl_located_var_decl_list error END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed incomplete located variable(s) declaration."); yyerrok;}
-| VAR RETAIN incompl_located_var_decl_list error END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed incomplete retentive located variable(s) declaration."); yyerrok;}
-| VAR NON_RETAIN incompl_located_var_decl_list error END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed incomplete non-retentive located variable(s) declaration."); yyerrok;}
-| VAR error incompl_located_var_decl_list END_VAR
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unexpected token after 'VAR' in incomplete located variable(s) declaration."); yyerrok;}
-| VAR RETAIN error incompl_located_var_decl_list END_VAR
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "unexpected token after 'RETAIN' in retentive located variable(s) declaration."); yyerrok;}
-| VAR NON_RETAIN error incompl_located_var_decl_list END_VAR
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "unexpected token after 'NON_RETAIN' in non-retentive located variable(s) declaration."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-/* helper symbol for incompl_located_var_declarations */
-incompl_located_var_decl_list:
- incompl_located_var_decl ';'
- {$$ = new incompl_located_var_decl_list_c(locloc(@$)); $$->add_element($1);}
-| incompl_located_var_decl_list incompl_located_var_decl ';'
- {$$ = $1; $$->add_element($2);}
-/* ERROR_CHECK_BEGIN */
-| incompl_located_var_decl error
- {$$ = new incompl_located_var_decl_list_c(locloc(@$)); print_err_msg(locl(@1), locf(@2), "';' missing at end of incomplete located variable declaration."); yyerrok;}
-| incompl_located_var_decl_list incompl_located_var_decl error
- {$$ = $1; print_err_msg(locl(@2), locf(@3), "';' missing at end of incomplete located variable declaration."); yyerrok;}
-| incompl_located_var_decl_list error ';'
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "invalid incomplete located variable declaration."); yyerrok;}
-| incompl_located_var_decl_list ';'
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected ';' after incomplete located variable declaration."); yynerrs++;}
-/* ERROR_CHECK_END */
-;
-
-
-incompl_located_var_decl:
- variable_name incompl_location ':' var_spec
- {$$ = new incompl_located_var_decl_c($1, $2, $4, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| variable_name incompl_location var_spec
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between incomplete located variable and type specification."); yynerrs++;
- }
-| variable_name incompl_location ':' error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no specification defined in incomplete located variable declaration.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid specification in incomplete located variable declaration."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-incompl_location:
- AT incompl_location_token
- {$$ = new incompl_location_c($2, locloc(@$));}
-;
-
-
-var_spec:
- simple_specification
-| subrange_specification
-| enumerated_specification
-| array_specification
-| prev_declared_structure_type_name
-| string_spec
-;
-
-
-/* helper symbol for var_spec */
-/* NOTE: The constructs
- *
- * STRING
- * and
- * WSTRING
- *
- * were removed as they are already contained
- * within a simple_specification.
- */
-string_spec:
-/* STRING
- {$$ = new single_byte_string_spec_c(NULL, NULL, locloc(@$));}
-*/
- STRING '[' integer ']'
- {$$ = new single_byte_string_spec_c($3, NULL, locloc(@$));}
-/*
-| WSTRING
- {$$ = new double_byte_string_spec_c(NULL, NULL, locloc(@$));}
-*/
-| WSTRING '[' integer ']'
- {$$ = new double_byte_string_spec_c($3, NULL, locloc(@$));}
-;
-
-
-
-
-/* intermediate helper symbol for:
- * - non_retentive_var_decls
- * - var_declarations
- */
-var_init_decl_list:
- var_init_decl ';'
- {$$ = new var_init_decl_list_c(locloc(@$)); $$->add_element($1);}
-| var_init_decl_list var_init_decl ';'
- {$$ = $1; $$->add_element($2);}
-/* ERROR_CHECK_BEGIN */
-| var_init_decl_list var_init_decl error
- {$$ = $1; print_err_msg(locl(@2), locf(@3), "';' missing at end of variable(s) declaration."); yyerrok;}
-| var_init_decl_list error ';'
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "invalid variable(s) declaration."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-
-
-/***********************/
-/* B 1.5.1 - Functions */
-/***********************/
-/*
-function_name:
- prev_declared_derived_function_name
-| standard_function_name
-;
-*/
-
-/* The following rules should be set such as:
- * function_name: function_name_no_clashes | function_name_simpleop_clashes | function_name_expression_clashes
- * function_name: function_name_no_NOT_clashes | function_name_NOT_clashes;
- */
-
-function_name_no_clashes: prev_declared_derived_function_name | standard_function_name_no_clashes;
-function_name_simpleop_clashes: standard_function_name_simpleop_clashes;
-//function_name_expression_clashes: standard_function_name_expression_clashes;
-
-function_name_no_NOT_clashes: prev_declared_derived_function_name | standard_function_name_no_NOT_clashes;
-//function_name_NOT_clashes: standard_function_name_NOT_clashes;
-
-
-/* NOTE: The list of standard function names
- * includes the standard functions MOD(), NOT()
- *
- * Strangely enough, MOD and NOT are reserved keywords,
- * so shouldn't be used for function names.
- *
- * The specification contradicts itself!
- * Our workaround is to treat MOD as a token,
- * but to include this token as a
- * standard_function_name.
- *
- * The names of all other standard functions get
- * preloaded into the library_element_symbol_table
- * with the token value of
- * standard_function_name_token
- * Actually, simply for completeness, MOD is also
- * loaded into the library_element_symbol_table, but
- * it is irrelevant since flex will catch MOD as a
- * token, before it interprets it as an identifier,
- * and looks in the library_element_symbol_table to check
- * whether it has been previously declared.
- *
- * NOTE: The same as the above also occurs with the IL
- * operators NOT AND OR XOR ADD SUB MUL DIV MOD
- * GT GE EQ LT LE NE.
- * Note that MOD is once again in the list!
- * Anyway, we give these the same treatement as
- * MOD, since we are writing a parser for ST and
- * IL simultaneously. If this were not the case,
- * the ST parser would not need the tokens NOT AND ...
- *
- * NOTE: Note that 'NOT' is special, as it conflicts
- * with two operators: the IL 'NOT' operator, and
- * the unary operator 'NOT' in ST!!
- *
- * NOTE: The IL language is ambiguous, since using NOT, AND, ...
- * may be interpreted as either an IL operator, or
- * as a standard function call!
- * I (Mario) opted to interpret it as an IL operator.
- * This requires changing the syntax for IL language
- * function calling, to exclude all function with
- * names that clash with IL operators. I therefore
- * created the constructs
- * function_name_without_clashes
- * standard_function_name_without_clashes
- * to include all function names, except those that clash
- * with IL operators. These constructs are only used
- * within the IL language!
- */
-/* The following rules should be set such as:
- * standard_function_name: standard_function_name_no_clashes | standard_function_name_simpleop_clashes | standard_function_name_expression_clashes
- * standard_function_name: standard_function_name_no_NOT_clashes | standard_function_name_NOT_clashes;
- */
-
-/*
-standard_function_name:
- standard_function_name_no_clashes
-| standard_function_name_expression_clashes
-| standard_function_name_NOT_clashes
-//| standard_function_name_simpleop_only_clashes
-;
-*/
-
-standard_function_name_no_NOT_clashes:
- standard_function_name_no_clashes
-| standard_function_name_expression_clashes
-//| standard_function_name_simpleop_only_clashes
-;
-
-standard_function_name_no_clashes:
- standard_function_name_token
- {$$ = new identifier_c($1, locloc(@$));}
-;
-
-
-standard_function_name_simpleop_clashes:
- standard_function_name_NOT_clashes
-//| standard_function_name_simpleop_only_clashes
-;
-
-standard_function_name_NOT_clashes:
- NOT
- {$$ = new identifier_c(strdup("NOT"), locloc(@$));}
-;
-
-/* Add here any other IL simple operators that collide
- * with standard function names!
- * Don't forget to uncomment the equivalent lines in
- * - standard_function_name_simpleop_clashes
- * - standard_function_name
- * - standard_function_name_no_NOT_clashes
- */
-/*
-standard_function_name_simpleop_only_clashes:
-;
-*/
-
-standard_function_name_expression_clashes:
- AND {$$ = new identifier_c(strdup("AND"), locloc(@$));}
-| OR {$$ = new identifier_c(strdup("OR"), locloc(@$));}
-| XOR {$$ = new identifier_c(strdup("XOR"), locloc(@$));}
-| ADD {$$ = new identifier_c(strdup("ADD"), locloc(@$));}
-| SUB {$$ = new identifier_c(strdup("SUB"), locloc(@$));}
-| MUL {$$ = new identifier_c(strdup("MUL"), locloc(@$));}
-| DIV {$$ = new identifier_c(strdup("DIV"), locloc(@$));}
-| MOD {$$ = new identifier_c(strdup("MOD"), locloc(@$));}
-| GT {$$ = new identifier_c(strdup("GT"), locloc(@$));}
-| GE {$$ = new identifier_c(strdup("GE"), locloc(@$));}
-| EQ {$$ = new identifier_c(strdup("EQ"), locloc(@$));}
-| LT {$$ = new identifier_c(strdup("LT"), locloc(@$));}
-| LE {$$ = new identifier_c(strdup("LE"), locloc(@$));}
-| NE {$$ = new identifier_c(strdup("NE"), locloc(@$));}
-/*
- AND_operator {$$ = il_operator_c_2_identifier_c($1);}
-//NOTE: AND2 (corresponding to the source code string '&') does not clash
-// with a standard function name, so should be commented out!
-//| AND2_operator {$$ = il_operator_c_2_identifier_c($1);}
-| OR_operator {$$ = il_operator_c_2_identifier_c($1);}
-| XOR_operator {$$ = il_operator_c_2_identifier_c($1);}
-| ADD_operator {$$ = il_operator_c_2_identifier_c($1);}
-| SUB_operator {$$ = il_operator_c_2_identifier_c($1);}
-| MUL_operator {$$ = il_operator_c_2_identifier_c($1);}
-| DIV_operator {$$ = il_operator_c_2_identifier_c($1);}
-| MOD_operator {$$ = il_operator_c_2_identifier_c($1);}
-| GT_operator {$$ = il_operator_c_2_identifier_c($1);}
-| GE_operator {$$ = il_operator_c_2_identifier_c($1);}
-| EQ_operator {$$ = il_operator_c_2_identifier_c($1);}
-| LT_operator {$$ = il_operator_c_2_identifier_c($1);}
-| LE_operator {$$ = il_operator_c_2_identifier_c($1);}
-| NE_operator {$$ = il_operator_c_2_identifier_c($1);}
-*/
-;
-
-
-derived_function_name:
- identifier
-| prev_declared_derived_function_name
- {$$ = $1;
- if (not(allow_function_overloading)) {
- fprintf(stderr, "Function overloading not allowed. Invalid identifier %s\n", ((token_c *)($1))->value);
- ERROR;
- }
- }
-;
-
-
-function_declaration:
-/* FUNCTION derived_function_name ':' elementary_type_name io_OR_function_var_declarations_list function_body END_FUNCTION */
- function_name_declaration ':' elementary_type_name io_OR_function_var_declarations_list function_body END_FUNCTION
- {$$ = new function_declaration_c($1, $3, $4, $5, locloc(@$));
- add_en_eno_param_decl_c::add_to($$); /* add EN and ENO declarations, if not already there */
- variable_name_symtable.pop();
- direct_variable_symtable.pop();
- if (allow_function_overloading) {
- switch (library_element_symtable.find_value($1)) {
- case prev_declared_derived_function_name_token:
- /* do nothing, already in map. */
- break;
- case BOGUS_TOKEN_ID:
- /* Not yet in map. Must insert...*/
- library_element_symtable.insert($1, prev_declared_derived_function_name_token);
- break;
- default:
- /* Already in map but associated with something else other than a funtion name! */
- ERROR;
- }
- } else {
- library_element_symtable.insert($1, prev_declared_derived_function_name_token);
- }
- }
-/* | FUNCTION derived_function_name ':' derived_type_name io_OR_function_var_declarations_list function_body END_FUNCTION */
-| function_name_declaration ':' derived_type_name io_OR_function_var_declarations_list function_body END_FUNCTION
- {$$ = new function_declaration_c($1, $3, $4, $5, locloc(@$));
- add_en_eno_param_decl_c::add_to($$); /* add EN and ENO declarations, if not already there */
- variable_name_symtable.pop();
- direct_variable_symtable.pop();
- if (allow_function_overloading) {
- switch (library_element_symtable.find_value($1)) {
- case prev_declared_derived_function_name_token: /* do nothing, already in map. */ break;
- case BOGUS_TOKEN_ID: library_element_symtable.insert($1, prev_declared_derived_function_name_token); break;
- default: ERROR;
- }
- } else {
- library_element_symtable.insert($1, prev_declared_derived_function_name_token);
- }
- }
-/* ERROR_CHECK_BEGIN */
-| function_name_declaration elementary_type_name io_OR_function_var_declarations_list function_body END_FUNCTION
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing after function name in function declaration."); yynerrs++;}
-| function_name_declaration derived_type_name io_OR_function_var_declarations_list function_body END_FUNCTION
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing after function name in function declaration."); yynerrs++;}
-| function_name_declaration ':' io_OR_function_var_declarations_list function_body END_FUNCTION
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "no return type defined in function declaration."); yynerrs++;}
-| function_name_declaration ':' error io_OR_function_var_declarations_list function_body END_FUNCTION
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid return type defined in function declaration."); yyerrok;}
-| function_name_declaration ':' elementary_type_name function_body END_FUNCTION
- {$$ = NULL; print_err_msg(locl(@3), locf(@4), "no variable(s) declared in function declaration."); yynerrs++;}
-| function_name_declaration ':' derived_type_name function_body END_FUNCTION
- {$$ = NULL; print_err_msg(locl(@3), locf(@4), "no variable(s) declared in function declaration."); yynerrs++;}
-| function_name_declaration ':' elementary_type_name io_OR_function_var_declarations_list END_FUNCTION
- {$$ = NULL; print_err_msg(locl(@4), locf(@5), "no body defined in function declaration."); yynerrs++;}
-| function_name_declaration ':' derived_type_name io_OR_function_var_declarations_list END_FUNCTION
- {$$ = NULL; print_err_msg(locl(@4), locf(@5), "no body defined in function declaration."); yynerrs++;}
-| function_name_declaration ':' elementary_type_name END_FUNCTION
- {$$ = NULL; print_err_msg(locl(@3), locf(@4), "no variable(s) declared and body defined in function declaration."); yynerrs++;}
-| function_name_declaration ':' derived_type_name END_FUNCTION
- {$$ = NULL; print_err_msg(locl(@3), locf(@4), "no variable(s) declared and body defined in function declaration."); yynerrs++;}
-| function_name_declaration ':' elementary_type_name io_OR_function_var_declarations_list function_body END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locf(@3), "unclosed function declaration."); yynerrs++;}
-| function_name_declaration ':' derived_type_name io_OR_function_var_declarations_list function_body END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@3), "unclosed function declaration."); yynerrs++;}
-| function_name_declaration error END_FUNCTION
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in function declaration."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-
-/* helper symbol for function_declaration */
-/* NOTE: due to reduce/reduce conflicts between identifiers
- * being reduced to either a variable or an enumerator value,
- * we were forced to keep a symbol table of the names
- * of all declared variables. Variables are no longer
- * created from simple identifier_token, but from
- * prev_declared_variable_name_token.
- *
- * BUT, in functions the function name itself may be used as
- * a variable! In order to be able to parse this correctly,
- * the token parser (flex) must return a prev_declared_variable_name_token
- * when it comes across the function name, while parsing
- * the function itself.
- * We do this by inserting the function name into the variable
- * symbol table, and having flex return a prev_declared_variable_name_token
- * whenever it comes across it.
- * When we finish parsing the function the variable name
- * symbol table is cleared of all entries, and the function
- * name is inserted into the library element symbol table. This
- * means that from then onwards flex will return a
- * derived_function_name_token whenever it comes across the
- * function name.
- *
- * In order to insert the function name into the variable_name
- * symbol table BEFORE the function body gets parsed, we
- * need the parser to reduce a construct that contains the
- * the function name. That is why we created this extra
- * construct (function_name_declaration), i.e. to force
- * the parser to reduce it, before parsing the function body!
- */
-function_name_declaration:
- FUNCTION derived_function_name
- {$$ = $2;
- /* the function name functions as a
- * variable within the function itself!
- *
- * Remember that the variable_name_symtable
- * is cleared once the end of the function
- * is parsed.
- */
- variable_name_symtable.insert($2, prev_declared_variable_name_token);
- }
-/* ERROR_CHECK_BEGIN */
-| FUNCTION error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@1), locf(@2), "no function name defined in function declaration.");}
- else {print_err_msg(locf(@2), locl(@2), "invalid function name in function declaration."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-
-/* intermediate helper symbol for function_declaration */
-io_OR_function_var_declarations_list:
- io_var_declarations
- {$$ = new var_declarations_list_c(locloc(@1));$$->add_element($1);}
-| function_var_decls
- {$$ = new var_declarations_list_c(locloc(@1));$$->add_element($1);}
-| io_OR_function_var_declarations_list io_var_declarations
- {$$ = $1; $$->add_element($2);}
-| io_OR_function_var_declarations_list function_var_decls
- {$$ = $1; $$->add_element($2);}
-/* ERROR_CHECK_BEGIN */
-| io_OR_function_var_declarations_list retentive_var_declarations
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected retentive variable(s) declaration in function declaration."); yynerrs++;}
-| io_OR_function_var_declarations_list located_var_declarations
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected located variable(s) declaration in function declaration."); yynerrs++;}
-| io_OR_function_var_declarations_list external_var_declarations
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected external variable(s) declaration in function declaration."); yynerrs++;}
-| io_OR_function_var_declarations_list global_var_declarations
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected global variable(s) declaration in function declaration."); yynerrs++;}
-| io_OR_function_var_declarations_list incompl_located_var_declarations
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected incomplete located variable(s) declaration in function declaration."); yynerrs++;}
-| io_OR_function_var_declarations_list temp_var_decls
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected temporary located variable(s) declaration in function declaration."); yynerrs++;}
-| io_OR_function_var_declarations_list non_retentive_var_decls
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected non-retentive variable(s) declaration in function declaration."); yynerrs++;}
-/*| io_OR_function_var_declarations_list access_declarations
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected access variable(s) declaration in function declaration."); yynerrs++;}*/
-| io_OR_function_var_declarations_list instance_specific_initializations
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected instance specific initialization(s) in function declaration."); yynerrs++;}
-/* ERROR_CHECK_END */
-;
-
-
-io_var_declarations:
- input_declarations
-| output_declarations
-| input_output_declarations
-;
-
-
-function_var_decls:
- VAR CONSTANT var2_init_decl_list END_VAR
- {$$ = new function_var_decls_c(new constant_option_c(locloc(@2)), $3, locloc(@$));}
-| VAR var2_init_decl_list END_VAR
- {$$ = new function_var_decls_c(NULL, $2, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| VAR error var2_init_decl_list END_VAR
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unexpected token after 'VAR' in function variable(s) declaration."); yyerrok;}
-| VAR CONSTANT error var2_init_decl_list END_VAR
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "unexpected token after 'CONSTANT' in constant function variable(s) declaration."); yyerrok;}
-| VAR var2_init_decl_list error END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed function variable(s) declaration."); yyerrok;}
-| VAR CONSTANT var2_init_decl_list error END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed constant function variable(s) declaration."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-/* intermediate helper symbol for function_var_decls */
-var2_init_decl_list:
- var2_init_decl ';'
- {$$ = new var2_init_decl_list_c(locloc(@$)); $$->add_element($1);}
-| var2_init_decl_list var2_init_decl ';'
- {$$ = $1; $$->add_element($2);}
-/* ERROR_CHECK_BEGIN */
-| var2_init_decl error
- {$$ = new var2_init_decl_list_c(locloc(@$)); print_err_msg(locl(@1), locf(@2), "';' missing at end of function variable(s) declaration."); yyerrok;}
-| var2_init_decl_list var2_init_decl error
- {$$ = $1; print_err_msg(locl(@2), locf(@3), "';' missing at end of function variable(s) declaration."); yyerrok;}
-| var2_init_decl_list error ';'
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "invalid function variable(s) declaration."); yyerrok;}
-| var2_init_decl_list ';'
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected ';' after function variable(s) declaration."); yynerrs++;}
-/* ERROR_CHECK_END */
-;
-
-
-function_body:
- statement_list {$$ = $1;} /* if we leave it for the default action we get a type clash! */
-| instruction_list {$$ = $1;} /* if we leave it for the default action we get a type clash! */
-/*
-| ladder_diagram
-| function_block_diagram
-*/
-;
-
-
-var2_init_decl:
- var1_init_decl
-| array_var_init_decl
-| structured_var_init_decl
-| string_var_declaration
-;
-
-
-
-/*****************************/
-/* B 1.5.2 - Function Blocks */
-/*****************************/
-function_block_type_name:
- prev_declared_derived_function_block_name
-| standard_function_block_name
-;
-
-
-standard_function_block_name: standard_function_block_name_token {$$ = new identifier_c($1, locloc(@$));};
-
-derived_function_block_name: identifier;
-
-
-function_block_declaration:
- FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations_list function_block_body END_FUNCTION_BLOCK
- {$$ = new function_block_declaration_c($2, $3, $4, locloc(@$));
- add_en_eno_param_decl_c::add_to($$); /* add EN and ENO declarations, if not already there */
- library_element_symtable.insert($2, prev_declared_derived_function_block_name_token);
- /* Clear the variable_name_symtable. Since
- * we have finished parsing the function block,
- * the variable names are now out of scope, so
- * are no longer valid!
- */
- variable_name_symtable.pop();
- direct_variable_symtable.pop();
- }
-/* ERROR_CHECK_BEGIN */
-| FUNCTION_BLOCK io_OR_other_var_declarations_list function_block_body END_FUNCTION_BLOCK
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no function block name defined in function block declaration."); yynerrs++;}
-| FUNCTION_BLOCK error io_OR_other_var_declarations_list function_block_body END_FUNCTION_BLOCK
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid function block name in function block declaration."); yyerrok;}
-| FUNCTION_BLOCK derived_function_block_name function_block_body END_FUNCTION_BLOCK
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable(s) declared in function declaration."); yynerrs++;}
-| FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations_list END_FUNCTION_BLOCK
- {$$ = NULL; print_err_msg(locl(@3), locf(@4), "no body defined in function block declaration."); yynerrs++;}
-| FUNCTION_BLOCK derived_function_block_name END_FUNCTION_BLOCK
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable(s) declared and body defined in function block declaration."); yynerrs++;}
-| FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations_list function_block_body END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@2), "no variable(s) declared and body defined in function block declaration."); yynerrs++;}
-| FUNCTION_BLOCK error END_FUNCTION_BLOCK
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in function block declaration."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-
-/* intermediate helper symbol for function_declaration */
-/* { io_var_declarations | other_var_declarations } */
-/*
- * NOTE: we re-use the var_declarations_list_c
- */
-io_OR_other_var_declarations_list:
- io_var_declarations
- {$$ = new var_declarations_list_c(locloc(@$));$$->add_element($1);}
-| other_var_declarations
- {$$ = new var_declarations_list_c(locloc(@$));$$->add_element($1);}
-| io_OR_other_var_declarations_list io_var_declarations
- {$$ = $1; $$->add_element($2);}
-| io_OR_other_var_declarations_list other_var_declarations
- {$$ = $1; $$->add_element($2);}
-/* ERROR_CHECK_BEGIN */
-| io_OR_other_var_declarations_list located_var_declarations
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected located variable(s) declaration in function block declaration."); yynerrs++;}
-| io_OR_other_var_declarations_list global_var_declarations
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected global variable(s) declaration in function block declaration."); yynerrs++;}
-/*| io_OR_other_var_declarations_list access_declarations
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected access variable(s) declaration in function block declaration."); yynerrs++;}*/
-| io_OR_other_var_declarations_list instance_specific_initializations
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected instance specific initialization(s) in function block declaration."); yynerrs++;}
-/* ERROR_CHECK_END */
-;
-
-/* NOTE:
- * The IEC specification gives the following definition:
- * other_var_declarations ::=
- * external_var_declarations
- * | var_declarations
- * | retentive_var_declarations
- * | non_retentive_var_declarations
- * | temp_var_decls
- * | incompl_located_var_declarations
- *
- * Nvertheless, the symbol non_retentive_var_declarations
- * is not defined in the spec. This seems to me (Mario)
- * to be a typo, so non_retentive_var_declarations
- * has been replaced with non_retentive_var_decls
- * in the following rule!
- */
-other_var_declarations:
- temp_var_decls
-| non_retentive_var_decls
-| external_var_declarations
-| var_declarations
-| retentive_var_declarations
-| incompl_located_var_declarations
-;
-
-
-temp_var_decls:
- VAR_TEMP temp_var_decls_list END_VAR
- {$$ = new temp_var_decls_c($2, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| VAR_TEMP END_VAR
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no variable declared in temporary variable(s) declaration."); yynerrs++;}
-| VAR_TEMP temp_var_decls_list error END_OF_INPUT
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "unclosed temporary variable(s) declaration."); yyerrok;}
-| VAR_TEMP error temp_var_decls_list END_VAR
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unexpected token after 'VAR_TEMP' in function variable(s) declaration."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-/* intermediate helper symbol for temp_var_decls */
-temp_var_decls_list:
- temp_var_decl ';'
- {$$ = new temp_var_decls_list_c(locloc(@$)); $$->add_element($1);}
-| temp_var_decls_list temp_var_decl ';'
- {$$ = $1; $$->add_element($2);}
-/* ERROR_CHECK_BEGIN */
-| error ';'
- {$$ = new temp_var_decls_list_c(locloc(@$)); print_err_msg(locf(@1), locl(@1), "invalid temporary variable(s) declaration."); yyerrok;}
-| temp_var_decl error
- {$$ = new temp_var_decls_list_c(locloc(@$)); print_err_msg(locl(@1), locf(@2), "';' missing at end of temporary variable(s) declaration."); yyerrok;}
-| temp_var_decls_list temp_var_decl error
- {$$ = $1; print_err_msg(locl(@2), locf(@3), "';' missing at end of temporary variable(s) declaration."); yyerrok;}
-| temp_var_decls_list error ';'
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "invalid temporary variable(s) declaration."); yyerrok;}
-| temp_var_decls_list ';'
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected ';' after temporary variable(s) declaration."); yynerrs++;}
-/* ERROR_CHECK_END */
-;
-
-
-non_retentive_var_decls:
- VAR NON_RETAIN var_init_decl_list END_VAR
- {$$ = new non_retentive_var_decls_c($3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| VAR NON_RETAIN var_init_decl_list error END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "unclosed non-retentive temporary variable(s) declaration."); yyerrok;}
-| VAR NON_RETAIN error var_init_decl_list END_VAR
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "unexpected token after 'NON_RETAIN' in non-retentive temporary variable(s) declaration."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-
-function_block_body:
- statement_list {$$ = $1;}
-| instruction_list {$$ = $1;}
-| sequential_function_chart {$$ = $1;}
-/*
-| ladder_diagram
-| function_block_diagram
-| <other languages>
-*/
-;
-
-
-
-
-/**********************/
-/* B 1.5.3 - Programs */
-/**********************/
-program_type_name: identifier;
-
-
-program_declaration:
- PROGRAM program_type_name program_var_declarations_list function_block_body END_PROGRAM
- {$$ = new program_declaration_c($2, $3, $4, locloc(@$));
- library_element_symtable.insert($2, prev_declared_program_type_name_token);
- /* Clear the variable_name_symtable. Since
- * we have finished parsing the program declaration,
- * the variable names are now out of scope, so
- * are no longer valid!
- */
- variable_name_symtable.pop();
- direct_variable_symtable.pop();
- }
-/* ERROR_CHECK_BEGIN */
-| PROGRAM program_var_declarations_list function_block_body END_PROGRAM
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no program name defined in program declaration.");}
-| PROGRAM error program_var_declarations_list function_block_body END_PROGRAM
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid program name in program declaration."); yyerrok;}
-| PROGRAM program_type_name function_block_body END_PROGRAM
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable(s) declared in program declaration."); yynerrs++;}
-| PROGRAM program_type_name program_var_declarations_list END_PROGRAM
- {$$ = NULL; print_err_msg(locl(@3), locf(@4), "no body defined in program declaration."); yynerrs++;}
-| PROGRAM program_type_name END_PROGRAM
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable(s) declared and body defined in program declaration."); yynerrs++;}
-| PROGRAM program_type_name program_var_declarations_list function_block_body END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed program declaration."); yynerrs++;}
-| PROGRAM error END_PROGRAM
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in program declaration."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-/* helper symbol for program_declaration */
-/*
- * NOTE: we re-use the var_declarations_list_c
- */
-program_var_declarations_list:
- io_var_declarations
- {$$ = new var_declarations_list_c(locloc(@$)); $$->add_element($1);}
-| other_var_declarations
- {$$ = new var_declarations_list_c(locloc(@$)); $$->add_element($1);}
-| located_var_declarations
- {$$ = new var_declarations_list_c(locloc(@$)); $$->add_element($1);}
-| program_var_declarations_list io_var_declarations
- {$$ = $1; $$->add_element($2);}
-| program_var_declarations_list other_var_declarations
- {$$ = $1; $$->add_element($2);}
-| program_var_declarations_list located_var_declarations
- {$$ = $1; $$->add_element($2);}
-/*
-| program_var_declarations_list program_access_decls
- {$$ = $1; $$->add_element($2);}
-*/
-/* ERROR_CHECK_BEGIN */
-| program_var_declarations_list global_var_declarations
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected global variable(s) declaration in function block declaration."); yynerrs++;}
-/*| program_var_declarations_list access_declarations
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected access variable(s) declaration in function block declaration."); yynerrs++;}*/
-| program_var_declarations_list instance_specific_initializations
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected instance specific initialization(s) in function block declaration."); yynerrs++;
- }
-/* ERROR_CHECK_END */
-;
-
-
-/* TODO ... */
-/*
-program_access_decls:
- VAR_ACCESS program_access_decl_list END_VAR
-;
-*/
-
-/* helper symbol for program_access_decls */
-/*
-program_access_decl_list:
- program_access_decl ';'
-| program_access_decl_list program_access_decl ';'
-;
-*/
-
-/*
-program_access_decl:
- access_name ':' symbolic_variable ':' non_generic_type_name
-| access_name ':' symbolic_variable ':' non_generic_type_name direction
-;
-*/
-
-
-
-/********************************************/
-/* B 1.6 Sequential Function Chart elements *
-/********************************************/
-
-sequential_function_chart:
- sfc_network
- {$$ = new sequential_function_chart_c(locloc(@$)); $$->add_element($1);}
-| sequential_function_chart sfc_network
- {$$ = $1; $$->add_element($2);}
-;
-
-sfc_network:
- initial_step
- {$$ = new sfc_network_c(locloc(@$)); $$->add_element($1);}
-| sfc_network step
- {$$ = $1; $$->add_element($2);}
-| sfc_network transition
- {$$ = $1; $$->add_element($2);}
-| sfc_network action
- {$$ = $1; $$->add_element($2);}
-/* ERROR_CHECK_BEGIN */
-| sfc_network error
- {$$ = $1; print_err_msg(locl(@1), locf(@2), "unexpected token after SFC network in sequencial function chart."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-initial_step:
- INITIAL_STEP step_name ':' action_association_list END_STEP
-// INITIAL_STEP identifier ':' action_association_list END_STEP
- {$$ = new initial_step_c($2, $4, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| INITIAL_STEP ':' action_association_list END_STEP
- {$$ = NULL; print_err_msg(locf(@1), locl(@2), "no step name defined in initial step declaration."); yynerrs++;}
-| INITIAL_STEP error ':' action_association_list END_STEP
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid step name defined in initial step declaration."); yyerrok;}
-| INITIAL_STEP step_name action_association_list END_STEP
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "':' missing after step name in initial step declaration."); yynerrs++;}
-| INITIAL_STEP step_name ':' error END_STEP
- {$$ = NULL; print_err_msg(locf(@4), locl(@4), "invalid action association list in initial step declaration."); yyerrok;}
-| INITIAL_STEP step_name ':' action_association_list END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@3), "unclosed initial step declaration."); yynerrs++;}
-| INITIAL_STEP error END_STEP
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in initial step declaration."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-step:
- STEP step_name ':' action_association_list END_STEP
-// STEP identifier ':' action_association_list END_STEP
- {$$ = new step_c($2, $4, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| STEP ':' action_association_list END_STEP
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no step name defined in step declaration."); yynerrs++;}
-| STEP error ':' action_association_list END_STEP
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid step name defined in step declaration."); yyerrok;}
-| STEP step_name action_association_list END_STEP
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "':' missing after step name in step declaration."); yynerrs++;}
-| STEP step_name ':' error END_STEP
- {$$ = NULL; print_err_msg(locf(@4), locl(@4), "invalid action association list in step declaration."); yyerrok;}
-| STEP step_name ':' action_association_list END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@3), "invalid action association list in step declaration."); yynerrs++;}
-| STEP error END_STEP
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in step declaration."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-/* helper symbol for:
- * - initial_step
- * - step
- */
-action_association_list:
- /* empty */
- {$$ = new action_association_list_c(locloc(@$));}
-| action_association_list action_association ';'
- {$$ = $1; $$->add_element($2);}
-/* ERROR_CHECK_BEGIN */
-| action_association_list action_association error
- {$$ = $1; print_err_msg(locl(@2), locf(@3), "';' missing at end of action association declaration."); yyerrok;}
-| action_association_list ';'
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected ';' after action association declaration."); yynerrs++;}
-/* ERROR_CHECK_END */
-;
-
-
-// step_name: identifier;
-step_name: any_identifier;
-
-action_association:
- action_name '(' {cmd_goto_sfc_qualifier_state();} action_qualifier {cmd_pop_state();} indicator_name_list ')'
- {$$ = new action_association_c($1, $4, $6, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-/*| action_name '(' error ')'
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid qualifier defined in action association."); yyerrok;}*/
-/* ERROR_CHECK_END */
-;
-
-/* helper symbol for action_association */
-indicator_name_list:
- /* empty */
- {$$ = new indicator_name_list_c(locloc(@$));}
-| indicator_name_list ',' indicator_name
- {$$ = $1; $$->add_element($3);}
-/* ERROR_CHECK_BEGIN */
-| indicator_name_list indicator_name
- {$$ = $1; print_err_msg(locl(@1), locf(@2), "',' missing at end of action association declaration."); yynerrs++;}
-| indicator_name_list ',' error
- {$$ = $1;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no indicator defined in indicator list.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid indicator in indicator list."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-// action_name: identifier;
-action_name: any_identifier;
-
-action_qualifier:
- /* empty */
- {$$ = NULL;}
-| qualifier
- {$$ = new action_qualifier_c($1, NULL, locloc(@$));}
-| timed_qualifier ',' action_time
- {$$ = new action_qualifier_c($1, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| timed_qualifier action_time
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "',' missing between timed qualifier and action time in action qualifier."); yynerrs++;}
-| timed_qualifier ',' error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no action time defined in action qualifier.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid action time in action qualifier."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-qualifier:
- N {$$ = new qualifier_c(strdup("N"), locloc(@$));}
-| R {$$ = new qualifier_c(strdup("R"), locloc(@$));}
-| S {$$ = new qualifier_c(strdup("S"), locloc(@$));}
-| P {$$ = new qualifier_c(strdup("P"), locloc(@$));}
-;
-
-timed_qualifier:
- L {$$ = new timed_qualifier_c(strdup("L"), locloc(@$));}
-| D {$$ = new timed_qualifier_c(strdup("D"), locloc(@$));}
-| SD {$$ = new timed_qualifier_c(strdup("SD"), locloc(@$));}
-| DS {$$ = new timed_qualifier_c(strdup("DS"), locloc(@$));}
-| SL {$$ = new timed_qualifier_c(strdup("SL"), locloc(@$));}
-;
-
-action_time:
- duration
-| variable
-;
-
-indicator_name: variable;
-
-// transition_name: identifier;
-transition_name: any_identifier;
-
-
-steps:
- step_name
- {$$ = new steps_c($1, NULL, locloc(@$));}
-| '(' step_name_list ')'
- {$$ = new steps_c(NULL, $2, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| '(' step_name_list error
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "expecting ')' at the end of step list in transition declaration."); yyerrok;}
-| '(' error ')'
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid step list in transition declaration."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-step_name_list:
- step_name ',' step_name
- {$$ = new step_name_list_c(locloc(@$)); $$->add_element($1); $$->add_element($3);}
-| step_name_list ',' step_name
- {$$ = $1; $$->add_element($3);}
-/* ERROR_CHECK_BEGIN */
-| step_name_list step_name
- {$$ = $1; print_err_msg(locl(@1), locf(@2), "',' missing in step list."); yynerrs++;}
-| step_name_list ',' error
- {$$ = $1;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no step name defined in step list.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid step name in step list."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-/* NOTE: flex will automatically pop() out of body_state to previous state.
- * We do not need to give a command from bison to return to previous flex state,
- * after forcing flex to go to body_state.
- */
-transition:
- TRANSITION transition_priority
- FROM steps TO steps
- {cmd_goto_body_state();} transition_condition
- END_TRANSITION
- {$$ = new transition_c(NULL, $2, $4, $6, $8, locloc(@$));}
-//| TRANSITION identifier FROM steps TO steps ...
-| TRANSITION transition_name transition_priority
- FROM steps TO steps
- {cmd_goto_body_state();} transition_condition
- END_TRANSITION
- {$$ = new transition_c($2, $3, $5, $7, $9, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| TRANSITION error transition_priority FROM steps TO steps {cmd_goto_body_state();} transition_condition END_TRANSITION
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid transition name defined in transition declaration."); yyerrok;}
-| TRANSITION transition_name error FROM steps TO steps {cmd_goto_body_state();} transition_condition END_TRANSITION
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid transition priority defined in transition declaration."); yyerrok;}
-| TRANSITION transition_priority FROM TO steps {cmd_goto_body_state();} transition_condition END_TRANSITION
- {$$ = NULL; print_err_msg(locl(@3), locf(@4), "no origin step(s) defined in transition declaration."); yynerrs++;}
-| TRANSITION transition_name transition_priority FROM TO steps {cmd_goto_body_state();} transition_condition END_TRANSITION
- {$$ = NULL; print_err_msg(locl(@4), locf(@5), "no origin step(s) defined in transition declaration."); yynerrs++;}
-| TRANSITION transition_priority FROM error TO steps {cmd_goto_body_state();} transition_condition END_TRANSITION
- {$$ = NULL; print_err_msg(locf(@4), locl(@4), "invalid origin step(s) defined in transition declaration."); yyerrok;}
-| TRANSITION transition_name transition_priority FROM error TO steps {cmd_goto_body_state();} transition_condition END_TRANSITION
- {$$ = NULL; print_err_msg(locf(@5), locl(@5), "invalid origin step(s) defined in transition declaration."); yyerrok;}
-| TRANSITION transition_priority FROM steps steps {cmd_goto_body_state();} transition_condition END_TRANSITION
- {$$ = NULL; print_err_msg(locl(@4), locf(@5), "'TO' missing between origin step(s) and destination step(s) in transition declaration."); yynerrs++;}
-| TRANSITION transition_name transition_priority FROM steps steps {cmd_goto_body_state();} transition_condition END_TRANSITION
- {$$ = NULL; print_err_msg(locl(@5), locf(@6), "'TO' missing between origin step(s) and destination step(s) in transition declaration."); yynerrs++;}
-| TRANSITION transition_priority FROM steps TO {cmd_goto_body_state();} transition_condition END_TRANSITION
- {$$ = NULL; print_err_msg(locl(@5), locf(@7), "no destination step(s) defined in transition declaration."); yynerrs++;}
-| TRANSITION transition_name transition_priority FROM steps TO {cmd_goto_body_state();} transition_condition END_TRANSITION
- {$$ = NULL; print_err_msg(locl(@6), locf(@8), "no destination step(s) defined in transition declaration."); yynerrs++;}
-| TRANSITION transition_priority FROM steps TO error {cmd_goto_body_state();} transition_condition END_TRANSITION
- {$$ = NULL; print_err_msg(locf(@6), locl(@6), "invalid destination step(s) defined in transition declaration."); yyerrok;}
-| TRANSITION transition_name transition_priority FROM steps TO error {cmd_goto_body_state();} transition_condition END_TRANSITION
- {$$ = NULL; print_err_msg(locf(@7), locl(@7), "invalid destination step(s) defined in transition declaration."); yyerrok;}
-| TRANSITION transition_priority {cmd_goto_body_state();} transition_condition END_TRANSITION
- {$$ = NULL; print_err_msg(locl(@2), locf(@4), "no origin and destination step(s) defined in transition declaration."); yynerrs++;}
-| TRANSITION transition_name transition_priority {cmd_goto_body_state();} transition_condition END_TRANSITION
- {$$ = NULL; print_err_msg(locl(@3), locf(@5), "no origin and destination step(s) defined in transition declaration."); yynerrs++;}
-/*| TRANSITION transition_priority FROM steps TO steps {cmd_goto_body_state();} transition_condition error END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@6), "unclosed transition declaration."); yyerrok;}
-| TRANSITION transition_name transition_priority FROM steps TO steps {cmd_goto_body_state();} transition_condition error END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@7), "unclosed transition declaration."); yyerrok;}*/
-| TRANSITION error END_TRANSITION
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in transition declaration."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-transition_priority:
- /* empty */
- {$$ = NULL;}
-| '(' {cmd_goto_sfc_priority_state();} PRIORITY {cmd_pop_state();} ASSIGN integer ')'
- {$$ = $6;}
-/* ERROR_CHECK_BEGIN
-| '(' ASSIGN integer ')'
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "'PRIORITY' missing between '(' and ':=' in transition declaration with priority."); yynerrs++;}
-| '(' error ASSIGN integer ')'
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "expecting 'PRIORITY' between '(' and ':=' in transition declaration with priority."); yyerrok;}
- ERROR_CHECK_END */
-;
-
-
-transition_condition:
- ':' eol_list simple_instr_list
- {$$ = new transition_condition_c($3, NULL, locloc(@$));}
-| ASSIGN expression ';'
- {$$ = new transition_condition_c(NULL, $2, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| eol_list simple_instr_list
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing before IL condition in transition declaration."); yynerrs++;}
-| ':' eol_list error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no instructions defined in IL condition of transition declaration.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid instructions in IL condition of transition declaration."); yyclearin;}
- yyerrok;
- }
-| ASSIGN ';'
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no expression defined in ST condition of transition declaration."); yynerrs++;}
-| ASSIGN error ';'
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid expression defined in ST condition of transition declaration."); yyerrok;}
-| ASSIGN expression error
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "expecting ';' after expression defined in ST condition of transition declaration."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-
-action:
-// ACTION identifier ':' ...
- ACTION action_name {cmd_goto_body_state();} action_body END_ACTION
- {$$ = new action_c($2, $4, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| ACTION {cmd_goto_body_state();} action_body END_ACTION
- {$$ = NULL; print_err_msg(locl(@1), locf(@3), "no action name defined in action declaration."); yynerrs++;}
-| ACTION error {cmd_goto_body_state();} action_body END_ACTION
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid action name defined in action declaration."); yyerrok;}
-| ACTION action_name {cmd_goto_body_state();} function_block_body END_ACTION
- {$$ = NULL; print_err_msg(locl(@2), locf(@4), "':' missing after action name in action declaration."); yynerrs++;}
-/*| ACTION action_name {cmd_goto_body_state();} action_body END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed action declaration."); yyerrok;}*/
-| ACTION error END_ACTION
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in action declaration."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-action_body:
- ':' function_block_body
- {$$ = $2;}
-/* ERROR_CHECK_BEGIN */
-| ':' error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@1), locf(@2), "no body defined in action declaration.");}
- else {print_err_msg(locf(@2), locl(@2), "invalid body defined in action declaration."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-/********************************/
-/* B 1.7 Configuration elements */
-/********************************/
-/* NOTE:
- * It is not clear from reading the specification to which namespace
- * the names of resources, tasks and programs belong to.
- *
- * The following syntax assumes that resource and program names belong to the
- * same namespace as the variables defined within
- * the resource/configuration (i.e. VAR_GLOBAL).
- * Task names belong to a namespace all of their own, since they don't
- * produce conflicts in the syntax parser, so we might just as well
- * leave them be! ;-)
- * The above decision was made taking into
- * account that inside a VAR_CONFIG declaration global variables
- * may be referenced starting off from the resource name as:
- * resource_name.program_name.variable_name
- * Notice how resource names and program names are used in a very similar
- * manner as are variable names.
- * Using a single namespace for all the above mentioned names
- * also makes it easier to write the syntax parser!! ;-) Using a private
- * namespace for each of the name types (resource names, program names,
- * global varaiable names), i.e. letting the names be re-used across
- * each of the groups (resource, program, global variables), produces
- * reduce/reduce conflicts in the syntax parser. Actually, it is only
- * the resource names that need to be distinguished into a
- * prev_declared_resource_name so as not to conflict with [gloabl] variable
- * names in the 'data' construct.
- * The program names are only tracked to make sure that two programs do not
- * get the same name.
- *
- * Using a single namespace does have the drawback that the user will
- * not be able to re-use names for resources or programs if these
- * have already been used to name a variable!
- *
- * If it ever becomes necessary to change this interpretation of
- * the syntax, then this section of the syntax parser must be updated!
- */
-prev_declared_global_var_name: prev_declared_global_var_name_token {$$ = new identifier_c($1, locloc(@$));};
-prev_declared_resource_name: prev_declared_resource_name_token {$$ = new identifier_c($1, locloc(@$));};
-prev_declared_program_name: prev_declared_program_name_token {$$ = new identifier_c($1, locloc(@$));};
-// prev_declared_task_name: prev_declared_task_name_token {$$ = new identifier_c($1, locloc(@$));};
-
-
-
-
-
-
-configuration_name: identifier;
-
-/* NOTE: The specification states that valid resource type names
- * are implementation defined, i.e. each implementaion will define
- * what resource types it supports.
- * We are implementing this syntax parser to be used by any
- * implementation, so at the moment we accept any identifier
- * as a resource type name.
- * This implementation should probably be changed in the future. We
- * should probably have a resource_type_name_token, and let the
- * implementation load the global symbol library with the
- * accepted resource type names before parsing the code.
- *
- */
-resource_type_name: any_identifier;
-
-configuration_declaration:
- CONFIGURATION configuration_name
- optional_global_var_declarations
- single_resource_declaration
- {variable_name_symtable.pop();
- direct_variable_symtable.pop();}
- optional_access_declarations
- optional_instance_specific_initializations
- END_CONFIGURATION
- {$$ = new configuration_declaration_c($2, $3, $4, $6, $7, locloc(@$));
- library_element_symtable.insert($2, prev_declared_configuration_name_token);
- variable_name_symtable.pop();
- direct_variable_symtable.pop();
- }
-| CONFIGURATION configuration_name
- optional_global_var_declarations
- resource_declaration_list
- optional_access_declarations
- optional_instance_specific_initializations
- END_CONFIGURATION
- {$$ = new configuration_declaration_c($2, $3, $4, $5, $6, locloc(@$));
- library_element_symtable.insert($2, prev_declared_configuration_name_token);
- variable_name_symtable.pop();
- direct_variable_symtable.pop();
-}
-/* ERROR_CHECK_BEGIN */
-| CONFIGURATION
- optional_global_var_declarations
- single_resource_declaration
- {variable_name_symtable.pop();
- direct_variable_symtable.pop();}
- optional_access_declarations
- optional_instance_specific_initializations
- END_CONFIGURATION
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no configuration name defined in configuration declaration."); yynerrs++;}
-| CONFIGURATION
- optional_global_var_declarations
- resource_declaration_list
- optional_access_declarations
- optional_instance_specific_initializations
- END_CONFIGURATION
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no configuration name defined in configuration declaration."); yynerrs++;}
-| CONFIGURATION error
- optional_global_var_declarations
- single_resource_declaration
- {variable_name_symtable.pop();
- direct_variable_symtable.pop();}
- optional_access_declarations
- optional_instance_specific_initializations
- END_CONFIGURATION
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid configuration name defined in configuration declaration."); yyerrok;}
-| CONFIGURATION error
- optional_global_var_declarations
- resource_declaration_list
- optional_access_declarations
- optional_instance_specific_initializations
- END_CONFIGURATION
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid configuration name defined in configuration declaration."); yyerrok;}
-| CONFIGURATION configuration_name
- optional_global_var_declarations
- optional_access_declarations
- optional_instance_specific_initializations
- END_CONFIGURATION
- {$$ = NULL; print_err_msg(locl(@3), locf(@4), "no resource(s) defined in configuration declaration."); yynerrs++;}
-| CONFIGURATION configuration_name
- optional_global_var_declarations
- error
- optional_access_declarations
- optional_instance_specific_initializations
- END_CONFIGURATION
- {$$ = NULL; print_err_msg(locf(@4), locl(@4), "invalid resource(s) defined in configuration declaration."); yyerrok;}
-/*| CONFIGURATION configuration_name
- optional_global_var_declarations
- single_resource_declaration
- {variable_name_symtable.pop();
- direct_variable_symtable.pop();}
- optional_access_declarations
- optional_instance_specific_initializations
- END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed configuration declaration."); yyerrok;}*/
-| CONFIGURATION configuration_name
- optional_global_var_declarations
- resource_declaration_list
- optional_access_declarations
- optional_instance_specific_initializations
- END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed configuration declaration."); yyerrok;}
-| CONFIGURATION error END_CONFIGURATION
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in configuration declaration."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-// helper symbol for
-// - configuration_declaration
-// - resource_declaration
-//
-optional_global_var_declarations:
- // empty
- {$$ = NULL;}
-| global_var_declarations
-;
-
-
-// helper symbol for configuration_declaration //
-optional_access_declarations:
- // empty
- {$$ = NULL;}
-//| access_declarations
-;
-
-// helper symbol for configuration_declaration //
-optional_instance_specific_initializations:
- // empty
- {$$ = NULL;}
-| instance_specific_initializations
-;
-
-// helper symbol for configuration_declaration //
-resource_declaration_list:
- resource_declaration
- {$$ = new resource_declaration_list_c(locloc(@$)); $$->add_element($1);}
-| resource_declaration_list resource_declaration
- {$$ = $1; $$->add_element($2);}
-/* ERROR_CHECK_BEGIN */
-| resource_declaration_list error
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected token after resource declaration."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-resource_declaration:
- RESOURCE {variable_name_symtable.push();direct_variable_symtable.push();} resource_name ON resource_type_name
- optional_global_var_declarations
- single_resource_declaration
- END_RESOURCE
- {$$ = new resource_declaration_c($3, $5, $6, $7, locloc(@$));
- variable_name_symtable.pop();
- direct_variable_symtable.pop();
- variable_name_symtable.insert($3, prev_declared_resource_name_token);
- }
-/* ERROR_CHECK_BEGIN */
-| RESOURCE {variable_name_symtable.push();direct_variable_symtable.push();} ON resource_type_name
- optional_global_var_declarations
- single_resource_declaration
- END_RESOURCE
- {$$ = NULL; print_err_msg(locl(@1), locf(@3), "no resource name defined in resource declaration."); yynerrs++;}
-/*| RESOURCE {variable_name_symtable.push();direct_variable_symtable.push();} resource_name ON resource_type_name
- optional_global_var_declarations
- single_resource_declaration
- END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@5), "unclosed resource declaration."); yyerrok;}*/
-| RESOURCE error END_RESOURCE
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in resource declaration."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-single_resource_declaration:
- task_configuration_list program_configuration_list
- {$$ = new single_resource_declaration_c($1, $2, locloc(@$));}
-;
-
-
-// helper symbol for single_resource_declaration //
-task_configuration_list:
- // empty
- {$$ = new task_configuration_list_c(locloc(@$));}
-| task_configuration_list task_configuration ';'
- {$$ = $1; $$->add_element($2);}
-/* ERROR_CHECK_BEGIN */
-| task_configuration_list task_configuration error
- {$$ = $1; print_err_msg(locl(@1), locf(@2), "';' missing at the end of task configuration in resource declaration."); yyerrok;}
-| task_configuration_list ';'
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected ';' after task configuration in resource declaration."); yynerrs++;}
-/* ERROR_CHECK_END */
-;
-
-
-// helper symbol for single_resource_declaration //
-program_configuration_list:
- program_configuration ';'
- {$$ = new program_configuration_list_c(locloc(@$)); $$->add_element($1);}
-| program_configuration_list program_configuration ';'
- {$$ = $1; $$->add_element($2);}
-/* ERROR_CHECK_BEGIN */
-| program_configuration error
- {$$ = new program_configuration_list_c(locloc(@$)); print_err_msg(locl(@1), locf(@2), "';' missing at the end of program configuration in resource declaration."); yyerrok;}
-| program_configuration_list program_configuration error
- {$$ = $1; print_err_msg(locl(@2), locf(@3), "';' missing at the end of program configuration in resource declaration."); yyerrok;}
-| program_configuration_list error ';'
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "invalid program configuration in resource declaration."); yyerrok;}
-| program_configuration_list ';'
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected ';' after program configuration in resource declaration."); yynerrs++;}
-/* ERROR_CHECK_END */
-;
-
-
-resource_name: identifier;
-
-/*
-access_declarations:
- VAR_ACCESS access_declaration_list END_VAR
- {$$ = NULL;}
-// ERROR_CHECK_BEGIN //
-| VAR_ACCESS END_VAR
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no variable declared in access variable(s) declaration."); yynerrs++;}
-| VAR_ACCESS error access_declaration_list END_VAR
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unexpected token after 'VAR_ACCESS' in access variable(s) declaration."); yyerrok;}
-| VAR_ACCESS access_declaration_list error END_VAR
- {$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed access variable(s) declaration."); yyerrok;}
-| VAR_ACCESS error END_VAR
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in access variable(s) declaration."); yyerrok;}
-// ERROR_CHECK_END //
-;
-
-// helper symbol for access_declarations //
-access_declaration_list:
- access_declaration ';'
-| access_declaration_list access_declaration ';'
-// ERROR_CHECK_BEGIN //
-| error ';'
- {$$ = // create a new list //;
- print_err_msg(locf(@1), locl(@1), "invalid access variable declaration."); yyerrok;}
-| access_declaration error
- {$$ = // create a new list //;
- print_err_msg(locl(@1), locf(@2), "';' missing at the end of access variable declaration."); yyerrok;}
-| access_declaration_list access_declaration error
- {$$ = $1; print_err_msg(locl(@2), locf(@3), "';' missing at the end of access variable declaration."); yyerrok;}
-| access_declaration_list error ';'
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "invalid access variable declaration."); yyerrok;}
-| access_declaration_list ';'
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected ';' after access variable declaration."); yynerrs++;}
-// ERROR_CHECK_END //
-;
-
-
-access_declaration:
- access_name ':' access_path ':' non_generic_type_name
-| access_name ':' access_path ':' non_generic_type_name direction
-;
-
-
-access_path:
- prev_declared_direct_variable
-| prev_declared_resource_name '.' prev_declared_direct_variable
-| any_fb_name_list symbolic_variable
-| prev_declared_resource_name '.' any_fb_name_list symbolic_variable
-| prev_declared_program_name '.' any_fb_name_list symbolic_variable
-| prev_declared_resource_name '.' prev_declared_program_name '.' any_fb_name_list symbolic_variable
-;
-*/
-
-// helper symbol for
-// - access_path
-// - instance_specific_init
-//
-/* NOTE: The fb_name_list refers to funtion block variables
- * that have been declared in a scope outside the one we are
- * currently parsing, so we must accept them to be any_identifier!
- *
- * Beware that other locations of this syntax parser also require
- * a fb_name_list. In those locations the function blocks are being declared,
- * so only currently un-used identifiers (i.e. identifier) may be accepted.
- *
- * In order to distinguish the two, here we use any_fb_name_list, while
- * in the the locations we simply use fb_name_list!
- */
-any_fb_name_list:
- // empty
- {$$ = new any_fb_name_list_c(locloc(@$));}
-//| fb_name_list fb_name '.'
-| any_fb_name_list any_identifier '.'
- {$$ = $1; $$->add_element($2);}
-;
-
-
-
-global_var_reference:
-// [resource_name '.'] global_var_name ['.' structure_element_name] //
- prev_declared_global_var_name
- {$$ = new global_var_reference_c(NULL, $1, NULL, locloc(@$));}
-| prev_declared_global_var_name '.' structure_element_name
- {$$ = new global_var_reference_c(NULL, $1, $3, locloc(@$));}
-| prev_declared_resource_name '.' prev_declared_global_var_name
- {$$ = new global_var_reference_c($1, $3, NULL, locloc(@$));}
-| prev_declared_resource_name '.' prev_declared_global_var_name '.' structure_element_name
- {$$ = new global_var_reference_c($1, $3, $5, locloc(@$));}
-;
-
-
-//access_name: identifier;
-
-
-program_output_reference:
-/* NOTE:
- * program_output_reference is merely used within data_source.
- * data_source is merely used within task_initialization
- * task_initialization appears in a configuration declaration
- * _before_ the programs are declared, so we cannot use
- * prev_declared_program_name, as what might seem correct at first.
- *
- * The semantic checker must later check whether the identifier
- * used really refers to a program declared after the task
- * initialization!
- */
-// prev_declared_program_name '.' symbolic_variable
- program_name '.' symbolic_variable
- {$$ = new program_output_reference_c($1, $3, locloc(@$));}
-;
-
-program_name: identifier;
-
-/*
-direction:
- READ_WRITE
- {$$ = NULL;}
-| READ_ONLY
- {$$ = NULL;}
-;
-*/
-
-task_configuration:
- TASK task_name task_initialization
- {$$ = new task_configuration_c($2, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| TASK task_initialization
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no task name defined in task declaration."); yynerrs++;}
-| TASK error task_initialization
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid task name defined in task declaration."); yyerrok;}
-| TASK task_name error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no task initialization defined in task declaration.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid task initialization in task declaration."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-/* NOTE: The specification does not mention the namespace to which task names
- * should belong to. Unlike resource and program names, for the moment we
- * let the task names belong to their own private namespace, as they do not
- * produce any conflicts in the syntax parser.
- * If in the future our interpretation of the spec. turns out to be incorrect,
- * the definition of task_name may have to be changed!
- */
-task_name: any_identifier;
-
-
-task_initialization:
-// '(' [SINGLE ASSIGN data_source ','] [INTERVAL ASSIGN data_source ','] PRIORITY ASSIGN integer ')' //
- '(' {cmd_goto_task_init_state();} task_initialization_single task_initialization_interval task_initialization_priority ')'
- {$$ = new task_initialization_c($3, $4, $5, locloc(@$));}
-;
-
-
-task_initialization_single:
-// [SINGLE ASSIGN data_source ',']
- /* empty */
- {$$ = NULL;}
-| SINGLE ASSIGN {cmd_pop_state();} data_source ',' {cmd_goto_task_init_state();}
- {$$ = $4;}
-/* ERROR_CHECK_BEGIN */
-| SINGLE {cmd_pop_state();} data_source ',' {cmd_goto_task_init_state();}
- {$$ = NULL; print_err_msg(locl(@1), locf(@3), "':=' missing after 'SINGLE' in task initialization."); yynerrs++;}
-| SINGLE ASSIGN {cmd_pop_state();} ',' {cmd_goto_task_init_state();}
- {$$ = NULL; print_err_msg(locl(@2), locf(@4), "no data source defined in 'SINGLE' statement of task initialization."); yynerrs++;}
-| SINGLE ASSIGN {cmd_pop_state();} error ',' {cmd_goto_task_init_state();}
- {$$ = NULL; print_err_msg(locf(@4), locl(@4), "invalid data source defined in 'SINGLE' statement of task initialization."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-task_initialization_interval:
-// [INTERVAL ASSIGN data_source ',']
- /* empty */
- {$$ = NULL;}
-| INTERVAL ASSIGN {cmd_pop_state();} data_source ',' {cmd_goto_task_init_state();}
- {$$ = $4;}
-/* ERROR_CHECK_BEGIN */
-| INTERVAL {cmd_pop_state();} data_source ',' {cmd_goto_task_init_state();}
- {$$ = NULL; print_err_msg(locl(@1), locf(@3), "':=' missing after 'INTERVAL' in task initialization.");}
-| INTERVAL ASSIGN {cmd_pop_state();} ',' {cmd_goto_task_init_state();}
- {$$ = NULL; print_err_msg(locl(@2), locf(@4), "no data source defined in 'INTERVAL' statement of task initialization."); yynerrs++;}
-| INTERVAL ASSIGN {cmd_pop_state();} error ',' {cmd_goto_task_init_state();}
- {$$ = NULL; print_err_msg(locf(@4), locl(@4), "invalid data source defined in 'INTERVAL' statement of task initialization."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-
-task_initialization_priority:
-// PRIORITY ASSIGN integer
- PRIORITY ASSIGN {cmd_pop_state();} integer
- {$$ = $4;}
-/* ERROR_CHECK_BEGIN */
-| PRIORITY {cmd_pop_state();} integer
- {$$ = NULL; print_err_msg(locl(@1), locf(@3), "':=' missing after 'PRIORITY' in task initialization."); yynerrs++;}
-| PRIORITY ASSIGN {cmd_pop_state();} error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@4), "no priority number defined in 'PRIORITY' statement of task initialization.");}
- else {print_err_msg(locf(@4), locl(@4), "invalid priority number in 'PRIORITY' statement of task initialization."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-
-data_source:
- constant
-| global_var_reference
-| program_output_reference
-| prev_declared_direct_variable
-;
-
-program_configuration:
-// PROGRAM [RETAIN | NON_RETAIN] program_name [WITH task_name] ':' program_type_name ['(' prog_conf_elements ')'] //
- PROGRAM program_name optional_task_name ':' prev_declared_program_type_name optional_prog_conf_elements
- {$$ = new program_configuration_c(NULL, $2, $3, $5, $6, locloc(@$));
- variable_name_symtable.insert($2, prev_declared_program_name_token);
- }
-| PROGRAM RETAIN program_name optional_task_name ':' prev_declared_program_type_name optional_prog_conf_elements
- {$$ = new program_configuration_c(new retain_option_c(locloc(@2)), $3, $4, $6, $7, locloc(@$));
- variable_name_symtable.insert($3, prev_declared_program_name_token);
- }
-| PROGRAM NON_RETAIN program_name optional_task_name ':' prev_declared_program_type_name optional_prog_conf_elements
- {$$ = new program_configuration_c(new non_retain_option_c(locloc(@2)), $3, $4, $6, $7, locloc(@$));
- variable_name_symtable.insert($3, prev_declared_program_name_token);
- }
-/* ERROR_CHECK_BEGIN */
-| PROGRAM program_name optional_task_name ':' identifier optional_prog_conf_elements
- {$$ = NULL; print_err_msg(locf(@5), locl(@5), "invalid program type name after ':' in program configuration."); yynerrs++;}
-| PROGRAM RETAIN program_name optional_task_name ':' identifier optional_prog_conf_elements
- {$$ = NULL; print_err_msg(locf(@6), locl(@6), "invalid program type name after ':' in program configuration."); yynerrs++;}
-| PROGRAM NON_RETAIN program_name optional_task_name ':' identifier optional_prog_conf_elements
- {$$ = NULL; print_err_msg(locf(@6), locl(@6), "invalid program type name after ':' in program configuration."); yynerrs++;}
-| PROGRAM error program_name optional_task_name ':' prev_declared_program_type_name optional_prog_conf_elements
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unexpected token after 'PROGRAM' in program configuration."); yyerrok;}
-| PROGRAM RETAIN error program_name optional_task_name ':' prev_declared_program_type_name optional_prog_conf_elements
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "unexpected token after 'RETAIN' in retentive program configuration."); yyerrok;}
-| PROGRAM NON_RETAIN error program_name optional_task_name ':' prev_declared_program_type_name optional_prog_conf_elements
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "unexpected token after 'NON_RETAIN' in non-retentive program configuration."); yyerrok;}
-| PROGRAM optional_task_name ':' prev_declared_program_type_name optional_prog_conf_elements
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no program name defined in program configuration."); yynerrs++;}
-| PROGRAM RETAIN optional_task_name ':' prev_declared_program_type_name optional_prog_conf_elements
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "no program name defined in retentive program configuration."); yynerrs++;}
-| PROGRAM NON_RETAIN optional_task_name ':' prev_declared_program_type_name optional_prog_conf_elements
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "no program name defined in non-retentive program configuration."); yynerrs++;}
-| PROGRAM error optional_task_name ':' prev_declared_program_type_name optional_prog_conf_elements
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid program name defined in program configuration."); yyerrok;}
-| PROGRAM RETAIN error optional_task_name ':' prev_declared_program_type_name optional_prog_conf_elements
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid program name defined in retentive program configuration."); yyerrok;}
-| PROGRAM NON_RETAIN error optional_task_name ':' prev_declared_program_type_name optional_prog_conf_elements
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid program name defined in non-retentive program configuration."); yyerrok;}
-| PROGRAM program_name optional_task_name prev_declared_program_type_name optional_prog_conf_elements
- {$$ = NULL; print_err_msg(locl(@3), locf(@4), "':' missing after program name or optional task name in program configuration."); yynerrs++;}
-| PROGRAM RETAIN program_name optional_task_name prev_declared_program_type_name optional_prog_conf_elements
- {$$ = NULL; print_err_msg(locl(@4), locf(@5), "':' missing after program name or optional task name in retentive program configuration."); yynerrs++;}
-| PROGRAM NON_RETAIN program_name optional_task_name prev_declared_program_type_name optional_prog_conf_elements
- {$$ = NULL; print_err_msg(locl(@4), locf(@5), "':' missing after program name or optional task name in non-retentive program configuration."); yynerrs++;}
-| PROGRAM program_name optional_task_name ':' optional_prog_conf_elements
- {$$ = NULL; print_err_msg(locl(@4), locf(@5), "no program type defined in program configuration."); yynerrs++;}
-| PROGRAM RETAIN program_name optional_task_name ':' optional_prog_conf_elements
- {$$ = NULL; print_err_msg(locl(@5), locf(@6), "no program type defined in retentive program configuration."); yynerrs++;}
-| PROGRAM NON_RETAIN program_name optional_task_name ':' optional_prog_conf_elements
- {$$ = NULL; print_err_msg(locl(@5), locf(@6), "no program type defined in non-retentive program configuration."); yynerrs++;}
-/* ERROR_CHECK_END */
-;
-
-// helper symbol for program_configuration //
-optional_task_name:
- // empty //
- {$$ = NULL;}
-| WITH task_name
- {$$ = $2;}
-/* ERROR_CHECK_BEGIN */
-| WITH error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@1), locf(@2), "no task name defined in optional task name of program configuration.");}
- else {print_err_msg(locf(@2), locl(@2), "invalid task name in optional task name of program configuration."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-// helper symbol for program_configuration //
-optional_prog_conf_elements:
- // empty //
- {$$ = NULL;}
-| '(' prog_conf_elements ')'
- {$$ = $2;}
-/* ERROR_CHECK_BEGIN */
-| '(' error ')'
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid program configuration elements in program configuration."); yyerrok;}
-| '(' prog_conf_elements error
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "')' missing at the end of program configuration elements in program configuration."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-prog_conf_elements:
- prog_conf_element
- {$$ = new prog_conf_elements_c(locloc(@$)); $$->add_element($1);}
-| prog_conf_elements ',' prog_conf_element
- {$$ = $1; $$->add_element($3);}
-/* ERROR_CHECK_BEGIN */
-| prog_conf_elements prog_conf_element
- {$$ = $1; print_err_msg(locl(@1), locf(@2), "',' missing in program configuration elements list."); yynerrs++;}
-| prog_conf_elements ',' error
- {$$ = $1;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no value defined for program configuration element in program configuration list.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid value for program configuration element in program configuration list."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-prog_conf_element:
- fb_task
-| prog_cnxn
-;
-
-
-fb_task:
- // fb_name WITH task_name
-/* NOTE: The fb_name refers to funtion block variables
- * that have been declared in a scope outside the one we are
- * currently parsing, so we must accept them to be any_identifier!
- */
- any_identifier WITH task_name
- {$$ = new fb_task_c($1, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| any_identifier WITH error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no task name defined in function block configuration.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid task name in function block configuration."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-/* NOTE:
- * The semantics of configuring a program are rather confusing, so here is
- * my (Mario) understanding on the issue...
- *
- * A function/program may have as its input variables a simple variable
- * (BYTE, WORD, etc...), an array (ARRAY [1 .. 3] OF BYTE, ...) , or a structure.
- * Nevertheless, when calling this function from within a st or il language statement
- * it is not possible to allocate a value to a single element of the array or structure
- * typed input variable, as the accepted syntax is simply '(' variable_name ':=' variable ')'
- * Notice how the variable_name does not include things such as 'a.elem1' or 'a[1]'!
- *
- * Nevertheless, when configuring a program from within a configuration,
- * it becomes possible to allocate values to individual elements of the
- * array or structured type input variable, as the syntax is now
- * '(' symbolic_variable ':=' data_sink|prog_data_source ')'
- * Notice how the symbolic_variable _does_ include things such as 'a.elem1' or 'a[1]'!
- *
- * Conclusion: Unlike other locations in the syntax where SENDTO appears,
- * here it is not valid to replace symbolic_variable with any_identifier!
- * Nevertheless, it is also not correct to leave symbolic_variable as it is,
- * as we have defined it to only include previously declared variables,
- * which is not the case in this situation. Here symbolic_variable is refering
- * to variables that were defined within the scope of the program that is being
- * called, and _not_ within the scope of the configuration that is calling the
- * program, so the variables in question are not declared in the current scope!
- *
- * We therefore need to define a new symbolic_variable, that accepts any_identifier
- * instead of previosuly declared variable names, to be used in the definition of
- * prog_cnxn!
- */
-prog_cnxn:
- any_symbolic_variable ASSIGN prog_data_source
- {$$ = new prog_cnxn_assign_c($1, $3, locloc(@$));}
-| any_symbolic_variable SENDTO data_sink
- {$$ = new prog_cnxn_sendto_c($1, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| any_symbolic_variable constant
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':=' missing between parameter and value in program configuration element."); yynerrs++;}
-| any_symbolic_variable enumerated_value
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':=' missing between parameter and value in program configuration element."); yynerrs++;}
-| any_symbolic_variable data_sink
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':=' or '=>' missing between parameter and variable in program configuration element."); yynerrs++;}
-| any_symbolic_variable ASSIGN error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no value or variable defined in program configuration assignment element.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid value or variable in program configuration assignment element."); yyclearin;}
- yyerrok;
- }
-| any_symbolic_variable SENDTO error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no variable defined in program configuration sendto element.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid variable in program configuration sendto element."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-prog_data_source:
- constant
-| enumerated_value
-| global_var_reference
-| prev_declared_direct_variable
-;
-
-data_sink:
- global_var_reference
-| prev_declared_direct_variable
-;
-
-instance_specific_initializations:
- VAR_CONFIG instance_specific_init_list END_VAR
- {$$ = new instance_specific_initializations_c($2, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| VAR_CONFIG END_VAR
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no variable declared in configuration variable(s) initialization."); yynerrs++;}
-| VAR_CONFIG error instance_specific_init_list END_VAR
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unexpected token after 'VAR_CONFIG' in configuration variable(s) initialization."); yyerrok;}
-| VAR_CONFIG instance_specific_init_list error END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed configuration variable(s) initialization."); yyerrok;}
-| VAR_CONFIG error END_VAR
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in configuration variable(s) initialization."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-// helper symbol for instance_specific_initializations //
-instance_specific_init_list:
- instance_specific_init ';'
- {$$ = new instance_specific_init_list_c(locloc(@$)); $$->add_element($1);}
-| instance_specific_init_list instance_specific_init ';'
- {$$ = $1; $$->add_element($2);}
-/* ERROR_CHECK_BEGIN */
-| error ';'
- {$$ = new instance_specific_init_list_c(locloc(@$)); print_err_msg(locf(@1), locl(@1), "invalid configuration variable initialization."); yyerrok;}
-| instance_specific_init error
- {$$ = new instance_specific_init_list_c(locloc(@$)); print_err_msg(locl(@1), locf(@2), "';' missing at the end of configuration variable initialization."); yyerrok;}
-| instance_specific_init_list instance_specific_init error
- {$$ = $1; print_err_msg(locl(@2), locf(@3), "';' missing at the end of configuration variable initialization."); yyerrok;}
-| instance_specific_init_list error ';'
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "invalid configuration variable initialization."); yyerrok;}
-| instance_specific_init_list ';'
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected ';' after configuration variable initialization."); yynerrs++;}
-/* ERROR_CHECK_END */
-;
-
-
-instance_specific_init:
-//
-// resource_name '.' program_name '.' {fb_name '.'}
-// ((variable_name [location] ':' located_var_spec_init) | (fb_name ':' function_block_type_name ':=' structure_initialization))
-//
-// prev_declared_resource_name '.' prev_declared_program_name '.' any_fb_name_list variable_name ':' located_var_spec_init
-/* NOTE: variable_name has been changed to any_identifier (and not simply identifier) because the
- * variables being referenced have been declared outside the scope currently being parsed!
- */
-/* NOTE: program_name has not been changed to prev_declared_program_name because the
- * programs being referenced have been declared outside the scope currently being parsed!
- * The programs are only kept inside the scope of the resource in which they are defined.
- */
- prev_declared_resource_name '.' program_name '.' any_fb_name_list any_identifier ':' located_var_spec_init
- {$$ = new instance_specific_init_c($1, $3, $5, $6, NULL, $8, locloc(@$));}
-| prev_declared_resource_name '.' program_name '.' any_fb_name_list any_identifier location ':' located_var_spec_init
- {$$ = new instance_specific_init_c($1, $3, $5, $6, $7, $9, locloc(@$));}
-| prev_declared_resource_name '.' program_name '.' any_fb_name_list any_identifier ':' fb_initialization
- {$5->add_element($6); $$ = new instance_specific_init_c($1, $3, $5, NULL, NULL, $8, locloc(@$));}
-;
-
-
-/* helper symbol for instance_specific_init */
-fb_initialization:
- function_block_type_name ASSIGN structure_initialization
- {$$ = new fb_initialization_c($1, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| function_block_type_name structure_initialization
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':=' missing between function block name and initialization in function block initialization."); yynerrs++;}
-| function_block_type_name ASSIGN error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no initial value defined in function block initialization.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid initial value in function block initialization."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-/***********************************/
-/* B 2.1 Instructions and Operands */
-/***********************************/
-/* helper symbol for many IL instructions, etc... */
-/* eat up any extra EOL tokens... */
-
-eol_list:
- EOL
-| eol_list EOL
-;
-
-
-
-instruction_list:
- il_instruction
- {$$ = new instruction_list_c(locloc(@$)); $$->add_element($1);}
-| any_pragma eol_list
- {$$ = new instruction_list_c(locloc(@$)); $$->add_element($1);}
-| instruction_list il_instruction
- {$$ = $1; $$->add_element($2);}
-| instruction_list any_pragma
- {$$ = $1; $$->add_element($2);}
-;
-
-
-
-il_instruction:
- il_incomplete_instruction eol_list
- {$$ = new il_instruction_c(NULL, $1, locloc(@$));}
-| label ':' il_incomplete_instruction eol_list
- {$$ = new il_instruction_c($1, $3, locloc(@$));}
-| label ':' eol_list
- {$$ = new il_instruction_c($1, NULL, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| error eol_list
- {$$ = NULL; print_err_msg(locf(@1), locl(@1), "invalid IL instruction."); yyerrok;}
-| il_incomplete_instruction error
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "EOL missing at the end of IL instruction."); yyerrok;}
-| error ':' il_incomplete_instruction eol_list
- {$$ = NULL; print_err_msg(locf(@1), locl(@1), "invalid label in IL instruction."); yyerrok;}
-| label il_incomplete_instruction eol_list
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing after label in IL instruction."); yynerrs++;}
-| label ':' error eol_list
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid IL instruction."); yyerrok;}
-| label ':' il_incomplete_instruction error
- {$$ = NULL; print_err_msg(locl(@3), locf(@4), "EOL missing at the end of IL instruction."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-/* helper symbol for il_instruction */
-il_incomplete_instruction:
- il_simple_operation
-| il_expression
-| il_jump_operation
-| il_fb_call
-| il_formal_funct_call
-| il_return_operator
-;
-
-
-label: identifier;
-
-
-
-il_simple_operation:
-// (il_simple_operator [il_operand]) | (function_name [il_operand_list])
- il_simple_operator
- {$$ = new il_simple_operation_c($1, NULL, locloc(@$));}
-/*
- * Note: Bison is getting confused with the following rule,
- * i.e. it is finding conflicts where there seemingly are really none.
- * The rule was therefore replaced by the equivalent following
- * two rules.
- */
-/*
-| il_simple_operator il_operand
- {$$ = new il_simple_operation_c($1, $2, locloc(@$));}
-*/
-| il_simple_operator_noclash il_operand
- {$$ = new il_simple_operation_c($1, $2, locloc(@$));}
-| il_simple_operator_clash il_operand
- {$$ = new il_simple_operation_c($1, $2, locloc(@$));}
-/* NOTE: the line
- * | il_simple_operator
- * already contains the 'NOT' operator, as well as all the
- * expression operators ('MOD', 'AND', etc...), all of which
- * may also be a function name! This means that these operators/functions,
- * without any operands, could be reduced to either an operator or a
- * function call.
- *
- * I (Mario) have chosen to reduce it to an operator.
- * In order to do this, we must remove from the syntax that defines
- * function calls all the functions whose names clash with the IL operators.
- *
- * The line
- * | function_name
- * has been replaced with the lines
- * | function_name_no_clashes
- * in order to include all possible function names except
- * those whose names coincide with operators !!
- */
-| function_name_no_clashes
- {$$ = new il_function_call_c($1, NULL, locloc(@$));}
-/* NOTE: the line
- * | il_simple_operator il_operand
- * already contains the 'NOT', 'MOD', etc. operators, followed by a single il_operand.
- * However, this same code (MOD x) may also be reduced to a function call to the MOD
- * function. This means that (MOD, AND,...) could be interpret as a function name
- * or as an IL operator! This would lead us to a reduce/reduce conflict!
- *
- * I (Mario) have chosen to reduce it to an operand, rather than a function call.
- * In order to do this, we must remove from the syntax that defines
- * function calls all the functions whose names clash with the IL operators.
- *
- * The line
- * | function_name il_operand_list
- * has been replaced with the line
- * | function_name_no_clashes il_operand_list
- * in order to include all possible function names except
- * for the function names which clash with expression and simple operators.
- *
- * Note that:
- * this alternative syntax does not cover the possibility of
- * the function 'NOT', 'MOD', etc... being called with more than one il_operand,
- * in which case it is always a function call, and not an IL instruction.
- * We therefore need to include an extra rule where the
- * function_name_expression_clashes and function_name_simpleop_clashes
- * are followed by a il_operand_list with __two__ or more il_operands!!
- */
-| function_name_no_clashes il_operand_list
- {$$ = new il_function_call_c($1, $2, locloc(@$));}
-| il_simple_operator_clash il_operand_list2
- {$$ = new il_function_call_c(il_operator_c_2_identifier_c($1), $2, locloc(@$));}
-;
-
-
-
-il_expression:
-// il_expr_operator '(' [il_operand] EOL {EOL} [simple_instr_list] ')'
-/*
- * Note: Bison is getting confused with the use of il_expr_operator,
- * i.e. it is finding conflicts where there seemingly are really none.
- * il_expr_operator was therefore replaced by the equivalent
- * il_expr_operator_noclash | il_expr_operator_clash.
- */
- il_expr_operator_noclash '(' eol_list ')'
- {$$ = new il_expression_c($1, NULL, NULL, locloc(@$));}
-| il_expr_operator_noclash '(' il_operand eol_list ')'
- {$$ = new il_expression_c($1, $3, NULL, locloc(@$));}
-| il_expr_operator_noclash '(' eol_list simple_instr_list ')'
- {$$ = new il_expression_c($1, NULL, $4, locloc(@$));}
-| il_expr_operator_noclash '(' il_operand eol_list simple_instr_list ')'
- {$$ = new il_expression_c($1, $3, $5, locloc(@$));}
-| il_expr_operator_clash '(' eol_list ')'
- {$$ = new il_expression_c($1, NULL, NULL, locloc(@$));}
-| il_expr_operator_clash '(' il_operand eol_list ')'
- {$$ = new il_expression_c($1, $3, NULL, locloc(@$));}
-| il_expr_operator_clash '(' il_operand eol_list simple_instr_list ')'
- {$$ = new il_expression_c($1, $3, $5, locloc(@$));}
-| il_expr_operator_clash_eol_list simple_instr_list ')'
- {$$ = new il_expression_c($1, NULL, $2, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| il_expr_operator_noclash '(' eol_list error
- {$$ = NULL; print_err_msg(locl(@3), locf(@4), "')' missing at the end of IL expression."); yyerrok;}
-| il_expr_operator_noclash '(' il_operand eol_list error
- {$$ = NULL; print_err_msg(locl(@4), locf(@5), "')' missing at the end of IL expression."); yyerrok;}
-| il_expr_operator_noclash '(' eol_list simple_instr_list error
- {$$ = NULL; print_err_msg(locl(@4), locf(@5), "')' missing at the end of IL expression."); yyerrok;}
-| il_expr_operator_noclash '(' il_operand eol_list simple_instr_list error
- {$$ = NULL; print_err_msg(locl(@5), locf(@6), "')' missing at the end of IL expression."); yyerrok;}
-| il_expr_operator_clash '(' il_operand eol_list error
- {$$ = NULL; print_err_msg(locl(@4), locf(@5), "')' missing at the end of IL expression."); yyerrok;}
-| il_expr_operator_clash '(' il_operand eol_list simple_instr_list error
- {$$ = NULL; print_err_msg(locl(@5), locf(@6), "')' missing at the end of IL expression."); yyerrok;}
-| il_expr_operator_clash_eol_list simple_instr_list error
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "')' missing at the end of IL expression."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-il_jump_operation:
- il_jump_operator label
- {$$ = new il_jump_operation_c($1, $2, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| il_jump_operator error
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid label defined in IL jump operation."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-il_fb_call:
-// il_call_operator fb_name ['(' (EOL {EOL} [il_param_list]) | [il_operand_list] ')']
- il_call_operator prev_declared_fb_name
- {$$ = new il_fb_call_c($1, $2, NULL, NULL, locloc(@$));}
-| il_call_operator prev_declared_fb_name '(' ')'
- {$$ = new il_fb_call_c($1, $2, NULL, NULL, locloc(@$));}
-| il_call_operator prev_declared_fb_name '(' eol_list ')'
- {$$ = new il_fb_call_c($1, $2, NULL, NULL, locloc(@$));}
-| il_call_operator prev_declared_fb_name '(' il_operand_list ')'
- {$$ = new il_fb_call_c($1, $2, $4, NULL, locloc(@$));}
-| il_call_operator prev_declared_fb_name '(' eol_list il_param_list ')'
- {$$ = new il_fb_call_c($1, $2, NULL, $5, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| il_call_operator error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@1), locf(@2), "no function block name defined in IL function block call.");}
- else {print_err_msg(locf(@2), locl(@2), "invalid function block name in IL function block call."); yyclearin;}
- yyerrok;
- }
-| il_call_operator '(' ')'
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no function block name defined in IL function block call."); yynerrs++;}
-| il_call_operator '(' eol_list ')'
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no function block name defined in IL function block call."); yynerrs++;}
-| il_call_operator '(' il_operand_list ')'
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no function block name defined in IL function block call."); yynerrs++;}
-| il_call_operator '(' eol_list il_param_list ')'
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no function block name defined in IL function block call."); yynerrs++;}
-| il_call_operator error '(' ')'
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid function block name defined in IL function block call."); yyerrok;}
-| il_call_operator error '(' eol_list ')'
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid function block name defined in IL function block call."); yyerrok;}
-| il_call_operator error '(' il_operand_list ')'
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid function block name defined in IL function block call."); yyerrok;}
-| il_call_operator error '(' eol_list il_param_list ')'
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid function block name defined in IL function block call."); yyerrok;}
-| il_call_operator prev_declared_fb_name ')'
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "'(' missing after function block name defined in IL function block call."); yynerrs++;}
-| il_call_operator prev_declared_fb_name il_operand_list ')'
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "'(' missing after function block name defined in IL function block call."); yynerrs++;}
-| il_call_operator prev_declared_fb_name '(' error
- {$$ = NULL; print_err_msg(locl(@3), locf(@4), "')' missing at the end of IL function block call."); yyerrok;}
-| il_call_operator prev_declared_fb_name '(' eol_list error
- {$$ = NULL; print_err_msg(locl(@4), locf(@5), "')' missing at the end of IL function block call."); yyerrok;}
-| il_call_operator prev_declared_fb_name '(' il_operand_list error
- {$$ = NULL; print_err_msg(locl(@4), locf(@5), "')' missing at the end of IL function block call."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-/* NOTE: Please read note above the definition of function_name_without_clashes */
-il_formal_funct_call:
-// function_name '(' EOL {EOL} [il_param_list] ')'
-/* function_name '(' eol_list ')' */
-/* NOTE: il_formal_funct_call is only used in the definition of
- * - il_incomplete_instruction
- * - il_simple_instruction
- * In both of the above, il_expression also
- * shows up as another option. This means that the functions whose
- * names clash with expressions, followed by '(' eol_list ')', are
- * already included. We must therefore leave them out in this
- * definition in order to remove reduce/reduce conflicts.
- *
- * In summary: 'MOD' '(' eol_list ')', and all other functions whose
- * names clash with expressions may be interpreted by the syntax by
- * two different routes. I (Mario) chose to interpret them
- * as operators, rather than as function calls!
- * (AND MOD OR XOR ADD DIV EQ GT GE LT LE MUL NE SUB)
- */
- function_name_no_clashes '(' eol_list ')'
- {$$ = new il_formal_funct_call_c($1, NULL, locloc(@$));}
-| function_name_simpleop_clashes '(' eol_list ')'
- {$$ = new il_formal_funct_call_c($1, NULL, locloc(@$));}
-/* | function_name '(' eol_list il_param_list ')' */
-/* For the above syntax, we no longer have two ways of interpreting the
- * same syntax. The above is always a function call!
- * However, some of the functions that we may be calling
- * may have the same name as an IL operator. This means that
- * flex will be parsing them and handing them over to bison as
- * IL operator tokens, and not as function name tokens.
- * (when parsing ST, flex no longer recognizes IL operators,
- * so will always return the correct function name, unless that
- * name also coincides with an operator used in ST -> XOR, OR, MOD, AND, NOT)
- *
- * We must therefore interpret the IL operators as function names!
- */
-| function_name_no_clashes '(' eol_list il_param_list ')'
- {$$ = new il_formal_funct_call_c($1, $4, locloc(@$));}
-| function_name_simpleop_clashes '(' eol_list il_param_list ')'
- {$$ = new il_formal_funct_call_c($1, $4, locloc(@$));}
-/* The following line should read:
- *
- * | function_name_expression_clashes '(' eol_list il_param_list ')'
- *
- * but the function_name_expression_clashes had to be first reduced to
- * an intermediary symbol in order to remove a reduce/reduce conflict.
- * In essence, the syntax requires more than one look ahead token
- * in order to be parsed. We resolve this by reducing a collection of
- * symbols into a temporary symbol (il_expr_operator_clash_eol_list), that
- * will later be replaced by the correct symbol. The correct symbol will
- * now be determined by a single look ahead token, as all the common
- * symbols have been reduced to the temporary symbol
- * il_expr_operator_clash_eol_list !
- *
- * Unfortunately, this work around results in the wrong symbol
- * being created for the abstract syntax tree.
- * We need to figure out which symbol was created, destroy it,
- * and create the correct symbol for our case.
- * This is a lot of work, so I put it in a function
- * at the end of this file... il_operator_c_2_identifier_c()
- */
-| il_expr_operator_clash_eol_list il_param_list ')'
- {$$ = new il_formal_funct_call_c(il_operator_c_2_identifier_c($1), $2, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| function_name_no_clashes '(' eol_list error ')'
- {$$ = NULL; print_err_msg(locf(@4), locl(@4), "invalid parameter list defined in IL formal function call."); yyerrok;}
-| function_name_simpleop_clashes '(' eol_list error ')'
- {$$ = NULL; print_err_msg(locf(@4), locl(@4), "invalid parameter list defined in IL formal function call."); yyerrok;}
-| il_expr_operator_clash_eol_list error ')'
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid parameter list defined in IL formal function call."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-il_expr_operator_clash_eol_list:
- il_expr_operator_clash '(' eol_list
- {$$ = $1;}
-/* ERROR_CHECK_BEGIN */
-| il_expr_operator_clash '(' error
- {$$ = $1; print_err_msg(locl(@2), locf(@3), "EOL missing after '(' in IL instruction."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-il_operand:
- variable
-| enumerated_value
-| constant
-;
-
-
-il_operand_list:
- il_operand
- {$$ = new il_operand_list_c(locloc(@$)); $$->add_element($1);}
-| il_operand_list2
-;
-
-
-/* List with 2 or more il_operands */
-il_operand_list2:
- il_operand ',' il_operand
- {$$ = new il_operand_list_c(locloc(@$)); $$->add_element($1); $$->add_element($3);}
-| il_operand_list2 ',' il_operand
- {$$ = $1; $$->add_element($3);}
-/* ERROR_CHECK_BEGIN */
-| il_operand_list2 il_operand
- {$$ = $1; print_err_msg(locl(@1), locf(@2), "',' missing in IL operand list."); yynerrs++;}
-| il_operand ',' error
- {$$ = new il_operand_list_c(locloc(@$));
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no operand defined in IL operand list.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid operand name in IL operand list."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-simple_instr_list:
- il_simple_instruction
- {$$ = new simple_instr_list_c(locloc(@$)); $$->add_element($1);}
-| simple_instr_list il_simple_instruction
- {$$ = $1; $$->add_element($2);}
-;
-
-
-il_simple_instruction:
- il_simple_operation eol_list
-| il_expression eol_list
-| il_formal_funct_call eol_list
-/* ERROR_CHECK_BEGIN */
-| il_expression error
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "EOL missing after expression IL instruction."); yyerrok;}
-| il_formal_funct_call error
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "EOL missing after formal function call IL instruction."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-/* NOTE: the correct definition of il_param_list is
- * il_param_list ::= {il_param_instruction} il_param_last_instruction
- *
- * where {...} denotes zero or many il_param_instruction's.
- *
- * We could do this by defining the following:
- * il_param_list: il_param_instruction_list il_param_last_instruction;
- * il_param_instruction_list : ** empty ** | il_param_instruction_list il_param_instruction;
- *
- * Unfortunately, the above leads to reduce/reduce conflicts.
- * The chosen alternative (as follows) does not have any conflicts!
- * il_param_list: il_param_last_instruction | il_param_instruction_list il_param_last_instruction;
- * il_param_instruction_list : il_param_instruction_list | il_param_instruction_list il_param_instruction;
- */
-il_param_list:
- il_param_instruction_list il_param_last_instruction
- {$$ = $1; $$->add_element($2);}
-| il_param_last_instruction
- {$$ = new il_param_list_c(locloc(@$)); $$->add_element($1);}
-/* ERROR_CHECK_BEGIN */
-| il_param_instruction_list error
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "invalid parameter assignment in parameter assignment list."); yyerrok;}
-| il_param_last_instruction il_param_last_instruction
- {$$ = 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++;}
-| il_param_instruction_list il_param_last_instruction il_param_last_instruction
- {$$ = $1; print_err_msg(locl(@2), locf(@3), "',' missing at the end of parameter assignment in parameter assignment list."); yynerrs++;}
-/* ERROR_CHECK_END */
-;
-
-
-/* Helper symbol for il_param_list */
-il_param_instruction_list:
- il_param_instruction
- {$$ = new il_param_list_c(locloc(@$)); $$->add_element($1);}
-| il_param_instruction_list il_param_instruction
- {$$ = $1; $$->add_element($2);}
-/* ERROR_CHECK_BEGIN */
-| il_param_last_instruction il_param_instruction
- {$$ = 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++;}
-| il_param_instruction_list il_param_last_instruction il_param_instruction
- {$$ = $1; print_err_msg(locl(@2), locf(@3), "',' missing at the end of parameter assignment in parameter assignment list."); yynerrs++;}
-/* ERROR_CHECK_END */
-;
-
-
-il_param_instruction:
- il_param_assignment ',' eol_list
-| il_param_out_assignment ',' eol_list
-/* ERROR_CHECK_BEGIN */
-| il_param_assignment ',' error
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "EOL missing at the end of parameter assignment in parameter assignment list."); yyerrok;}
-| il_param_out_assignment ',' error
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "EOL missing at the end of parameter out assignment in parameter assignment list."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-il_param_last_instruction:
- il_param_assignment eol_list
-| il_param_out_assignment eol_list
-/* ERROR_CHECK_BEGIN */
-| il_param_assignment error
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "EOL missing at the end of last parameter assignment in parameter assignment list."); yyerrok;}
-| il_param_out_assignment error
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "EOL missing at the end of last parameter out assignment in parameter assignment list."); yyerrok;}
-/* ERROR_CHECK_END */
-
-;
-
-
-il_param_assignment:
- il_assign_operator il_operand
- {$$ = new il_param_assignment_c($1, $2, NULL, locloc(@$));}
-| il_assign_operator '(' eol_list simple_instr_list ')'
- {$$ = new il_param_assignment_c($1, NULL, $4, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| error il_operand
- {$$ = NULL; print_err_msg(locf(@1), locl(@1), "invalid operator in parameter assignment."); yyerrok;}
-| error '(' eol_list simple_instr_list ')'
- {$$ = NULL; print_err_msg(locf(@1), locl(@1), "invalid operator in parameter assignment."); yyerrok;}
-| il_assign_operator error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@1), locf(@2), "no operand defined in parameter assignment.");}
- else {print_err_msg(locf(@2), locl(@2), "invalid operand in parameter assignment."); yyclearin;}
- yyerrok;
- }
-| il_assign_operator '(' eol_list ')'
- {$$ = NULL; print_err_msg(locl(@3), locf(@4), "no instruction list defined in parameter assignment."); yynerrs++;}
-| il_assign_operator '(' eol_list error ')'
- {$$ = NULL; print_err_msg(locf(@4), locl(@4), "invalid instruction list defined in parameter assignment."); yyerrok;}
-| il_assign_operator '(' eol_list simple_instr_list error
- {$$ = NULL; print_err_msg(locl(@4), locf(@5), "')' missing at the end of instruction list defined in parameter assignment."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-il_param_out_assignment:
- il_assign_out_operator variable
- {$$ = new il_param_out_assignment_c($1, $2, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| il_assign_out_operator error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@1), locf(@2), "no variable defined in IL operand list.");}
- else {print_err_msg(locf(@2), locl(@2), "invalid variable in IL operand list."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-
-/*******************/
-/* B 2.2 Operators */
-/*******************/
-sendto_identifier: sendto_identifier_token {$$ = new identifier_c($1, locloc(@$));};
-
-
-/* NOTE:
- * The spec includes the operator 'EQ '
- * Note that EQ is followed by a space.
- * I am considering this a typo, and defining the operator
- * as 'EQ'
- * (Mario)
- */
-LD_operator: LD {$$ = new LD_operator_c(locloc(@$));};
-LDN_operator: LDN {$$ = new LDN_operator_c(locloc(@$));};
-ST_operator: ST {$$ = new ST_operator_c(locloc(@$));};
-STN_operator: STN {$$ = new STN_operator_c(locloc(@$));};
-NOT_operator: NOT {$$ = new NOT_operator_c(locloc(@$));};
-S_operator: S {$$ = new S_operator_c(locloc(@$));};
-R_operator: R {$$ = new R_operator_c(locloc(@$));};
-S1_operator: S1 {$$ = new S1_operator_c(locloc(@$));};
-R1_operator: R1 {$$ = new R1_operator_c(locloc(@$));};
-CLK_operator: CLK {$$ = new CLK_operator_c(locloc(@$));};
-CU_operator: CU {$$ = new CU_operator_c(locloc(@$));};
-CD_operator: CD {$$ = new CD_operator_c(locloc(@$));};
-PV_operator: PV {$$ = new PV_operator_c(locloc(@$));};
-IN_operator: IN {$$ = new IN_operator_c(locloc(@$));};
-PT_operator: PT {$$ = new PT_operator_c(locloc(@$));};
-AND_operator: AND {$$ = new AND_operator_c(locloc(@$));};
-AND2_operator: AND2 {$$ = new AND_operator_c(locloc(@$));}; /* '&' in the source code! */
-OR_operator: OR {$$ = new OR_operator_c(locloc(@$));};
-XOR_operator: XOR {$$ = new XOR_operator_c(locloc(@$));};
-ANDN_operator: ANDN {$$ = new ANDN_operator_c(locloc(@$));};
-ANDN2_operator: ANDN2 {$$ = new ANDN_operator_c(locloc(@$));}; /* '&N' in the source code! */
-ORN_operator: ORN {$$ = new ORN_operator_c(locloc(@$));};
-XORN_operator: XORN {$$ = new XORN_operator_c(locloc(@$));};
-ADD_operator: ADD {$$ = new ADD_operator_c(locloc(@$));};
-SUB_operator: SUB {$$ = new SUB_operator_c(locloc(@$));};
-MUL_operator: MUL {$$ = new MUL_operator_c(locloc(@$));};
-DIV_operator: DIV {$$ = new DIV_operator_c(locloc(@$));};
-MOD_operator: MOD {$$ = new MOD_operator_c(locloc(@$));};
-GT_operator: GT {$$ = new GT_operator_c(locloc(@$));};
-GE_operator: GE {$$ = new GE_operator_c(locloc(@$));};
-EQ_operator: EQ {$$ = new EQ_operator_c(locloc(@$));};
-LT_operator: LT {$$ = new LT_operator_c(locloc(@$));};
-LE_operator: LE {$$ = new LE_operator_c(locloc(@$));};
-NE_operator: NE {$$ = new NE_operator_c(locloc(@$));};
-CAL_operator: CAL {$$ = new CAL_operator_c(locloc(@$));};
-CALC_operator: CALC {$$ = new CALC_operator_c(locloc(@$));};
-CALCN_operator: CALCN {$$ = new CALCN_operator_c(locloc(@$));};
-RET_operator: RET {$$ = new RET_operator_c(locloc(@$));};
-RETC_operator: RETC {$$ = new RETC_operator_c(locloc(@$));};
-RETCN_operator: RETCN {$$ = new RETCN_operator_c(locloc(@$));};
-JMP_operator: JMP {$$ = new JMP_operator_c(locloc(@$));};
-JMPC_operator: JMPC {$$ = new JMPC_operator_c(locloc(@$));};
-JMPCN_operator: JMPCN {$$ = new JMPCN_operator_c(locloc(@$));};
-
-
-il_simple_operator:
- il_simple_operator_clash
-| il_simple_operator_noclash
-;
-
-
-il_simple_operator_noclash:
- LD_operator
-| LDN_operator
-| ST_operator
-| STN_operator
-| S_operator
-| R_operator
-| S1_operator
-| R1_operator
-| CLK_operator
-| CU_operator
-| CD_operator
-| PV_operator
-| IN_operator
-| PT_operator
-| il_expr_operator_noclash
-;
-
-
-il_simple_operator_clash:
- il_simple_operator_clash1
-| il_simple_operator_clash2
-;
-
-il_simple_operator_clash1:
- NOT_operator
-;
-
-il_simple_operator_clash2:
- il_expr_operator_clash
-;
-
-
-/*
-il_expr_operator:
- il_expr_operator_noclash
-| il_expr_operator_clash
-;
-*/
-
-il_expr_operator_clash:
- AND_operator
-| OR_operator
-| XOR_operator
-| ADD_operator
-| SUB_operator
-| MUL_operator
-| DIV_operator
-| MOD_operator
-| GT_operator
-| GE_operator
-| EQ_operator
-| LT_operator
-| LE_operator
-| NE_operator
-;
-
-
-il_expr_operator_noclash:
- ANDN_operator
-| ANDN2_operator /* string '&N' in source code! */
-| AND2_operator /* string '&' in source code! */
-| ORN_operator
-| XORN_operator
-;
-
-
-
-
-il_assign_operator:
-/* variable_name ASSIGN */
- any_identifier ASSIGN
- {$$ = new il_assign_operator_c($1, locloc(@$));}
-| en_identifier ASSIGN
- {$$ = new il_assign_operator_c($1, locloc(@$));}
-| S1_operator ASSIGN
- {$$ = new il_assign_operator_c(il_operator_c_2_identifier_c($1), locloc(@$));}
-| R1_operator ASSIGN
- {$$ = new il_assign_operator_c(il_operator_c_2_identifier_c($1), locloc(@$));}
-| CLK_operator ASSIGN
- {$$ = new il_assign_operator_c(il_operator_c_2_identifier_c($1), locloc(@$));}
-| CU_operator ASSIGN
- {$$ = new il_assign_operator_c(il_operator_c_2_identifier_c($1), locloc(@$));}
-| CD_operator ASSIGN
- {$$ = new il_assign_operator_c(il_operator_c_2_identifier_c($1), locloc(@$));}
-| PV_operator ASSIGN
- {$$ = new il_assign_operator_c(il_operator_c_2_identifier_c($1), locloc(@$));}
-| IN_operator ASSIGN
- {$$ = new il_assign_operator_c(il_operator_c_2_identifier_c($1), locloc(@$));}
-| PT_operator ASSIGN
- {$$ = new il_assign_operator_c(il_operator_c_2_identifier_c($1), locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| error ASSIGN
- {$$ = NULL; print_err_msg(locf(@1), locl(@1), "invalid parameter defined in parameter assignment."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-il_assign_out_operator:
-/* variable_name SENDTO */
-/* any_identifier SENDTO */
- sendto_identifier SENDTO
- {$$ = new il_assign_out_operator_c(NULL, $1, locloc(@$));}
-/* The following is not required, as the sendto_identifier_token returned by flex will
- * also include the 'ENO' identifier.
- * The resulting abstract syntax tree is identical with or without this following rule,
- * as both the eno_identifier and the sendto_identifier are stored as
- * an identifier_c !!
- *
- * To understand why we must even explicitly consider the use of ENO here,
- * please read the comment above the definition of 'variable' in section B1.4 for details.
- */
-/*
-| eno_identifier SENDTO
- {$$ = new il_assign_out_operator_c(NULL, $1, locloc(@$));}
-*/
-/*| NOT variable_name SENDTO */
-| NOT sendto_identifier SENDTO
- {$$ = new il_assign_out_operator_c(new not_paramassign_c(locloc(@1)), $2, locloc(@$));}
-/* The following is not required, as the sendto_identifier_token returned by flex will
- * also include the 'ENO' identifier.
- * The resulting abstract syntax tree is identical with or without this following rule,
- * as both the eno_identifier and the sendto_identifier are stored as
- * an identifier_c !!
- *
- * To understand why we must even explicitly consider the use of ENO here,
- * please read the comment above the definition of 'variable' in section B1.4 for details.
- *
- * NOTE: Removing the following rule also removes a shift/reduce conflict from the parser.
- * This conflict is not really an error/ambiguity in the syntax, but rather
- * due to the fact that more than a single look-ahead token would be required
- * to correctly parse the syntax, something that bison does not support.
- *
- * The shift/reduce conflict arises because bison does not know whether
- * to parse the 'NOT ENO' in the following code
- * LD 1
- * funct_name (
- * NOT ENO => bool_var,
- * EN := TRUE
- * )
- * as either a il_param_assignment (wrong!) or an il_param_out_assignment.(correct).
- * The '=>' delimiter (known as SEND_TO in this iec.y file) is a dead giveaway that
- * it should be parsed as an il_param_out_assignment, but still, bison gets confused!
- * Bison considers the possibility of reducing the 'NOT ENO' as an NOT_operator with
- * the 'ENO' operand
- * (NOT_operator -> il_simple_operator -> il_simple_operation -> il_simple_instruction ->
- * -> simple_instr_list -> il_param_assignment)
- * instead of reducing it to an il_param_out_operator.
- * ( il_param_out_operator -> il_param_out_assignment)
- *
- * Note that the shift/reduce conflict only manifests itself in the il_formal_funct_call,
- * where both the il_param_out_assignment and il_param_assignment are used!
- *
- * il_param_out_assignment --+--> il_param_instruction -> il_param_instruction_list --+
- * | |
- * il_param_assignment --+ |
- * |
- * il_formal_funct_call <- il_param_list <-+
- *
- */
-/*
-| NOT eno_identifier SENDTO
- {$$ = new il_assign_out_operator_c(new not_paramassign_c(locloc(@1)), $2, locloc(@$));}
-*/
-/* ERROR_CHECK_BEGIN */
-| error SENDTO
- {$$ = NULL; print_err_msg(locf(@1), locl(@1), "invalid parameter defined in parameter out assignment."); yyerrok;}
-| NOT SENDTO
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no parameter defined in parameter out assignment."); yynerrs++;}
-| NOT error SENDTO
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid parameter defined in parameter out assignment."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-il_call_operator:
- CAL_operator
-| CALC_operator
-| CALCN_operator
-;
-
-
-il_return_operator:
- RET_operator
-| RETC_operator
-| RETCN_operator
-;
-
-
-il_jump_operator:
- JMP_operator
-| JMPC_operator
-| JMPCN_operator
-;
-
-
-/***********************/
-/* B 3.1 - Expressions */
-/***********************/
-expression:
- xor_expression
-| expression OR xor_expression
- {$$ = new or_expression_c($1, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| expression OR error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined after 'OR' in ST expression.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid expression after 'OR' in ST expression."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-xor_expression:
- and_expression
-| xor_expression XOR and_expression
- {$$ = new xor_expression_c($1, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| xor_expression XOR error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined after 'XOR' in ST expression.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid expression after 'XOR' in ST expression."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-and_expression:
- comparison
-| and_expression '&' comparison
- {$$ = new and_expression_c($1, $3, locloc(@$));}
-| and_expression AND comparison
- {$$ = new and_expression_c($1, $3, locloc(@$));}
-/* NOTE: The lexical parser never returns the token '&'.
- * The '&' string is interpreted by the lexcial parser as the token
- * AND2!
- * This means that the first rule with '&' is actually not required,
- * but we leave it in nevertheless just in case we later decide
- * to remove the AND2 token...
- */
-| and_expression AND2 comparison
- {$$ = new and_expression_c($1, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| and_expression '&' error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined after '&' in ST expression.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid expression after '&' in ST expression."); yyclearin;}
- yyerrok;
- }
-| and_expression AND error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined after 'AND' in ST expression.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid expression after 'AND' in ST expression."); yyclearin;}
- yyerrok;
- }
-| and_expression AND2 error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined after '&' in ST expression.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid expression after '&' in ST expression."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-comparison:
- equ_expression
-| comparison '=' equ_expression
- {$$ = new equ_expression_c($1, $3, locloc(@$));}
-| comparison OPER_NE equ_expression
- {$$ = new notequ_expression_c($1, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| comparison '=' error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined after '=' in ST expression.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid expression after '=' in ST expression."); yyclearin;}
- yyerrok;
- }
-| comparison OPER_NE error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined after '<>' in ST expression.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid expression after '<>' in ST expression."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-equ_expression:
- add_expression
-| equ_expression '<' add_expression
- {$$ = new lt_expression_c($1, $3, locloc(@$));}
-| equ_expression '>' add_expression
- {$$ = new gt_expression_c($1, $3, locloc(@$));}
-| equ_expression OPER_LE add_expression
- {$$ = new le_expression_c($1, $3, locloc(@$));}
-| equ_expression OPER_GE add_expression
- {$$ = new ge_expression_c($1, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| equ_expression '<' error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined after '<' in ST expression.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid expression after '<' in ST expression."); yyclearin;}
- yyerrok;
- }
-| equ_expression '>' error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined after '>' in ST expression.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid expression after '>' in ST expression."); yyclearin;}
- yyerrok;
- }
-| equ_expression OPER_LE error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined after '<=' in ST expression.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid expression after '<=' in ST expression."); yyclearin;}
- yyerrok;
- }
-| equ_expression OPER_GE error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined after '>=' in ST expression.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid expression after '>=' in ST expression."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-/* Not required...
-comparison_operator: '<' | '>' | '>=' '<='
-*/
-
-add_expression:
- term
-| add_expression '+' term
- {$$ = new add_expression_c($1, $3, locloc(@$));}
-| add_expression '-' term
- {$$ = new sub_expression_c($1, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| add_expression '+' error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined after '+' in ST expression.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid expression after '+' in ST expression."); yyclearin;}
- yyerrok;
- }
-| add_expression '-' error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined after '-' in ST expression.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid expression after '-' in ST expression."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-/* Not required...
-add_operator: '+' | '-'
-*/
-
-term:
- power_expression
-| term '*' power_expression
- {$$ = new mul_expression_c($1, $3, locloc(@$));}
-| term '/' power_expression
- {$$ = new div_expression_c($1, $3, locloc(@$));}
-| term MOD power_expression
- {$$ = new mod_expression_c($1, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| term '*' error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined after '*' in ST expression.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid expression after '*' in ST expression."); yyclearin;}
- yyerrok;
- }
-| term '/' error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined after '/' in ST expression.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid expression after '/' in ST expression."); yyclearin;}
- yyerrok;
- }
-| term MOD error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined after 'MOD' in ST expression.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid expression after 'MOD' in ST expression."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-/* Not required...
-multiply_operator: '*' | '/' | 'MOD'
-*/
-
-power_expression:
- unary_expression
-| power_expression OPER_EXP unary_expression
- {$$ = new power_expression_c($1, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| power_expression OPER_EXP error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined after '**' in ST expression.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid expression after '**' in ST expression."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-unary_expression:
- non_negative_primary_expression
-| '-' non_negative_primary_expression
- {$$ = new neg_expression_c($2, locloc(@$));}
-| NOT primary_expression
- {$$ = new not_expression_c($2, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| '-' error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@1), locf(@2), "no expression defined after '-' in ST expression.");}
- else {print_err_msg(locf(@2), locl(@2), "invalid expression after '-' in ST expression."); yyclearin;}
- yyerrok;
- }
-| NOT error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@1), locf(@2), "no expression defined after 'NOT' in ST expression.");}
- else {print_err_msg(locf(@2), locl(@2), "invalid expression after 'NOT' in ST expression."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-/* Not required...
-unary_operator: '-' | 'NOT'
-*/
-
-
-/* NOTE: using constant as a possible symbol for primary_expression
- * leads to a reduce/reduce conflict.
- *
- * The text '-9' may be parsed as either a
- * expression<-primary_expression<-constant<-signed_integer
- * (i.e. the constant 9 negative)
- * OR
- * expression<-unary_expression<-constant<-integer
- * (i.e. the constant 9, preceded by a unary negation)
- *
- * To remove the conflict, we only allow constants without
- * a preceding '-' to be used in primary_expression
- * (i.e. as a parameter to the unary negation operator)
- */
-/* NOTE: We use enumerated_value_without_identifier instead of enumerated_value
- * in order to remove a reduce/reduce conflict between reducing an
- * identifier to a variable or an enumerated_value.
- *
- * This change follows the IEC specification. The specification seems to
- * imply (by introducing syntax that allows to unambiguosly reference an
- * enumerated value - enum_type#enum_value) that in case the same identifier is used
- * for a variable and an enumerated value, then the variable shall be
- * considered.
- */
-non_negative_primary_expression:
- non_negative_constant
-//| enumerated_value_without_identifier
-| enumerated_value
-| variable
-| '(' expression ')'
- {$$ = $2;}
-| function_invocation
-/* ERROR_CHECK_BEGIN */
-| '(' expression error
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "')' missing at the end of expression in ST expression."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-primary_expression:
- constant
-//| enumerated_value_without_identifier
-| enumerated_value
-| variable
-| '(' expression ')'
- {$$ = $2;}
-| function_invocation
-/* ERROR_CHECK_BEGIN */
-| '(' expression error
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "')' missing at the end of expression in ST expression."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-
-/* intermediate helper symbol for primary_expression */
-/* NOTE: function_name includes the standard function name 'NOT' !
- * This introduces a reduce/reduce conflict, as NOT(var)
- * may be parsed as either a function_invocation, or a
- * unary_expression.
- *
- * I (Mario) have opted to remove the possible reduction
- * to function invocation, which means replacing the rule
- * function_name '(' param_assignment_list ')'
- * with
- * function_name_no_NOT_clashes '(' param_assignment_list ')'
- *
- * Notice how the new rule does not include the situation where
- * the function NOT is called with more than one parameter, which
- * the original rule does include! Callinf the NOT function with more
- * than one argument is probably a semantic error anyway, so it
- * doesn't make much sense to take it into account.
- *
- * Nevertheless, if we were to to it entirely correctly,
- * leaving the semantic checks for the next compiler stage,
- * this syntax parser would need to include such a possibility.
- *
- * We will leave this out for now. No need to complicate the syntax
- * more than the specification does by contradicting itself, and
- * letting names clash!
- */
-function_invocation:
-/* function_name '(' [param_assignment_list] ')' */
- function_name_no_NOT_clashes '(' param_assignment_formal_list ')'
- {$$ = new function_invocation_c($1, $3, NULL, locloc(@$));}
-| function_name_no_NOT_clashes '(' param_assignment_nonformal_list ')'
- {$$ = new function_invocation_c($1, NULL, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| function_name_no_NOT_clashes param_assignment_formal_list ')'
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "'(' missing after function name in ST expression."); yynerrs++;}
-| function_name_no_NOT_clashes '(' ')'
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "no parameter defined in function invocation of ST expression."); yynerrs++;}
-| function_name_no_NOT_clashes '(' error ')'
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid parameter(s) defined in function invocation of ST expression."); yyerrok;}
-| function_name_no_NOT_clashes '(' param_assignment_formal_list error
- {$$ = NULL; print_err_msg(locl(@3), locf(@4), "')' missing at the end of function invocation in ST expression."); yyerrok;}
-| function_name_no_NOT_clashes '(' param_assignment_nonformal_list error
- {$$ = NULL; print_err_msg(locl(@3), locf(@4), "')' missing at the end of function invocation in ST expression."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-/********************/
-/* B 3.2 Statements */
-/********************/
-statement_list:
- statement ';'
- {$$ = new statement_list_c(locloc(@$)); $$->add_element($1);}
-| any_pragma
- {$$ = new statement_list_c(locloc(@$)); $$->add_element($1);}
-| statement_list statement ';'
- {$$ = $1; $$->add_element($2);}
-| statement_list any_pragma
- {$$ = $1; $$->add_element($2);}
-/* ERROR_CHECK_BEGIN */
-| statement error
- {$$ = new statement_list_c(locloc(@$)); print_err_msg(locl(@1), locf(@2), "';' missing at the end of statement in ST statement."); yyerrok;}
-| statement_list statement error
- {$$ = $1; print_err_msg(locl(@2), locf(@3), "';' missing at the end of statement in ST statement."); yyerrok;}
-| statement_list error ';'
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "invalid statement in ST statement."); yyerrok;}
-| statement_list ';'
- {$$ = $1; print_err_msg(locf(@2), locl(@2), "unexpected ';' after statement in ST statement."); yynerrs++;}
-/* ERROR_CHECK_END */
-;
-
-
-statement:
- assignment_statement
-| subprogram_control_statement
-| selection_statement
-| iteration_statement
-;
-
-
-/*********************************/
-/* B 3.2.1 Assignment Statements */
-/*********************************/
-assignment_statement:
- variable ASSIGN expression
- {$$ = new assignment_statement_c($1, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| error ASSIGN expression
- {$$ = NULL; print_err_msg(locf(@1), locl(@1), "invalid variable before ':=' in ST assignment statement."); yyerrok;}
-| variable ASSIGN error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined after ':=' in ST assignment statement.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid expression after ':=' in ST assignment statement."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-
-
-/*****************************************/
-/* B 3.2.2 Subprogram Control Statements */
-/*****************************************/
-subprogram_control_statement:
- fb_invocation
-| return_statement
-;
-
-return_statement:
- RETURN {$$ = new return_statement_c(locloc(@$));}
-;
-
-
-
-fb_invocation:
- prev_declared_fb_name '(' ')'
- {$$ = new fb_invocation_c($1, NULL, NULL, locloc(@$)); }
-| prev_declared_fb_name '(' param_assignment_formal_list ')'
- {$$ = new fb_invocation_c($1, $3, NULL, locloc(@$));}
-| prev_declared_fb_name '(' param_assignment_nonformal_list ')'
- {$$ = new fb_invocation_c($1, NULL, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| prev_declared_fb_name ')'
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "'(' missing after function block name in ST statement."); yynerrs++;}
-| prev_declared_fb_name param_assignment_formal_list ')'
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "'(' missing after function block name in ST statement."); yynerrs++;}
-| prev_declared_fb_name '(' error ')'
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid parameter list in function block invocation in ST statement."); yyerrok;}
-| prev_declared_fb_name '(' error
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "')' missing after parameter list of function block invocation in ST statement."); yyerrok;}
-| prev_declared_fb_name '(' param_assignment_formal_list error
- {$$ = NULL; print_err_msg(locl(@3), locf(@4), "')' missing after parameter list of function block invocation in ST statement."); yyerrok;}
-| prev_declared_fb_name '(' param_assignment_nonformal_list error
- {$$ = NULL; print_err_msg(locl(@3), locf(@4), "')' missing after parameter list of function block invocation in ST statement."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-/* helper symbol for
- * - fb_invocation
- * - function_invocation
- */
-param_assignment_formal_list:
- param_assignment_formal
- {$$ = new param_assignment_list_c(locloc(@$)); $$->add_element($1);}
-| param_assignment_formal_list ',' param_assignment_formal
- {$$ = $1; $$->add_element($3);}
-/* ERROR_CHECK_BEGIN */
-| param_assignment_formal_list ',' error
- {$$ = $1;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no parameter assignment defined in ST parameter assignment list.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid parameter assignment in ST parameter assignment list."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-/* helper symbol for
- * - fb_invocation
- * - function_invocation
- */
-param_assignment_nonformal_list:
- param_assignment_nonformal
- {$$ = new param_assignment_list_c(locloc(@$)); $$->add_element($1);}
-| param_assignment_nonformal_list ',' param_assignment_nonformal
- {$$ = $1; $$->add_element($3);}
-/* ERROR_CHECK_BEGIN */
-| param_assignment_nonformal_list ',' error
- {$$ = $1;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no parameter assignment defined in ST parameter assignment list.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid parameter assignment in ST parameter assignment list."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-/* NOTE: According to the IEC 61131-3 standard, there are two possible
- * syntaxes for calling function blocks within ST.
- * The formal method has the form:
- * fb ( invar := x, inoutvar := var1, outvar => var2);
- * The non-formal method has the form:
- * fb (x, var1, var2);
- * In the text of IEC 61131-3 (where the semantics are defined),
- * it is obvious that mixing the two syntaxes is considered incorrect.
- * The following should therefore be incorrect:
- * fb ( invar := x, var1, var2);
- * However, according to the syntax definition, as defined in IEC 61131-3,
- * mixing the formal and non-formal methods of invocation is allowed.
- * We have two alternatives:
- * (a) implement the syntax here in iec.y according to the standard,
- * and leave it to the semantic analyser stage to find this error
- * (b) or implement the syntax in iec.y correctly, not allowing
- * the mixing of formal and non-formal invocation syntaxes.
- * Considering that this is a syntax issue, and not semantic issue,
- * I (Mario) have decided to go with alternative (a).
- * In other words, in iec.y we do not follow the syntax as defined in
- * Annex B of the IEC 61131-3 standard, but rather implement
- * the syntax also taking into account the textual part of the standard too.
- */
-/*
-param_assignment:
- variable_name ASSIGN expression
-*/
-param_assignment_nonformal:
- expression
-;
-
-
-param_assignment_formal:
- any_identifier ASSIGN expression
- {$$ = new input_variable_param_assignment_c($1, $3, locloc(@$));}
-| en_identifier ASSIGN expression
- {$$ = new input_variable_param_assignment_c($1, $3, locloc(@$));}
-/*| variable_name SENDTO variable */
-/*| any_identifier SENDTO variable */
-| sendto_identifier SENDTO variable
- {$$ = new output_variable_param_assignment_c(NULL, $1, $3, locloc(@$));}
-/* The following is not required, as the sendto_identifier_token returned by flex will
- * also include the 'ENO' identifier.
- * The resulting abstract syntax tree is identical with or without this following rule,
- * as both the eno_identifier and the sendto_identifier are stored as
- * an identifier_c !!
- *
- * To understand why we must even explicitly consider the use of ENO here,
- * please read the comment above the definition of 'variable' in section B1.4 for details.
- */
-/*
-| eno_identifier SENDTO variable
- {$$ = new output_variable_param_assignment_c(NULL, $1, $3, locloc(@$));}
-*/
-/*| NOT variable_name SENDTO variable */
-/*| NOT any_identifier SENDTO variable*/
-| NOT sendto_identifier SENDTO variable
- {$$ = new output_variable_param_assignment_c(new not_paramassign_c(locloc(@$)), $2, $4, locloc(@$));}
-/* The following is not required, as the sendto_identifier_token returned by flex will
- * also include the 'ENO' identifier.
- * The resulting abstract syntax tree is identical with or without this following rule,
- * as both the eno_identifier and the sendto_identifier are stored as
- * an identifier_c !!
- *
- * To understand why we must even explicitly consider the use of ENO here,
- * please read the comment above the definition of 'variable' in section B1.4 for details.
- */
-/*
-| NOT eno_identifier SENDTO variable
- {$$ = new output_variable_param_assignment_c(new not_paramassign_c(locloc(@$)), $2, $4, locloc(@$));}
-*/
-/* ERROR_CHECK_BEGIN */
-| any_identifier ASSIGN error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined in ST formal parameter assignment.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid expression in ST formal parameter assignment."); yyclearin;}
- yyerrok;
- }
-| en_identifier ASSIGN error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined in ST formal parameter assignment.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid expression in ST formal parameter assignment."); yyclearin;}
- yyerrok;
- }
-| sendto_identifier SENDTO error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined in ST formal parameter out assignment.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid expression in ST formal parameter out assignment."); yyclearin;}
- yyerrok;
- }
-/*
-| eno_identifier SENDTO error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined in ST formal parameter out assignment.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid expression in ST formal parameter out assignment."); yyclearin;}
- yyerrok;
- }
-*/
-| NOT SENDTO variable
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no parameter name defined in ST formal parameter out negated assignment."); yynerrs++;}
-| NOT error SENDTO variable
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid parameter name defined in ST formal parameter out negated assignment."); yyerrok;}
-| NOT sendto_identifier SENDTO error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@3), locf(@4), "no expression defined in ST formal parameter out negated assignment.");}
- else {print_err_msg(locf(@4), locl(@4), "invalid expression in ST formal parameter out negated assignment."); yyclearin;}
- yyerrok;
- }
-/*
-| NOT eno_identifier SENDTO error
- {$$ = NULL;
- if (is_current_syntax_token()) {print_err_msg(locl(@3), locf(@4), "no expression defined in ST formal parameter out negated assignment.");}
- else {print_err_msg(locf(@4), locl(@4), "invalid expression in ST formal parameter out negated assignment."); yyclearin;}
- yyerrok;
- }
-*/
-/* ERROR_CHECK_END */
-;
-
-
-
-
-
-/********************************/
-/* B 3.2.3 Selection Statements */
-/********************************/
-selection_statement:
- if_statement
-| case_statement
-;
-
-
-if_statement:
- IF expression THEN statement_list elseif_statement_list END_IF
- {$$ = new if_statement_c($2, $4, $5, NULL, locloc(@$));}
-| IF expression THEN statement_list elseif_statement_list ELSE statement_list END_IF
- {$$ = new if_statement_c($2, $4, $5, $7, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| IF THEN statement_list elseif_statement_list END_IF
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no test expression defined in ST 'IF' statement."); yynerrs++;}
-| IF THEN statement_list elseif_statement_list ELSE statement_list END_IF
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no test expression defined in ST 'IF' statement."); yynerrs++;}
-| IF error THEN statement_list elseif_statement_list END_IF
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid test expression defined for ST 'IF' statement."); yyerrok;}
-| IF error THEN statement_list elseif_statement_list ELSE statement_list END_IF
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid test expression defined for ST 'IF' statement."); yyerrok;}
-| IF expression error statement_list elseif_statement_list END_IF
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "expecting 'THEN' after test expression in ST 'IF' statement."); yyerrok;}
-| IF expression error statement_list elseif_statement_list ELSE statement_list END_IF
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "expecting 'THEN' after test expression in ST 'IF' statement."); yyerrok;}
-| IF expression THEN elseif_statement_list END_IF
- {$$ = NULL; print_err_msg(locl(@3), locf(@4), "no statement defined after 'THEN' in ST 'IF' statement."); yynerrs++;}
-| IF expression THEN elseif_statement_list ELSE statement_list END_IF
- {$$ = NULL; print_err_msg(locl(@3), locf(@4), "no statement defined after 'THEN' in ST 'IF' statement."); yynerrs++;}
-| IF expression THEN statement_list elseif_statement_list ELSE END_IF
- {$$ = NULL; print_err_msg(locl(@6), locf(@7), "no statement defined after 'ELSE' in ST 'IF' statement."); yynerrs++;}
-| IF expression THEN statement_list elseif_statement_list ELSE error END_IF
- {$$ = NULL; print_err_msg(locf(@7), locl(@7), "invalid statement defined after 'ELSE' in ST 'IF' statement."); yynerrs++; yyerrok;}
-| IF expression error END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed 'IF' statement in ST."); yyerrok;}
-| IF expression THEN statement_list elseif_statement_list END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@3), "unclosed 'IF' statement in ST."); yynerrs++;}
-| IF expression THEN statement_list elseif_statement_list ELSE statement_list END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@3), "unclosed 'IF' statement in ST."); yynerrs++;}
-| IF error END_IF
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in ST 'IF' statement."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-/* helper symbol for if_statement */
-elseif_statement_list:
- /* empty */
- {$$ = new elseif_statement_list_c(locloc(@$));}
-| elseif_statement_list elseif_statement
- {$$ = $1; $$->add_element($2);}
-;
-
-/* helper symbol for elseif_statement_list */
-elseif_statement:
- ELSIF expression THEN statement_list
- {$$ = new elseif_statement_c($2, $4, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| ELSIF THEN statement_list
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no test expression defined for 'ELSEIF' statement in ST 'IF' statement."); yynerrs++;}
-| ELSIF error THEN statement_list
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid test expression defined for 'ELSEIF' statement in ST 'IF' statement."); yyerrok;}
-| ELSIF expression error statement_list
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "expecting 'THEN' after test expression in 'ELSEIF' statement of ST 'IF' statement."); yyerrok;}
-| ELSIF expression THEN error
- {$$ = NULL; print_err_msg(locf(@4), locl(@4), "invalid statement list in 'ELSEIF' statement of ST 'IF' statement."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-case_statement:
- CASE expression OF case_element_list END_CASE
- {$$ = new case_statement_c($2, $4, NULL, locloc(@$));}
-| CASE expression OF case_element_list ELSE statement_list END_CASE
- {$$ = new case_statement_c($2, $4, $6, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| CASE OF case_element_list END_CASE
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no test expression defined in ST 'CASE' statement."); yynerrs++;}
-| CASE OF case_element_list ELSE statement_list END_CASE
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no test expression defined in ST 'CASE' statement."); yynerrs++;}
-| CASE error OF case_element_list END_CASE
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid test expression defined for ST 'CASE' statement."); yyerrok;}
-| CASE error OF case_element_list ELSE statement_list END_CASE
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid test expression defined for ST 'CASE' statement."); yyerrok;}
-| CASE expression error case_element_list END_CASE
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "expecting 'OF' after test expression in ST 'CASE' statement."); yyerrok;}
-| CASE expression error case_element_list ELSE statement_list END_CASE
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "expecting 'OF' after test expression in ST 'CASE' statement."); yyerrok;}
-| CASE expression OF END_CASE
- {$$ = NULL; print_err_msg(locl(@3), locf(@4), "no case element(s) defined after 'OF' in ST 'CASE' statement."); yynerrs++;}
-| CASE expression OF ELSE statement_list END_CASE
- {$$ = NULL; print_err_msg(locl(@3), locf(@4), "no case element(s) defined after 'OF' in ST 'CASE' statement."); yynerrs++;}
-| CASE expression OF error END_CASE
- {$$ = NULL; print_err_msg(locf(@4), locl(@4), "invalid case element(s) defined after 'OF' in ST 'CASE' statement."); yyerrok;}
-| CASE expression OF error ELSE statement_list END_CASE
- {$$ = NULL; print_err_msg(locf(@4), locl(@4), "invalid case element(s) defined after 'OF' in ST 'CASE' statement."); yyerrok;}
-| CASE expression OF case_element_list ELSE END_CASE
- {$$ = NULL; print_err_msg(locl(@5), locf(@6), "no statement defined after 'ELSE' in ST 'CASE' statement."); yynerrs++;}
-| CASE expression OF case_element_list ELSE error END_CASE
- {$$ = NULL; print_err_msg(locf(@6), locl(@6), "invalid statement defined after 'ELSE' in ST 'CASE' statement."); yyerrok;}
-| CASE expression error END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed 'CASE' statement in ST."); yyerrok;}
-| CASE expression OF case_element_list END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@3), "unclosed 'CASE' statement in ST."); yynerrs++;}
-| CASE expression OF case_element_list ELSE statement_list END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@3), "unclosed 'CASE' statement in ST."); yynerrs++;}
-| CASE error END_CASE
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in ST 'CASE' statement."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-/* helper symbol for case_statement */
-case_element_list:
- case_element
- {$$ = new case_element_list_c(locloc(@$)); $$->add_element($1);}
-| case_element_list case_element
- {$$ = $1; $$->add_element($2);}
-;
-
-
-case_element:
- case_list ':' statement_list
- {$$ = new case_element_c($1, $3, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| case_list statement_list
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing after case list in ST 'CASE' statement."); yynerrs++;}
-| case_list ':' error
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid statement in case element of ST 'CASE' statement."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-case_list:
- case_list_element
- {$$ = new case_list_c(locloc(@$)); $$->add_element($1);}
-| case_list ',' case_list_element
- {$$ = $1; $$->add_element($3);}
-/* ERROR_CHECK_BEGIN */
-| case_list ',' error
- {$$ = $1;
- if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no case defined in case list of ST parameter assignment list.");}
- else {print_err_msg(locf(@3), locl(@3), "invalid case in case list of ST parameter assignment list."); yyclearin;}
- yyerrok;
- }
-/* ERROR_CHECK_END */
-;
-
-
-case_list_element:
- signed_integer
-| subrange
-| enumerated_value
-;
-
-
-
-
-
-/********************************/
-/* B 3.2.4 Iteration Statements */
-/********************************/
-iteration_statement:
- for_statement
-| while_statement
-| repeat_statement
-| exit_statement
-;
-
-
-for_statement:
- FOR control_variable ASSIGN expression TO expression BY expression DO statement_list END_FOR
- {$$ = new for_statement_c($2, $4, $6, $8, $10, locloc(@$));}
-| FOR control_variable ASSIGN expression TO expression DO statement_list END_FOR
- {$$ = new for_statement_c($2, $4, $6, NULL, $8, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| FOR ASSIGN expression TO expression BY expression DO statement_list END_FOR
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no control variable defined in ST 'FOR' statement."); yynerrs++;}
-| FOR ASSIGN expression TO expression DO statement_list END_FOR
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no control variable defined in ST 'FOR' statement."); yynerrs++;}
-| FOR error ASSIGN expression TO expression BY expression DO statement_list END_FOR
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid control variable defined for ST 'FOR' statement."); yyerrok;}
-| FOR error ASSIGN expression TO expression DO statement_list END_FOR
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid control variable defined for ST 'FOR' statement."); yyerrok;}
-| FOR control_variable expression TO expression BY expression DO statement_list END_FOR
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "':=' missing between control variable and start expression in ST 'FOR' statement."); yynerrs++;}
-| FOR control_variable expression TO expression DO statement_list END_FOR
- {$$ = NULL; print_err_msg(locl(@2), locf(@3), "':=' missing between control variable and start expression in ST 'FOR' statement."); yynerrs++;}
-| FOR control_variable error expression TO expression BY expression DO statement_list END_FOR
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "expecting ':=' between control variable and start expression in ST 'FOR' statement."); yyerrok;}
-| FOR control_variable error expression TO expression DO statement_list END_FOR
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "expecting ':=' between control variable and start expression in ST 'FOR' statement."); yyerrok;}
-| FOR control_variable ASSIGN TO expression BY expression DO statement_list END_FOR
- {$$ = NULL; print_err_msg(locl(@3), locf(@4), "no start expression defined in ST 'FOR' statement."); yynerrs++;}
-| FOR control_variable ASSIGN TO expression DO statement_list END_FOR
- {$$ = NULL; print_err_msg(locl(@3), locf(@4), "no start expression defined in ST 'FOR' statement."); yynerrs++;}
-| FOR control_variable ASSIGN error TO expression BY expression DO statement_list END_FOR
- {$$ = NULL; print_err_msg(locf(@4), locl(@4), "invalid start expression defined in ST 'FOR' statement."); yyerrok;}
-| FOR control_variable ASSIGN error TO expression DO statement_list END_FOR
- {$$ = NULL; print_err_msg(locf(@4), locl(@4), "invalid start expression in ST 'FOR' statement."); yyerrok;}
-| FOR control_variable ASSIGN expression error expression BY expression DO statement_list END_FOR
- {$$ = NULL; print_err_msg(locf(@5), locl(@5), "expecting 'TO' between start expression and end expression in ST 'FOR' statement."); yyerrok;}
-| FOR control_variable ASSIGN expression error expression DO statement_list END_FOR
- {$$ = NULL; print_err_msg(locf(@5), locl(@5), "expecting 'TO' between start expression and end expression in ST 'FOR' statement."); yyerrok;}
-| FOR control_variable ASSIGN expression TO expression error expression DO statement_list END_FOR
- {$$ = NULL; print_err_msg(locf(@7), locl(@7), "expecting 'BY' between end expression and step expression in ST 'FOR' statement."); yyerrok;}
-| FOR control_variable ASSIGN expression TO expression BY expression error statement_list END_FOR
- {$$ = NULL; print_err_msg(locf(@9), locl(@9), "expecting 'DO' after step expression in ST 'FOR' statement."); yyerrok;}
-| FOR control_variable ASSIGN expression TO expression error statement_list END_FOR
- {$$ = NULL; print_err_msg(locf(@7), locl(@7), "expecting 'DO' after end expression in ST 'FOR' statement."); yyerrok;}
-| FOR control_variable ASSIGN expression TO expression BY expression DO END_FOR
- {$$ = NULL; print_err_msg(locl(@9), locf(@10), "no statement(s) defined after 'DO' in ST 'FOR' statement."); yynerrs++;}
-| FOR control_variable ASSIGN expression TO expression DO END_FOR
- {$$ = NULL; print_err_msg(locl(@7), locf(@8), "no statement(s) defined after 'DO' in ST 'FOR' statement."); yynerrs++;}
-| FOR control_variable ASSIGN expression TO expression BY expression DO error END_FOR
- {$$ = NULL; print_err_msg(locf(@10), locl(@10), "invalid statement(s) defined after 'DO' in ST 'FOR' statement."); yyerrok;}
-| FOR control_variable ASSIGN expression TO expression DO error END_FOR
- {$$ = NULL; print_err_msg(locf(@8), locl(@8), "invalid statement(s) defined after 'DO' in ST 'FOR' statement."); yyerrok;}
-| FOR control_variable error END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed 'FOR' statement in ST."); yyerrok;}
-| FOR control_variable ASSIGN expression error END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed 'FOR' statement in ST."); yyerrok;}
-| FOR control_variable ASSIGN expression TO expression DO statement_list END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed 'FOR' statement in ST."); yynerrs++;}
-| FOR control_variable ASSIGN expression TO expression BY expression error END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed 'FOR' statement in ST."); yyerrok;}
-| FOR control_variable ASSIGN expression TO expression BY expression DO statement_list END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed 'FOR' statement in ST."); yynerrs++;}
-| FOR error END_FOR
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in ST 'FOR' statement."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-/* The spec has the syntax
- * control_variable: identifier;
- * but then defines the semantics of control_variable
- * (Section 3.3.2.4) as being of an integer type
- * (e.g., SINT, INT, or DINT).
- *
- * Obviously this presuposes that the control_variable
- * must have been declared in some VAR .. END_VAR
- * We must therefore change the syntax to read
- * control_variable: prev_declared_variable_name;
- *
- * If we don't, then the correct use of any previosuly declared
- * variable would result in an incorrect syntax error
-*/
-control_variable:
- prev_declared_variable_name
- {$$ = new symbolic_variable_c($1,locloc(@$));};
-// control_variable: identifier {$$ = $1;};
-
-/* Integrated directly into for_statement */
-/*
-for_list:
- expression TO expression [BY expression]
-;
-*/
-
-
-while_statement:
- WHILE expression DO statement_list END_WHILE
- {$$ = new while_statement_c($2, $4, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| WHILE DO statement_list END_WHILE
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no test expression defined in ST 'WHILE' statement."); yynerrs++;}
-| WHILE error DO statement_list END_WHILE
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid test expression defined for ST 'WHILE' statement."); yyerrok;}
-| WHILE expression error statement_list END_WHILE
- {$$ = NULL; print_err_msg(locf(@3), locl(@3), "expecting 'DO' after test expression in ST 'WHILE' statement."); yyerrok;}
-| WHILE expression DO END_WHILE
- {$$ = NULL; print_err_msg(locl(@3), locf(@4), "no statement(s) defined after 'DO' in ST 'WHILE' statement."); yynerrs++;}
-| WHILE expression DO error END_WHILE
- {$$ = NULL; print_err_msg(locf(@4), locl(@4), "invalid statement(s) defined after 'DO' in ST 'WHILE' statement."); yyerrok;}
-| WHILE expression error END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed 'WHILE' statement in ST."); yyerrok;}
-| WHILE expression DO statement_list END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed 'WHILE' statement in ST."); yynerrs++;}
-| WHILE error END_WHILE
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in ST 'WHILE' statement."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-repeat_statement:
- REPEAT statement_list UNTIL expression END_REPEAT
- {$$ = new repeat_statement_c($2, $4, locloc(@$));}
-/* ERROR_CHECK_BEGIN */
-| REPEAT UNTIL expression END_REPEAT
- {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no statement(s) defined after 'REPEAT' in ST 'REPEAT' statement."); yynerrs++;}
-| REPEAT error UNTIL expression END_REPEAT
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid statement(s) defined after 'REPEAT' for ST 'REPEAT' statement."); yyerrok;}
-| REPEAT statement_list UNTIL END_REPEAT
- {$$ = NULL; print_err_msg(locl(@3), locf(@4), "no test expression defined after 'UNTIL' in ST 'REPEAT' statement.");}
-| REPEAT statement_list UNTIL error END_REPEAT
- {$$ = NULL; print_err_msg(locf(@4), locl(@4), "invalid test expression defined after 'UNTIL' in ST 'REPEAT' statement."); yyerrok;}
-| REPEAT statement_list END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed 'REPEAT' statement in ST."); yynerrs++;}
-| REPEAT statement_list UNTIL expression error END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed 'REPEAT' statement in ST."); yyerrok;}
-| REPEAT error END_REPEAT
- {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in ST 'REPEAT' statement."); yyerrok;}
-/* ERROR_CHECK_END */
-;
-
-
-exit_statement:
- EXIT {$$ = new exit_statement_c(locloc(@$));}
-;
-
-
-
-
-
-%%
-
-#include <stdio.h> /* required for printf() */
-#include <errno.h>
-#include "../util/symtable.hh"
-
-/* variables defined in code generated by flex... */
-extern FILE *yyin;
-extern int yylineno;
-extern tracking_t* current_tracking;
-
-
-
-
-/*************************************************************************************************/
-/* NOTE: These variables are really parameters we would like the stage2__ function to pass */
-/* to the yyparse() function. However, the yyparse() function is created automatically */
-/* by bison, so we cannot add parameters to this function. The only other */
-/* option is to use global variables! yuck! */
-/*************************************************************************************************/
-
-/* A global flag used to tell the parser if overloaded funtions should be allowed.
- * The IEC 61131-3 standard allows overloaded funtions in the standard library,
- * but disallows them in user code...
- *
- * In essence, a parameter we would like to pass to the yyparse() function but
- * have to do it using a global variable, as the yyparse() prototype is fixed by bison.
- */
-bool allow_function_overloading = false;
-
-/* A global flag used to tell the parser whether to include the full variable location
- * when printing out error messages...
- */
-bool full_token_loc;
-
-/* A pointer to the root of the parsing tree that will be generated
- * by bison.
- */
-symbol_c *tree_root;
-
-
-
-/* The following function is called automatically by bison whenever it comes across
- * an error. Unfortunately it calls this function before executing the code that handles
- * the error itself, so we cannot print out the correct line numbers of the error location
- * over here.
- * Our solution is to store the current error message in a global variable, and have all
- * error action handlers call the function print_err_msg() after setting the location
- * (line number) variable correctly.
- */
-const char *current_error_msg;
-void yyerror (const char *error_msg) {
- current_error_msg = error_msg;
-/* fprintf(stderr, "error %d: %s\n", yynerrs // global variable //, error_msg); */
-/* print_include_stack(); */
-}
-
-
-/* ERROR_CHECK_BEGIN */
-bool is_current_syntax_token() {
- switch (yychar) {
- case ';':
- case ',':
- case ')':
- case ']':
- case '+':
- case '*':
- case '-':
- case '/':
- case '<':
- case '>':
- case '=':
- case '&':
- case OR:
- case XOR:
- case AND:
- case AND2:
- case OPER_NE:
- case OPER_LE:
- case OPER_GE:
- case MOD:
- case OPER_EXP:
- case NOT:
- return true;
- default:
- return false;
- }
-}
-/* ERROR_CHECK_END */
-
-
-void print_err_msg(int first_line,
- int first_column,
- const char *first_filename,
- long int first_order,
- int last_line,
- int last_column,
- const char *last_filename,
- long int last_order,
- const char *additional_error_msg) {
-
- const char *unknown_file = "<unknown_file>";
- if (first_filename == NULL) first_filename = unknown_file;
- if ( last_filename == NULL) last_filename = unknown_file;
-
- if (full_token_loc) {
- if (first_filename == last_filename)
- fprintf(stderr, "%s:%d-%d..%d-%d: error : %s\n", first_filename, first_line, first_column, last_line, last_column, additional_error_msg);
- else
- 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);
- } else {
- fprintf(stderr, "%s:%d: error : %s\n", first_filename, first_line, additional_error_msg);
- }
- //fprintf(stderr, "error %d: %s\n", yynerrs /* a global variable */, additional_error_msg);
- print_include_stack();
- //fprintf(stderr, "%s(%d-%d): %s\n", current_filename, first_line, last_line, current_error_msg);
-}
-
-
-
-/* convert between an il_operator to a function name */
-/* This a kludge!
- * It is required because our language requires more than one
- * look ahead token, and bison only works with one!
- */
-#define op_2_str(op, str) {\
- op ## _operator_c *ptr = dynamic_cast<op ## _operator_c *>(il_operator); \
- if (ptr != NULL) name = str; \
-}
-
-/* NOTE: this code is very ugly and un-eficient, but I (Mario) have many
- * more things to worry about right now, so just let it be...
- */
-symbol_c *il_operator_c_2_identifier_c(symbol_c *il_operator) {
- const char *name = NULL;
- identifier_c *res;
-
- op_2_str(NOT, "NOT");
-
- op_2_str(AND, "AND");
- op_2_str(OR, "OR");
- op_2_str(XOR, "XOR");
- op_2_str(ADD, "ADD");
- op_2_str(SUB, "SUB");
- op_2_str(MUL, "MUL");
- op_2_str(DIV, "DIV");
- op_2_str(MOD, "MOD");
- op_2_str(GT, "GT");
- op_2_str(GE, "GE");
- op_2_str(EQ, "EQ");
- op_2_str(LT, "LT");
- op_2_str(LE, "LE");
- op_2_str(NE, "NE");
-
- op_2_str(LD, "LD");
- op_2_str(LDN, "LDN");
- op_2_str(ST, "ST");
- op_2_str(STN, "STN");
-
- op_2_str(S, "S");
- op_2_str(R, "R");
- op_2_str(S1, "S1");
- op_2_str(R1, "R1");
-
- op_2_str(CLK, "CLK");
- op_2_str(CU, "CU");
- op_2_str(CD, "CD");
- op_2_str(PV, "PV");
- op_2_str(IN, "IN");
- op_2_str(PT, "PT");
-
- op_2_str(ANDN, "ANDN");
- op_2_str(ORN, "ORN");
- op_2_str(XORN, "XORN");
-
- op_2_str(ADD, "ADD");
- op_2_str(SUB, "SUB");
- op_2_str(MUL, "MUL");
- op_2_str(DIV, "DIV");
-
- op_2_str(GT, "GT");
- op_2_str(GE, "GE");
- op_2_str(EQ, "EQ");
- op_2_str(LT, "LT");
- op_2_str(LE, "LE");
- op_2_str(NE, "NE");
-
- op_2_str(CAL, "CAL");
- op_2_str(CALC, "CALC");
- op_2_str(CALCN, "CALCN");
- op_2_str(RET, "RET");
- op_2_str(RETC, "RETC");
- op_2_str(RETCN, "RETCN");
- op_2_str(JMP, "JMP");
- op_2_str(JMPC, "JMPC");
- op_2_str(JMPCN, "JMPCN");
-
- if (name == NULL)
- ERROR;
-
- res = new identifier_c(strdup(name),
- il_operator->first_line,
- il_operator->first_column,
- il_operator->first_file,
- il_operator->first_order,
- il_operator->last_line,
- il_operator->last_column,
- il_operator->last_file,
- il_operator->last_order
- );
- free(il_operator);
- return res;
-}
-
-
-#include "standard_function_names.c"
-
-const char *standard_function_block_names[] = {
-// 2.5.2.3.1 Bistable elements
-// Table 34 - Standard bistable function blocks
-"SR","RS",
-// 2.5.2.3.2 Edge detection
-// Table 35 - Standard edge detection function blocks
-"R_TRIG","F_TRIG",
-// 2.5.2.3.3 Counters
-// Table 36 - Standard counter function blocks
-"CTU","CTU_DINT","CTU_LINT","CTU_UDINT","CTU_ULINT",
-"CTD","CTD_DINT","CTD_LINT","CTD_UDINT","CTD_ULINT",
-"CTUD","CTUD_DINT","CTUD_LINT","CTUD_ULINT",
-// 2.5.2.3.4 Timers
-// Table 37 - Standard timer function blocks
-"TP","TON","TOF",
-/* end of array marker! Do not remove! */
-NULL
-};
-
-
-#define LIBFILE "ieclib.txt"
-#define DEF_LIBFILENAME LIBDIRECTORY "/" LIBFILE
-
-extern const char *INCLUDE_DIRECTORIES[];
-
-
-
-int stage2__(const char *filename,
- const char *includedir, /* Include directory, where included files will be searched for... */
- symbol_c **tree_root_ref,
- bool full_token_loc_ /* error messages specify full token location */
- ) {
-
- FILE *in_file = NULL, *lib_file = NULL;
- char *libfilename = NULL;
-
- for(int i = 0; standard_function_names[i] != NULL; i++)
- if (library_element_symtable.find_value(standard_function_names[i]) ==
- library_element_symtable.end_value())
- library_element_symtable.insert(standard_function_names[i], standard_function_name_token);
-
- if((in_file = fopen(filename, "r")) == NULL) {
- char *errmsg = strdup2("Error opening main file ", filename);
- perror(errmsg);
- free(errmsg);
- return -1;
- }
-
- if (includedir != NULL) {
- INCLUDE_DIRECTORIES[0] = includedir;
- }
- if ((libfilename = strdup3(INCLUDE_DIRECTORIES[0], "/", LIBFILE)) == NULL) {
- fprintf (stderr, "Out of memory. Bailing out!\n");
- return -1;
- }
-
- if((lib_file = fopen(libfilename, "r")) == NULL) {
- char *errmsg = strdup2("Error opening library file ", libfilename);
- perror(errmsg);
- free(errmsg);
- }
-
- if (lib_file == NULL) {
- /* we give up... */
- free(libfilename);
- fclose(in_file);
- return -1;
- }
-
- /* first parse the standard library file... */
- /*
- #if YYDEBUG
- yydebug = 1;
- #endif
- */
- yyin = lib_file;
- allow_function_overloading = true;
- full_token_loc = full_token_loc_;
- current_filename = libfilename;
- current_tracking = GetNewTracking(yyin);
- if (yyparse() != 0)
- ERROR;
-
- if (yynerrs > 0) {
- fprintf (stderr, "\nFound %d error(s) in %s. Bailing out!\n", yynerrs /* global variable */, libfilename);
- ERROR;
- }
- free(libfilename);
- fclose(lib_file);
-
- /* if by any chance the library is not complete, we
- * now add the missing reserved keywords to the list!!!
- */
- for(int i = 0; standard_function_block_names[i] != NULL; i++)
- if (library_element_symtable.find_value(standard_function_block_names[i]) ==
- library_element_symtable.end_value())
- library_element_symtable.insert(standard_function_block_names[i], standard_function_block_name_token);
-
-
- /* now parse the input file... */
- #if YYDEBUG
- yydebug = 1;
- #endif
- yyin = in_file;
- allow_function_overloading = false;
- full_token_loc = full_token_loc_;
- current_filename = filename;
- current_tracking = GetNewTracking(yyin);
- {int res;
- if ((res = yyparse()) != 0) {
- fprintf (stderr, "\nParsing failed because of too many consecutive syntax errors. Bailing out!\n");
- exit(EXIT_FAILURE);
- }
- }
-
- if (yynerrs > 0) {
- fprintf (stderr, "\nFound %d error(s). Bailing out!\n", yynerrs /* global variable */);
- exit(EXIT_FAILURE);
- }
-
- if (tree_root_ref != NULL)
- *tree_root_ref = tree_root;
-
- fclose(in_file);
- return 0;
-}
-
-
-