etisserant@0: /* msousa@267: * matiec - a compiler for the programming languages defined in IEC 61131-3 etisserant@0: * msousa@267: * Copyright (C) 2003-2011 Mario de Sousa (msousa@fe.up.pt) Edouard@279: * Copyright (C) 2007-2011 Laurent Bessard and Edouard Tisserant etisserant@0: * msousa@267: * This program is free software: you can redistribute it and/or modify msousa@267: * it under the terms of the GNU General Public License as published by msousa@267: * the Free Software Foundation, either version 3 of the License, or msousa@267: * (at your option) any later version. msousa@267: * msousa@267: * This program is distributed in the hope that it will be useful, msousa@267: * but WITHOUT ANY WARRANTY; without even the implied warranty of msousa@267: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the msousa@267: * GNU General Public License for more details. msousa@267: * msousa@267: * You should have received a copy of the GNU General Public License msousa@267: * along with this program. If not, see . msousa@267: * 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@267: * 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: /* etisserant@0: * Code to be included into the code generated by the 4th stage. etisserant@0: * etisserant@0: * This is part of the 4th stage that generates etisserant@0: * a ST and IL source program equivalent to the IL and ST etisserant@0: * code. etisserant@0: * This is expected to be used mainly in debuging the syntax etisserant@0: * and lexical parser, and as a starting point for other etisserant@0: * 4th stages. etisserant@0: */ etisserant@0: etisserant@0: etisserant@0: msousa@580: /* Compile with the following option, to print out the const_value of each symbol, which was filled in by constant_folding_c during stage3 */ msousa@580: // #define DEBUG_CONST_VALUE etisserant@0: etisserant@0: etisserant@0: etisserant@0: // #include /* required for NULL */ etisserant@0: #include etisserant@0: #include etisserant@27: #include ccb@202: #include etisserant@0: #include "generate_iec.hh" etisserant@0: etisserant@0: #include "../stage4.hh" msousa@596: #include "../../main.hh" // required for ERROR() and ERROR_MSG() macros. msousa@596: msousa@596: msousa@596: mjsousa@878: /***********************************************************************/ mjsousa@878: /***********************************************************************/ mjsousa@878: /***********************************************************************/ mjsousa@878: /***********************************************************************/ mjsousa@878: mjsousa@878: /* Parse command line options passed from main.c !! */ mjsousa@878: mjsousa@878: int stage4_parse_options(char *options) {return 0;} mjsousa@878: mjsousa@878: void stage4_print_options(void) { mjsousa@878: printf(" (no options available when generating IEC 61131-3 code)\n"); mjsousa@878: } mjsousa@878: mjsousa@878: /***********************************************************************/ mjsousa@878: /***********************************************************************/ mjsousa@878: /***********************************************************************/ mjsousa@878: /***********************************************************************/ etisserant@0: etisserant@0: etisserant@0: //class generate_iec_c: public iterator_visitor_c { etisserant@0: class generate_iec_c: public visitor_c { etisserant@0: private: etisserant@0: stage4out_c &s4o; etisserant@0: etisserant@0: etisserant@0: public: etisserant@0: generate_iec_c(stage4out_c *s4o_ptr): s4o(*s4o_ptr) {} etisserant@0: ~generate_iec_c(void) {} etisserant@0: etisserant@0: etisserant@0: private: etisserant@0: msousa@580: msousa@580: void print_const_value(symbol_c *symbol) { msousa@580: #ifdef DEBUG_CONST_VALUE msousa@580: if (NULL == symbol) return; msousa@580: bool first = true; msousa@580: msousa@580: if (NULL != symbol->const_value_uint64) { msousa@580: first?s4o.print("{"):s4o.print("; "); msousa@580: first = false; msousa@580: s4o.print("uint64:"); msousa@580: if (symbol->const_value_uint64->status == symbol_c::cs_const_value) msousa@580: s4o.print_uint64(symbol->const_value_uint64->value); msousa@580: if (symbol->const_value_uint64->status == symbol_c::cs_overflow) msousa@580: s4o.print("OVERFLOW"); msousa@580: } msousa@580: if (NULL != symbol->const_value_int64) { msousa@580: first?s4o.print("{"):s4o.print("; "); msousa@580: first = false; msousa@580: s4o.print("int64:"); msousa@580: if (symbol->const_value_int64->status == symbol_c::cs_const_value) msousa@580: s4o.print_int64(symbol->const_value_int64->value); msousa@580: if (symbol->const_value_int64->status == symbol_c::cs_overflow) msousa@580: s4o.print("OVERFLOW"); msousa@580: } msousa@580: if (NULL != symbol->const_value_real64) { msousa@580: first?s4o.print("{"):s4o.print("; "); msousa@580: first = false; msousa@580: s4o.print("real64:"); msousa@580: if (symbol->const_value_real64->status == symbol_c::cs_const_value) msousa@580: s4o.print_real64(symbol->const_value_real64->value); msousa@580: if (symbol->const_value_real64->status == symbol_c::cs_overflow) msousa@580: s4o.print("OVERFLOW"); msousa@580: } msousa@580: if (NULL != symbol->const_value_bool) { msousa@580: first?s4o.print("{"):s4o.print("; "); msousa@580: first = false; msousa@580: s4o.print("bool:"); msousa@580: if (symbol->const_value_bool->status == symbol_c::cs_const_value) msousa@580: s4o.print((symbol->const_value_bool->value)?"true":"false"); msousa@580: if (symbol->const_value_bool->status == symbol_c::cs_overflow) msousa@580: s4o.print("OVERFLOW"); msousa@580: } msousa@580: if (!first) s4o.print("}"); msousa@580: #endif msousa@580: return; msousa@580: } msousa@580: msousa@580: msousa@580: etisserant@0: void *print_token(token_c *token) { msousa@580: print_const_value(token); etisserant@0: return s4o.print(token->value); etisserant@0: } etisserant@0: msousa@580: etisserant@0: void *print_literal(symbol_c *type, symbol_c *value) { msousa@580: print_const_value(value); msousa@257: if (NULL != type) { msousa@257: type->accept(*this); msousa@257: s4o.print("#"); msousa@257: } etisserant@0: value->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: void *print_list(list_c *list, etisserant@0: std::string pre_elem_str = "", etisserant@0: std::string inter_elem_str = "", etisserant@0: std::string post_elem_str = "") { etisserant@0: if (list->n > 0) { etisserant@0: s4o.print(pre_elem_str); etisserant@0: list->elements[0]->accept(*this); etisserant@0: } etisserant@0: etisserant@0: for(int i = 1; i < list->n; i++) { etisserant@0: s4o.print(inter_elem_str); etisserant@0: list->elements[i]->accept(*this); etisserant@0: } etisserant@0: etisserant@0: if (list->n > 0) etisserant@0: s4o.print(post_elem_str); etisserant@0: etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: msousa@580: void *print_binary_expression(symbol_c *symbol, msousa@580: symbol_c *l_exp, etisserant@0: symbol_c *r_exp, etisserant@0: const char *operation) { msousa@580: print_const_value(symbol); etisserant@0: s4o.print("("); etisserant@0: l_exp->accept(*this); etisserant@0: s4o.print(operation); etisserant@0: r_exp->accept(*this); etisserant@0: s4o.print(")"); etisserant@0: return NULL; etisserant@0: } etisserant@0: msousa@580: void *print_unary_expression(symbol_c *symbol, msousa@580: symbol_c *exp, etisserant@0: const char *operation) { msousa@580: print_const_value(symbol); etisserant@0: s4o.print(operation); etisserant@0: exp->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: etisserant@0: etisserant@0: etisserant@0: etisserant@0: public: lbessard@143: lbessard@143: /* EN/ENO */ ccb@202: #if 0 lbessard@143: void *visit(en_param_c *symbol) { lbessard@143: s4o.print("EN"); lbessard@143: return NULL; lbessard@143: } lbessard@143: lbessard@143: void *visit(eno_param_c *symbol) { lbessard@143: s4o.print("ENO"); lbessard@143: return NULL; lbessard@143: } ccb@202: void *visit(en_param_c *symbol) { ccb@202: return symbol->param_name->accept(*this); ccb@202: } ccb@202: ccb@202: void *visit(eno_param_c *symbol) { ccb@202: return symbol->param_name->accept(*this); ccb@202: } ccb@202: #endif ccb@202: ccb@202: msousa@459: /* A class used to identify an entry (literal, variable, etc...) in the abstract syntax tree with an invalid data type */ msousa@459: /* This is only used from stage3 onwards. Stages 1 and 2 will never create any instances of invalid_type_name_c */ msousa@459: // SYM_REF0(invalid_type_name_c) msousa@459: void *visit(invalid_type_name_c *symbol) { msousa@459: ERROR; msousa@459: return NULL; msousa@459: } ccb@202: lbessard@143: msousa@267: /******************/ msousa@267: /* 2.1.6 Pragmas */ msousa@267: /******************/ msousa@267: void *visit(enable_code_generation_pragma_c*) {s4o.print("{enable code generation}"); return NULL;} msousa@267: void *visit(disable_code_generation_pragma_c*) {s4o.print("{disable code generation}"); return NULL;} msousa@267: void *visit(pragma_c *symbol) {return print_token(symbol);} etisserant@0: etisserant@0: etisserant@0: /***************************/ etisserant@0: /* B 0 - Programming Model */ etisserant@0: /***************************/ etisserant@0: void *visit(library_c *symbol) {return print_list(symbol);} etisserant@0: etisserant@0: /*******************************************/ etisserant@0: /* B 1.1 - Letters, digits and identifiers */ etisserant@0: /*******************************************/ etisserant@0: void *visit(identifier_c *symbol) {return print_token(symbol);} etisserant@0: etisserant@0: /*********************/ etisserant@0: /* B 1.2 - Constants */ etisserant@0: /*********************/ mjsousa@919: /*********************************/ mjsousa@919: /* B 1.2.XX - Reference Literals */ mjsousa@919: /*********************************/ mjsousa@919: /* defined in IEC 61131-3 v3 - Basically the 'NULL' keyword! */ mjsousa@919: void *visit(ref_value_null_literal_c *symbol) {s4o.print("NULL"); return NULL;} etisserant@0: etisserant@0: /******************************/ etisserant@0: /* B 1.2.1 - Numeric Literals */ etisserant@0: /******************************/ msousa@257: void *visit(real_c *symbol) {return print_token(symbol);} msousa@580: void *visit(neg_real_c *symbol) {return print_unary_expression(symbol, symbol->exp, "-");} msousa@257: void *visit(integer_c *symbol) {return print_token(symbol);} msousa@580: void *visit(neg_integer_c *symbol) {return print_unary_expression(symbol, symbol->exp, "-");} msousa@257: void *visit(binary_integer_c *symbol) {return print_token(symbol);} msousa@257: void *visit(octal_integer_c *symbol) {return print_token(symbol);} msousa@257: void *visit(hex_integer_c *symbol) {return print_token(symbol);} msousa@257: msousa@257: void *visit(integer_literal_c *symbol) {return print_literal(symbol->type, symbol->value);} msousa@257: void *visit(real_literal_c *symbol) {return print_literal(symbol->type, symbol->value);} etisserant@0: void *visit(bit_string_literal_c *symbol) {return print_literal(symbol->type, symbol->value);} msousa@257: void *visit(boolean_literal_c *symbol) {return print_literal(symbol->type, symbol->value);} etisserant@0: etisserant@0: /* helper class for boolean_literal_c */ mjsousa@919: void *visit(boolean_true_c *symbol) {s4o.print(/*"TRUE" */"1"); return NULL;} msousa@257: void *visit(boolean_false_c *symbol) {s4o.print(/*"FALSE"*/"0"); return NULL;} etisserant@0: etisserant@0: /*******************************/ etisserant@0: /* B.1.2.2 Character Strings */ etisserant@0: /*******************************/ etisserant@0: void *visit(double_byte_character_string_c *symbol) {return print_token(symbol);} etisserant@0: void *visit(single_byte_character_string_c *symbol) {return print_token(symbol);} etisserant@0: etisserant@0: etisserant@0: /***************************/ etisserant@0: /* B 1.2.3 - Time Literals */ etisserant@0: /***************************/ etisserant@0: etisserant@0: /************************/ etisserant@0: /* B 1.2.3.1 - Duration */ etisserant@0: /************************/ etisserant@0: void *visit(neg_time_c *symbol) {s4o.print("-"); return NULL;} etisserant@0: etisserant@0: void *visit(duration_c *symbol) { etisserant@0: s4o.print("TIME#"); etisserant@0: if (symbol->neg != NULL) etisserant@0: symbol->neg->accept(*this); etisserant@0: symbol->interval->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: void *visit(fixed_point_c *symbol) {return print_token(symbol);} etisserant@0: msousa@547: /* SYM_REF5(interval_c, days, hours, minutes, seconds, milliseconds) */ msousa@547: void *visit(interval_c *symbol) { msousa@547: if (NULL != symbol->days) { msousa@547: symbol->days->accept(*this); msousa@547: s4o.print("d"); msousa@547: } msousa@547: msousa@547: if (NULL != symbol->hours) { etisserant@0: symbol->hours->accept(*this); msousa@547: s4o.print("h"); msousa@547: } msousa@547: msousa@547: if (NULL != symbol->minutes) { etisserant@0: symbol->minutes->accept(*this); msousa@547: s4o.print("m"); msousa@547: } msousa@547: msousa@547: if (NULL != symbol->seconds) { etisserant@0: symbol->seconds->accept(*this); msousa@547: s4o.print("s"); msousa@547: } msousa@547: msousa@547: if (NULL != symbol->milliseconds) { etisserant@0: symbol->milliseconds->accept(*this); msousa@547: s4o.print("ms"); msousa@547: } msousa@547: msousa@547: return NULL; msousa@547: } msousa@547: msousa@547: etisserant@0: etisserant@0: /************************************/ etisserant@0: /* B 1.2.3.2 - Time of day and Date */ etisserant@0: /************************************/ etisserant@0: etisserant@0: void *visit(time_of_day_c *symbol) { etisserant@0: s4o.print("TIME_OF_DAY#"); etisserant@0: symbol->daytime->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: void *visit(daytime_c *symbol) { etisserant@0: symbol->day_hour->accept(*this); etisserant@0: s4o.print(":"); etisserant@0: symbol->day_minute->accept(*this); etisserant@0: s4o.print(":"); etisserant@0: symbol->day_second->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: etisserant@0: void *visit(date_c *symbol) { etisserant@0: s4o.print("DATE#"); etisserant@0: symbol->date_literal->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: void *visit(date_literal_c *symbol) { etisserant@0: symbol->year->accept(*this); etisserant@0: s4o.print("-"); etisserant@0: symbol->month->accept(*this); etisserant@0: s4o.print("-"); etisserant@0: symbol->day->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: void *visit(date_and_time_c *symbol) { etisserant@0: s4o.print("DATE_AND_TIME#"); etisserant@0: symbol->date_literal->accept(*this); etisserant@0: s4o.print("-"); etisserant@0: symbol->daytime->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: etisserant@0: etisserant@0: /***********************************/ etisserant@0: /* B 1.3.1 - Elementary Data Types */ etisserant@0: /***********************************/ msousa@257: void *visit(time_type_name_c *symbol) {s4o.print("TIME"); return NULL;} msousa@257: void *visit(bool_type_name_c *symbol) {s4o.print("BOOL"); return NULL;} msousa@257: void *visit(sint_type_name_c *symbol) {s4o.print("SINT"); return NULL;} msousa@257: void *visit(int_type_name_c *symbol) {s4o.print("INT"); return NULL;} msousa@257: void *visit(dint_type_name_c *symbol) {s4o.print("DINT"); return NULL;} msousa@257: void *visit(lint_type_name_c *symbol) {s4o.print("LINT"); return NULL;} msousa@257: void *visit(usint_type_name_c *symbol) {s4o.print("USINT"); return NULL;} msousa@257: void *visit(uint_type_name_c *symbol) {s4o.print("UINT"); return NULL;} msousa@257: void *visit(udint_type_name_c *symbol) {s4o.print("UDINT"); return NULL;} msousa@257: void *visit(ulint_type_name_c *symbol) {s4o.print("ULINT"); return NULL;} msousa@257: void *visit(real_type_name_c *symbol) {s4o.print("REAL"); return NULL;} msousa@257: void *visit(lreal_type_name_c *symbol) {s4o.print("LREAL"); return NULL;} msousa@257: void *visit(date_type_name_c *symbol) {s4o.print("DATE"); return NULL;} msousa@257: void *visit(tod_type_name_c *symbol) {s4o.print("TOD"); return NULL;} msousa@257: void *visit(dt_type_name_c *symbol) {s4o.print("DT"); return NULL;} msousa@257: void *visit(byte_type_name_c *symbol) {s4o.print("BYTE"); return NULL;} msousa@257: void *visit(word_type_name_c *symbol) {s4o.print("WORD"); return NULL;} msousa@257: void *visit(lword_type_name_c *symbol) {s4o.print("LWORD"); return NULL;} msousa@257: void *visit(dword_type_name_c *symbol) {s4o.print("DWORD"); return NULL;} msousa@257: void *visit(string_type_name_c *symbol) {s4o.print("STRING"); return NULL;} msousa@257: void *visit(wstring_type_name_c *symbol) {s4o.print("WSTRING"); return NULL;} msousa@257: msousa@257: void *visit(safetime_type_name_c *symbol) {s4o.print("SAFETIME"); return NULL;} msousa@257: void *visit(safebool_type_name_c *symbol) {s4o.print("SAFEBOOL"); return NULL;} msousa@257: void *visit(safesint_type_name_c *symbol) {s4o.print("SAFESINT"); return NULL;} msousa@257: void *visit(safeint_type_name_c *symbol) {s4o.print("SAFEINT"); return NULL;} msousa@257: void *visit(safedint_type_name_c *symbol) {s4o.print("SAFEDINT"); return NULL;} msousa@257: void *visit(safelint_type_name_c *symbol) {s4o.print("SAFELINT"); return NULL;} msousa@257: void *visit(safeusint_type_name_c *symbol) {s4o.print("SAFEUSINT"); return NULL;} msousa@257: void *visit(safeuint_type_name_c *symbol) {s4o.print("SAFEUINT"); return NULL;} msousa@257: void *visit(safeudint_type_name_c *symbol) {s4o.print("SAFEUDINT"); return NULL;} msousa@257: void *visit(safeulint_type_name_c *symbol) {s4o.print("SAFEULINT"); return NULL;} msousa@257: void *visit(safereal_type_name_c *symbol) {s4o.print("SAFEREAL"); return NULL;} msousa@257: void *visit(safelreal_type_name_c *symbol) {s4o.print("SAFELREAL"); return NULL;} msousa@257: void *visit(safedate_type_name_c *symbol) {s4o.print("SAFEDATE"); return NULL;} msousa@257: void *visit(safetod_type_name_c *symbol) {s4o.print("SAFETOD"); return NULL;} msousa@257: void *visit(safedt_type_name_c *symbol) {s4o.print("SAFEDT"); return NULL;} msousa@257: void *visit(safebyte_type_name_c *symbol) {s4o.print("SAFEBYTE"); return NULL;} msousa@257: void *visit(safeword_type_name_c *symbol) {s4o.print("SAFEWORD"); return NULL;} msousa@257: void *visit(safelword_type_name_c *symbol) {s4o.print("SAFELWORD"); return NULL;} msousa@257: void *visit(safedword_type_name_c *symbol) {s4o.print("SAFEDWORD"); return NULL;} msousa@257: void *visit(safestring_type_name_c *symbol) {s4o.print("SAFESTRING"); return NULL;} msousa@257: void *visit(safewstring_type_name_c *symbol) {s4o.print("SAFEWSTRING"); return NULL;} msousa@257: mjsousa@921: /********************************/ mjsousa@921: /* B.1.3.2 - Generic data types */ mjsousa@921: /********************************/ mjsousa@921: void *visit(generic_type_any_c *symbol) {s4o.print("ANY"); return NULL;} etisserant@0: etisserant@0: /********************************/ etisserant@0: /* B 1.3.3 - Derived data types */ etisserant@0: /********************************/ etisserant@0: /* TYPE type_declaration_list END_TYPE */ etisserant@0: void *visit(data_type_declaration_c *symbol) { etisserant@0: s4o.print("TYPE\n"); etisserant@0: s4o.indent_right(); etisserant@0: symbol->type_declaration_list->accept(*this); etisserant@0: s4o.indent_left(); etisserant@0: s4o.print("END_TYPE\n\n\n"); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: etisserant@0: /* helper symbol for data_type_declaration */ etisserant@0: /*| type_declaration_list type_declaration ';' */ etisserant@0: void *visit(type_declaration_list_c *symbol) { etisserant@0: return print_list(symbol, s4o.indent_spaces, ";\n" + s4o.indent_spaces, ";\n"); etisserant@0: } etisserant@0: etisserant@0: etisserant@0: /* simple_type_name ':' simple_spec_init */ etisserant@0: void *visit(simple_type_declaration_c *symbol) { etisserant@0: symbol->simple_type_name->accept(*this); etisserant@0: s4o.print(" : "); etisserant@0: symbol->simple_spec_init->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* simple_specification ASSIGN constant */ etisserant@0: void *visit(simple_spec_init_c *symbol) { etisserant@0: symbol->simple_specification->accept(*this); etisserant@0: if (symbol->constant != NULL) { etisserant@0: s4o.print(" := "); etisserant@0: symbol->constant->accept(*this); etisserant@0: } etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* subrange_type_name ':' subrange_spec_init */ etisserant@0: void *visit(subrange_type_declaration_c *symbol) { etisserant@0: symbol->subrange_type_name->accept(*this); etisserant@0: s4o.print(" : "); etisserant@0: symbol->subrange_spec_init->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* subrange_specification ASSIGN signed_integer */ etisserant@0: void *visit(subrange_spec_init_c *symbol) { etisserant@0: symbol->subrange_specification->accept(*this); etisserant@0: if (symbol->signed_integer != NULL) { etisserant@0: s4o.print(" := "); etisserant@0: symbol->signed_integer->accept(*this); etisserant@0: } etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* integer_type_name '(' subrange')' */ etisserant@0: void *visit(subrange_specification_c *symbol) { etisserant@0: symbol->integer_type_name->accept(*this); lbessard@98: if (symbol->subrange != NULL) { lbessard@98: s4o.print("("); lbessard@98: symbol->subrange->accept(*this); lbessard@98: s4o.print(")"); lbessard@98: } etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* signed_integer DOTDOT signed_integer */ etisserant@0: void *visit(subrange_c *symbol) { etisserant@0: symbol->lower_limit->accept(*this); etisserant@0: s4o.print(" .. "); etisserant@0: symbol->upper_limit->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* enumerated_type_name ':' enumerated_spec_init */ etisserant@0: void *visit(enumerated_type_declaration_c *symbol) { etisserant@0: symbol->enumerated_type_name->accept(*this); etisserant@0: s4o.print(" : "); etisserant@0: symbol->enumerated_spec_init->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* enumerated_specification ASSIGN enumerated_value */ etisserant@0: void *visit(enumerated_spec_init_c *symbol) { etisserant@0: symbol->enumerated_specification->accept(*this); etisserant@0: if (symbol->enumerated_value != NULL) { etisserant@0: s4o.print(" := "); etisserant@0: symbol->enumerated_value->accept(*this); etisserant@0: } etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* helper symbol for enumerated_specification->enumerated_spec_init */ etisserant@0: /* enumerated_value_list ',' enumerated_value */ etisserant@0: void *visit(enumerated_value_list_c *symbol) {print_list(symbol, "(", ", ", ")"); return NULL;} etisserant@0: etisserant@0: /* enumerated_type_name '#' identifier */ etisserant@0: void *visit(enumerated_value_c *symbol) { lbessard@144: if (symbol->type != NULL) { lbessard@144: symbol->type->accept(*this); lbessard@144: s4o.print("#"); lbessard@144: } etisserant@0: symbol->value->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* identifier ':' array_spec_init */ etisserant@0: void *visit(array_type_declaration_c *symbol) { etisserant@0: symbol->identifier->accept(*this); etisserant@0: s4o.print(" : "); etisserant@0: symbol->array_spec_init->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* array_specification [ASSIGN array_initialization} */ etisserant@0: /* array_initialization may be NULL ! */ etisserant@0: void *visit(array_spec_init_c *symbol) { etisserant@0: symbol->array_specification->accept(*this); etisserant@0: if (symbol->array_initialization != NULL) { etisserant@0: s4o.print(" := "); etisserant@0: symbol->array_initialization->accept(*this); etisserant@0: } etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */ etisserant@0: void *visit(array_specification_c *symbol) { etisserant@0: s4o.print("ARRAY ["); etisserant@0: symbol->array_subrange_list->accept(*this); etisserant@0: s4o.print("] OF "); etisserant@0: symbol->non_generic_type_name->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* helper symbol for array_specification */ etisserant@0: /* array_subrange_list ',' subrange */ etisserant@0: void *visit(array_subrange_list_c *symbol) {print_list(symbol, "", ", "); return NULL;} etisserant@0: etisserant@0: /* helper symbol for array_initialization */ etisserant@0: /* array_initial_elements_list ',' array_initial_elements */ etisserant@0: void *visit(array_initial_elements_list_c *symbol) {print_list(symbol, "[", ", ", "]"); return NULL;} etisserant@0: etisserant@0: /* integer '(' [array_initial_element] ')' */ etisserant@0: /* array_initial_element may be NULL ! */ etisserant@0: void *visit(array_initial_elements_c *symbol) { etisserant@0: symbol->integer->accept(*this); etisserant@0: s4o.print("("); etisserant@0: if (symbol->array_initial_element != NULL) etisserant@0: symbol->array_initial_element->accept(*this); etisserant@0: s4o.print(")"); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* structure_type_name ':' structure_specification */ etisserant@0: void *visit(structure_type_declaration_c *symbol) { etisserant@0: symbol->structure_type_name->accept(*this); etisserant@0: s4o.print(" : "); etisserant@0: symbol->structure_specification->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* structure_type_name ASSIGN structure_initialization */ etisserant@0: /* structure_initialization may be NULL ! */ etisserant@0: void *visit(initialized_structure_c *symbol) { etisserant@0: symbol->structure_type_name->accept(*this); etisserant@0: if (symbol->structure_initialization != NULL) { etisserant@0: s4o.print(" := "); etisserant@0: symbol->structure_initialization->accept(*this); etisserant@0: } etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* helper symbol for structure_declaration */ etisserant@0: /* structure_declaration: STRUCT structure_element_declaration_list END_STRUCT */ etisserant@0: /* structure_element_declaration_list structure_element_declaration ';' */ etisserant@0: void *visit(structure_element_declaration_list_c *symbol) { etisserant@0: s4o.print("STRUCT\n"); etisserant@0: s4o.indent_right(); etisserant@0: print_list(symbol, s4o.indent_spaces, ";\n" + s4o.indent_spaces, ";\n" + s4o.indent_spaces); etisserant@0: s4o.print("END_STRUCT"); etisserant@0: s4o.indent_left(); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* structure_element_name ':' *_spec_init */ etisserant@0: void *visit(structure_element_declaration_c *symbol) { etisserant@0: symbol->structure_element_name->accept(*this); etisserant@0: s4o.print(" : "); etisserant@0: symbol->spec_init->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* helper symbol for structure_initialization */ etisserant@0: /* structure_initialization: '(' structure_element_initialization_list ')' */ etisserant@0: /* structure_element_initialization_list ',' structure_element_initialization */ etisserant@0: void *visit(structure_element_initialization_list_c *symbol) {print_list(symbol, "(", ", ", ")"); return NULL;} etisserant@0: etisserant@0: /* structure_element_name ASSIGN value */ etisserant@0: void *visit(structure_element_initialization_c *symbol) { etisserant@0: symbol->structure_element_name->accept(*this); etisserant@0: s4o.print(" := "); etisserant@0: symbol->value->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* string_type_name ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init */ etisserant@0: void *visit(string_type_declaration_c *symbol) { etisserant@0: symbol->string_type_name->accept(*this); etisserant@0: s4o.print(" : "); etisserant@0: symbol->elementary_string_type_name->accept(*this); etisserant@0: symbol->string_type_declaration_size->accept(*this); etisserant@0: if (symbol->string_type_declaration_init != NULL) etisserant@0: symbol->string_type_declaration_init->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: msousa@810: /* function_block_type_name ASSIGN structure_initialization */ msousa@810: /* structure_initialization -> may be NULL ! */ msousa@810: void *visit(fb_spec_init_c *symbol) { msousa@810: symbol->function_block_type_name->accept(*this); msousa@810: if (symbol->structure_initialization != NULL) { msousa@810: s4o.print(" := "); msousa@810: symbol->structure_initialization->accept(*this); msousa@810: } msousa@810: return NULL; msousa@810: } etisserant@0: etisserant@0: etisserant@0: mjsousa@876: /* ref_spec: REF_TO (non_generic_type_name | function_block_type_name) */ mjsousa@876: // SYM_REF1(ref_spec_c, type_name) mjsousa@876: void *visit(ref_spec_c *symbol) { mjsousa@876: s4o.print("REF_TO "); mjsousa@876: symbol->type_name->accept(*this); mjsousa@876: return NULL; mjsousa@876: } mjsousa@876: mjsousa@876: /* For the moment, we do not support initialising reference data types */ mjsousa@909: /* ref_spec_init: ref_spec [ ASSIGN ref_initialization ]; */ mjsousa@909: /* NOTE: ref_initialization may be NULL!! */ mjsousa@909: // SYM_REF2(ref_spec_init_c, ref_spec, ref_initialization) mjsousa@909: void *visit(ref_spec_init_c *symbol) { mjsousa@909: symbol->ref_spec->accept(*this); mjsousa@909: if (symbol->ref_initialization != NULL) { mjsousa@909: s4o.print(" := "); mjsousa@909: symbol->ref_initialization->accept(*this); mjsousa@909: } mjsousa@909: return NULL; mjsousa@909: } mjsousa@876: mjsousa@876: /* ref_type_decl: identifier ':' ref_spec_init */ mjsousa@876: // SYM_REF2(ref_type_decl_c, ref_type_name, ref_spec_init) mjsousa@876: void *visit(ref_type_decl_c *symbol) { mjsousa@876: symbol->ref_type_name->accept(*this); mjsousa@876: s4o.print(" : "); mjsousa@876: symbol->ref_spec_init->accept(*this); mjsousa@876: return NULL; mjsousa@876: } mjsousa@876: mjsousa@876: mjsousa@876: mjsousa@876: mjsousa@876: mjsousa@876: mjsousa@876: mjsousa@876: etisserant@0: /*********************/ etisserant@0: /* B 1.4 - Variables */ etisserant@0: /*********************/ etisserant@0: void *visit(symbolic_variable_c *symbol) { etisserant@0: symbol->var_name->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /********************************************/ etisserant@0: /* B.1.4.1 Directly Represented Variables */ etisserant@0: /********************************************/ etisserant@0: void *visit(direct_variable_c *symbol) {return print_token(symbol);} etisserant@0: etisserant@0: etisserant@0: /*************************************/ etisserant@0: /* B.1.4.2 Multi-element Variables */ etisserant@0: /*************************************/ etisserant@0: /* subscripted_variable '[' subscript_list ']' */ etisserant@0: void *visit(array_variable_c *symbol) { etisserant@0: symbol->subscripted_variable->accept(*this); etisserant@0: s4o.print("["); etisserant@0: symbol->subscript_list->accept(*this); etisserant@0: s4o.print("]"); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: etisserant@0: /* subscript_list ',' subscript */ etisserant@0: void *visit(subscript_list_c *symbol) {return print_list(symbol, "", ", ");} etisserant@0: etisserant@0: /* record_variable '.' field_selector */ etisserant@0: void *visit(structured_variable_c *symbol) { etisserant@0: symbol->record_variable->accept(*this); etisserant@0: s4o.print("."); etisserant@0: symbol->field_selector->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: etisserant@0: /******************************************/ etisserant@0: /* B 1.4.3 - Declaration & Initialisation */ etisserant@0: /******************************************/ etisserant@0: void *visit(constant_option_c *symbol) {s4o.print("CONSTANT"); return NULL;} etisserant@0: void *visit(retain_option_c *symbol) {s4o.print("RETAIN"); return NULL;} etisserant@0: void *visit(non_retain_option_c *symbol) {s4o.print("NON_RETAIN"); return NULL;} etisserant@0: etisserant@0: /* VAR_INPUT [RETAIN | NON_RETAIN] input_declaration_list END_VAR */ etisserant@0: /* option -> the RETAIN/NON_RETAIN/ directive... */ etisserant@0: void *visit(input_declarations_c *symbol) { ccb@202: if (typeid(*(symbol->method)) == typeid(explicit_definition_c)) { ccb@202: s4o.print(s4o.indent_spaces); s4o.print("VAR_INPUT "); ccb@202: if (symbol->option != NULL) ccb@202: symbol->option->accept(*this); ccb@202: s4o.print("\n"); ccb@202: s4o.indent_right(); ccb@202: symbol->input_declaration_list->accept(*this); ccb@202: s4o.indent_left(); ccb@202: s4o.print(s4o.indent_spaces); s4o.print("END_VAR\n"); ccb@202: } etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* helper symbol for input_declarations */ etisserant@0: /*| input_declaration_list input_declaration ';' */ etisserant@0: void *visit(input_declaration_list_c *symbol) { etisserant@0: return print_list(symbol, s4o.indent_spaces, ";\n" + s4o.indent_spaces, ";\n"); etisserant@0: } etisserant@0: etisserant@0: /* edge -> The F_EDGE or R_EDGE directive */ etisserant@0: void *visit(edge_declaration_c *symbol) { etisserant@0: symbol->var1_list->accept(*this); etisserant@0: s4o.print(" : BOOL "); etisserant@0: symbol->edge->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: ccb@202: /* dummy classes only used as flags! */ ccb@202: void *visit(explicit_definition_c *symbol) {return NULL;} ccb@202: void *visit(implicit_definition_c *symbol) {return NULL;} ccb@202: ccb@202: /* EN : BOOL := 1 */ lbessard@146: void *visit(en_param_declaration_c *symbol) { ccb@202: if (typeid(*(symbol->method)) == typeid(explicit_definition_c)) { ccb@202: symbol->name->accept(*this); ccb@202: s4o.print(" : "); msousa@805: symbol->type_decl->accept(*this); ccb@202: } ccb@202: return NULL; ccb@202: } ccb@202: ccb@202: /* ENO : BOOL */ ccb@202: void *visit(eno_param_declaration_c *symbol) { ccb@202: if (typeid(*(symbol->method)) == typeid(explicit_definition_c)) { ccb@202: symbol->name->accept(*this); ccb@202: s4o.print(" : "); ccb@202: symbol->type->accept(*this); ccb@202: } lbessard@146: return NULL; lbessard@146: } etisserant@0: etisserant@0: void *visit(raising_edge_option_c *symbol) { etisserant@0: s4o.print("R_EDGE"); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: void *visit(falling_edge_option_c *symbol) { etisserant@0: s4o.print("F_EDGE"); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: etisserant@0: /* var1_list is one of the following... etisserant@0: * simple_spec_init_c * etisserant@0: * subrange_spec_init_c * etisserant@0: * enumerated_spec_init_c * etisserant@0: */ etisserant@0: void *visit(var1_init_decl_c *symbol) { etisserant@0: symbol->var1_list->accept(*this); etisserant@0: s4o.print(" : "); etisserant@0: symbol->spec_init->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: etisserant@0: void *visit(var1_list_c *symbol) {return print_list(symbol, "", ", ");} etisserant@0: msousa@350: /* | [var1_list ','] variable_name '..' */ msousa@350: /* NOTE: This is an extension to the standard!!! */ msousa@350: /* In order to be able to handle extensible standard functions msousa@350: * (i.e. standard 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: * we have extended the acceptable syntax to allow var_name '..' msousa@350: * in an input variable declaration. msousa@350: * msousa@350: * This allows us to parse the declaration of standard msousa@350: * extensible functions and load their interface definition msousa@350: * into the abstract syntax tree just like we do to other msousa@350: * user defined functions. msousa@350: * This has the advantage that we can later do semantic msousa@350: * checking of calls to functions (be it a standard or user defined msousa@350: * function) in (almost) exactly the same way. msousa@350: * msousa@350: * Of course, we have a flag that disables this syntax when parsing user msousa@350: * written code, so we only allow this extra syntax while parsing the msousa@350: * 'header' file that declares all the standard IEC 61131-3 functions. msousa@350: */ msousa@350: void *visit(extensible_input_parameter_c *symbol) { msousa@350: symbol->var_name->accept(*this); msousa@350: s4o.print(" .. "); msousa@350: return NULL; msousa@350: } msousa@350: etisserant@0: etisserant@0: /* var1_list ':' array_spec_init */ etisserant@0: void *visit(array_var_init_decl_c *symbol) { etisserant@0: symbol->var1_list->accept(*this); etisserant@0: s4o.print(" : "); etisserant@0: symbol->array_spec_init->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: etisserant@0: /* var1_list ':' initialized_structure */ etisserant@0: void *visit(structured_var_init_decl_c *symbol) { etisserant@0: symbol->var1_list->accept(*this); etisserant@0: s4o.print(" : "); etisserant@0: symbol->initialized_structure->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* name_list ':' function_block_type_name ASSIGN structure_initialization */ etisserant@0: /* structure_initialization -> may be NULL ! */ etisserant@0: void *visit(fb_name_decl_c *symbol) { etisserant@0: symbol->fb_name_list->accept(*this); etisserant@0: s4o.print(" : "); msousa@810: symbol->fb_spec_init->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* name_list ',' fb_name */ etisserant@0: void *visit(fb_name_list_c *symbol) {return print_list(symbol, "", ", ");} etisserant@0: etisserant@0: /* VAR_OUTPUT [RETAIN | NON_RETAIN] var_init_decl_list END_VAR */ etisserant@0: /* option -> may be NULL ! */ etisserant@0: void *visit(output_declarations_c *symbol) { ccb@202: if (typeid(*(symbol->method)) == typeid(explicit_definition_c)) { ccb@202: s4o.print(s4o.indent_spaces); s4o.print("VAR_OUTPUT "); ccb@202: if (symbol->option != NULL) ccb@202: symbol->option->accept(*this); ccb@202: s4o.print("\n"); ccb@202: s4o.indent_right(); ccb@202: symbol->var_init_decl_list->accept(*this); ccb@202: s4o.indent_left(); ccb@202: s4o.print(s4o.indent_spaces); s4o.print("END_VAR\n"); ccb@202: } lbessard@146: return NULL; lbessard@146: } lbessard@146: etisserant@0: /* VAR_IN_OUT END_VAR */ etisserant@0: void *visit(input_output_declarations_c *symbol) { etisserant@0: s4o.print(s4o.indent_spaces); s4o.print("VAR_IN_OUT "); etisserant@0: s4o.print("\n"); etisserant@0: s4o.indent_right(); etisserant@0: symbol->var_declaration_list->accept(*this); etisserant@0: s4o.indent_left(); etisserant@0: s4o.print(s4o.indent_spaces); s4o.print("END_VAR\n"); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* helper symbol for input_output_declarations */ etisserant@0: /* var_declaration_list var_declaration ';' */ etisserant@0: void *visit(var_declaration_list_c *symbol) { etisserant@0: return print_list(symbol, s4o.indent_spaces, ";\n" + s4o.indent_spaces, ";\n"); etisserant@0: } etisserant@0: etisserant@0: /* var1_list ':' array_specification */ etisserant@0: void *visit(array_var_declaration_c *symbol) { etisserant@0: symbol->var1_list->accept(*this); etisserant@0: s4o.print(" : "); etisserant@0: symbol->array_specification->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* var1_list ':' structure_type_name */ etisserant@0: void *visit(structured_var_declaration_c *symbol) { etisserant@0: symbol->var1_list->accept(*this); etisserant@0: s4o.print(" : "); etisserant@0: symbol->structure_type_name->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* VAR [CONSTANT] var_init_decl_list END_VAR */ etisserant@0: /* option -> may be NULL ! */ etisserant@0: void *visit(var_declarations_c *symbol) { etisserant@0: s4o.print(s4o.indent_spaces); s4o.print("VAR "); etisserant@0: if (symbol->option != NULL) etisserant@0: symbol->option->accept(*this); etisserant@0: s4o.print("\n"); etisserant@0: s4o.indent_right(); etisserant@0: symbol->var_init_decl_list->accept(*this); etisserant@0: s4o.indent_left(); etisserant@0: s4o.print(s4o.indent_spaces); s4o.print("END_VAR\n"); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* VAR RETAIN var_init_decl_list END_VAR */ etisserant@0: void *visit(retentive_var_declarations_c *symbol) { etisserant@0: s4o.print(s4o.indent_spaces); s4o.print("VAR RETAIN "); etisserant@0: s4o.print("\n"); etisserant@0: s4o.indent_right(); etisserant@0: symbol->var_init_decl_list->accept(*this); etisserant@0: s4o.indent_left(); etisserant@0: s4o.print(s4o.indent_spaces); s4o.print("END_VAR\n"); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* VAR [CONSTANT|RETAIN|NON_RETAIN] located_var_decl_list END_VAR */ etisserant@0: /* option -> may be NULL ! */ etisserant@0: void *visit(located_var_declarations_c *symbol) { etisserant@0: s4o.print(s4o.indent_spaces); s4o.print("VAR "); etisserant@0: if (symbol->option != NULL) etisserant@0: symbol->option->accept(*this); etisserant@0: s4o.print("\n"); etisserant@0: s4o.indent_right(); etisserant@0: symbol->located_var_decl_list->accept(*this); etisserant@0: s4o.indent_left(); etisserant@0: s4o.print(s4o.indent_spaces); s4o.print("END_VAR\n"); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* helper symbol for located_var_declarations */ etisserant@0: /* located_var_decl_list located_var_decl ';' */ etisserant@0: void *visit(located_var_decl_list_c *symbol) { etisserant@0: return print_list(symbol, s4o.indent_spaces, ";\n" + s4o.indent_spaces, ";\n"); etisserant@0: } etisserant@0: etisserant@0: /* [variable_name] location ':' located_var_spec_init */ etisserant@0: /* variable_name -> may be NULL ! */ etisserant@0: void *visit(located_var_decl_c *symbol) { etisserant@0: if (symbol->variable_name != NULL) { etisserant@0: symbol->variable_name->accept(*this); etisserant@0: s4o.print(" "); etisserant@0: } etisserant@0: symbol->location->accept(*this); etisserant@0: s4o.print(" : "); etisserant@0: symbol->located_var_spec_init->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: etisserant@0: /*| VAR_EXTERNAL [CONSTANT] external_declaration_list END_VAR */ etisserant@0: /* option -> may be NULL ! */ etisserant@0: void *visit(external_var_declarations_c *symbol) { etisserant@0: s4o.print(s4o.indent_spaces); s4o.print("VAR_EXTERNAL "); etisserant@0: if (symbol->option != NULL) etisserant@0: symbol->option->accept(*this); etisserant@0: s4o.print("\n"); etisserant@0: s4o.indent_right(); etisserant@0: symbol->external_declaration_list->accept(*this); etisserant@0: s4o.indent_left(); etisserant@0: s4o.print(s4o.indent_spaces); s4o.print("END_VAR\n"); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* helper symbol for external_var_declarations */ etisserant@0: /*| external_declaration_list external_declaration';' */ etisserant@0: void *visit(external_declaration_list_c *symbol) { etisserant@0: return print_list(symbol, s4o.indent_spaces, ";\n" + s4o.indent_spaces, ";\n"); etisserant@0: } etisserant@0: etisserant@0: /* global_var_name ':' (simple_specification|subrange_specification|enumerated_specification|array_specification|prev_declared_structure_type_name|function_block_type_name) */ etisserant@0: void *visit(external_declaration_c *symbol) { etisserant@0: symbol->global_var_name->accept(*this); etisserant@0: s4o.print(" : "); etisserant@0: symbol->specification->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /*| VAR_GLOBAL [CONSTANT|RETAIN] global_var_decl_list END_VAR */ etisserant@0: /* option -> may be NULL ! */ etisserant@0: void *visit(global_var_declarations_c *symbol) { etisserant@0: s4o.print(s4o.indent_spaces); s4o.print("VAR_GLOBAL "); etisserant@0: if (symbol->option != NULL) etisserant@0: symbol->option->accept(*this); etisserant@0: s4o.print("\n"); etisserant@0: s4o.indent_right(); etisserant@0: symbol->global_var_decl_list->accept(*this); etisserant@0: s4o.indent_left(); etisserant@0: s4o.print(s4o.indent_spaces); s4o.print("END_VAR\n"); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* helper symbol for global_var_declarations */ etisserant@0: /*| global_var_decl_list global_var_decl ';' */ etisserant@0: void *visit(global_var_decl_list_c *symbol) { etisserant@0: return print_list(symbol, s4o.indent_spaces, ";\n" + s4o.indent_spaces, ";\n"); etisserant@0: } etisserant@0: etisserant@0: /*| global_var_spec ':' [located_var_spec_init|function_block_type_name] */ etisserant@0: /* type_specification ->may be NULL ! */ etisserant@0: void *visit(global_var_decl_c *symbol) { etisserant@0: symbol->global_var_spec->accept(*this); etisserant@0: s4o.print(" : "); etisserant@0: if (symbol->type_specification != NULL) etisserant@0: symbol->type_specification->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /*| global_var_name location */ etisserant@0: void *visit(global_var_spec_c *symbol) { etisserant@0: symbol->global_var_name->accept(*this); etisserant@0: s4o.print(" "); etisserant@0: symbol->location->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* AT direct_variable */ etisserant@0: void *visit(location_c *symbol) { etisserant@0: s4o.print("AT "); etisserant@0: symbol->direct_variable->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /*| global_var_list ',' global_var_name */ etisserant@0: void *visit(global_var_list_c *symbol) {return print_list(symbol, "", ", ");} etisserant@0: etisserant@0: /* var1_list ':' single_byte_string_spec */ etisserant@0: void *visit(single_byte_string_var_declaration_c *symbol) { etisserant@0: symbol->var1_list->accept(*this); etisserant@0: s4o.print(" : "); etisserant@0: symbol->single_byte_string_spec->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: msousa@350: /* single_byte_limited_len_string_spec [ASSIGN single_byte_character_string] */ etisserant@0: /* single_byte_character_string ->may be NULL ! */ etisserant@0: void *visit(single_byte_string_spec_c *symbol) { msousa@350: symbol->string_spec->accept(*this); etisserant@0: if (symbol->single_byte_character_string != NULL) { etisserant@0: s4o.print(" := "); etisserant@0: symbol->single_byte_character_string->accept(*this); etisserant@0: } etisserant@0: return NULL; etisserant@0: } etisserant@0: msousa@350: /* STRING ['[' integer ']'] */ msousa@350: /* integer ->may be NULL ! */ msousa@350: void *visit(single_byte_limited_len_string_spec_c *symbol) { msousa@350: symbol->string_type_name->accept(*this); msousa@350: if (symbol->character_string_len != NULL) { msousa@350: s4o.print(" ["); msousa@350: symbol->character_string_len->accept(*this); msousa@350: s4o.print("]"); msousa@350: } msousa@350: return NULL; msousa@350: } msousa@350: etisserant@0: /* var1_list ':' double_byte_string_spec */ etisserant@0: void *visit(double_byte_string_var_declaration_c *symbol) { etisserant@0: symbol->var1_list->accept(*this); etisserant@0: s4o.print(" : "); etisserant@0: symbol->double_byte_string_spec->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: msousa@350: /* double_byte_limited_len_string_spec [ASSIGN double_byte_character_string] */ etisserant@0: /* integer ->may be NULL ! */ etisserant@0: /* double_byte_character_string ->may be NULL ! */ etisserant@0: void *visit(double_byte_string_spec_c *symbol) { msousa@350: symbol->string_spec->accept(*this); etisserant@0: if (symbol->double_byte_character_string != NULL) { etisserant@0: s4o.print(" := "); etisserant@0: symbol->double_byte_character_string->accept(*this); etisserant@0: } etisserant@0: return NULL; etisserant@0: } etisserant@0: msousa@350: /* WSTRING ['[' integer ']'] */ msousa@350: /* integer ->may be NULL ! */ msousa@350: void *visit(double_byte_limited_len_string_spec_c *symbol) { msousa@350: symbol->string_type_name->accept(*this); msousa@350: if (symbol->character_string_len != NULL) { msousa@350: s4o.print(" ["); msousa@350: symbol->character_string_len->accept(*this); msousa@350: s4o.print("]"); msousa@350: } msousa@350: return NULL; msousa@350: } msousa@350: etisserant@0: /*| VAR [RETAIN|NON_RETAIN] incompl_located_var_decl_list END_VAR */ etisserant@0: /* option ->may be NULL ! */ etisserant@0: void *visit(incompl_located_var_declarations_c *symbol) { etisserant@0: s4o.print(s4o.indent_spaces); s4o.print("VAR "); etisserant@0: if (symbol->option != NULL) etisserant@0: symbol->option->accept(*this); etisserant@0: s4o.print("\n"); etisserant@0: s4o.indent_right(); etisserant@0: symbol->incompl_located_var_decl_list->accept(*this); etisserant@0: s4o.indent_left(); etisserant@0: s4o.print(s4o.indent_spaces); s4o.print("END_VAR\n"); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* helper symbol for incompl_located_var_declarations */ etisserant@0: /*| incompl_located_var_decl_list incompl_located_var_decl ';' */ etisserant@0: void *visit(incompl_located_var_decl_list_c *symbol) { etisserant@0: return print_list(symbol, s4o.indent_spaces, ";\n" + s4o.indent_spaces, ";\n"); etisserant@0: } etisserant@0: etisserant@0: /* variable_name incompl_location ':' var_spec */ etisserant@0: void *visit(incompl_located_var_decl_c *symbol) { etisserant@0: symbol->variable_name->accept(*this); etisserant@0: s4o.print(" "); etisserant@0: symbol->incompl_location->accept(*this); etisserant@0: s4o.print(" : "); etisserant@0: symbol->var_spec->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: etisserant@0: /* AT incompl_location_token */ etisserant@0: void *visit(incompl_location_c *symbol) { etisserant@0: s4o.print(" AT "); lbessard@10: return print_token(symbol); etisserant@0: } etisserant@0: etisserant@0: etisserant@0: /* intermediate helper symbol for: etisserant@0: * - non_retentive_var_decls etisserant@0: * - output_declarations etisserant@0: */ etisserant@0: /* | var_init_decl_list var_init_decl ';' */ etisserant@0: void *visit(var_init_decl_list_c *symbol) { etisserant@0: return print_list(symbol, s4o.indent_spaces, ";\n" + s4o.indent_spaces, ";\n"); etisserant@0: } etisserant@0: etisserant@0: etisserant@0: /***********************/ etisserant@0: /* B 1.5.1 - Functions */ etisserant@0: /***********************/ etisserant@0: void *visit(function_declaration_c *symbol) { etisserant@0: s4o.print("FUNCTION "); etisserant@0: symbol->derived_function_name->accept(*this); etisserant@0: s4o.print(" : "); etisserant@0: symbol->type_name->accept(*this); etisserant@0: s4o.print("\n"); etisserant@0: s4o.indent_right(); etisserant@0: symbol->var_declarations_list->accept(*this); etisserant@0: s4o.print("\n"); etisserant@0: symbol->function_body->accept(*this); etisserant@0: s4o.indent_left(); etisserant@0: s4o.print(s4o.indent_spaces + "END_FUNCTION\n\n\n"); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* intermediate helper symbol for function_declaration */ etisserant@0: void *visit(var_declarations_list_c *symbol) {return print_list(symbol);} etisserant@0: etisserant@0: void *visit(function_var_decls_c *symbol) { etisserant@1: //s4o.print(s4o.indent_spaces); etisserant@1: s4o.print("VAR "); etisserant@0: if (symbol->option != NULL) etisserant@0: symbol->option->accept(*this); etisserant@0: s4o.print("\n"); etisserant@0: s4o.indent_right(); etisserant@0: symbol->decl_list->accept(*this); etisserant@0: s4o.indent_left(); etisserant@0: s4o.print(s4o.indent_spaces); s4o.print("END_VAR\n"); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* intermediate helper symbol for function_var_decls */ etisserant@0: void *visit(var2_init_decl_list_c *symbol) { etisserant@0: print_list(symbol, s4o.indent_spaces, ";\n" + s4o.indent_spaces, ";\n"); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /*****************************/ etisserant@0: /* B 1.5.2 - Function Blocks */ etisserant@0: /*****************************/ etisserant@0: /* FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations function_block_body END_FUNCTION_BLOCK */ etisserant@0: void *visit(function_block_declaration_c *symbol) { etisserant@0: s4o.print("FUNCTION_BLOCK "); etisserant@0: symbol->fblock_name->accept(*this); etisserant@0: s4o.print("\n"); etisserant@0: s4o.indent_right(); etisserant@0: symbol->var_declarations->accept(*this); etisserant@0: s4o.print("\n"); etisserant@0: symbol->fblock_body->accept(*this); etisserant@0: s4o.indent_left(); etisserant@0: s4o.print(s4o.indent_spaces + "END_FUNCTION_BLOCK\n\n\n"); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* VAR_TEMP temp_var_decl_list END_VAR */ etisserant@0: void *visit(temp_var_decls_c *symbol) { etisserant@0: s4o.print("VAR_TEMP\n"); etisserant@0: s4o.indent_right(); etisserant@0: symbol->var_decl_list->accept(*this); etisserant@0: s4o.indent_left(); etisserant@0: s4o.print("END_VAR\n"); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* intermediate helper symbol for temp_var_decls */ etisserant@0: void *visit(temp_var_decls_list_c *symbol) {return print_list(symbol);} etisserant@0: etisserant@0: /* VAR NON_RETAIN var_init_decl_list END_VAR */ etisserant@0: void *visit(non_retentive_var_decls_c *symbol) { etisserant@0: s4o.print("VAR NON_RETAIN\n"); etisserant@0: s4o.indent_right(); etisserant@0: symbol->var_decl_list->accept(*this); etisserant@0: s4o.indent_left(); etisserant@0: s4o.print("END_VAR\n"); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: etisserant@0: /**********************/ etisserant@0: /* B 1.5.3 - Programs */ etisserant@0: /**********************/ etisserant@0: /* PROGRAM program_type_name program_var_declarations_list function_block_body END_PROGRAM */ etisserant@0: void *visit(program_declaration_c *symbol) { etisserant@0: s4o.print("PROGRAM "); etisserant@0: symbol->program_type_name->accept(*this); etisserant@0: s4o.print("\n"); etisserant@0: s4o.indent_right(); etisserant@0: symbol->var_declarations->accept(*this); etisserant@0: s4o.print("\n"); etisserant@0: symbol->function_block_body->accept(*this); etisserant@0: s4o.indent_left(); etisserant@1: s4o.print("END_PROGRAM\n\n\n"); etisserant@1: return NULL; etisserant@1: } etisserant@1: etisserant@1: /***********************************/ etisserant@1: /* B 1.6 Sequential Function Chart */ etisserant@1: /***********************************/ mario@8: mario@7: /* sequential_function_chart {sfc_network} */ etisserant@1: void *visit(sequential_function_chart_c *symbol) { lbessard@10: print_list(symbol, "", "\n", ""); etisserant@1: return NULL; etisserant@1: } etisserant@1: mario@7: /* sfc_network {step | transition | action} */ etisserant@1: void *visit(sfc_network_c *symbol) { lbessard@10: print_list(symbol, "", "\n", ""); etisserant@1: return NULL; etisserant@1: } etisserant@1: mario@7: /* INITIAL_STEP step_name ':' [action_association_list] END_STEP */ etisserant@1: void *visit(initial_step_c *symbol) { etisserant@1: s4o.print(s4o.indent_spaces); etisserant@1: s4o.print("INITIAL_STEP "); etisserant@1: symbol->step_name->accept(*this); lbessard@10: s4o.print(":\n"); etisserant@1: s4o.indent_right(); etisserant@1: symbol->action_association_list->accept(*this); etisserant@1: s4o.print("\n"); etisserant@1: s4o.indent_left(); etisserant@1: s4o.print(s4o.indent_spaces); lbessard@10: s4o.print("END_STEP\n"); etisserant@1: return NULL; etisserant@1: } etisserant@1: mario@7: /* STEP step_name ':' [action_association_list] END_STEP */ etisserant@1: void *visit(step_c *symbol) { etisserant@1: s4o.print(s4o.indent_spaces); etisserant@1: s4o.print("STEP "); etisserant@1: symbol->step_name->accept(*this); lbessard@10: s4o.print(":\n"); etisserant@1: s4o.indent_right(); etisserant@1: symbol->action_association_list->accept(*this); etisserant@1: s4o.print("\n"); etisserant@1: s4o.indent_left(); etisserant@1: s4o.print(s4o.indent_spaces); lbessard@10: s4o.print("END_STEP\n"); etisserant@1: return NULL; etisserant@1: } etisserant@1: mario@7: /* action_association_list {action_association} */ etisserant@1: void *visit(action_association_list_c *symbol) { etisserant@1: print_list(symbol, "", "\n", ""); etisserant@1: return NULL; etisserant@1: } etisserant@1: mario@7: /* action_name '(' [action_qualifier] [indicator_name_list] ')' */ etisserant@1: void *visit(action_association_c *symbol) { lbessard@10: s4o.print(s4o.indent_spaces); lbessard@10: symbol->action_name->accept(*this); lbessard@10: s4o.print("("); etisserant@1: if(symbol->action_qualifier != NULL){ etisserant@1: symbol->action_qualifier->accept(*this); etisserant@1: } mario@7: if(symbol->indicator_name_list != NULL){ lbessard@10: symbol->indicator_name_list->accept(*this); lbessard@10: } lbessard@10: s4o.print(");"); etisserant@1: return NULL; etisserant@1: } etisserant@1: mario@7: /* indicator_name_list ',' indicator_name */ etisserant@1: void *visit(indicator_name_list_c *symbol) { lbessard@10: print_list(symbol, ", ", ", ", ""); mario@7: return NULL; mario@7: } mario@7: mario@7: /* action_qualifier [',' action_time] */ etisserant@1: void *visit(action_qualifier_c *symbol) { mario@7: symbol->action_qualifier->accept(*this); mario@7: if(symbol->action_time != NULL){ mario@7: s4o.print(", "); mario@7: symbol->action_time->accept(*this); mario@7: } mario@7: return NULL; mario@7: } mario@7: mario@7: /* N | R | S | P */ etisserant@1: void *visit(qualifier_c *symbol) { lbessard@10: print_token(symbol); mario@8: return NULL; etisserant@1: } etisserant@1: mario@7: /* L | D | SD | DS | SL */ etisserant@1: void *visit(timed_qualifier_c *symbol) { lbessard@10: print_token(symbol); mario@8: return NULL; mario@8: } mario@8: mario@71: /* TRANSITION [transition_name] ['(''PRIORITY'':='integer')'] mario@71: * FROMstepsTO steps lbessard@17: * ':' simple_instr_list | ':=' expression mario@8: * END_TRANSITION mario@8: */ etisserant@1: void *visit(transition_c *symbol) { etisserant@1: s4o.print(s4o.indent_spaces); etisserant@1: s4o.print("TRANSITION "); etisserant@1: if (symbol->transition_name != NULL){ etisserant@1: symbol->transition_name->accept(*this); etisserant@1: s4o.print(" "); etisserant@1: } etisserant@1: if (symbol->integer != NULL){ etisserant@1: s4o.print("(PRIORITY := "); etisserant@1: symbol->integer->accept(*this); etisserant@1: s4o.print(") "); etisserant@1: } etisserant@1: s4o.print("FROM "); etisserant@1: symbol->from_steps->accept(*this); lbessard@10: s4o.print(" TO "); etisserant@1: symbol->to_steps->accept(*this); etisserant@1: s4o.indent_right(); lbessard@87: symbol->transition_condition->accept(*this); lbessard@87: s4o.indent_left(); lbessard@87: s4o.print(s4o.indent_spaces); lbessard@87: s4o.print("END_TRANSITION\n"); lbessard@87: return NULL; lbessard@87: } lbessard@87: lbessard@87: void *visit(transition_condition_c *symbol) { lbessard@3: if (symbol->transition_condition_il != NULL) { lbessard@87: s4o.print(":\n"); lbessard@17: symbol->transition_condition_il->accept(*this); lbessard@3: } lbessard@3: if (symbol->transition_condition_st != NULL) { lbessard@87: s4o.print("\n"); lbessard@17: s4o.print(s4o.indent_spaces); lbessard@17: s4o.print(":= "); lbessard@17: symbol->transition_condition_st->accept(*this); lbessard@17: s4o.print(";\n"); lbessard@3: } etisserant@1: return NULL; etisserant@1: } etisserant@1: mario@8: /* step_name | step_name_list */ etisserant@1: void *visit(steps_c *symbol) { etisserant@1: if(symbol->step_name != NULL){ etisserant@1: symbol->step_name->accept(*this); etisserant@1: } etisserant@1: if(symbol->step_name_list != NULL){ etisserant@1: symbol->step_name_list->accept(*this); etisserant@1: } etisserant@1: return NULL; etisserant@1: } etisserant@1: mario@8: /* '(' step_name ',' step_name {',' step_name} ')' */ etisserant@1: void *visit(step_name_list_c *symbol) { lbessard@16: print_list(symbol, "(", ", ", ")"); etisserant@1: return NULL; etisserant@1: } etisserant@1: mario@8: /* ACTION action_name ':' function_block_body END_ACTION */ etisserant@1: void *visit(action_c *symbol) { mario@8: s4o.print(s4o.indent_spaces); mario@8: s4o.print("ACTION "); mario@8: symbol->action_name->accept(*this); lbessard@10: s4o.print(":\n"); lbessard@10: s4o.indent_right(); lbessard@10: symbol->function_block_body->accept(*this); lbessard@10: s4o.indent_left(); mario@8: s4o.print(s4o.indent_spaces); lbessard@10: s4o.print("END_ACTION\n"); mario@8: return NULL; mario@8: } mario@8: mario@8: mario@8: etisserant@0: /********************************/ etisserant@0: /* B 1.7 Configuration elements */ etisserant@0: /********************************/ etisserant@0: /* etisserant@0: CONFIGURATION configuration_name etisserant@0: optional_global_var_declarations etisserant@0: (resource_declaration_list | single_resource_declaration) etisserant@0: optional_access_declarations etisserant@0: optional_instance_specific_initializations etisserant@0: END_CONFIGURATION etisserant@0: */ etisserant@0: void *visit(configuration_declaration_c *symbol) { etisserant@0: s4o.print("CONFIGURATION "); etisserant@0: symbol->configuration_name->accept(*this); etisserant@0: s4o.print("\n"); etisserant@0: s4o.indent_right(); etisserant@0: if (symbol->global_var_declarations != NULL) etisserant@0: symbol->global_var_declarations->accept(*this); etisserant@0: symbol->resource_declarations->accept(*this); etisserant@0: if (symbol->access_declarations != NULL) etisserant@0: symbol->access_declarations->accept(*this); etisserant@0: if (symbol->instance_specific_initializations != NULL) etisserant@0: symbol->instance_specific_initializations->accept(*this); etisserant@0: s4o.indent_left(); etisserant@0: s4o.print(s4o.indent_spaces + "END_CONFIGURATION\n\n\n"); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: mjsousa@862: /* intermediate helper symbol for configuration_declaration */ mjsousa@862: /* { global_var_declarations_list } */ mjsousa@862: void *visit(global_var_declarations_list_c *symbol) {return print_list(symbol);} mjsousa@862: etisserant@0: /* helper symbol for configuration_declaration */ etisserant@0: /*| resource_declaration_list resource_declaration */ etisserant@0: void *visit(resource_declaration_list_c *symbol) {return print_list(symbol);} etisserant@0: etisserant@0: etisserant@0: /* etisserant@0: RESOURCE resource_name ON resource_type_name etisserant@0: optional_global_var_declarations etisserant@0: single_resource_declaration etisserant@0: END_RESOURCE etisserant@0: */ etisserant@0: void *visit(resource_declaration_c *symbol) { etisserant@0: s4o.print(s4o.indent_spaces + "RESOURCE "); etisserant@0: symbol->resource_name->accept(*this); etisserant@0: s4o.print(" ON "); etisserant@0: symbol->resource_type_name->accept(*this); etisserant@0: s4o.print("\n"); etisserant@0: s4o.indent_right(); etisserant@0: if (symbol->global_var_declarations != NULL) etisserant@0: symbol->global_var_declarations->accept(*this); etisserant@0: symbol->resource_declaration->accept(*this); etisserant@0: s4o.indent_left(); etisserant@0: s4o.print(s4o.indent_spaces + "END_RESOURCE\n"); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: etisserant@0: /* task_configuration_list program_configuration_list */ etisserant@0: void *visit(single_resource_declaration_c *symbol) { etisserant@0: symbol->task_configuration_list->accept(*this); etisserant@0: symbol->program_configuration_list->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* helper symbol for single_resource_declaration */ etisserant@0: /*| task_configuration_list task_configuration ';'*/ etisserant@0: void *visit(task_configuration_list_c *symbol) { etisserant@0: return print_list(symbol, s4o.indent_spaces, ";\n" + s4o.indent_spaces, ";\n"); etisserant@0: } etisserant@0: etisserant@0: etisserant@0: /* helper symbol for single_resource_declaration */ etisserant@0: /*| program_configuration_list program_configuration ';'*/ etisserant@0: void *visit(program_configuration_list_c *symbol) { etisserant@0: return print_list(symbol, s4o.indent_spaces, ";\n" + s4o.indent_spaces, ";\n"); etisserant@0: } etisserant@0: etisserant@0: etisserant@0: /* helper symbol for etisserant@0: * - access_path etisserant@0: * - instance_specific_init etisserant@0: */ etisserant@0: /* | any_fb_name_list any_identifier '.'*/ etisserant@0: void *visit(any_fb_name_list_c *symbol) {return print_list(symbol, ".", ".");} etisserant@0: etisserant@0: etisserant@0: /* [resource_name '.'] global_var_name ['.' structure_element_name] */ etisserant@0: void *visit(global_var_reference_c *symbol) { etisserant@0: if (symbol->resource_name != NULL) { etisserant@0: symbol->resource_name->accept(*this); etisserant@0: s4o.print("."); etisserant@0: } etisserant@0: symbol->global_var_name->accept(*this); etisserant@0: if (symbol->structure_element_name != NULL) { etisserant@0: s4o.print("."); etisserant@0: symbol->structure_element_name->accept(*this); etisserant@0: } etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* program_name '.' symbolic_variable */ etisserant@0: void *visit(program_output_reference_c *symbol) { etisserant@0: symbol->program_name->accept(*this); etisserant@0: s4o.print("."); etisserant@0: symbol->symbolic_variable->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* TASK task_name task_initialization */ etisserant@0: void *visit(task_configuration_c *symbol) { etisserant@0: s4o.print("TASK "); etisserant@0: symbol->task_name->accept(*this); etisserant@0: s4o.print(" "); etisserant@0: symbol->task_initialization->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* '(' [SINGLE ASSIGN data_source ','] [INTERVAL ASSIGN data_source ','] PRIORITY ASSIGN integer ')' */ etisserant@0: void *visit(task_initialization_c *symbol) { etisserant@0: s4o.print("("); etisserant@0: if (symbol->single_data_source != NULL) { etisserant@0: s4o.print("SINGLE := "); etisserant@0: symbol->single_data_source->accept(*this); etisserant@0: s4o.print(", "); etisserant@0: } etisserant@0: if (symbol->interval_data_source != NULL) { etisserant@0: s4o.print("INTERVAL := "); etisserant@0: symbol->interval_data_source->accept(*this); etisserant@0: s4o.print(", "); etisserant@0: } etisserant@0: s4o.print("PRIORITY := "); etisserant@0: symbol->priority_data_source->accept(*this); etisserant@0: s4o.print(")"); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* PROGRAM [RETAIN | NON_RETAIN] program_name [WITH task_name] ':' program_type_name ['(' prog_conf_elements ')'] */ etisserant@0: void *visit(program_configuration_c *symbol) { etisserant@0: s4o.print("PROGRAM "); etisserant@0: if (symbol->retain_option != NULL) etisserant@0: symbol->retain_option->accept(*this); etisserant@0: symbol->program_name->accept(*this); etisserant@0: if (symbol->task_name != NULL) { etisserant@0: s4o.print(" WITH "); etisserant@0: symbol->task_name->accept(*this); etisserant@0: } etisserant@0: s4o.print(" : "); etisserant@0: symbol->program_type_name->accept(*this); etisserant@0: if (symbol->prog_conf_elements != NULL) { etisserant@0: s4o.print("("); etisserant@0: symbol->prog_conf_elements->accept(*this); etisserant@0: s4o.print(")"); etisserant@0: } etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: etisserant@0: /* prog_conf_elements ',' prog_conf_element */ etisserant@0: void *visit(prog_conf_elements_c *symbol) {return print_list(symbol, "", ", ");} etisserant@0: etisserant@0: /* fb_name WITH task_name */ etisserant@0: void *visit(fb_task_c *symbol) { etisserant@0: symbol->fb_name->accept(*this); etisserant@0: s4o.print(" WITH "); etisserant@0: symbol->task_name->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* any_symbolic_variable ASSIGN prog_data_source */ etisserant@0: void *visit(prog_cnxn_assign_c *symbol) { etisserant@0: symbol->symbolic_variable->accept(*this); etisserant@0: s4o.print(" := "); etisserant@0: symbol->prog_data_source->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* any_symbolic_variable SENDTO data_sink */ etisserant@0: void *visit(prog_cnxn_sendto_c *symbol) { etisserant@0: symbol->symbolic_variable->accept(*this); etisserant@0: s4o.print(" => "); lbessard@28: symbol->data_sink->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* VAR_CONFIG instance_specific_init_list END_VAR */ etisserant@0: void *visit(instance_specific_initializations_c *symbol) { etisserant@0: s4o.print(s4o.indent_spaces + "VAR_CONFIG\n"); etisserant@0: s4o.indent_right(); etisserant@0: symbol->instance_specific_init_list->accept(*this); etisserant@0: s4o.indent_left(); etisserant@0: s4o.print(s4o.indent_spaces + "END_VAR\n"); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* helper symbol for instance_specific_initializations */ etisserant@0: /*| instance_specific_init_list instance_specific_init ';'*/ etisserant@0: void *visit(instance_specific_init_list_c *symbol) { etisserant@0: return print_list(symbol, s4o.indent_spaces, ";\n" + s4o.indent_spaces, ";\n"); etisserant@0: } etisserant@0: etisserant@0: /* resource_name '.' program_name '.' optional_fb_name_list '.' etisserant@0: ((variable_name [location] ':' located_var_spec_init) | (fb_name ':' fb_initialization)) etisserant@0: */ etisserant@0: void *visit(instance_specific_init_c *symbol) { etisserant@0: symbol->resource_name->accept(*this); etisserant@0: s4o.print("."); etisserant@0: symbol->program_name->accept(*this); etisserant@0: symbol->any_fb_name_list->accept(*this); etisserant@0: if (symbol->variable_name != NULL) { etisserant@0: s4o.print("."); etisserant@0: symbol->variable_name->accept(*this); etisserant@0: } etisserant@0: if (symbol->location != NULL) { etisserant@0: s4o.print(" "); etisserant@0: symbol->location->accept(*this); etisserant@0: } etisserant@0: s4o.print(" : "); etisserant@0: symbol->initialization->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* helper symbol for instance_specific_init */ etisserant@0: /* function_block_type_name ':=' structure_initialization */ etisserant@0: void *visit(fb_initialization_c *symbol) { etisserant@0: symbol->function_block_type_name->accept(*this); etisserant@0: s4o.print(" := "); etisserant@0: symbol->structure_initialization->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: etisserant@0: /***********************************/ etisserant@0: /* B 2.1 Instructions and Operands */ etisserant@0: /***********************************/ etisserant@0: /*| instruction_list il_instruction */ etisserant@0: void *visit(instruction_list_c *symbol) { etisserant@0: return print_list(symbol, s4o.indent_spaces, "\n" + s4o.indent_spaces, "\n"); etisserant@0: } etisserant@0: etisserant@0: /* | label ':' [il_incomplete_instruction] eol_list */ etisserant@0: void *visit(il_instruction_c *symbol) { etisserant@0: if (symbol->label != NULL) { etisserant@0: symbol->label->accept(*this); etisserant@0: s4o.print(": "); etisserant@0: } msousa@311: if (symbol->il_instruction != NULL) { msousa@311: symbol->il_instruction->accept(*this); msousa@311: } etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: etisserant@0: /* | il_simple_operator [il_operand] */ etisserant@0: void *visit(il_simple_operation_c *symbol) { etisserant@0: symbol->il_simple_operator->accept(*this); etisserant@0: if (symbol->il_operand != NULL) etisserant@0: symbol->il_operand->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* | function_name [il_operand_list] */ etisserant@0: void *visit(il_function_call_c *symbol) { etisserant@0: symbol->function_name->accept(*this); etisserant@0: s4o.print(" "); etisserant@0: if (symbol->il_operand_list != NULL) etisserant@0: symbol->il_operand_list->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: etisserant@0: /* | il_expr_operator '(' [il_operand] eol_list [simple_instr_list] ')' */ etisserant@0: void *visit(il_expression_c *symbol) { msousa@690: /* Since stage2 will insert an artificial (and equivalent) LD to the simple_instr_list when an 'il_operand' exists, we know msousa@690: * that if (symbol->il_operand != NULL), then the first IL instruction in the simple_instr_list will be the equivalent and artificial msousa@690: * 'LD ' IL instruction. msousa@690: * Since we do not want the extra LD instruction, we simply remove it! msousa@690: */ msousa@690: if (symbol->il_operand != NULL) msousa@690: ((list_c *)symbol->simple_instr_list)->remove_element(0); msousa@690: etisserant@0: symbol->il_expr_operator->accept(*this); etisserant@0: s4o.print("("); etisserant@0: if (symbol->il_operand != NULL) etisserant@0: symbol->il_operand->accept(*this); etisserant@0: if (symbol->simple_instr_list != NULL) { etisserant@0: s4o.print("\n"); etisserant@0: s4o.indent_right(); etisserant@0: symbol->simple_instr_list->accept(*this); lbessard@10: s4o.print(s4o.indent_spaces); etisserant@0: s4o.indent_left(); etisserant@0: } etisserant@0: s4o.print(")"); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* il_jump_operator label */ etisserant@0: void *visit(il_jump_operation_c *symbol) { etisserant@0: symbol->il_jump_operator->accept(*this); etisserant@0: symbol->label->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* il_call_operator prev_declared_fb_name etisserant@0: * | il_call_operator prev_declared_fb_name '(' ')' etisserant@0: * | il_call_operator prev_declared_fb_name '(' eol_list ')' etisserant@0: * | il_call_operator prev_declared_fb_name '(' il_operand_list ')' etisserant@0: * | il_call_operator prev_declared_fb_name '(' eol_list il_param_list ')' etisserant@0: */ etisserant@0: void *visit(il_fb_call_c *symbol) { etisserant@0: symbol->il_call_operator->accept(*this); etisserant@0: symbol->fb_name->accept(*this); etisserant@0: s4o.print("("); etisserant@0: if (symbol->il_operand_list != NULL) etisserant@0: symbol->il_operand_list->accept(*this); etisserant@0: if (symbol->il_param_list != NULL) { etisserant@0: s4o.print("\n"); etisserant@0: s4o.indent_right(); etisserant@0: symbol->il_param_list->accept(*this); etisserant@0: s4o.indent_left(); etisserant@0: } etisserant@0: s4o.print(")"); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: etisserant@0: /* | function_name '(' eol_list [il_param_list] ')' */ etisserant@0: void *visit(il_formal_funct_call_c *symbol) { etisserant@0: symbol->function_name->accept(*this); etisserant@0: s4o.print("("); mario@71: s4o.print("\n"); etisserant@0: if (symbol->il_param_list != NULL) { etisserant@0: s4o.indent_right(); etisserant@0: symbol->il_param_list->accept(*this); etisserant@0: s4o.print(")"); mario@71: s4o.indent_left(); etisserant@0: } etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: etisserant@0: /* | il_operand_list ',' il_operand */ mario@71: void *visit(il_operand_list_c *symbol) { mario@71: return print_list(symbol, "", ", "); mario@71: } etisserant@0: etisserant@0: /* | simple_instr_list il_simple_instruction */ etisserant@0: void *visit(simple_instr_list_c *symbol) { lbessard@10: return print_list(symbol, s4o.indent_spaces, "\n" + s4o.indent_spaces, "\n"); etisserant@0: } etisserant@0: msousa@453: msousa@453: /* il_simple_instruction: msousa@453: * il_simple_operation eol_list msousa@453: * | il_expression eol_list msousa@453: * | il_formal_funct_call eol_list msousa@453: */ msousa@453: void *visit(il_simple_instruction_c *symbol) { msousa@453: return symbol->il_simple_instruction->accept(*this); msousa@453: } msousa@453: msousa@453: etisserant@0: /* | il_initial_param_list il_param_instruction */ mario@71: void *visit(il_param_list_c *symbol) { mario@71: // return print_list(symbol); mario@71: return print_list(symbol, s4o.indent_spaces, ",\n" + s4o.indent_spaces, "\n" + s4o.indent_spaces); mario@71: } etisserant@0: etisserant@0: /* il_assign_operator il_operand etisserant@0: * | il_assign_operator '(' eol_list simple_instr_list ')' etisserant@0: */ etisserant@0: void *visit(il_param_assignment_c *symbol) { etisserant@0: symbol->il_assign_operator->accept(*this); mario@71: s4o.print(" := "); etisserant@0: if (symbol->il_operand != NULL) etisserant@0: symbol->il_operand->accept(*this); etisserant@0: if (symbol->simple_instr_list != NULL) { etisserant@0: s4o.print("(\n"); etisserant@0: s4o.indent_right(); etisserant@0: symbol->simple_instr_list->accept(*this); lbessard@10: s4o.print(s4o.indent_spaces); mario@71: s4o.print(")"); etisserant@0: s4o.indent_left(); etisserant@0: } etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* il_assign_out_operator variable */ etisserant@0: void *visit(il_param_out_assignment_c *symbol) { etisserant@0: symbol->il_assign_out_operator->accept(*this); mario@71: s4o.print(" => "); etisserant@0: symbol->variable->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: etisserant@0: /*******************/ etisserant@0: /* B 2.2 Operators */ etisserant@0: /*******************/ etisserant@0: void *visit(LD_operator_c *symbol) {s4o.print("LD "); return NULL;} etisserant@0: void *visit(LDN_operator_c *symbol) {s4o.print("LDN "); return NULL;} etisserant@0: void *visit(ST_operator_c *symbol) {s4o.print("ST "); return NULL;} etisserant@0: void *visit(STN_operator_c *symbol) {s4o.print("STN "); return NULL;} etisserant@0: void *visit(NOT_operator_c *symbol) {s4o.print("NOT "); return NULL;} etisserant@0: void *visit(S_operator_c *symbol) {s4o.print("S "); return NULL;} etisserant@0: void *visit(R_operator_c *symbol) {s4o.print("R "); return NULL;} etisserant@0: void *visit(S1_operator_c *symbol) {s4o.print("S1 "); return NULL;} etisserant@0: void *visit(R1_operator_c *symbol) {s4o.print("R1 "); return NULL;} etisserant@0: void *visit(CLK_operator_c *symbol) {s4o.print("CLK "); return NULL;} etisserant@0: void *visit(CU_operator_c *symbol) {s4o.print("CU "); return NULL;} etisserant@0: void *visit(CD_operator_c *symbol) {s4o.print("CD "); return NULL;} etisserant@0: void *visit(PV_operator_c *symbol) {s4o.print("PV "); return NULL;} etisserant@0: void *visit(IN_operator_c *symbol) {s4o.print("IN "); return NULL;} etisserant@0: void *visit(PT_operator_c *symbol) {s4o.print("PT "); return NULL;} etisserant@0: void *visit(AND_operator_c *symbol) {s4o.print("AND "); return NULL;} etisserant@0: void *visit(OR_operator_c *symbol) {s4o.print("OR "); return NULL;} etisserant@0: void *visit(XOR_operator_c *symbol) {s4o.print("XOR "); return NULL;} etisserant@0: void *visit(ANDN_operator_c *symbol) {s4o.print("ANDN "); return NULL;} etisserant@0: void *visit(ORN_operator_c *symbol) {s4o.print("ORN "); return NULL;} etisserant@0: void *visit(XORN_operator_c *symbol) {s4o.print("XORN "); return NULL;} etisserant@0: void *visit(ADD_operator_c *symbol) {s4o.print("ADD "); return NULL;} etisserant@0: void *visit(SUB_operator_c *symbol) {s4o.print("SUB "); return NULL;} etisserant@0: void *visit(MUL_operator_c *symbol) {s4o.print("MUL "); return NULL;} etisserant@0: void *visit(DIV_operator_c *symbol) {s4o.print("DIV "); return NULL;} etisserant@0: void *visit(MOD_operator_c *symbol) {s4o.print("MOD "); return NULL;} etisserant@0: void *visit(GT_operator_c *symbol) {s4o.print("GT "); return NULL;} etisserant@0: void *visit(GE_operator_c *symbol) {s4o.print("GE "); return NULL;} etisserant@0: void *visit(EQ_operator_c *symbol) {s4o.print("EQ "); return NULL;} etisserant@0: void *visit(LT_operator_c *symbol) {s4o.print("LT "); return NULL;} etisserant@0: void *visit(LE_operator_c *symbol) {s4o.print("LE "); return NULL;} etisserant@0: void *visit(NE_operator_c *symbol) {s4o.print("NE "); return NULL;} etisserant@0: void *visit(CAL_operator_c *symbol) {s4o.print("CAL "); return NULL;} etisserant@0: void *visit(CALC_operator_c *symbol) {s4o.print("CALC "); return NULL;} etisserant@0: void *visit(CALCN_operator_c *symbol) {s4o.print("CALCN "); return NULL;} etisserant@0: void *visit(RET_operator_c *symbol) {s4o.print("RET "); return NULL;} etisserant@0: void *visit(RETC_operator_c *symbol) {s4o.print("RETC "); return NULL;} etisserant@0: void *visit(RETCN_operator_c *symbol) {s4o.print("RETCN "); return NULL;} etisserant@0: void *visit(JMP_operator_c *symbol) {s4o.print("JMP "); return NULL;} etisserant@0: void *visit(JMPC_operator_c *symbol) {s4o.print("JMPC "); return NULL;} etisserant@0: void *visit(JMPCN_operator_c *symbol) {s4o.print("JMPCN "); return NULL;} etisserant@0: lbessard@143: /*| any_identifier ASSIGN */ lbessard@143: void *visit(il_assign_operator_c *symbol) { lbessard@143: symbol->variable_name->accept(*this); lbessard@143: s4o.print(" := "); lbessard@143: return NULL; lbessard@143: } lbessard@143: etisserant@0: /*| [NOT] any_identifier SENDTO */ etisserant@0: void *visit(il_assign_out_operator_c *symbol) { etisserant@0: if (symbol->option != NULL) etisserant@0: symbol->option->accept(*this); etisserant@0: symbol->variable_name->accept(*this); etisserant@0: s4o.print(" => "); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: etisserant@0: /***********************/ etisserant@0: /* B 3.1 - Expressions */ etisserant@0: /***********************/ mjsousa@936: void *visit( deref_operator_c *symbol) {return symbol->exp->accept(*this); s4o.print("^");} /* an extension to the IEC 61131-3 standard - based on the IEC 61131-3 v3 standard. ^ -> dereferences an address into a variable! */ mjsousa@936: void *visit( deref_expression_c *symbol) {return s4o.print("DREF("); symbol->exp->accept(*this); s4o.print(")");} /* an extension to the IEC 61131-3 standard - based on the IEC 61131-3 v3 standard. DREF() -> dereferences an address into a variable! */ mjsousa@936: void *visit( ref_expression_c *symbol) {return s4o.print( "REF("); symbol->exp->accept(*this); s4o.print(")");} /* an extension to the IEC 61131-3 standard - based on the IEC 61131-3 v3 standard. REF() -> returns address of the varible! */ mjsousa@933: void *visit( or_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " OR ");} mjsousa@933: void *visit( xor_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " XOR ");} mjsousa@933: void *visit( and_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " AND ");} mjsousa@933: void *visit( equ_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " = ");} msousa@580: void *visit(notequ_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " <> ");} mjsousa@933: void *visit( lt_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " < ");} mjsousa@933: void *visit( gt_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " > ");} mjsousa@933: void *visit( le_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " <= ");} mjsousa@933: void *visit( ge_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " >= ");} mjsousa@933: void *visit( add_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " + ");} mjsousa@933: void *visit( sub_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " - ");} mjsousa@933: void *visit( mul_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " * ");} mjsousa@933: void *visit( div_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " / ");} mjsousa@933: void *visit( mod_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " MOD ");} mjsousa@933: void *visit( power_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " ** ");} mjsousa@933: void *visit( neg_expression_c *symbol) {return print_unary_expression (symbol, symbol->exp, "-");} mjsousa@933: void *visit( not_expression_c *symbol) {return print_unary_expression (symbol, symbol->exp, "NOT ");} etisserant@0: etisserant@0: void *visit(function_invocation_c *symbol) { etisserant@0: symbol->function_name->accept(*this); etisserant@0: s4o.print("("); ccb@202: ccb@202: /* If the syntax parser is working correctly, exactly one of the ccb@202: * following two symbols will be NULL, while the other is != NULL. ccb@202: */ ccb@202: if (symbol-> formal_param_list != NULL) symbol-> formal_param_list->accept(*this); ccb@202: if (symbol->nonformal_param_list != NULL) symbol->nonformal_param_list->accept(*this); ccb@202: etisserant@0: s4o.print(")"); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /********************/ etisserant@0: /* B 3.2 Statements */ etisserant@0: /********************/ etisserant@0: void *visit(statement_list_c *symbol) { etisserant@0: return print_list(symbol, s4o.indent_spaces, ";\n" + s4o.indent_spaces, ";\n"); etisserant@0: } etisserant@0: etisserant@0: /*********************************/ etisserant@0: /* B 3.2.1 Assignment Statements */ etisserant@0: /*********************************/ etisserant@0: void *visit( assignment_statement_c *symbol) { etisserant@0: symbol->l_exp->accept(*this); etisserant@0: s4o.print(" := "); etisserant@0: symbol->r_exp->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /*****************************************/ etisserant@0: /* B 3.2.2 Subprogram Control Statements */ etisserant@0: /*****************************************/ lbessard@143: etisserant@0: /* RETURN */ etisserant@0: void *visit(return_statement_c *symbol) { etisserant@0: s4o.print("RETURN"); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: etisserant@0: /* fb_name '(' [param_assignment_list] ')' */ etisserant@0: void *visit(fb_invocation_c *symbol) { etisserant@0: symbol->fb_name->accept(*this); etisserant@0: s4o.print("("); ccb@202: /* If the syntax parser is working correctly, at most one of the ccb@202: * following two symbols will be NULL, while the other is != NULL. ccb@202: * The two may be NULL simultaneously! ccb@202: */ ccb@202: if (symbol-> formal_param_list != NULL) symbol-> formal_param_list->accept(*this); ccb@202: if (symbol->nonformal_param_list != NULL) symbol->nonformal_param_list->accept(*this); ccb@202: etisserant@0: s4o.print(")"); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: etisserant@0: /* helper symbol for fb_invocation */ etisserant@0: /* param_assignment_list ',' param_assignment */ etisserant@0: void *visit(param_assignment_list_c *symbol) {return print_list(symbol, "", ", ");} etisserant@0: etisserant@0: etisserant@0: void *visit(input_variable_param_assignment_c *symbol) { etisserant@0: symbol->variable_name->accept(*this); etisserant@0: s4o.print(" := "); etisserant@0: symbol->expression->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: etisserant@0: void *visit(output_variable_param_assignment_c *symbol) { etisserant@0: if (symbol->not_param != NULL) etisserant@0: symbol->not_param->accept(*this); etisserant@0: symbol->variable_name->accept(*this); etisserant@0: s4o.print(" => "); etisserant@0: symbol->variable->accept(*this); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: etisserant@0: void *visit(not_paramassign_c *symbol) { etisserant@0: s4o.print("NOT "); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: etisserant@0: /********************************/ etisserant@0: /* B 3.2.3 Selection Statements */ etisserant@0: /********************************/ etisserant@0: void *visit(if_statement_c *symbol) { etisserant@0: s4o.print("IF "); etisserant@0: symbol->expression->accept(*this); etisserant@0: s4o.print(" THEN\n"); etisserant@0: s4o.indent_right(); etisserant@0: symbol->statement_list->accept(*this); etisserant@0: s4o.indent_left(); etisserant@0: symbol->elseif_statement_list->accept(*this); etisserant@0: etisserant@0: if (symbol->else_statement_list != NULL) { etisserant@0: s4o.print(s4o.indent_spaces); s4o.print("ELSE\n"); etisserant@0: s4o.indent_right(); etisserant@0: symbol->else_statement_list->accept(*this); etisserant@0: s4o.indent_left(); etisserant@0: } etisserant@0: s4o.print(s4o.indent_spaces); s4o.print("END_IF"); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* helper symbol for if_statement */ etisserant@0: void *visit(elseif_statement_list_c *symbol) {return print_list(symbol);} etisserant@0: etisserant@0: /* helper symbol for elseif_statement_list */ etisserant@0: void *visit(elseif_statement_c *symbol) { etisserant@0: s4o.print(s4o.indent_spaces); s4o.print("ELSIF "); etisserant@0: symbol->expression->accept(*this); etisserant@0: s4o.print(s4o.indent_spaces); s4o.print("THEN\n"); etisserant@0: s4o.indent_right(); etisserant@0: symbol->statement_list->accept(*this); etisserant@0: s4o.indent_left(); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: void *visit(case_statement_c *symbol) { etisserant@0: s4o.print("CASE "); etisserant@0: symbol->expression->accept(*this); etisserant@0: s4o.print(" OF\n"); etisserant@0: s4o.indent_right(); etisserant@0: symbol->case_element_list->accept(*this); etisserant@0: if (symbol->statement_list != NULL) { etisserant@0: s4o.print(s4o.indent_spaces + "ELSE\n"); etisserant@0: s4o.indent_right(); etisserant@0: symbol->statement_list->accept(*this); etisserant@0: s4o.indent_left(); etisserant@0: } etisserant@0: s4o.indent_left(); etisserant@0: s4o.print(s4o.indent_spaces + "END_CASE"); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /* helper symbol for case_statement */ etisserant@0: void *visit(case_element_list_c *symbol) { etisserant@0: return print_list(symbol); etisserant@0: } etisserant@0: etisserant@0: void *visit(case_element_c *symbol) { etisserant@0: s4o.print(s4o.indent_spaces); etisserant@0: symbol->case_list->accept(*this); etisserant@0: s4o.print(":\n"); etisserant@0: s4o.indent_right(); etisserant@0: symbol->statement_list->accept(*this); etisserant@0: s4o.indent_left(); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: void *visit(case_list_c *symbol) {return print_list(symbol, "", ", ");} etisserant@0: etisserant@0: /********************************/ etisserant@0: /* B 3.2.4 Iteration Statements */ etisserant@0: /********************************/ etisserant@0: void *visit(for_statement_c *symbol) { etisserant@0: s4o.print("FOR "); etisserant@0: symbol->control_variable->accept(*this); etisserant@0: s4o.print(" := "); etisserant@0: symbol->beg_expression->accept(*this); etisserant@0: s4o.print(" TO "); etisserant@0: symbol->end_expression->accept(*this); etisserant@0: if (symbol->by_expression != NULL) { etisserant@0: s4o.print(" BY "); etisserant@0: symbol->by_expression->accept(*this); etisserant@0: } etisserant@0: s4o.print(" DO\n"); etisserant@0: s4o.indent_right(); etisserant@0: symbol->statement_list->accept(*this); etisserant@0: s4o.indent_left(); etisserant@0: s4o.print(s4o.indent_spaces); s4o.print("END_FOR"); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: void *visit(while_statement_c *symbol) { etisserant@0: s4o.print("WHILE "); etisserant@0: symbol->expression->accept(*this); etisserant@0: s4o.print(" DO\n"); etisserant@0: s4o.indent_right(); etisserant@0: symbol->statement_list->accept(*this); etisserant@0: s4o.indent_left(); etisserant@0: s4o.print(s4o.indent_spaces); s4o.print("END_WHILE"); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: void *visit(repeat_statement_c *symbol) { etisserant@0: s4o.print("REPEAT\n"); etisserant@0: s4o.indent_right(); etisserant@0: symbol->statement_list->accept(*this); etisserant@0: s4o.indent_left(); etisserant@0: s4o.print(s4o.indent_spaces); s4o.print("UNTIL "); etisserant@0: symbol->expression->accept(*this); etisserant@0: s4o.print("\n" + s4o.indent_spaces + "END_REPEAT"); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: void *visit(exit_statement_c *symbol) { etisserant@0: s4o.print("EXIT"); etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: etisserant@0: }; /* class generate_iec_c */ etisserant@0: etisserant@0: etisserant@0: etisserant@0: /***********************************************************************/ etisserant@0: /***********************************************************************/ etisserant@0: /***********************************************************************/ etisserant@0: /***********************************************************************/ etisserant@0: /***********************************************************************/ etisserant@0: /***********************************************************************/ etisserant@0: /***********************************************************************/ etisserant@0: /***********************************************************************/ etisserant@0: etisserant@0: etisserant@0: etisserant@0: lbessard@46: visitor_c *new_code_generator(stage4out_c *s4o, const char *builddir) {return new generate_iec_c(s4o);} etisserant@0: void delete_code_generator(visitor_c *code_generator) {delete code_generator;} etisserant@0: etisserant@0: etisserant@0: etisserant@0: etisserant@0: etisserant@0: etisserant@0: etisserant@0: etisserant@0: etisserant@0: etisserant@0: etisserant@0: etisserant@0: etisserant@0: etisserant@0: