1 /* |
1 /* |
2 * (c) 2003 Mario de Sousa |
2 * matiec - a compiler for the programming languages defined in IEC 61131-3 |
3 * |
3 * |
4 * Offered to the public under the terms of the GNU General Public License |
4 * Copyright (C) 2003-2011 Mario de Sousa (msousa@fe.up.pt) |
5 * as published by the Free Software Foundation; either version 2 of the |
5 * |
6 * License, or (at your option) any later version. |
6 * This program is free software: you can redistribute it and/or modify |
7 * |
7 * it under the terms of the GNU General Public License as published by |
8 * This program is distributed in the hope that it will be useful, but |
8 * the Free Software Foundation, either version 3 of the License, or |
9 * WITHOUT ANY WARRANTY; without even the implied warranty of |
9 * (at your option) any later version. |
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General |
10 * |
11 * Public License for more details. |
11 * This program is distributed in the hope that it will be useful, |
|
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
14 * GNU General Public License for more details. |
|
15 * |
|
16 * You should have received a copy of the GNU General Public License |
|
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
18 * |
12 * |
19 * |
13 * This code is made available on the understanding that it will not be |
20 * This code is made available on the understanding that it will not be |
14 * used in safety-critical situations without a full and competent review. |
21 * used in safety-critical situations without a full and competent review. |
15 */ |
22 */ |
16 |
23 |
17 /* |
24 /* |
18 * An IEC 61131-3 IL and ST compiler. |
25 * An IEC 61131-3 compiler. |
19 * |
26 * |
20 * Based on the |
27 * Based on the |
21 * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10) |
28 * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10) |
22 * |
29 * |
23 */ |
30 */ |
142 extern const char *current_filename; |
152 extern const char *current_filename; |
143 */ |
153 */ |
144 |
154 |
145 |
155 |
146 /* We will not be using unput() in our flex code... */ |
156 /* We will not be using unput() in our flex code... */ |
|
157 /* NOTE: it seems that this #define is no longer needed, It has been |
|
158 * replaced by %option nounput. |
|
159 * Should we simply delete it? |
|
160 * For now leave it in, in case someone is using an old version of flex. |
|
161 * In any case, the most harm that can result in a warning message |
|
162 * when compiling iec.flex.c: |
|
163 * warning: ‘void yyunput(int, char*)’ defined but not used |
|
164 */ |
147 #define YY_NO_UNPUT |
165 #define YY_NO_UNPUT |
148 |
166 |
149 /* Variable defined by the bison parser. |
167 /* Variable defined by the bison parser. |
150 * It must be initialised with the location |
168 * It must be initialised with the location |
151 * of the token being parsed. |
169 * of the token being parsed. |
436 |
454 |
437 /*****************************/ |
455 /*****************************/ |
438 /* Prelimenary constructs... */ |
456 /* Prelimenary constructs... */ |
439 /*****************************/ |
457 /*****************************/ |
440 |
458 |
441 |
459 /* In order to allow the declaration of POU prototypes (Function, FB, Program, ...), |
442 /* A pragma... */ |
460 * especially the prototypes of Functions and FBs defined in the standard |
|
461 * (i.e. standard functions and FBs), we extend the IEC 61131-3 standard syntax |
|
462 * with two pragmas to indicate that the code is to be parsed (going through the |
|
463 * lexical, syntactical, and semantic analysers), but no code is to be generated. |
|
464 * |
|
465 * The accepted syntax is: |
|
466 * {no_code_generation begin} |
|
467 * ... prototypes ... |
|
468 * {no_code_generation end} |
|
469 * |
|
470 * When parsing these prototypes the abstract syntax tree will be populated as usual, |
|
471 * allowing the semantic analyser to correctly analyse the semantics of calls to these |
|
472 * functions/FBs. However, stage4 will simply ignore all IEC61131-3 code |
|
473 * between the above two pragmas. |
|
474 */ |
|
475 |
|
476 disable_code_generation_pragma "{disable code generation}" |
|
477 enable_code_generation_pragma "{enable code generation}" |
|
478 |
|
479 |
|
480 /* Any other pragma... */ |
443 |
481 |
444 pragma "{"[^}]*"}" |
482 pragma "{"[^}]*"}" |
445 |
483 |
446 /* NOTE: this seemingly unnecessary complex definition is required |
484 /* NOTE: this seemingly unnecessary complex definition is required |
447 * to be able to eat up comments such as: |
485 * to be able to eat up comments such as: |
723 /* Handle the pragmas! */ |
761 /* Handle the pragmas! */ |
724 /***************************/ |
762 /***************************/ |
725 |
763 |
726 /* We start off by searching for the pragmas we handle in the lexical parser. */ |
764 /* We start off by searching for the pragmas we handle in the lexical parser. */ |
727 <INITIAL>{file_include_pragma} unput_text(0); yy_push_state(include_beg); |
765 <INITIAL>{file_include_pragma} unput_text(0); yy_push_state(include_beg); |
|
766 |
|
767 /* Pragmas sent to syntax analyser (bison) */ |
|
768 {disable_code_generation_pragma} return disable_code_generation_pragma_token; |
|
769 {enable_code_generation_pragma} return enable_code_generation_pragma_token; |
|
770 <body_state>{disable_code_generation_pragma} return disable_code_generation_pragma_token; |
|
771 <body_state>{enable_code_generation_pragma} return enable_code_generation_pragma_token; |
728 |
772 |
729 /* Any other pragma we find, we just pass it up to the syntax parser... */ |
773 /* Any other pragma we find, we just pass it up to the syntax parser... */ |
730 /* Note that the <body_state> state is exclusive, so we have to include it here too. */ |
774 /* Note that the <body_state> state is exclusive, so we have to include it here too. */ |
731 {pragma} {/* return the pragmma without the enclosing '{' and '}' */ |
775 {pragma} {/* return the pragmma without the enclosing '{' and '}' */ |
732 yytext[strlen(yytext)-1] = '\0'; |
776 yytext[strlen(yytext)-1] = '\0'; |
960 /***************************************/ |
1004 /***************************************/ |
961 /* NOTE: pragmas are handled right at the beginning... */ |
1005 /* NOTE: pragmas are handled right at the beginning... */ |
962 |
1006 |
963 <INITIAL,config_state,decl_state,st_state,sfc_state,task_init_state,sfc_qualifier_state>{st_whitespace_no_pragma} /* Eat any whitespace */ |
1007 <INITIAL,config_state,decl_state,st_state,sfc_state,task_init_state,sfc_qualifier_state>{st_whitespace_no_pragma} /* Eat any whitespace */ |
964 <il_state>{il_whitespace_no_pragma} /* Eat any whitespace */ |
1008 <il_state>{il_whitespace_no_pragma} /* Eat any whitespace */ |
|
1009 |
965 |
1010 |
966 |
1011 |
967 /*****************************************/ |
1012 /*****************************************/ |
968 /* B.1.1 Letters, digits and identifiers */ |
1013 /* B.1.1 Letters, digits and identifiers */ |
969 /*****************************************/ |
1014 /*****************************************/ |
1032 |
1077 |
1033 /******************************/ |
1078 /******************************/ |
1034 /* B 1.2.1 - Numeric Literals */ |
1079 /* B 1.2.1 - Numeric Literals */ |
1035 /******************************/ |
1080 /******************************/ |
1036 TRUE return TRUE; /* Keyword */ |
1081 TRUE return TRUE; /* Keyword */ |
1037 BOOL#1 return TRUE; /* Keyword (Data Type) + Delimiter */ |
1082 BOOL#1 return boolean_true_literal_token; |
1038 BOOL#TRUE return TRUE; /* Keyword (Data Type) + Delimiter + Keyword */ |
1083 BOOL#TRUE return boolean_true_literal_token; |
|
1084 SAFEBOOL#1 {if (get_opt_safe_extensions()) {return safeboolean_true_literal_token;} else{REJECT;}} /* Keyword (Data Type) */ |
|
1085 SAFEBOOL#TRUE {if (get_opt_safe_extensions()) {return safeboolean_true_literal_token;} else{REJECT;}} /* Keyword (Data Type) */ |
|
1086 |
1039 FALSE return FALSE; /* Keyword */ |
1087 FALSE return FALSE; /* Keyword */ |
1040 BOOL#0 return FALSE; /* Keyword (Data Type) + Delimiter */ |
1088 BOOL#0 return boolean_false_literal_token; |
1041 BOOL#FALSE return FALSE; /* Keyword (Data Type) + Delimiter + Keyword */ |
1089 BOOL#FALSE return boolean_false_literal_token; |
|
1090 SAFEBOOL#0 {if (get_opt_safe_extensions()) {return safeboolean_false_literal_token;} else{REJECT;}} /* Keyword (Data Type) */ |
|
1091 SAFEBOOL#FALSE {if (get_opt_safe_extensions()) {return safeboolean_false_literal_token;} else{REJECT;}} /* Keyword (Data Type) */ |
1042 |
1092 |
1043 |
1093 |
1044 /************************/ |
1094 /************************/ |
1045 /* B 1.2.3.1 - Duration */ |
1095 /* B 1.2.3.1 - Duration */ |
1046 /************************/ |
1096 /************************/ |
1062 |
1112 |
1063 |
1113 |
1064 /***********************************/ |
1114 /***********************************/ |
1065 /* B 1.3.1 - Elementary Data Types */ |
1115 /* B 1.3.1 - Elementary Data Types */ |
1066 /***********************************/ |
1116 /***********************************/ |
|
1117 BOOL return BOOL; /* Keyword (Data Type) */ |
|
1118 |
1067 BYTE return BYTE; /* Keyword (Data Type) */ |
1119 BYTE return BYTE; /* Keyword (Data Type) */ |
1068 WORD return WORD; /* Keyword (Data Type) */ |
1120 WORD return WORD; /* Keyword (Data Type) */ |
1069 DWORD return DWORD; /* Keyword (Data Type) */ |
1121 DWORD return DWORD; /* Keyword (Data Type) */ |
1070 LWORD return LWORD; /* Keyword (Data Type) */ |
1122 LWORD return LWORD; /* Keyword (Data Type) */ |
1071 |
1123 |
|
1124 SINT return SINT; /* Keyword (Data Type) */ |
|
1125 INT return INT; /* Keyword (Data Type) */ |
|
1126 DINT return DINT; /* Keyword (Data Type) */ |
|
1127 LINT return LINT; /* Keyword (Data Type) */ |
|
1128 |
|
1129 USINT return USINT; /* Keyword (Data Type) */ |
|
1130 UINT return UINT; /* Keyword (Data Type) */ |
|
1131 UDINT return UDINT; /* Keyword (Data Type) */ |
|
1132 ULINT return ULINT; /* Keyword (Data Type) */ |
|
1133 |
|
1134 REAL return REAL; /* Keyword (Data Type) */ |
|
1135 LREAL return LREAL; /* Keyword (Data Type) */ |
|
1136 |
|
1137 WSTRING return WSTRING; /* Keyword (Data Type) */ |
|
1138 STRING return STRING; /* Keyword (Data Type) */ |
|
1139 |
|
1140 TIME return TIME; /* Keyword (Data Type) */ |
|
1141 DATE return DATE; /* Keyword (Data Type) */ |
|
1142 DT return DT; /* Keyword (Data Type) */ |
|
1143 TOD return TOD; /* Keyword (Data Type) */ |
|
1144 DATE_AND_TIME return DATE_AND_TIME; /* Keyword (Data Type) */ |
|
1145 TIME_OF_DAY return TIME_OF_DAY; /* Keyword (Data Type) */ |
|
1146 |
|
1147 /*****************************************************************/ |
|
1148 /* Keywords defined in "Safety Software Technical Specification" */ |
|
1149 /*****************************************************************/ |
|
1150 /* |
|
1151 * NOTE: The following keywords are define in |
|
1152 * "Safety Software Technical Specification, |
|
1153 * Part 1: Concepts and Function Blocks, |
|
1154 * Version 1.0 – Official Release" |
|
1155 * written by PLCopen - Technical Committee 5 |
|
1156 * |
|
1157 * We only support these extensions and keywords |
|
1158 * if the apropriate command line option is given. |
|
1159 */ |
|
1160 SAFEBOOL {if (get_opt_safe_extensions()) {return SAFEBOOL;} else {REJECT;}} |
|
1161 |
|
1162 SAFEBYTE {if (get_opt_safe_extensions()) {return SAFEBYTE;} else {REJECT;}} |
|
1163 SAFEWORD {if (get_opt_safe_extensions()) {return SAFEWORD;} else {REJECT;}} |
|
1164 SAFEDWORD {if (get_opt_safe_extensions()) {return SAFEDWORD;} else{REJECT;}} |
|
1165 SAFELWORD {if (get_opt_safe_extensions()) {return SAFELWORD;} else{REJECT;}} |
|
1166 |
|
1167 SAFEREAL {if (get_opt_safe_extensions()) {return SAFESINT;} else{REJECT;}} |
|
1168 SAFELREAL {if (get_opt_safe_extensions()) {return SAFELREAL;} else{REJECT;}} |
|
1169 |
|
1170 SAFESINT {if (get_opt_safe_extensions()) {return SAFESINT;} else{REJECT;}} |
|
1171 SAFEINT {if (get_opt_safe_extensions()) {return SAFEINT;} else{REJECT;}} |
|
1172 SAFEDINT {if (get_opt_safe_extensions()) {return SAFEDINT;} else{REJECT;}} |
|
1173 SAFELINT {if (get_opt_safe_extensions()) {return SAFELINT;} else{REJECT;}} |
|
1174 |
|
1175 SAFEUSINT {if (get_opt_safe_extensions()) {return SAFEUSINT;} else{REJECT;}} |
|
1176 SAFEUINT {if (get_opt_safe_extensions()) {return SAFEUINT;} else{REJECT;}} |
|
1177 SAFEUDINT {if (get_opt_safe_extensions()) {return SAFEUDINT;} else{REJECT;}} |
|
1178 SAFEULINT {if (get_opt_safe_extensions()) {return SAFEULINT;} else{REJECT;}} |
|
1179 |
|
1180 /* SAFESTRING and SAFEWSTRING are not yet supported, i.e. checked correctly, in the semantic analyser (stage 3) */ |
|
1181 /* so it is best not to support them at all... */ |
|
1182 /* |
|
1183 SAFEWSTRING {if (get_opt_safe_extensions()) {return SAFEWSTRING;} else{REJECT;}} |
|
1184 SAFESTRING {if (get_opt_safe_extensions()) {return SAFESTRING;} else{REJECT;}} |
|
1185 */ |
|
1186 |
|
1187 SAFETIME {if (get_opt_safe_extensions()) {return SAFETIME;} else{REJECT;}} |
|
1188 SAFEDATE {if (get_opt_safe_extensions()) {return SAFEDATE;} else{REJECT;}} |
|
1189 SAFEDT {if (get_opt_safe_extensions()) {return SAFEDT;} else{REJECT;}} |
|
1190 SAFETOD {if (get_opt_safe_extensions()) {return SAFETOD;} else{REJECT;}} |
|
1191 SAFEDATE_AND_TIME {if (get_opt_safe_extensions()) {return SAFEDATE_AND_TIME;} else{REJECT;}} |
|
1192 SAFETIME_OF_DAY {if (get_opt_safe_extensions()) {return SAFETIME_OF_DAY;} else{REJECT;}} |
1072 |
1193 |
1073 /********************************/ |
1194 /********************************/ |
1074 /* B 1.3.2 - Generic data types */ |
1195 /* B 1.3.2 - Generic data types */ |
1075 /********************************/ |
1196 /********************************/ |
1076 /* Strangely, the following symbols do not seem to be required! */ |
1197 /* Strangely, the following symbols do not seem to be required! */ |
1103 |
1224 |
1104 |
1225 |
1105 /*********************/ |
1226 /*********************/ |
1106 /* B 1.4 - Variables */ |
1227 /* B 1.4 - Variables */ |
1107 /*********************/ |
1228 /*********************/ |
1108 REAL return REAL; /* Keyword (Data Type) */ |
|
1109 LREAL return LREAL; /* Keyword (Data Type) */ |
|
1110 |
|
1111 SINT return SINT; /* Keyword (Data Type) */ |
|
1112 INT return INT; /* Keyword (Data Type) */ |
|
1113 DINT return DINT; /* Keyword (Data Type) */ |
|
1114 LINT return LINT; /* Keyword (Data Type) */ |
|
1115 |
|
1116 USINT return USINT; /* Keyword (Data Type) */ |
|
1117 UINT return UINT; /* Keyword (Data Type) */ |
|
1118 UDINT return UDINT; /* Keyword (Data Type) */ |
|
1119 ULINT return ULINT; /* Keyword (Data Type) */ |
|
1120 |
|
1121 |
|
1122 WSTRING return WSTRING; /* Keyword (Data Type) */ |
|
1123 STRING return STRING; /* Keyword (Data Type) */ |
|
1124 BOOL return BOOL; /* Keyword (Data Type) */ |
|
1125 TIME return TIME; /* Keyword (Data Type) */ |
|
1126 DATE return DATE; /* Keyword (Data Type) */ |
|
1127 DT return DT; /* Keyword (Data Type) */ |
|
1128 TOD return TOD; /* Keyword (Data Type) */ |
|
1129 DATE_AND_TIME return DATE_AND_TIME; /* Keyword (Data Type) */ |
|
1130 TIME_OF_DAY return TIME_OF_DAY; /* Keyword (Data Type) */ |
|
1131 |
|
1132 |
1229 |
1133 /******************************************/ |
1230 /******************************************/ |
1134 /* B 1.4.3 - Declaration & Initialisation */ |
1231 /* B 1.4.3 - Declaration & Initialisation */ |
1135 /******************************************/ |
1232 /******************************************/ |
1136 VAR_INPUT return VAR_INPUT; /* Keyword */ |
1233 VAR_INPUT return VAR_INPUT; /* Keyword */ |
1386 END_REPEAT return END_REPEAT; /* Keyword */ |
1483 END_REPEAT return END_REPEAT; /* Keyword */ |
1387 |
1484 |
1388 EXIT return EXIT; /* Keyword */ |
1485 EXIT return EXIT; /* Keyword */ |
1389 |
1486 |
1390 |
1487 |
1391 /*****************************************************************/ |
1488 |
1392 /* Keywords defined in "Safety Software Technical Specification" */ |
|
1393 /*****************************************************************/ |
|
1394 /* |
|
1395 * NOTE: The following keywords are define in |
|
1396 * "Safety Software Technical Specification, |
|
1397 * Part 1: Concepts and Function Blocks, |
|
1398 * Version 1.0 – Official Release" |
|
1399 * written by PLCopen - Technical Committee 5 |
|
1400 * |
|
1401 * We only support these extensions and keywords |
|
1402 * if the apropriate command line option is given. |
|
1403 */ |
|
1404 SAFEBOOL {if (get_opt_safe_extensions()) {return SAFEBOOL;} else{REJECT;}} /* Keyword (Data Type) */ |
|
1405 |
1489 |
1406 |
1490 |
1407 |
1491 |
1408 /********************************************************/ |
1492 /********************************************************/ |
1409 /********************************************************/ |
1493 /********************************************************/ |