⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 node.cpp

📁 a LALR(1) grammar for C
💻 CPP
字号:
/*****************************************************
file: NODE.CPP       Copyright 1989 by John M. Dlugosz
   dealings with nodes
*****************************************************/

#include "usual.hpp"
#include <stream.hpp>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include "atom.hpp"
#include "node.hpp"

/* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */

node::node()
{
flavor= nf_base;
}

/* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */

node::~node()
{
}

/* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */

void node::print()
{
cout << "\nerror: base class node printed.\n";
}

/* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
/*   type_node                              */
/* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */

type_node::type_node ()
{
flavor= nf_type;
tag= -1;
to_what= NULL;
aggr= NULL;
flags= 0;
primary= -1;  //not filled in yet
}

/* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */

void type_node::print()
{
static char* typenames[]= {
   "void", //0
   "char", //1
   "int",  //2
   "long", //3
   "float",  //4
   "double", //5
   "long double", //6
      "enum ",  //7
      "class ", //8
      "union ", //9
   "pointer to ",  //10
   "reference to ",//11
   "array of ",    //12
   "function ",    //13
   };

if (isConst()) cout << "const ";
if (isVol()) cout << "volotile ";
if (isNear()) cout << "near ";
if (isFar()) cout << "far ";
if (primary < 10) {  // a simple type
   if (isUnsigned()) cout << "unsigned ";
   cout << typenames[primary];
   if (primary >= 7) {
      cout << (tag > -1 ? atoms[tag] : "<no name>");
      cout.put (' ');
      }
   }
else {  //something fancy
   cout << typenames[primary];
   if (primary == 12) {
      // >> print array dimention
      }
   else if (primary == 13) {
      cout.put('(');
      int max= aggr->size();
      for (int loop= 0;  loop < max;  loop++) {
         (*aggr)[loop]->type->print();
         if (loop < max-1) cout << ", ";
         }
      cout << ") returning ";
      }
   if (secondary()) to_what->print();
   else cout << "**unknown type**";
   }
}

/* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */

void type_node::stuff_primary (int x, atom tagname)
{
/* given the 'x' parameter from the grammer production, stick the right
   values into the 'primary' and set the 'unsigned' flag if needed. */

static int lookup[15]= { 0,  1,1,1,2,2,3,3,4,5,6,0,7,8,9};
assert (x >= 0 && x < 15);
primary= lookup[x];
tag= tagname;  //harmless if not needed
if (x == 3 || x==5) flags|=16;  //mark as unsigned
}
   
/* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */

bool strappend (char*& dest, char* source, int& length)
{
int len= strlen(source);
if (len > length) return FALSE;
memcpy (dest, source, len);
length -= len;
dest+=len;
return TRUE;
}

/* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */

bool ins_number (int value, char*& buf, int& length)
{
itoa (value, buf, 10);
int len= strlen(buf);
if (length < len) return FALSE;
length -= len;
buf += len;
return TRUE;
}

/* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */

bool type_node::mangled_name (unsigned flags, char*& buf, int& length)
{
/* the mangled type name is placed in the buffer.  The length parameter is
   the size of buf.  flags are: 1- supply function return value
   This function places type information in the buffer after the base
   name.  */

static char typenames[]= {
   'v', //0
   'c', //1
   'i',  //2
   'l', //3
   'f',  //4
   'd', //5
   'r', //6
      'i',  //7  enum is coded as an int
   };
/* 
      'N', //8   followed by name
      'N', //9   union?  same as class, I guess.
   "pointer to ",  //10
   "reference to ",//11
   "array of ",    //12
   "function ",    //13
   };
*/

while (this) {
   if (isConst()) {
      *buf++ = 'C';
      if (!--length) return FALSE; }
   if (isVol()) {
      *buf++ = 'V';
      if (!--length) return FALSE; }
   if (isUnsigned()) {
      *buf++ = 'U';
      if (!--length) return FALSE; }
   switch (primary) {
      case type_pointer:
         *buf++ = (isNear() ? 'p' : 'P');
         if (!--length) return FALSE;
         break;
      case type_reference:
         *buf++ = 'R';
         if (!--length) return FALSE;
         break;
      case type_array:
         *buf++ = 'A';
         if (!--length) return FALSE;
         // > do array dimention
         break;
      case type_class:
      case type_union:
         if (tag > -1) {
            ins_number (strlen(atoms[tag]), buf, length);
            strappend (buf, atoms[tag], length);
            }
         break;
      case type_function:
         // >> different letters for different types.  use 'F' for now
         *buf++ = 'F';
         if (!--length) return FALSE;
         for (int loop= 0; loop < aggr->size(); loop++) {
            //append each parameter
            (*aggr)[loop]->type->mangled_name (1, buf, length);
            }
         if (flags & 1) {  //append function return type
            *buf++ = '_';
            if (!--length) return FALSE;
            }
         else {  //stop here.
            *buf= '\0';
            return TRUE;
            }
      default: // a simple type
         *buf++ = typenames[primary];
         if (!--length) return FALSE;
         break;
      }
   this= secondary();
   }
*buf= '\0';
return TRUE;
}

/* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
/*    def_node                              */
/* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */

def_node::def_node (atom n, int store, type_node* t)
{
flavor= nf_def;
name= n;
storage_class= store;
type=t;
flags= 0;
}

/* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */

void def_node::print()
{
static char* names[]= {"", "static ", "extern ", "typedef ", "auto ", "register ", "inline " };
cout << names[storage_class] << atoms[name] << " is ";
type->print();
}

/* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */

char* def_node::mangled_name()
{
static char static_buffer[256];
char* buf= static_buffer;
int length= 256;
strappend (buf, atoms[name], length);
strappend (buf, "__", length);
// >> append class name
type->mangled_name (0, buf, length);
return static_buffer;
}

/* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
/*   node list                              */
/* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */

node_list::node_list()
{
count= 0;
list= malloc ((capacity=8) * sizeof (node*));
}

/* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */

node** node_list::access (int x)
{
if (x >= capacity) {
   capacity += capacity/2;
   list= realloc (list, capacity * sizeof (node*));
   }
return list+x;
}

/* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
/* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
/* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -