Add token reference to all symbol_c, and add list_c::find_element()
authorMario de Sousa <msousa@fe.up.pt>
Tue, 04 Apr 2017 15:21:42 +0100
changeset 1043 4165b7189c32
parent 1042 6d1cdb7da363
child 1044 519a30dbf96c
Add token reference to all symbol_c, and add list_c::find_element()
absyntax/absyntax.cc
absyntax/absyntax.hh
--- 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! */