etisserant@0: /* etisserant@0: * (c) 2003 Mario de Sousa etisserant@0: * etisserant@0: * Offered to the public under the terms of the GNU General Public License etisserant@0: * as published by the Free Software Foundation; either version 2 of the etisserant@0: * License, or (at your option) any later version. etisserant@0: * etisserant@0: * This program is distributed in the hope that it will be useful, but etisserant@0: * WITHOUT ANY WARRANTY; without even the implied warranty of etisserant@0: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General etisserant@0: * Public License for more details. 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: /* etisserant@0: * An IEC 61131-3 IL and ST 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: * VISITOR.HH etisserant@0: * etisserant@0: * etisserant@0: * The asbract syntax tree is scaned several times etisserant@0: * during the whole compilation process. For e.g., stage 3 verifies etisserant@0: * semantics, and stage 4 produces output. etisserant@0: * etisserant@0: * Since the number of functions that need to scan through etisserant@0: * the abtract syntax tree may increase in time, (e.g. new etisserant@0: * output formats, new semantic checks, etc...) while the etisserant@0: * abstract syntax tree class structure is pretty stable etisserant@0: * (i.e. the ST and IL languages will not be changing much...), etisserant@0: * we use the 'visitor' design patern. etisserant@0: * etisserant@0: * It is not strictly necessary to use this pattern, but it does etisserant@0: * have the advantage of bringing together the functions etisserant@0: * that implement the same algorithm, each on a different etisserant@0: * class of object in the abstract syntax tree. etisserant@0: * etisserant@0: * etisserant@0: * This file contains the interface that each visitor class etisserant@0: * must implement in order to be able to visit the abstract etisserant@0: * syntax tree (class visitor_c) etisserant@0: * etisserant@0: * Three implementations of this interface are also provided, etisserant@0: * that may be later extended to execute a particular algorithm. etisserant@0: * etisserant@0: * The null (class null_visitor_c) does nothing. etisserant@0: * etisserant@0: * The iterator (class iterator_visitor_c) iterates through etisserant@0: * every object in the syntax tree. etisserant@0: * etisserant@0: * The search class (class search_visitor_c) iterates through etisserant@0: * every object, until one returns a value != NULL. etisserant@0: */ etisserant@0: etisserant@0: etisserant@0: #ifndef _VISITOR_HH etisserant@0: #define _VISITOR_HH etisserant@0: etisserant@0: etisserant@0: etisserant@0: etisserant@0: #include "absyntax.hh" etisserant@0: etisserant@0: etisserant@0: etisserant@0: #define SYM_LIST(class_name_c) \ etisserant@0: virtual void *visit(class_name_c *symbol) = 0; etisserant@0: etisserant@0: #define SYM_TOKEN(class_name_c) \ etisserant@0: virtual void *visit(class_name_c *symbol) = 0; etisserant@0: etisserant@0: #define SYM_REF0(class_name_c) \ etisserant@0: virtual void *visit(class_name_c *symbol) = 0; etisserant@0: etisserant@0: #define SYM_REF2(class_name_c, ref1, ref2) \ etisserant@0: virtual void *visit(class_name_c *symbol) = 0; etisserant@0: etisserant@0: #define SYM_REF4(class_name_c, ref1, ref2, ref3, ref4) \ etisserant@0: virtual void *visit(class_name_c *symbol) = 0; etisserant@0: etisserant@0: #define SYM_REF6(class_name_c, ref1, ref2, ref3, ref4, ref5, ref6) \ etisserant@0: virtual void *visit(class_name_c *symbol) = 0; etisserant@0: etisserant@0: class visitor_c { etisserant@0: public: etisserant@0: #include "absyntax.def" etisserant@0: etisserant@0: virtual ~visitor_c(void); etisserant@0: }; etisserant@0: etisserant@0: #undef SYM_LIST etisserant@0: #undef SYM_TOKEN etisserant@0: #undef SYM_REF0 etisserant@0: #undef SYM_REF2 etisserant@0: #undef SYM_REF4 etisserant@0: #undef SYM_REF6 etisserant@0: etisserant@0: etisserant@0: etisserant@0: etisserant@0: etisserant@0: etisserant@0: #define SYM_LIST(class_name_c) \ etisserant@0: virtual void *visit(class_name_c *symbol); etisserant@0: etisserant@0: #define SYM_TOKEN(class_name_c) \ etisserant@0: virtual void *visit(class_name_c *symbol); etisserant@0: etisserant@0: #define SYM_REF0(class_name_c) \ etisserant@0: virtual void *visit(class_name_c *symbol); etisserant@0: etisserant@0: #define SYM_REF2(class_name_c, ref1, ref2) \ etisserant@0: virtual void *visit(class_name_c *symbol); etisserant@0: etisserant@0: #define SYM_REF4(class_name_c, ref1, ref2, ref3, ref4) \ etisserant@0: virtual void *visit(class_name_c *symbol); etisserant@0: etisserant@0: #define SYM_REF6(class_name_c, ref1, ref2, ref3, ref4, ref5, ref6) \ etisserant@0: virtual void *visit(class_name_c *symbol); etisserant@0: etisserant@0: etisserant@0: etisserant@0: etisserant@0: etisserant@0: class null_visitor_c: public visitor_c { etisserant@0: public: etisserant@0: #include "absyntax.def" etisserant@0: etisserant@0: virtual ~null_visitor_c(void); etisserant@0: }; etisserant@0: etisserant@0: etisserant@0: etisserant@0: class iterator_visitor_c: public visitor_c { etisserant@0: protected: etisserant@0: void *visit_list(list_c *list); etisserant@0: etisserant@0: public: etisserant@0: #include "absyntax.def" etisserant@0: etisserant@0: virtual ~iterator_visitor_c(void); etisserant@0: }; etisserant@0: etisserant@0: etisserant@0: class search_visitor_c: public visitor_c { etisserant@0: protected: etisserant@0: void *visit_list(list_c *list); etisserant@0: etisserant@0: public: etisserant@0: #include "absyntax.def" etisserant@0: etisserant@0: virtual ~search_visitor_c(void); etisserant@0: }; etisserant@0: etisserant@0: etisserant@0: #undef SYM_LIST etisserant@0: #undef SYM_TOKEN etisserant@0: #undef SYM_REF0 etisserant@0: #undef SYM_REF2 etisserant@0: #undef SYM_REF4 etisserant@0: #undef SYM_REF6 etisserant@0: etisserant@0: #endif /* _VISITOR_HH */