etisserant@0: /*
msousa@264: * matiec - a compiler for the programming languages defined in IEC 61131-3
msousa@264: *
msousa@264: * Copyright (C) 2003-2011 Mario de Sousa (msousa@fe.up.pt)
Edouard@279: * Copyright (C) 2007-2011 Laurent Bessard and Edouard Tisserant
msousa@264: *
msousa@264: * This program is free software: you can redistribute it and/or modify
msousa@264: * it under the terms of the GNU General Public License as published by
msousa@264: * the Free Software Foundation, either version 3 of the License, or
msousa@264: * (at your option) any later version.
msousa@264: *
msousa@264: * This program is distributed in the hope that it will be useful,
msousa@264: * but WITHOUT ANY WARRANTY; without even the implied warranty of
msousa@264: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
msousa@264: * GNU General Public License for more details.
msousa@264: *
msousa@264: * You should have received a copy of the GNU General Public License
msousa@264: * along with this program. If not, see .
msousa@264: *
etisserant@0: *
etisserant@0: * This code is made available on the understanding that it will not be
etisserant@0: * used in safety-critical situations without a full and competent review.
etisserant@0: */
etisserant@0:
etisserant@0: /*
msousa@264: * An IEC 61131-3 compiler.
etisserant@0: *
etisserant@0: * Based on the
etisserant@0: * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10)
etisserant@0: *
etisserant@0: */
etisserant@0:
etisserant@0: /*
etisserant@0: * Stage 2
etisserant@0: * =======
etisserant@0: *
etisserant@0: * This file contains the syntax definition of the textual
mario@91: * languages IL and ST, as well as the textual version of SFC.
mario@91: * The syntax parser, comprising the 2nd stage of the overall
mario@91: * compiler, is generated by runing bison on this file.
etisserant@0: */
etisserant@0:
etisserant@0:
etisserant@0:
etisserant@0:
etisserant@0: /**********************************************************************/
etisserant@0: /**********************************************************************/
etisserant@0: /**********************************************************************/
etisserant@0: /**********************************************************************/
etisserant@0: /******* *******/
etisserant@0: /******* The following syntax does not have any conflicts. *******/
etisserant@0: /******* *******/
etisserant@0: /******* P L E A S E K E E P I T T H A T W A Y ! *******/
etisserant@0: /******* =================================================== *******/
etisserant@0: /******* *******/
etisserant@0: /**********************************************************************/
etisserant@0: /**********************************************************************/
etisserant@0: /**********************************************************************/
etisserant@0: /**********************************************************************/
etisserant@0:
msousa@547: /* NOTE: the following file contains many rules used merely for detecting errors in
msousa@547: * the IEC source code being parsed.
msousa@547: * To remove all these rules, simply execute the command (first replace all '%' with '/'):
msousa@547: * $sed '\:%\* ERROR_CHECK_BEGIN \*%:,\:%\* ERROR_CHECK_END \*%: d' iec_bison.yy
msousa@547: *
msousa@547: * The above command had to be edited ('/' replaced by '%') so as not to include the C syntax that closes
msousa@547: * comments inside this comment!
msousa@547: * If you place the command in a shell script, be sure to remove the backslashes '\' before each asterisk '*' !!
msousa@547: */
msousa@547:
msousa@547:
etisserant@0:
etisserant@0:
etisserant@0:
etisserant@0: %{
etisserant@0: #include /* required for strdup() */
etisserant@0:
etisserant@0:
etisserant@0: /* declare the token parser generated by flex... */
etisserant@0: int yylex(void);
etisserant@0:
etisserant@0: /* declare the error handler defined at the end of this file */
etisserant@0: void yyerror (const char *error_msg);
etisserant@0:
etisserant@0: /* produce a more verbose parsing error message */
etisserant@0: #define YYERROR_VERBOSE
etisserant@0:
etisserant@0: /* Include debuging code.
etisserant@0: * Printing of debug info must then be activated by setting
etisserant@0: * the variable yydebug to 1.
etisserant@0: */
etisserant@41: #define YYDEBUG 0
etisserant@0:
etisserant@0:
etisserant@0: /* file with declaration of absyntax classes... */
etisserant@0: #include "../absyntax/absyntax.hh"
etisserant@0:
etisserant@0: /* file with declaration of token constants. Generated by bison! */
Edouard@822: #include "iec_bison.hh"
mario@15:
mario@68: /* The interface through which bison and flex interact. */
mario@15: #include "stage1_2_priv.hh"
conti@748: #include "create_enumtype_conversion_functions.hh"
etisserant@0:
msousa@315: #include "../absyntax_utils/add_en_eno_param_decl.hh" /* required for add_en_eno_param_decl_c */
msousa@315:
etisserant@0: /* an ugly hack!!
etisserant@0: * We will probably not need it when we decide
etisserant@0: * to cut down the abstract syntax down to size.
etisserant@0: * We keep it as it is until we get to write
etisserant@0: * stages 3 and 4 of the compiler. Who knows,
etisserant@0: * we might just find out that we really do need
etisserant@0: * the abstract syntax tree to stay as it is
etisserant@0: * afterall!
etisserant@0: */
etisserant@0: /* for each element in list_c *
etisserant@0: * execute the code
etisserant@0: */
etisserant@0: #define FOR_EACH_ELEMENT(elem, list, code) { \
etisserant@0: symbol_c *elem; \
etisserant@0: for(int i = 0; i < list->n; i++) { \
msousa@1041: elem = list->get_element(i); \
etisserant@0: code; \
etisserant@0: } \
etisserant@0: }
etisserant@0:
etisserant@0:
mario@68:
mario@68: /* Macros used to pass the line and column locations when
mario@68: * creating a new object for the abstract syntax tree.
mario@68: */
msousa@287: #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
msousa@287: #define locf(foo) foo.first_line, foo.first_column, foo.first_file, foo.first_order
msousa@287: #define locl(foo) foo.last_line, foo.last_column, foo.last_file, foo.last_order
msousa@286:
msousa@286: /* Redefine the default action to take for each rule, so that the filenames are correctly processed... */
msousa@286: # define YYLLOC_DEFAULT(Current, Rhs, N) \
msousa@286: do \
msousa@286: if (N) \
msousa@286: { \
msousa@286: (Current).first_line = YYRHSLOC(Rhs, 1).first_line; \
msousa@286: (Current).first_column = YYRHSLOC(Rhs, 1).first_column; \
msousa@286: (Current).first_file = YYRHSLOC(Rhs, 1).first_file; \
msousa@287: (Current).first_order = YYRHSLOC(Rhs, 1).first_order; \
msousa@286: (Current).last_line = YYRHSLOC(Rhs, N).last_line; \
msousa@286: (Current).last_column = YYRHSLOC(Rhs, N).last_column; \
msousa@286: (Current).last_file = YYRHSLOC(Rhs, 1).last_file; \
msousa@287: (Current).last_order = YYRHSLOC(Rhs, 1).last_order; \
msousa@286: } \
msousa@286: else \
msousa@286: { \
msousa@286: (Current).first_line = (Current).last_line = \
msousa@286: YYRHSLOC(Rhs, 0).last_line; \
msousa@286: (Current).first_column = (Current).last_column = \
msousa@286: YYRHSLOC(Rhs, 0).last_column; \
msousa@286: (Current).first_file = (Current).last_file = \
msousa@286: YYRHSLOC(Rhs, 0).last_file; \
msousa@287: (Current).first_order = (Current).last_order = \
msousa@287: YYRHSLOC(Rhs, 0).last_order; \
msousa@286: } \
msousa@286: while (0)
mario@68:
mario@68:
msousa@596: #include "../main.hh" // required for ERROR() and ERROR_MSG() macros.
etisserant@0:
etisserant@0:
etisserant@0:
etisserant@0: /*************************/
etisserant@0: /* global variables... */
etisserant@0: /*************************/
mario@15: /* NOTE: For some strange reason bison ver 2.3 is including these declarations
Edouard@822: * in the iec_bison.hh file, which is in turn included by flex.
mario@15: * We cannot therefore define any variables over here, but merely declare
mario@15: * their existance (otherwise we get errors when linking the code, since we
Edouard@822: * would get a new variable defined each time iec_bison.hh is included!).
mario@15: * Even though the variables are declared 'extern' over here, they will in
mario@15: * fact be defined towards the end of this same file (i.e. in the prologue)
mario@15: */
etisserant@0:
mario@177:
mario@177: /* NOTE: These variable are really parameters we would like the stage2__ function to pass
mario@177: * to the yyparse() function. However, the yyparse() function is created automatically
mario@177: * by bison, so we cannot add parameters to this function. The only other
mario@177: * option is to use global variables! yuck!
mario@177: */
mario@177:
etisserant@0: /* A global flag used to tell the parser if overloaded funtions should be allowed.
etisserant@0: * The IEC 61131-3 standard allows overloaded funtions in the standard library,
etisserant@0: * but disallows them in user code...
etisserant@0: */
mario@15: extern bool allow_function_overloading;
mario@15:
msousa@350: /* A flag to tell the compiler whether to allow the declaration
msousa@350: * of extensible function (i.e. functions that may have a variable number of
msousa@350: * input parameters, such as AND(word#33, word#44, word#55, word#66).
msousa@350: * This is an extension to the standard syntax.
msousa@350: * See comments below for details why we support this!
msousa@350: */
msousa@350: extern bool allow_extensible_function_parameters;
msousa@350:
mjsousa@934: /* A global flag used to tell the parser whether to allow use of DREF and '^' operators (defined in IEC 61131-3 v3) */
mjsousa@934: extern bool allow_ref_dereferencing;
mjsousa@934:
mjsousa@934: /* A global flag used to tell the parser whether to allow use of REF_TO ANY datatypes (non-standard extension to IEC 61131-3 v3) */
mjsousa@924: extern bool allow_ref_to_any;
mjsousa@924:
mjsousa@932: /* A global flag used to tell the parser whether to allow use of REF_TO as a struct or array element (non-standard extension) */
mjsousa@932: extern bool allow_ref_to_in_derived_datatypes;
mjsousa@932:
mjsousa@932: /* A pointer to the root of the parsing tree that will be generated by bison. */
mario@15: extern symbol_c *tree_root;
mario@15:
etisserant@0:
etisserant@0:
etisserant@0: /************************/
etisserant@0: /* forward declarations */
etisserant@0: /************************/
etisserant@0: /* The functions declared here are defined at the end of this file... */
etisserant@0:
etisserant@0: /* Convert an il_operator_c into an identifier_c */
mjsousa@958: identifier_c *il_operator_c_2_identifier_c (symbol_c *il_operator);
mjsousa@958: /* Convert an il_operator_c into an poutype_identifier_c */
mjsousa@958: poutype_identifier_c *il_operator_c_2_poutype_identifier_c(symbol_c *il_operator);
mjsousa@958:
etisserant@0:
lbessard@136: /* return if current token is a syntax element */
ccb@202: /* ERROR_CHECK_BEGIN */
lbessard@136: bool is_current_syntax_token();
ccb@202: /* ERROR_CHECK_END */
lbessard@136:
etisserant@0: /* print an error message */
lbessard@136: void print_err_msg(int first_line,
mario@95: int first_column,
msousa@286: const char *first_filename,
msousa@287: long int first_order,
mario@95: int last_line,
mario@95: int last_column,
msousa@286: const char *last_filename,
msousa@287: long int last_order,
msousa@756: const char *additional_error_msg);
etisserant@0: %}
etisserant@0:
etisserant@0:
etisserant@0:
mario@15:
mario@20: // %glr-parser
mario@13: // %expect-rr 1
mario@13:
mario@13:
msousa@286: /* The following definitions need to be inside a '%code requires'
msousa@286: * so that they are also included in the header files. If this were not the case,
msousa@286: * YYLTYPE would be delcared as something in the iec.cc file, and another thing
Edouard@822: * (actually the default value of YYLTYPE) in the iec_bison.hh heder file.
msousa@286: */
msousa@286: %code requires {
msousa@286: /* define a new data type to store the locations, so we can also store
msousa@286: * the filename in which the token is expressed.
msousa@286: */
Edouard@822: /* NOTE: since this code will be placed in the iec_bison.hh header file,
Edouard@822: * as well as the iec.cc file that also includes the iec_bison.hh header file,
msousa@286: * declaring the typedef struct yyltype__local here would result in a
msousa@286: * compilation error when compiling iec.cc, as this struct would be
msousa@286: * declared twice.
msousa@286: * We therefore use the #if !defined YYLTYPE ...
msousa@286: * to make sure only the first declaration is parsed by the C++ compiler.
msousa@286: */
msousa@286: #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
conti@415: typedef struct YYLTYPE {
msousa@287: int first_line;
msousa@287: int first_column;
msousa@286: const char *first_file;
msousa@287: long int first_order;
msousa@287: int last_line;
msousa@287: int last_column;
msousa@286: const char *last_file;
msousa@287: long int last_order;
conti@415: } YYLTYPE;
conti@415: #define YYLTYPE_IS_DECLARED 1
msousa@823: #define YYLTYPE_IS_TRIVIAL 0
msousa@286: #endif
conti@415:
msousa@286: }
msousa@286:
mario@13:
mario@13:
etisserant@0: %union {
etisserant@0: symbol_c *leaf;
etisserant@0: list_c *list;
etisserant@0: char *ID; /* token value */
etisserant@0: }
etisserant@0:
mario@68: /*
mario@68: TODO: DO we need to define a destructor do free
mario@68: memory when recovering from errors, or do the
mario@68: class destructors already handle this?
mario@68: Following is example on how to define
mario@68: detructors, using the syntax:
mario@68: %destructor { CODE } SYMBOLS
mario@68: %union
mario@68: {
mario@68: char *string;
mario@68: }
mario@68: %token STRING
mario@68: %type string
mario@68: %destructor { free ($$); } STRING string
mario@68: */
etisserant@0:
etisserant@0:
etisserant@0:
etisserant@0:
ccb@202: /*************************************/
ccb@202: /* Prelimenary helpful constructs... */
ccb@202: /*************************************/
mario@73: /* A token used to identify the very end of the input file
mario@73: * after all includes have already been processed.
mario@73: *
mario@73: * Flex automatically returns the token with value 0
mario@74: * at the end of the file. We therefore specify here
mario@74: * a token with that exact same value here, so we can use it
mario@74: * to detect the very end of the input files.
mario@73: */
mario@73: %token END_OF_INPUT 0
mario@73:
etisserant@0: /* A bogus token that, in principle, flex MUST NEVER generate */
etisserant@0: /* USE 1:
etisserant@0: * ======
etisserant@0: * This token is currently also being used as the default
etisserant@0: * initialisation value of the token_id member in
etisserant@0: * the symbol_c base class.
etisserant@0: *
etisserant@0: * USE 2
etisserant@0: * =====
etisserant@0: * This token may also be used in the future to remove
etisserant@0: * mysterious reduce/reduce conflicts due to the fact
etisserant@0: * that our grammar may not be LALR(1) but merely LR(1).
etisserant@0: * This means that bison cannot handle it without some
etisserant@0: * caoxing from ourselves. We will then need this token
etisserant@0: * to do the coaxing...
etisserant@0: */
etisserant@0: %token BOGUS_TOKEN_ID
etisserant@0:
mario@68: %type start
mario@15:
mario@15: %type any_identifier
mario@15:
mario@15: %token prev_declared_variable_name_token
lbessard@175: %token prev_declared_direct_variable_token
mario@15: %token prev_declared_fb_name_token
mario@15: %type prev_declared_variable_name
lbessard@175: %type prev_declared_direct_variable
mario@15: %type prev_declared_fb_name
mario@15:
mario@15: %token prev_declared_simple_type_name_token
mario@15: %token prev_declared_subrange_type_name_token
mario@15: %token prev_declared_enumerated_type_name_token
mario@15: %token prev_declared_array_type_name_token
mario@15: %token prev_declared_structure_type_name_token
mario@15: %token prev_declared_string_type_name_token
mjsousa@876: %token prev_declared_ref_type_name_token /* defined in IEC 61131-3 v3 */
mario@15:
mario@15: %type prev_declared_simple_type_name
mario@15: %type prev_declared_subrange_type_name
mario@15: %type prev_declared_enumerated_type_name
mario@15: %type prev_declared_array_type_name
mario@15: %type prev_declared_structure_type_name
mario@15: %type prev_declared_string_type_name
mjsousa@876: %type prev_declared_ref_type_name /* defined in IEC 61131-3 v3 */
mario@15:
mario@15: %token prev_declared_derived_function_name_token
mario@15: %token prev_declared_derived_function_block_name_token
mario@15: %token prev_declared_program_type_name_token
mario@15: %type prev_declared_derived_function_name
mario@15: %type prev_declared_derived_function_block_name
mario@15: %type prev_declared_program_type_name
mario@15:
mjsousa@1016: /* Tokens used to help resolve a reduce/reduce conflict */
mjsousa@1016: /* The mentioned conflict only arises due to a non-standard feature added to matiec.
mjsousa@1016: * Namely, the permission to call functions returning VOID as an ST statement.
mjsousa@1016: * e.g.: FUNCTION foo: VOID
mjsousa@1016: * VAR_INPUT i: INT; END_VAR;
mjsousa@1016: * ...
mjsousa@1016: * END_FUNCTION
mjsousa@1016: *
mjsousa@1016: * FUNCTION BAR: BOOL
mjsousa@1016: * VAR b: bool; END_VAR
mjsousa@1016: * foo(i:=42); <--- Calling foo outside an expression. Function invocation is considered an ST statement!!
mjsousa@1016: * END_FUNCTION
mjsousa@1016: *
mjsousa@1016: * The above function invocation may also be reduced to a formal IL function invocation, so we get a
mjsousa@1016: * reduce/reduce conflict to st_statement_list/instruction_list (or something equivalent).
mjsousa@1016: *
mjsousa@1016: * We solve this by having flex determine if it is ST or IL invocation (ST ends with a ';' !!).
mjsousa@1016: * At the start of a function/FB/program body, flex will tell bison whether to expect ST or IL code!
mjsousa@1016: * This is why we need the following two tokens!
mjsousa@1016: *
mjsousa@1016: * NOTE: flex was already determing whther it was parsing ST or IL code as it can only send
mjsousa@1016: * EOL tokens when parsing IL. However, did this silently without telling bison about this.
mjsousa@1016: * Now, it does
mjsousa@1016: */
mjsousa@1016: %token start_ST_body_token
mjsousa@1016: %token start_IL_body_token
mario@15:
mario@15:
mario@15:
ccb@202: /**********************************************************************************/
ccb@202: /* B XXX - Things that are missing from the standard, but should have been there! */
ccb@202: /**********************************************************************************/
ccb@202:
msousa@267: /* Pragmas that our compiler will accept.
msousa@267: * See the comment in iec.flex for why these pragmas exist.
msousa@267: */
msousa@267: %token disable_code_generation_pragma_token
msousa@267: %token enable_code_generation_pragma_token
msousa@267: %type disable_code_generation_pragma
msousa@267: %type enable_code_generation_pragma
msousa@267:
msousa@267:
msousa@267: /* All other pragmas that we do not support... */
msousa@267: /* In most stage 4, the text inside the pragmas will simply be copied to the output file.
msousa@267: * This allows us to insert C code (if using stage 4 generating C code)
msousa@267: * inside/interningled with the IEC 61131-3 code!
msousa@267: */
etisserant@0: %token pragma_token
etisserant@0: %type pragma
etisserant@0:
msousa@267: /* The joining of all previous pragmas, i.e. any possible pragma */
msousa@267: %type any_pragma
msousa@267:
etisserant@0:
ccb@202: /* Where do these tokens belong?? They are missing from the standard! */
ccb@202: /* NOTE: There are other tokens related to these 'EN' ENO', that are also
ccb@202: * missing from the standard. However, their location in the annex B is
ccb@202: * relatively obvious, so they have been inserted in what seems to us their
ccb@202: * correct place in order to ease understanding of the parser...
msousa@315: *
msousa@315: * please read the comment above the definition of 'variable' in section B1.4 for details.
ccb@202: */
etisserant@0: %token EN
etisserant@0: %token ENO
ccb@202: %type en_identifier
ccb@202: %type eno_identifier
ccb@202:
mjsousa@919: /* Keywords in IEC 61131-3 v3 */
mjsousa@873: %token REF
mjsousa@933: %token DREF
mjsousa@876: %token REF_TO
mjsousa@919: %token NULL_token /* cannot use simply 'NULL', as it conflicts with the NULL keyword in C++ */
etisserant@0:
etisserant@0:
etisserant@0:
etisserant@0: /***************************/
etisserant@0: /* B 0 - Programming Model */
etisserant@0: /***************************/
etisserant@0: %type library
etisserant@0: %type library_element_declaration
etisserant@0:
etisserant@0:
etisserant@0: /*******************************************/
etisserant@0: /* B 1.1 - Letters, digits and identifiers */
etisserant@0: /*******************************************/
etisserant@0: /* Done totally within flex...
etisserant@0: letter
etisserant@0: digit
etisserant@0: octal_digit
etisserant@0: hex_digit
etisserant@0: */
etisserant@0: %token identifier_token
etisserant@0: %type identifier
etisserant@0:
etisserant@0: /*********************/
etisserant@0: /* B 1.2 - Constants */
etisserant@0: /*********************/
etisserant@0: %type constant
msousa@643: %type non_int_or_real_constant
etisserant@0:
mjsousa@919: /*********************************/
mjsousa@919: /* B 1.2.XX - Reference Literals */
mjsousa@919: /*********************************/
mjsousa@919: /* NOTE: The following syntax was added by MJS in order to add support for the NULL keyword, defined in IEC 61131-3 v3
mjsousa@919: * In v3 expressions that reduce to a reference datatype (REF_TO) are handled explicitly in the syntax
mjsousa@919: * (e.g., any variable that is a of reference datatpe falls under the 'ref_name' rule), which means
mjsousa@919: * that we would need to keep track of which variables are declared as REF_TO.
mjsousa@919: * In order to reduce the changes to the current IEC 61131-3 v2 syntax, I have opted not to do this,
mjsousa@919: * and simply let the ref_expressions (Ref_Assign, Ref_Compare) be interpreted as all other standard expressions
mjsousa@919: * in v2. However, ref_expressions allow the use of the 'NULL' constant, which is handled explicitly
mjsousa@919: * in the ref_expressions syntax of v3.
mjsousa@919: * To allow the use of the 'NULL' constant in this extended v2, I have opted to interpret this 'NULL' constant
mjsousa@919: * as a literal.
mjsousa@919: */
mjsousa@919: %type ref_value_null_literal /* defined in IEC 61131-3 v3 - Basically the 'NULL' keyword! */
mjsousa@919:
mjsousa@919:
etisserant@0: /******************************/
etisserant@0: /* B 1.2.1 - Numeric Literals */
etisserant@0: /******************************/
etisserant@0: /* Done totally within flex...
etisserant@0: bit
etisserant@0: */
etisserant@0: %type numeric_literal
etisserant@0: %type integer_literal
etisserant@0: %type signed_integer
etisserant@0: %token integer_token
etisserant@0: %type integer
etisserant@0: %token binary_integer_token
etisserant@0: %type binary_integer
etisserant@0: %token octal_integer_token
etisserant@0: %type octal_integer
etisserant@0: %token hex_integer_token
etisserant@0: %type hex_integer
etisserant@0: %token real_token
etisserant@0: %type real
etisserant@0: %type signed_real
etisserant@0: %type real_literal
etisserant@0: // %type exponent
etisserant@0: %type bit_string_literal
etisserant@0: %type boolean_literal
etisserant@0:
msousa@257: %token safeboolean_true_literal_token
msousa@257: %token safeboolean_false_literal_token
msousa@257: %token boolean_true_literal_token
msousa@257: %token boolean_false_literal_token
msousa@257:
etisserant@0: %token FALSE
etisserant@0: %token TRUE
etisserant@0:
etisserant@0:
etisserant@0: /*******************************/
etisserant@0: /* B 1.2.2 - Character Strings */
etisserant@0: /*******************************/
etisserant@0: %token single_byte_character_string_token
etisserant@0: %token double_byte_character_string_token
etisserant@0:
etisserant@0: %type character_string
etisserant@0: %type single_byte_character_string
etisserant@0: %type double_byte_character_string
etisserant@0:
etisserant@0:
etisserant@0: /***************************/
etisserant@0: /* B 1.2.3 - Time Literals */
etisserant@0: /***************************/
etisserant@0: %type time_literal
etisserant@0:
etisserant@0:
etisserant@0: /************************/
etisserant@0: /* B 1.2.3.1 - Duration */
etisserant@0: /************************/
etisserant@0: %type duration
etisserant@0: %type interval
etisserant@0: %type days
etisserant@0: %type fixed_point
etisserant@0: %type hours
etisserant@0: %type minutes
etisserant@0: %type seconds
etisserant@0: %type milliseconds
etisserant@0:
etisserant@0: %token fixed_point_token
etisserant@0: %token fixed_point_d_token
etisserant@0: %token integer_d_token
etisserant@0: %token fixed_point_h_token
etisserant@0: %token integer_h_token
etisserant@0: %token fixed_point_m_token
etisserant@0: %token integer_m_token
etisserant@0: %token fixed_point_s_token
etisserant@0: %token integer_s_token
etisserant@0: %token fixed_point_ms_token
etisserant@0: %token integer_ms_token
msousa@547: %token end_interval_token
msousa@547: %token erroneous_interval_token
msousa@257: // %token TIME
etisserant@0: %token T_SHARP
etisserant@0:
etisserant@0:
etisserant@0: /************************************/
etisserant@0: /* B 1.2.3.2 - Time of day and Date */
etisserant@0: /************************************/
etisserant@0: %type time_of_day
etisserant@0: %type daytime
etisserant@0: %type day_hour
etisserant@0: %type day_minute
etisserant@0: %type day_second
etisserant@0: %type date
etisserant@0: %type date_literal
etisserant@0: %type year
etisserant@0: %type month
etisserant@0: %type day
etisserant@0: %type date_and_time
etisserant@0:
msousa@257: // %token TIME_OF_DAY
msousa@257: // %token DATE
etisserant@0: %token D_SHARP
msousa@257: // %token DATE_AND_TIME
etisserant@0:
etisserant@0:
etisserant@0: /**********************/
etisserant@0: /* B 1.3 - Data Types */
etisserant@0: /**********************/
etisserant@0: /* Strangely, the following symbol does seem to be required! */
etisserant@0: // %type data_type_name
etisserant@0: %type non_generic_type_name
etisserant@0:
etisserant@0:
etisserant@0: /***********************************/
etisserant@0: /* B 1.3.1 - Elementary Data Types */
etisserant@0: /***********************************/
etisserant@0: /* NOTES:
etisserant@0: *
etisserant@0: * - To make the definition of bit_string_literal more
etisserant@0: * concise, it is useful to use an extra non-terminal
etisserant@0: * symbol (i.e. a grouping or construct) that groups the
etisserant@0: * following elements (BYTE, WORD, DWORD, LWORD).
etisserant@0: * Note that the definition of bit_string_type_name
etisserant@0: * (according to the spec) includes the above elements
etisserant@0: * and an extra BOOL.
etisserant@0: * We could use an extra construct with the first four
etisserant@0: * elements to be used solely in the definition of
etisserant@0: * bit_string_literal, but with the objective of not
etisserant@0: * having to replicate the actions (if we ever need
etisserant@0: * to change them, they would need to be changed in both
etisserant@0: * bit_string_type_name and the extra grouping), we
etisserant@0: * have re-defined bit_string_type_name as only including
etisserant@0: * the first four elements.
etisserant@0: * In order to have our parser implement the specification
etisserant@0: * correctly we have augmented every occurence of
etisserant@0: * bit_string_type_name in other rules with the BOOL
etisserant@0: * token. Since bit_string_type_name only appears in
etisserant@0: * the rule for elementary_type_name, this does not
etisserant@0: * seem to be a big concession to make!
etisserant@0: *
etisserant@0: * - We have added a helper symbol to concentrate the
etisserant@0: * instantiation of STRING and WSTRING into a single
etisserant@0: * location (elementary_string_type_name).
etisserant@0: * These two elements show up in several other rules,
etisserant@0: * but we want to create the equivalent abstract syntax
etisserant@0: * in a single location of this file, in order to make
etisserant@0: * possible future changes easier to edit...
etisserant@0: */
etisserant@0: %type elementary_type_name
etisserant@0: %type numeric_type_name
etisserant@0: %type integer_type_name
etisserant@0: %type signed_integer_type_name
etisserant@0: %type unsigned_integer_type_name
etisserant@0: %type real_type_name
etisserant@0: %type date_type_name
etisserant@0: %type bit_string_type_name
etisserant@0: /* helper symbol to concentrate the instantiation
etisserant@0: * of STRING and WSTRING into a single location
etisserant@0: */
etisserant@0: %type elementary_string_type_name
etisserant@0:
etisserant@0: %token BYTE
etisserant@0: %token WORD
etisserant@0: %token DWORD
etisserant@0: %token LWORD
etisserant@0:
etisserant@0: %token LREAL
etisserant@0: %token REAL
etisserant@0:
etisserant@0: %token SINT
etisserant@0: %token INT
etisserant@0: %token DINT
etisserant@0: %token LINT
etisserant@0:
etisserant@0: %token USINT
etisserant@0: %token UINT
etisserant@0: %token UDINT
etisserant@0: %token ULINT
etisserant@0:
etisserant@0: %token WSTRING
etisserant@0: %token STRING
etisserant@0: %token BOOL
etisserant@0:
msousa@257: %token TIME
msousa@257: %token DATE
msousa@257: %token DATE_AND_TIME
etisserant@0: %token DT
msousa@257: %token TIME_OF_DAY
etisserant@0: %token TOD
etisserant@0:
mjsousa@1014: /* A non-standard extension! */
mjsousa@1014: %token VOID
mjsousa@1014:
msousa@257: /******************************************************/
msousa@257: /* Symbols defined in */
msousa@257: /* "Safety Software Technical Specification, */
msousa@257: /* Part 1: Concepts and Function Blocks, */
msousa@257: /* Version 1.0 – Official Release" */
msousa@257: /* by PLCopen - Technical Committee 5 - 2006-01-31 */
msousa@257: /******************************************************/
msousa@257:
msousa@257: %token SAFEBYTE
msousa@257: %token SAFEWORD
msousa@257: %token SAFEDWORD
msousa@257: %token SAFELWORD
msousa@257:
msousa@257: %token SAFELREAL
msousa@257: %token SAFEREAL
msousa@257:
msousa@257: %token SAFESINT
msousa@257: %token SAFEINT
msousa@257: %token SAFEDINT
msousa@257: %token SAFELINT
msousa@257:
msousa@257: %token SAFEUSINT
msousa@257: %token SAFEUINT
msousa@257: %token SAFEUDINT
msousa@257: %token SAFEULINT
msousa@257:
msousa@257: %token SAFEWSTRING
msousa@257: %token SAFESTRING
msousa@257: %token SAFEBOOL
msousa@257:
msousa@257: %token SAFETIME
msousa@257: %token SAFEDATE
msousa@257: %token SAFEDATE_AND_TIME
msousa@257: %token SAFEDT
msousa@257: %token SAFETIME_OF_DAY
msousa@257: %token SAFETOD
etisserant@0:
etisserant@0: /********************************/
etisserant@0: /* B 1.3.2 - Generic data types */
etisserant@0: /********************************/
etisserant@0: /* Strangely, the following symbol does seem to be required! */
etisserant@0: // %type generic_type_name
etisserant@0:
etisserant@0: /* The following tokens do not seem to be used either
etisserant@0: * but we declare them so they become reserved words...
etisserant@0: */
etisserant@0: %token ANY
etisserant@0: %token ANY_DERIVED
etisserant@0: %token ANY_ELEMENTARY
etisserant@0: %token ANY_MAGNITUDE
etisserant@0: %token ANY_NUM
etisserant@0: %token ANY_REAL
etisserant@0: %token ANY_INT
etisserant@0: %token ANY_BIT
etisserant@0: %token ANY_STRING
etisserant@0: %token ANY_DATE
etisserant@0:
etisserant@0:
etisserant@0: /********************************/
etisserant@0: /* B 1.3.3 - Derived data types */
etisserant@0: /********************************/
etisserant@0: %type derived_type_name
etisserant@0: %type single_element_type_name
etisserant@0: // %type simple_type_name
etisserant@0: // %type subrange_type_name
etisserant@0: // %type enumerated_type_name
etisserant@0: // %type array_type_name
etisserant@0: // %type structure_type_name
etisserant@0:
etisserant@0: %type data_type_declaration
etisserant@0: /* helper symbol for data_type_declaration */
etisserant@0: %type type_declaration_list
etisserant@0: %type type_declaration
etisserant@0: %type single_element_type_declaration
etisserant@0:
etisserant@0: %type simple_type_declaration
etisserant@0: %type simple_spec_init
etisserant@0: %type simple_specification
etisserant@0:
etisserant@0: %type subrange_type_declaration
etisserant@0: %type subrange_spec_init
etisserant@0: %type subrange_specification
etisserant@0: %type subrange
mjsousa@960: /* A non standard construct, used to support the use of variables in array subranges. e.g.: ARRAY [12..max] OF INT */
mjsousa@960: %type subrange_with_var
etisserant@0:
etisserant@0: %type enumerated_type_declaration
etisserant@0: %type enumerated_spec_init
etisserant@0: %type enumerated_specification
etisserant@0: /* helper symbol for enumerated_value */
etisserant@0: %type enumerated_value_list
etisserant@0: %type enumerated_value
mario@85: //%type enumerated_value_without_identifier
etisserant@0:
etisserant@0: %type array_type_declaration
etisserant@0: %type array_spec_init
etisserant@0: %type array_specification
etisserant@0: /* helper symbol for array_specification */
etisserant@0: %type array_subrange_list
etisserant@0: %type array_initialization
etisserant@0: /* helper symbol for array_initialization */
etisserant@0: %type array_initial_elements_list
etisserant@0: %type array_initial_elements
etisserant@0: %type array_initial_element
etisserant@0:
etisserant@0: %type structure_type_declaration
etisserant@0: %type structure_specification
etisserant@0: %type initialized_structure
etisserant@0: %type structure_declaration
etisserant@0: /* helper symbol for structure_declaration */
etisserant@0: %type structure_element_declaration_list
etisserant@0: %type structure_element_declaration
etisserant@0: %type structure_element_name
etisserant@0: %type structure_initialization
etisserant@0: /* helper symbol for structure_initialization */
etisserant@0: %type structure_element_initialization_list
etisserant@0: %type structure_element_initialization
etisserant@0:
etisserant@0: //%type string_type_name
etisserant@0: %type string_type_declaration
etisserant@0: /* helper symbol for string_type_declaration */
etisserant@0: %type string_type_declaration_size
etisserant@0: /* helper symbol for string_type_declaration */
etisserant@0: %type string_type_declaration_init
etisserant@0:
etisserant@0: %token ASSIGN
etisserant@0: %token DOTDOT /* ".." */
etisserant@0: %token TYPE
etisserant@0: %token END_TYPE
etisserant@0: %token ARRAY
etisserant@0: %token OF
etisserant@0: %token STRUCT
etisserant@0: %token END_STRUCT
etisserant@0:
etisserant@0:
mjsousa@932: %type ref_spec /* defined in IEC 61131-3 v3 */
mjsousa@932: %type ref_spec_non_recursive /* helper symbol */
mjsousa@932: %type ref_spec_init /* defined in IEC 61131-3 v3 */
mjsousa@932: %type ref_type_decl /* defined in IEC 61131-3 v3 */
mjsousa@876:
mjsousa@876:
etisserant@0:
etisserant@0: /*********************/
etisserant@0: /* B 1.4 - Variables */
etisserant@0: /*********************/
etisserant@0: %type variable
etisserant@0: %type symbolic_variable
etisserant@0: /* helper symbol for prog_cnxn */
etisserant@0: %type any_symbolic_variable
etisserant@0: %type variable_name
etisserant@0:
etisserant@0:
etisserant@0:
etisserant@0:
etisserant@0: /********************************************/
etisserant@0: /* B.1.4.1 Directly Represented Variables */
etisserant@0: /********************************************/
etisserant@0: /* Done totally within flex...
etisserant@0: location_prefix
etisserant@0: size_prefix
etisserant@0: */
etisserant@0: %token direct_variable_token
lbessard@175: //%type direct_variable
etisserant@0:
etisserant@0:
etisserant@0: /*************************************/
etisserant@0: /* B.1.4.2 Multi-element Variables */
etisserant@0: /*************************************/
etisserant@0: %type multi_element_variable
etisserant@0: /* helper symbol for any_symbolic_variable */
etisserant@0: %type any_multi_element_variable
etisserant@0: %type array_variable
etisserant@0: /* helper symbol for any_symbolic_variable */
etisserant@0: %type any_array_variable
etisserant@0: %type subscripted_variable
etisserant@0: /* helper symbol for any_symbolic_variable */
etisserant@0: %type any_subscripted_variable
etisserant@0: %type subscript_list
etisserant@0: %type subscript
etisserant@0: %type structured_variable
etisserant@0: /* helper symbol for any_symbolic_variable */
etisserant@0: %type any_structured_variable
etisserant@0: %type record_variable
etisserant@0: /* helper symbol for any_symbolic_variable */
etisserant@0: %type any_record_variable
etisserant@0: %type field_selector
etisserant@0:
etisserant@0:
etisserant@0: /******************************************/
etisserant@0: /* B 1.4.3 - Declaration & Initialisation */
etisserant@0: /******************************************/
etisserant@0: %type input_declarations
etisserant@0: /* helper symbol for input_declarations */
etisserant@0: %type input_declaration_list
etisserant@0: %type input_declaration
etisserant@0: %type edge_declaration
ccb@202: /* en_param_declaration is not in the standard, but should be! */
lbessard@146: %type en_param_declaration
etisserant@0: %type var_init_decl
etisserant@0: %type var1_init_decl
etisserant@0: %type var1_list
etisserant@0: %type array_var_init_decl
etisserant@0: %type structured_var_init_decl
etisserant@0: %type fb_name_decl
etisserant@0: /* helper symbol for fb_name_decl */
etisserant@0: %type fb_name_list_with_colon
etisserant@0: /* helper symbol for fb_name_list_with_colon */
etisserant@0: %type var1_list_with_colon
etisserant@0: // %type fb_name_list
etisserant@0: // %type fb_name
etisserant@0: %type output_declarations
lbessard@146: %type var_output_init_decl
lbessard@146: %type var_output_init_decl_list
ccb@202: /* eno_param_declaration is not in the standard, but should be! */
lbessard@147: %type eno_param_declaration
etisserant@0: %type input_output_declarations
etisserant@0: /* helper symbol for input_output_declarations */
etisserant@0: %type var_declaration_list
etisserant@0: %type var_declaration
etisserant@0: %type temp_var_decl
etisserant@0: %type var1_declaration
etisserant@0: %type array_var_declaration
etisserant@0: %type structured_var_declaration
etisserant@0: %type var_declarations
etisserant@0: %type retentive_var_declarations
etisserant@0: %type located_var_declarations
etisserant@0: /* helper symbol for located_var_declarations */
etisserant@0: %type located_var_decl_list
etisserant@0: %type located_var_decl
etisserant@0: %type external_var_declarations
etisserant@0: /* helper symbol for external_var_declarations */
etisserant@0: %type external_declaration_list
etisserant@0: %type external_declaration
etisserant@0: %type global_var_name
etisserant@0: %type global_var_declarations
etisserant@0: /* helper symbol for global_var_declarations */
etisserant@0: %type global_var_decl_list
etisserant@0: %type global_var_decl
etisserant@0: %type global_var_spec
etisserant@0: %type located_var_spec_init
etisserant@0: %type location
etisserant@0: %type global_var_list
etisserant@0: %type string_var_declaration
etisserant@0: %type single_byte_string_var_declaration
etisserant@0: %type single_byte_string_spec
etisserant@0: %type double_byte_string_var_declaration
etisserant@0: %type double_byte_string_spec
etisserant@0: %type incompl_located_var_declarations
etisserant@0: /* helper symbol for incompl_located_var_declarations */
etisserant@0: %type incompl_located_var_decl_list
etisserant@0: %type incompl_located_var_decl
etisserant@0: %type incompl_location
etisserant@0: %type var_spec
etisserant@0: /* helper symbol for var_spec */
etisserant@0: %type string_spec
etisserant@0: /* intermediate helper symbol for:
etisserant@0: * - non_retentive_var_decls
lbessard@146: * - var_declarations
etisserant@0: */
etisserant@0: %type var_init_decl_list
etisserant@0:
etisserant@0: %token incompl_location_token
etisserant@0:
etisserant@0: %token VAR_INPUT
etisserant@0: %token VAR_OUTPUT
etisserant@0: %token VAR_IN_OUT
etisserant@0: %token VAR_EXTERNAL
etisserant@0: %token VAR_GLOBAL
etisserant@0: %token END_VAR
etisserant@0: %token RETAIN
etisserant@0: %token NON_RETAIN
etisserant@0: %token R_EDGE
etisserant@0: %token F_EDGE
etisserant@0: %token AT
etisserant@0:
etisserant@0:
etisserant@0: /***********************/
etisserant@0: /* B 1.5.1 - Functions */
etisserant@0: /***********************/
mario@68: // %type function_name
etisserant@0: /* helper symbol for IL language */
etisserant@0: %type function_name_no_clashes
etisserant@0: %type function_name_simpleop_clashes
etisserant@0: //%type function_name_expression_clashes
etisserant@0: /* helper symbols for ST language */
etisserant@0: //%type function_name_NOT_clashes
etisserant@0: %type function_name_no_NOT_clashes
etisserant@0:
etisserant@0: //%type standard_function_name
etisserant@0: /* helper symbols for IL language */
etisserant@0: %type standard_function_name_no_clashes
etisserant@0: %type standard_function_name_simpleop_clashes
etisserant@0: %type standard_function_name_expression_clashes
etisserant@0: /* helper symbols for ST language */
etisserant@0: %type standard_function_name_NOT_clashes
etisserant@0: %type standard_function_name_no_NOT_clashes
etisserant@0:
etisserant@0: %type derived_function_name
etisserant@0: %type