stage1_2/iec.flex
changeset 270 f1674941c3ad
parent 267 0a1204bcc9af
child 286 a4f4990d5c66
--- a/stage1_2/iec.flex	Fri Apr 01 11:10:06 2011 +0200
+++ b/stage1_2/iec.flex	Mon Apr 04 13:25:39 2011 +0200
@@ -1,21 +1,28 @@
 /*
- * (c) 2003 Mario de Sousa
- *
- * Offered to the public under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2 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.
+ *  matiec - a compiler for the programming languages defined in IEC 61131-3
+ *
+ *  Copyright (C) 2003-2011  Mario de Sousa (msousa@fe.up.pt)
+ *
+ *  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 IL and ST compiler.
+ * An IEC 61131-3 compiler.
  *
  * Based on the
  * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10)
@@ -84,6 +91,9 @@
  */
 %option noyy_top_state
 
+/* We will not be using unput() in our flex code... */
+%option nounput
+
 /**************************************************/
 /* External Variable and Function declarations... */
 /**************************************************/
@@ -144,6 +154,14 @@
 
 
 /* We will not be using unput() in our flex code... */
+/* NOTE: it seems that this #define is no longer needed, It has been 
+ * replaced by %option nounput.
+ * Should we simply delete it?
+ * For now leave it in, in case someone is using an old version of flex.
+ * In any case, the most harm that can result in a warning message
+ * when compiling iec.flex.c:
+ * warning: ‘void yyunput(int, char*)’ defined but not used
+ */
 #define YY_NO_UNPUT
 
 /* Variable defined by the bison parser.
@@ -438,8 +456,28 @@
 /* Prelimenary constructs... */
 /*****************************/
 
-
-/* A pragma... */
+/* In order to allow the declaration of POU prototypes (Function, FB, Program, ...),
+ * especially the prototypes of Functions and FBs defined in the standard
+ * (i.e. standard functions and FBs), we extend the IEC 61131-3 standard syntax 
+ * with two pragmas to indicate that the code is to be parsed (going through the 
+ * lexical, syntactical, and semantic analysers), but no code is to be generated.
+ * 
+ * The accepted syntax is:
+ *  {no_code_generation begin}
+ *    ... prototypes ...
+ *  {no_code_generation end}
+ * 
+ * When parsing these prototypes the abstract syntax tree will be populated as usual,
+ * allowing the semantic analyser to correctly analyse the semantics of calls to these
+ * functions/FBs. However, stage4 will simply ignore all IEC61131-3 code
+ * between the above two pragmas.
+ */
+
+disable_code_generation_pragma	"{disable code generation}"
+enable_code_generation_pragma	"{enable code generation}"
+
+
+/* Any other pragma... */
 
 pragma "{"[^}]*"}"
 
@@ -726,6 +764,12 @@
 	/* We start off by searching for the pragmas we handle in the lexical parser. */
 <INITIAL>{file_include_pragma}	unput_text(0); yy_push_state(include_beg);
 
