# HG changeset patch # User Mario de Sousa # Date 1491315702 -3600 # Node ID 4165b7189c32bfa6a5d0ef8ebc595a7e111e1251 # Parent 6d1cdb7da363b81ec3adb1b9867d6064a92ffca3 Add token reference to all symbol_c, and add list_c::find_element() diff -r 6d1cdb7da363 -r 4165b7189c32 absyntax/absyntax.cc --- a/absyntax/absyntax.cc Tue Apr 04 10:41:11 2017 +0100 +++ b/absyntax/absyntax.cc Tue Apr 04 15:21:42 2017 +0100 @@ -58,6 +58,7 @@ this->last_column = last_column; this->last_order = last_order; this->parent = NULL; + this->token = NULL; this->datatype = NULL; this->scope = NULL; } @@ -69,6 +70,7 @@ int ll, int lc, const char *lfile, long int lorder) :symbol_c(fl, fc, ffile, forder, ll, lc, lfile, lorder) { this->value = value; + this->token = this; // every token is its own reference token. // printf("New token: %s\n", value); } @@ -83,7 +85,7 @@ int ll, int lc, const char *lfile, long int lorder) :symbol_c(fl, fc, ffile, forder, ll, lc, lfile, lorder),c(LIST_CAP_INIT) { n = 0; - elements = (symbol_c**)malloc(LIST_CAP_INIT*sizeof(symbol_c*)); + elements = (element_entry_t*)malloc(LIST_CAP_INIT*sizeof(element_entry_t)); if (NULL == elements) ERROR_MSG("out of memory"); } @@ -93,23 +95,58 @@ int ll, int lc, const char *lfile, long int lorder) :symbol_c(fl, fc, ffile, forder, ll, lc, lfile, lorder),c(LIST_CAP_INIT) { n = 0; - elements = (symbol_c**)malloc(LIST_CAP_INIT*sizeof(symbol_c*)); + elements = (element_entry_t*)malloc(LIST_CAP_INIT*sizeof(element_entry_t)); if (NULL == elements) ERROR_MSG("out of memory"); add_element(elem); } +/*******************************************/ /* get element in position pos of the list */ -symbol_c *list_c::get_element(int pos) {return elements[pos];} - +/*******************************************/ +symbol_c *list_c::get_element(int pos) {return elements[pos].symbol;} + + + +/******************************************/ +/* find element associated to token value */ +/******************************************/ +symbol_c *list_c::find_element(symbol_c *token) { + token_c *t = dynamic_cast(token); + if (t == NULL) ERROR; + return find_element((const char *)t->value); +} + +symbol_c *list_c::find_element(const char *token_value) { + // We could use strcasecmp(), but it's best to always use the same + // method of string comparison throughout matiec + nocasecmp_c ncc; + for (int i = 0; i < n; i++) + if (ncc(elements[i].token_value, token_value)) + return elements[i].symbol; + return NULL; // not found +} + + +/***********************************************/ /* append a new element to the end of the list */ -void list_c::add_element(symbol_c *elem) { - // printf("list_c::add_element()\n"); +/***********************************************/ +void list_c::add_element(symbol_c *elem) {add_element(elem, elem);} + +void list_c::add_element(symbol_c *elem, symbol_c *token) { + token_c *t = (token == NULL)? NULL : token->token; + add_element(elem, (t == NULL)? NULL : t->value); +} + +void list_c::add_element(symbol_c *elem, const char *token_value) { if (c <= n) - if (!(elements=(symbol_c**)realloc(elements,(c+=LIST_CAP_INCR)*sizeof(symbol_c *)))) + if (!(elements=(element_entry_t*)realloc(elements,(c+=LIST_CAP_INCR)*sizeof(element_entry_t)))) ERROR_MSG("out of memory"); - elements[n++] = elem; - + //elements[n++] = {token_value, elem}; // only available from C++11 onwards, best not use it for now. + elements[n].symbol = elem; + elements[n].token_value = token_value; + n++; + if (NULL == elem) return; /* Sometimes add_element() is called in stage3 or stage4 to temporarily add an AST symbol to the list. * Since this symbol already belongs in some other place in the aST, it will have the 'parent' pointer set, @@ -146,10 +183,21 @@ } } + +/*********************************************/ /* insert a new element before position pos. */ +/*********************************************/ /* To insert into the begining of list, call with pos=0 */ /* To insert into the end of list, call with pos=list->n */ -void list_c::insert_element(symbol_c *elem, int pos) { + +void list_c::insert_element(symbol_c *elem, int pos) {insert_element(elem, elem, pos);} + +void list_c::insert_element(symbol_c *elem, symbol_c *token, int pos) { + token_c *t = (token == NULL)? NULL : token->token; + insert_element(elem, (t == NULL)? NULL : t->value, pos); +} + +void list_c::insert_element(symbol_c *elem, const char *token_value, int pos) { if((pos<0) || (n=pos ; --i) elements[i+1] = elements[i]; - elements[pos] = elem; - } -} - - + elements[pos].symbol = elem; + elements[pos].token_value = token_value; + } +} + + +/***********************************/ /* remove element at position pos. */ +/***********************************/ void list_c::remove_element(int pos) { if((pos<0) || (n<=pos)) ERROR; @@ -171,12 +222,14 @@ for (int i = pos; i < n-1; i++) elements[i] = elements[i+1]; /* corrent the new size */ n--; - /* elements = (symbol_c **)realloc(elements, n * sizeof(symbol_c *)); */ + /* elements = (symbol_c **)realloc(elements, n * sizeof(element_entry_t)); */ /* TODO: adjust the location parameters, taking into account the removed element. */ } -/* remove element at position pos. */ +/**********************************/ +/* Remove all elements from list. */ +/**********************************/ void list_c::clear(void) { n = 0; /* TODO: adjust the location parameters, taking into account the removed element. */ diff -r 6d1cdb7da363 -r 4165b7189c32 absyntax/absyntax.hh --- a/absyntax/absyntax.hh Tue Apr 04 10:41:11 2017 +0100 +++ b/absyntax/absyntax.hh Tue Apr 04 15:21:42 2017 +0100 @@ -154,7 +154,8 @@ {return (_int64.is_valid() || _uint64.is_valid() || _real64.is_valid() || _bool.is_valid());} }; - +// A forward declaration +class token_c; /* The base class of all symbols */ class symbol_c { @@ -167,7 +168,18 @@ * Annotations produced during stage 1_2 */ /* Points to the parent symbol in the AST, i.e. the symbol in the AST that will contain the current symbol */ - symbol_c *parent; + symbol_c *parent; + /* Some symbols may not be tokens, but may be clearly identified by a token. + * For e.g., a FUNCTION declaration is not itself a token, but may be clearly identified by the + * token_c object that contains it's name. Another example is an element in a STRUCT declaration, + * where the structure_element_declaration_c is not itself a token, but can be clearly identified + * by the structure_element_name + * To make it easier to find these tokens from the top level object, we will have the stage1_2 populate this + * token_c *token wherever it makes sense. + * NOTE: This was a late addition to the AST. Not all objects may be currently so populated. + * If you need this please make sure the bison code is populating it correctly for your use case. + */ + token_c *token; /* Line number for the purposes of error checking. */ int first_line; @@ -261,7 +273,13 @@ int c,n; /* c: current capacity of list (malloc'd memory); n: current number of elements in list */ private: - symbol_c **elements; +// symbol_c **elements; + typedef struct { + const char *token_value; + symbol_c *symbol; + } element_entry_t; + element_entry_t *elements; + public: 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 */ @@ -274,12 +292,20 @@ ); /* get element in position pos of the list */ virtual symbol_c *get_element(int pos); + /* find element associated to token value */ + virtual symbol_c *find_element(symbol_c *token); + virtual symbol_c *find_element(const char *token_value); /* append a new element to the end of the list */ virtual void add_element(symbol_c *elem); + virtual void add_element(symbol_c *elem, symbol_c *token); + virtual void add_element(symbol_c *elem, const char *token_value); /* insert a new element before position pos. */ /* To insert into the begining of list, call with pos=0 */ /* To insert into the end of list, call with pos=list->n */ - virtual void insert_element(symbol_c *elem, int pos = 0); + virtual void insert_element(symbol_c *elem, const char *token_value, int pos = 0); + virtual void insert_element(symbol_c *elem, symbol_c *token, int pos = 0); + virtual void insert_element(symbol_c *elem, int pos = 0); + //virtual void insert_element(symbol_c *elem, int pos, std::string map_ref); /* remove element at position pos. */ virtual void remove_element(int pos = 0); /* remove all elements from list. Does not delete the elements in the list! */