--- 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_c *>(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)) ERROR;
/* add new element to end of list. Basically alocate required memory... */
@@ -158,12 +206,15 @@
/* if not inserting into end position, shift all elements up one position, to open up a slot in pos for new element */
if(pos < (n-1)){
for(int i=n-2 ; i>=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. */
--- 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! */