etisserant@0: /* msousa@261: * matiec - a compiler for the programming languages defined in IEC 61131-3 msousa@261: * Copyright (C) 2003-2011 Mario de Sousa (msousa@fe.up.pt) Edouard@279: * Copyright (C) 2007-2011 Laurent Bessard and Edouard Tisserant msousa@261: * msousa@261: * This program is free software: you can redistribute it and/or modify msousa@261: * it under the terms of the GNU General Public License as published by msousa@261: * the Free Software Foundation, either version 3 of the License, or msousa@261: * (at your option) any later version. msousa@261: * msousa@261: * This program is distributed in the hope that it will be useful, msousa@261: * but WITHOUT ANY WARRANTY; without even the implied warranty of msousa@261: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the msousa@261: * GNU General Public License for more details. msousa@261: * msousa@261: * You should have received a copy of the GNU General Public License msousa@261: * along with this program. If not, see . msousa@261: * 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@261: * 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: * 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: mario@69: #define SYM_REF1(class_name_c, ref1) \ mario@69: virtual void *visit(class_name_c *symbol) = 0; mario@69: etisserant@0: #define SYM_REF2(class_name_c, ref1, ref2) \ etisserant@0: virtual void *visit(class_name_c *symbol) = 0; etisserant@0: mario@69: #define SYM_REF3(class_name_c, ref1, ref2, ref3) \ mario@69: virtual void *visit(class_name_c *symbol) = 0; mario@69: etisserant@0: #define SYM_REF4(class_name_c, ref1, ref2, ref3, ref4) \ etisserant@0: virtual void *visit(class_name_c *symbol) = 0; etisserant@0: mario@69: #define SYM_REF5(class_name_c, ref1, ref2, ref3, ref4, ref5) \ mario@69: virtual void *visit(class_name_c *symbol) = 0; mario@69: 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 mario@69: #undef SYM_REF1 etisserant@0: #undef SYM_REF2 mario@69: #undef SYM_REF3 etisserant@0: #undef SYM_REF4 mario@69: #undef SYM_REF5 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: mario@69: #define SYM_REF1(class_name_c, ref1) \ mario@69: virtual void *visit(class_name_c *symbol); mario@69: etisserant@0: #define SYM_REF2(class_name_c, ref1, ref2) \ etisserant@0: virtual void *visit(class_name_c *symbol); etisserant@0: mario@69: #define SYM_REF3(class_name_c, ref1, ref2, ref3) \ mario@69: virtual void *visit(class_name_c *symbol); mario@69: etisserant@0: #define SYM_REF4(class_name_c, ref1, ref2, ref3, ref4) \ etisserant@0: virtual void *visit(class_name_c *symbol); etisserant@0: mario@69: #define SYM_REF5(class_name_c, ref1, ref2, ref3, ref4, ref5) \ mario@69: virtual void *visit(class_name_c *symbol); mario@69: 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 mario@69: #undef SYM_REF1 etisserant@0: #undef SYM_REF2 mario@69: #undef SYM_REF3 etisserant@0: #undef SYM_REF4 mario@69: #undef SYM_REF5 etisserant@0: #undef SYM_REF6 etisserant@0: etisserant@0: #endif /* _VISITOR_HH */