+	/* Pragmas sent to syntax analyser (bison) */
+{disable_code_generation_pragma}               return disable_code_generation_pragma_token;
+{enable_code_generation_pragma}                return enable_code_generation_pragma_token;
+<body_state>{disable_code_generation_pragma}   return disable_code_generation_pragma_token;
+<body_state>{enable_code_generation_pragma}    return enable_code_generation_pragma_token;
+
 	/* Any other pragma we find, we just pass it up to the syntax parser...   */
 	/* Note that the <body_state> state is exclusive, so we have to include it here too. */
 {pragma}	{/* return the pragmma without the enclosing '{' and '}' */
@@ -964,6 +1008,7 @@
 <il_state>{il_whitespace_no_pragma}		/* Eat any whitespace */
 
 
+
 	/*****************************************/
 	/* B.1.1 Letters, digits and identifiers */
 	/*****************************************/
@@ -1034,11 +1079,16 @@
 	/* B 1.2.1 - Numeric Literals */
 	/******************************/
 TRUE		return TRUE;		/* Keyword */
-BOOL#1  	return TRUE;		/* Keyword (Data Type) + Delimiter */
-BOOL#TRUE	return TRUE;		/* Keyword (Data Type) + Delimiter + Keyword */
+BOOL#1  	return boolean_true_literal_token;
+BOOL#TRUE	return boolean_true_literal_token;
+SAFEBOOL#1	{if (get_opt_safe_extensions()) {return safeboolean_true_literal_token;} else{REJECT;}} /* Keyword (Data Type) */ 
+SAFEBOOL#TRUE	{if (get_opt_safe_extensions()) {return safeboolean_true_literal_token;} else{REJECT;}} /* Keyword (Data Type) */
+
 FALSE		return FALSE;		/* Keyword */
-BOOL#0  	return FALSE;		/* Keyword (Data Type) + Delimiter */
-BOOL#FALSE  	return FALSE;		/* Keyword (Data Type) + Delimiter + Keyword */
+BOOL#0  	return boolean_false_literal_token;
+BOOL#FALSE  	return boolean_false_literal_token;
+SAFEBOOL#0	{if (get_opt_safe_extensions()) {return safeboolean_false_literal_token;} else{REJECT;}} /* Keyword (Data Type) */ 
+SAFEBOOL#FALSE	{if (get_opt_safe_extensions()) {return safeboolean_false_literal_token;} else{REJECT;}} /* Keyword (Data Type) */
 
 
 	/************************/
@@ -1064,11 +1114,82 @@
 	/***********************************/
 	/* B 1.3.1 - Elementary Data Types */
 	/***********************************/
+BOOL		return BOOL;		/* Keyword (Data Type) */
+
 BYTE		return BYTE;		/* Keyword (Data Type) */
 WORD		return WORD;		/* Keyword (Data Type) */
 DWORD		return DWORD;		/* Keyword (Data Type) */
 LWORD		return LWORD;		/* Keyword (Data Type) */
 
+SINT		return SINT;		/* Keyword (Data Type) */
+INT		return INT;		/* Keyword (Data Type) */
+DINT		return DINT;		/* Keyword (Data Type) */
+LINT		return LINT;		/* Keyword (Data Type) */
+
+USINT		return USINT;		/* Keyword (Data Type) */
+UINT		return UINT;		/* Keyword (Data Type) */
+UDINT		return UDINT;		/* Keyword (Data Type) */
+ULINT		return ULINT;		/* Keyword (Data Type) */
+
+REAL		return REAL;		/* Keyword (Data Type) */
+LREAL		return LREAL;		/* Keyword (Data Type) */
+
+WSTRING		return WSTRING;		/* Keyword (Data Type) */
+STRING		return STRING;		/* Keyword (Data Type) */
+
+TIME		return TIME;		/* Keyword (Data Type) */
+DATE		return DATE;		/* Keyword (Data Type) */
+DT		return DT;		/* Keyword (Data Type) */
+TOD		return TOD;		/* Keyword (Data Type) */
+DATE_AND_TIME	return DATE_AND_TIME;	/* Keyword (Data Type) */
+TIME_OF_DAY	return TIME_OF_DAY;	/* Keyword (Data Type) */
+
+	/*****************************************************************/
+	/* Keywords defined in "Safety Software Technical Specification" */
+	/*****************************************************************/
+        /* 
+         * NOTE: The following keywords are define in 
+         *       "Safety Software Technical Specification,
+         *        Part 1: Concepts and Function Blocks,  
+         *        Version 1.0 – Official Release"
+         *        written by PLCopen - Technical Committee 5
+         *
+         *        We only support these extensions and keywords
+         *        if the apropriate command line option is given.
+         */
+SAFEBOOL	     {if (get_opt_safe_extensions()) {return SAFEBOOL;}          else {REJECT;}} 
+
+SAFEBYTE	     {if (get_opt_safe_extensions()) {return SAFEBYTE;}          else {REJECT;}} 
+SAFEWORD	     {if (get_opt_safe_extensions()) {return SAFEWORD;}          else {REJECT;}} 
+SAFEDWORD	     {if (get_opt_safe_extensions()) {return SAFEDWORD;}         else{REJECT;}}
+SAFELWORD	     {if (get_opt_safe_extensions()) {return SAFELWORD;}         else{REJECT;}}
+               
+SAFEREAL	     {if (get_opt_safe_extensions()) {return SAFESINT;}          else{REJECT;}}
+SAFELREAL    	     {if (get_opt_safe_extensions()) {return SAFELREAL;}         else{REJECT;}}
+                  
+SAFESINT	     {if (get_opt_safe_extensions()) {return SAFESINT;}          else{REJECT;}}
+SAFEINT	             {if (get_opt_safe_extensions()) {return SAFEINT;}           else{REJECT;}}
+SAFEDINT	     {if (get_opt_safe_extensions()) {return SAFEDINT;}          else{REJECT;}}
+SAFELINT             {if (get_opt_safe_extensions()) {return SAFELINT;}          else{REJECT;}}
+
+SAFEUSINT            {if (get_opt_safe_extensions()) {return SAFEUSINT;}         else{REJECT;}}
+SAFEUINT             {if (get_opt_safe_extensions()) {return SAFEUINT;}          else{REJECT;}}
+SAFEUDINT            {if (get_opt_safe_extensions()) {return SAFEUDINT;}         else{REJECT;}}
+SAFEULINT            {if (get_opt_safe_extensions()) {return SAFEULINT;}         else{REJECT;}}
+
+ /* SAFESTRING and SAFEWSTRING are not yet supported, i.e. checked correctly, in the semantic analyser (stage 3) */
+ /*  so it is best not to support them at all... */
+ /*
+SAFEWSTRING          {if (get_opt_safe_extensions()) {return SAFEWSTRING;}       else{REJECT;}}
+SAFESTRING           {if (get_opt_safe_extensions()) {return SAFESTRING;}        else{REJECT;}}
+ */
+
+SAFETIME             {if (get_opt_safe_extensions()) {return SAFETIME;}          else{REJECT;}}
+SAFEDATE             {if (get_opt_safe_extensions()) {return SAFEDATE;}          else{REJECT;}}
+SAFEDT               {if (get_opt_safe_extensions()) {return SAFEDT;}            else{REJECT;}}
+SAFETOD              {if (get_opt_safe_extensions()) {return SAFETOD;}           else{REJECT;}}
+SAFEDATE_AND_TIME    {if (get_opt_safe_extensions()) {return SAFEDATE_AND_TIME;} else{REJECT;}}
+SAFETIME_OF_DAY      {if (get_opt_safe_extensions()) {return SAFETIME_OF_DAY;}   else{REJECT;}}
 
 	/********************************/
 	/* B 1.3.2 - Generic data types */
@@ -1105,30 +1226,6 @@
 	/*********************/
 	/* B 1.4 - Variables */
 	/*********************/
-REAL		return REAL;		/* Keyword (Data Type) */
-LREAL		return LREAL;		/* Keyword (Data Type) */
-
-SINT		return SINT;		/* Keyword (Data Type) */
-INT		return INT;		/* Keyword (Data Type) */
-DINT		return DINT;		/* Keyword (Data Type) */
-LINT		return LINT;		/* Keyword (Data Type) */
-
-USINT		return USINT;		/* Keyword (Data Type) */
-UINT		return UINT;		/* Keyword (Data Type) */
-UDINT		return UDINT;		/* Keyword (Data Type) */
-ULINT		return ULINT;		/* Keyword (Data Type) */
-
-
-WSTRING		return WSTRING;		/* Keyword (Data Type) */
-STRING		return STRING;		/* Keyword (Data Type) */
-BOOL		return BOOL;		/* Keyword (Data Type) */
-TIME		return TIME;		/* Keyword (Data Type) */
-DATE		return DATE;		/* Keyword (Data Type) */
-DT		return DT;		/* Keyword (Data Type) */
-TOD		return TOD;		/* Keyword (Data Type) */
-DATE_AND_TIME	return DATE_AND_TIME;	/* Keyword (Data Type) */
-TIME_OF_DAY	return TIME_OF_DAY;	/* Keyword (Data Type) */
-
 
 	/******************************************/
 	/* B 1.4.3 - Declaration & Initialisation */
@@ -1388,20 +1485,7 @@
 EXIT		return EXIT;		/* Keyword */
 
 
-	/*****************************************************************/
-	/* Keywords defined in "Safety Software Technical Specification" */
-	/*****************************************************************/
-        /* 
-         * NOTE: The following keywords are define in 
-         *       "Safety Software Technical Specification,
-         *        Part 1: Concepts and Function Blocks,  
-         *        Version 1.0 – Official Release"
-         *        written by PLCopen - Technical Committee 5
-         *
-         *        We only support these extensions and keywords
-         *        if the apropriate command line option is given.
-         */
-SAFEBOOL	{if (get_opt_safe_extensions()) {return SAFEBOOL;} else{REJECT;}}	/* Keyword (Data Type) */ 
+