diff -r 000000000000 -r fb772792efd1 absyntax/visitor.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/absyntax/visitor.cc Wed Jan 31 15:32:38 2007 +0100 @@ -0,0 +1,265 @@ +/* + * (c) 2003 Mario de Sousa + * + * Offered to the public under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * This code is made available on the understanding that it will not be + * used in safety-critical situations without a full and competent review. + */ + +/* + * An IEC 61131-3 IL and ST compiler. + * + * Based on the + * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10) + * + */ + + +/* + * VISITOR.CC + * + * Three base implementations of the visitor interface, + * that may be later extended to execute a particular algorithm. + * + * The null (class null_visitor_c) does nothing. + * + * The iterator (class iterator_visitor_c) iterates through + * every object in the syntax tree. + * + * The search class (class search_visitor_c) iterates through + * every object, until one returns a value != NULL. + */ + + + + + +#include + +#include /* required for NULL */ +#include "visitor.hh" + +#include + + +/******************/ +/* visitor_c */ +/******************/ + +visitor_c::~visitor_c(void) {return;} + + +/******************/ +/* null_visitor_c */ +/******************/ + +null_visitor_c::~null_visitor_c(void) {return;} + +#define SYM_LIST(class_name_c) \ + void *null_visitor_c::visit(class_name_c *symbol) {return NULL;} + +#define SYM_TOKEN(class_name_c) \ + void *null_visitor_c::visit(class_name_c *symbol) {return NULL;} + +#define SYM_REF0(class_name_c) \ + void *null_visitor_c::visit(class_name_c *symbol) {return NULL;} + +#define SYM_REF2(class_name_c, ref1, ref2) \ + void *null_visitor_c::visit(class_name_c *symbol) {return NULL;} + +#define SYM_REF4(class_name_c, ref1, ref2, ref3, ref4) \ + void *null_visitor_c::visit(class_name_c *symbol) {return NULL;} + +#define SYM_REF6(class_name_c, ref1, ref2, ref3, ref4, ref5, ref6) \ + void *null_visitor_c::visit(class_name_c *symbol) {return NULL;} + + +#include "absyntax.def" + + + + +#undef SYM_LIST +#undef SYM_TOKEN +#undef SYM_REF0 +#undef SYM_REF2 +#undef SYM_REF4 +#undef SYM_REF6 + + + + + + +/**********************/ +/* iterator_visitor_c */ +/**********************/ + +iterator_visitor_c::~iterator_visitor_c(void) {return;} + + +void *iterator_visitor_c::visit_list(list_c *list) { + for(int i = 0; i < list->n; i++) { + list->elements[i]->accept(*this); + } + return NULL; +} + + +#define SYM_LIST(class_name_c) \ + void *iterator_visitor_c::visit(class_name_c *symbol) {return visit_list(symbol);} + +#define SYM_TOKEN(class_name_c) \ + void *iterator_visitor_c::visit(class_name_c *symbol) {return NULL;} + +#define SYM_REF0(class_name_c) \ + void *iterator_visitor_c::visit(class_name_c *symbol) {return NULL;} + +#define SYM_REF2(class_name_c, ref1, ref2) \ +void *iterator_visitor_c::visit(class_name_c *symbol) { \ + if (symbol->ref1!=NULL) symbol->ref1->accept(*this); \ + if (symbol->ref2!=NULL) symbol->ref2->accept(*this); \ + return NULL; \ +} + +#define SYM_REF4(class_name_c, ref1, ref2, ref3, ref4) \ +void *iterator_visitor_c::visit(class_name_c *symbol) { \ + if (symbol->ref1) symbol->ref1->accept(*this); \ + if (symbol->ref2) symbol->ref2->accept(*this); \ + if (symbol->ref3) symbol->ref3->accept(*this); \ + if (symbol->ref4) symbol->ref4->accept(*this); \ + return NULL; \ +} + + +#define SYM_REF6(class_name_c, ref1, ref2, ref3, ref4, ref5, ref6) \ +void *iterator_visitor_c::visit(class_name_c *symbol) { \ + if (symbol->ref1) symbol->ref1->accept(*this); \ + if (symbol->ref2) symbol->ref2->accept(*this); \ + if (symbol->ref3) symbol->ref3->accept(*this); \ + if (symbol->ref4) symbol->ref4->accept(*this); \ + if (symbol->ref5) symbol->ref5->accept(*this); \ + if (symbol->ref6) symbol->ref6->accept(*this); \ + return NULL; \ +} + + + +#include "absyntax.def" + + + +#undef SYM_LIST +#undef SYM_TOKEN +#undef SYM_REF0 +#undef SYM_REF2 +#undef SYM_REF4 +#undef SYM_REF6 + + + + + + + + + + +/********************/ +/* search_visitor_c */ +/********************/ + +search_visitor_c::~search_visitor_c(void) {return;} + + +void *search_visitor_c::visit_list(list_c *list) { + for(int i = 0; i < list->n; i++) { + void *res = list->elements[i]->accept(*this); + if (res != NULL) + return res; + } + return NULL; +} + + +#define SYM_LIST(class_name_c) \ + void *search_visitor_c::visit(class_name_c *symbol) {return visit_list(symbol);} + +#define SYM_TOKEN(class_name_c) \ + void *search_visitor_c::visit(class_name_c *symbol) {return NULL;} + +#define SYM_REF0(class_name_c) \ + void *search_visitor_c::visit(class_name_c *symbol) {return NULL;} + +#define SYM_REF2(class_name_c, ref1, ref2) \ +void *search_visitor_c::visit(class_name_c *symbol) { \ + void *res = NULL; \ + if (symbol->ref1) res = symbol->ref1->accept(*this); \ + if (res != NULL) return res; \ + if (symbol->ref2) return symbol->ref2->accept(*this); \ + return NULL; \ +} + +#define SYM_REF4(class_name_c, ref1, ref2, ref3, ref4) \ +void *search_visitor_c::visit(class_name_c *symbol) { \ + void *res = NULL; \ + if (symbol->ref1) res = symbol->ref1->accept(*this); \ + if (res != NULL) return res; \ + if (symbol->ref2) res = symbol->ref2->accept(*this); \ + if (res != NULL) return res; \ + if (symbol->ref3) res = symbol->ref3->accept(*this); \ + if (res != NULL) return res; \ + if (symbol->ref4) return symbol->ref4->accept(*this); \ + return NULL; \ +} + + +#define SYM_REF6(class_name_c, ref1, ref2, ref3, ref4, ref5, ref6) \ +void *search_visitor_c::visit(class_name_c *symbol) { \ + void *res = NULL; \ + if (symbol->ref1) res = symbol->ref1->accept(*this); \ + if (res != NULL) return res; \ + if (symbol->ref2) res = symbol->ref2->accept(*this); \ + if (res != NULL) return res; \ + if (symbol->ref3) res = symbol->ref3->accept(*this); \ + if (res != NULL) return res; \ + if (symbol->ref4) res = symbol->ref4->accept(*this); \ + if (res != NULL) return res; \ + if (symbol->ref5) res = symbol->ref5->accept(*this); \ + if (res != NULL) return res; \ + if (symbol->ref6) return symbol->ref6->accept(*this); \ + return NULL; \ +} + + + +#include "absyntax.def" + + + +#undef SYM_LIST +#undef SYM_TOKEN +#undef SYM_REF0 +#undef SYM_REF2 +#undef SYM_REF4 +#undef SYM_REF6 + + + + + + + + + + + +