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: * Declaration of the Abstract Syntax data structure components etisserant@0: */ etisserant@0: etisserant@0: /* etisserant@0: * ABSYNTAX.H etisserant@0: * etisserant@0: * This generates the parse tree structure used to bind the components etisserant@0: * identified by Bison in the correct syntax order. At the end of the etisserant@0: * Bison analysis the tree is walked in a sequential fashion generating etisserant@0: * the relavent code. etisserant@0: */ etisserant@0: etisserant@0: #ifndef _ABSYNTAX_HH etisserant@0: #define _ABSYNTAX_HH etisserant@0: etisserant@0: etisserant@0: #include // required for NULL msousa@417: #include etisserant@0: etisserant@0: /* Forward declaration of the visitor interface etisserant@0: * dclared in the visitor.hh file etisserant@0: * We cannot include the visitor.hh file, as it will etisserant@0: * include this same file first, as it too requires references etisserant@0: * to the abstract syntax classes defined here. etisserant@0: */ etisserant@0: class visitor_c; // forward declaration etisserant@0: etisserant@0: etisserant@0: class symbol_c; // forward declaration etisserant@0: etisserant@0: etisserant@0: etisserant@0: /* The base class of all symbols */ etisserant@0: class symbol_c { etisserant@0: etisserant@0: public: etisserant@0: /* etisserant@0: * Line number for the purposes of error checking etisserant@0: */ mario@69: int first_line; mario@69: int first_column; msousa@286: const char *first_file; /* filename referenced by first line/column */ msousa@287: long int first_order; /* relative order in which it is read by lexcial analyser */ mario@69: int last_line; mario@69: int last_column; msousa@286: const char *last_file; /* filename referenced by last line/column */ msousa@287: long int last_order; /* relative order in which it is read by lexcial analyser */ msousa@417: symbol_c * datatype; /* data type of the expression/literal/etc. Filled in stage3 by narrow_candidate_datatypes_c */ msousa@417: std::vector candidate_datatypes; /* All possible data types the expression/literal/etc. may take. Filled in stage3 by fill_candidate_datatypes_c class */ msousa@417: etisserant@0: etisserant@0: public: etisserant@0: /* default constructor */ msousa@287: symbol_c(int fl = 0, int fc = 0, const char *ffile = NULL /* filename */, long int forder=0, /* order in which it is read by lexcial analyser */ msousa@287: int ll = 0, int lc = 0, const char *lfile = NULL /* filename */, long int lorder=0 /* order in which it is read by lexcial analyser */ mario@69: ); etisserant@0: etisserant@0: /* default destructor */ etisserant@0: /* must be virtual so compiler does not complain... */ etisserant@0: virtual ~symbol_c(void) {return;}; etisserant@0: etisserant@0: virtual void *accept(visitor_c &visitor) {return NULL;}; etisserant@0: }; etisserant@0: etisserant@0: etisserant@0: class token_c: public symbol_c { etisserant@0: public: etisserant@0: /* the value of the symbol. */ etisserant@0: const char *value; etisserant@0: etisserant@0: public: msousa@286: token_c(const char *value, msousa@287: int fl = 0, int fc = 0, const char *ffile = NULL /* filename */, long int forder=0, /* order in which it is read by lexcial analyser */ msousa@287: int ll = 0, int lc = 0, const char *lfile = NULL /* filename */, long int lorder=0 /* order in which it is read by lexcial analyser */ msousa@286: ); etisserant@0: }; etisserant@0: etisserant@0: etisserant@0: /* a list of symbols... */ etisserant@0: class list_c: public symbol_c { etisserant@0: public: etisserant@0: int n; etisserant@0: symbol_c **elements; etisserant@0: etisserant@0: public: msousa@287: list_c(int fl = 0, int fc = 0, const char *ffile = NULL /* filename */, long int forder=0, /* order in which it is read by lexcial analyser */ msousa@287: int ll = 0, int lc = 0, const char *lfile = NULL /* filename */, long int lorder=0 /* order in which it is read by lexcial analyser */ msousa@286: ); msousa@286: msousa@286: list_c(symbol_c *elem, msousa@287: int fl = 0, int fc = 0, const char *ffile = NULL /* filename */, long int forder=0, /* order in which it is read by lexcial analyser */ msousa@287: int ll = 0, int lc = 0, const char *lfile = NULL /* filename */, long int lorder=0 /* order in which it is read by lexcial analyser */ msousa@286: ); msousa@350: /* append a new element to the end of the list */ etisserant@0: virtual void add_element(symbol_c *elem); msousa@350: /* insert a new element before position pos. */ msousa@350: /* To insert into the begining of list, call with pos=0 */ msousa@350: /* To insert into the end of list, call with pos=list->n */ msousa@350: virtual void insert_element(symbol_c *elem, int pos = 0); msousa@438: /* remove element at position pos. */ msousa@438: virtual void remove_element(int pos = 0); msousa@350: }; msousa@350: msousa@350: msousa@350: msousa@350: msousa@350: #define SYM_LIST(class_name_c, ...) \ msousa@286: class class_name_c: public list_c { \ msousa@286: public: \ msousa@350: __VA_ARGS__ \ msousa@350: public: \ msousa@286: class_name_c( \ msousa@287: int fl = 0, int fc = 0, const char *ffile = NULL /* filename */, long int forder=0, \ msousa@287: int ll = 0, int lc = 0, const char *lfile = NULL /* filename */, long int lorder=0); \ msousa@286: class_name_c(symbol_c *elem, \ msousa@287: int fl = 0, int fc = 0, const char *ffile = NULL /* filename */, long int forder=0, \ msousa@287: int ll = 0, int lc = 0, const char *lfile = NULL /* filename */, long int lorder=0); \ msousa@286: virtual void *accept(visitor_c &visitor); \ msousa@286: }; msousa@286: msousa@286: msousa@350: #define SYM_TOKEN(class_name_c, ...) \ msousa@286: class class_name_c: public token_c { \ msousa@286: public: \ msousa@350: __VA_ARGS__ \ msousa@350: public: \ msousa@286: class_name_c(const char *value, \ msousa@287: int fl = 0, int fc = 0, const char *ffile = NULL /* filename */, long int forder=0, \ msousa@287: int ll = 0, int lc = 0, const char *lfile = NULL /* filename */, long int lorder=0); \ msousa@286: virtual void *accept(visitor_c &visitor); \ msousa@286: }; msousa@286: msousa@286: msousa@350: #define SYM_REF0(class_name_c, ...) \ msousa@350: class class_name_c: public symbol_c { \ msousa@350: public: \ msousa@350: __VA_ARGS__ \ msousa@286: public: \ msousa@286: class_name_c( \ msousa@287: int fl = 0, int fc = 0, const char *ffile = NULL /* filename */, long int forder=0, \ msousa@287: int ll = 0, int lc = 0, const char *lfile = NULL /* filename */, long int lorder=0); \ msousa@286: virtual void *accept(visitor_c &visitor); \ msousa@286: }; msousa@286: msousa@286: msousa@350: #define SYM_REF1(class_name_c, ref1, ...) \ msousa@350: class class_name_c: public symbol_c { \ msousa@350: public: \ msousa@350: symbol_c *ref1; \ msousa@350: __VA_ARGS__ \ msousa@350: public: \ msousa@350: class_name_c(symbol_c *ref1, \ msousa@350: int fl = 0, int fc = 0, const char *ffile = NULL /* filename */, long int forder=0, \ msousa@350: int ll = 0, int lc = 0, const char *lfile = NULL /* filename */, long int lorder=0); \ msousa@350: virtual void *accept(visitor_c &visitor); \ msousa@350: }; msousa@350: msousa@350: msousa@350: #define SYM_REF2(class_name_c, ref1, ref2, ...) \ msousa@350: class class_name_c: public symbol_c { \ msousa@350: public: \ msousa@350: symbol_c *ref1; \ msousa@350: symbol_c *ref2; \ msousa@350: __VA_ARGS__ \ msousa@286: public: \ msousa@286: class_name_c(symbol_c *ref1, \ msousa@286: symbol_c *ref2 = NULL, \ msousa@287: int fl = 0, int fc = 0, const char *ffile = NULL /* filename */, long int forder=0, \ msousa@287: int ll = 0, int lc = 0, const char *lfile = NULL /* filename */, long int lorder=0); \ msousa@286: virtual void *accept(visitor_c &visitor); \ msousa@286: }; msousa@286: msousa@286: msousa@350: #define SYM_REF3(class_name_c, ref1, ref2, ref3, ...) \ msousa@350: class class_name_c: public symbol_c { \ msousa@350: public: \ msousa@350: symbol_c *ref1; \ msousa@350: symbol_c *ref2; \ msousa@350: symbol_c *ref3; \ msousa@350: __VA_ARGS__ \ msousa@350: public: \ msousa@350: class_name_c(symbol_c *ref1, \ msousa@350: symbol_c *ref2, \ msousa@350: symbol_c *ref3, \ msousa@350: int fl = 0, int fc = 0, const char *ffile = NULL /* filename */, long int forder=0, \ msousa@350: int ll = 0, int lc = 0, const char *lfile = NULL /* filename */, long int lorder=0); \ msousa@350: virtual void *accept(visitor_c &visitor); \ msousa@350: }; msousa@350: msousa@350: msousa@350: #define SYM_REF4(class_name_c, ref1, ref2, ref3, ref4, ...) \ msousa@286: class class_name_c: public symbol_c { \ msousa@286: public: \ msousa@286: symbol_c *ref1; \ msousa@286: symbol_c *ref2; \ msousa@286: symbol_c *ref3; \ msousa@286: symbol_c *ref4; \ msousa@350: __VA_ARGS__ \ msousa@286: public: \ msousa@286: class_name_c(symbol_c *ref1, \ msousa@286: symbol_c *ref2, \ msousa@286: symbol_c *ref3, \ msousa@286: symbol_c *ref4 = NULL, \ msousa@287: int fl = 0, int fc = 0, const char *ffile = NULL /* filename */, long int forder=0, \ msousa@287: int ll = 0, int lc = 0, const char *lfile = NULL /* filename */, long int lorder=0); \ msousa@286: virtual void *accept(visitor_c &visitor); \ msousa@286: }; msousa@286: msousa@286: msousa@350: #define SYM_REF5(class_name_c, ref1, ref2, ref3, ref4, ref5, ...) \ msousa@286: class class_name_c: public symbol_c { \ msousa@286: public: \ msousa@286: symbol_c *ref1; \ msousa@286: symbol_c *ref2; \ msousa@286: symbol_c *ref3; \ msousa@286: symbol_c *ref4; \ msousa@286: symbol_c *ref5; \ msousa@350: __VA_ARGS__ \ msousa@286: public: \ msousa@286: class_name_c(symbol_c *ref1, \ msousa@286: symbol_c *ref2, \ msousa@286: symbol_c *ref3, \ msousa@286: symbol_c *ref4, \ msousa@286: symbol_c *ref5, \ msousa@287: int fl = 0, int fc = 0, const char *ffile = NULL /* filename */, long int forder=0, \ msousa@287: int ll = 0, int lc = 0, const char *lfile = NULL /* filename */, long int lorder=0); \ msousa@286: virtual void *accept(visitor_c &visitor); \ msousa@286: }; msousa@286: msousa@286: msousa@350: #define SYM_REF6(class_name_c, ref1, ref2, ref3, ref4, ref5, ref6, ...) \ msousa@286: class class_name_c: public symbol_c { \ msousa@286: public: \ msousa@286: symbol_c *ref1; \ msousa@286: symbol_c *ref2; \ msousa@286: symbol_c *ref3; \ msousa@286: symbol_c *ref4; \ msousa@286: symbol_c *ref5; \ msousa@286: symbol_c *ref6; \ msousa@350: __VA_ARGS__ \ msousa@286: public: \ msousa@286: class_name_c(symbol_c *ref1, \ msousa@286: symbol_c *ref2, \ msousa@286: symbol_c *ref3, \ msousa@286: symbol_c *ref4, \ msousa@286: symbol_c *ref5, \ msousa@286: symbol_c *ref6 = NULL, \ msousa@287: int fl = 0, int fc = 0, const char *ffile = NULL /* filename */, long int forder=0, \ msousa@287: int ll = 0, int lc = 0, const char *lfile = NULL /* filename */, long int lorder=0); \ msousa@286: virtual void *accept(visitor_c &visitor); \ etisserant@0: }; etisserant@0: etisserant@0: etisserant@0: #include "absyntax.def" 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: etisserant@0: etisserant@0: #endif /* _ABSYNTAX_HH */