Chinaunix首页 | 论坛 | 博客
  • 博客访问: 417505
  • 博文数量: 66
  • 博客积分: 1416
  • 博客等级: 上尉
  • 技术积分: 922
  • 用 户 组: 普通用户
  • 注册时间: 2006-09-16 10:37
个人简介

高級Oracle DBA,善長Linux系統維運以及Oracle數據庫管理,開發,調優. 具有多年PL/SQL開發經驗.

文章分类

全部博文(66)

文章存档

2015年(9)

2014年(4)

2013年(5)

2010年(1)

2009年(3)

2008年(6)

2007年(30)

2006年(8)

我的朋友

分类: C/C++

2007-09-17 15:47:09


在學習lex, yacc過程中,經常需要使用到符號表,用來存儲,訪問數據.
比較快捷的方法該是hash 表,
用數組也是可行的, 比較難以處理的是如何存儲名字,值.
不想多次使用malloc申請內存,構思了這樣一個方法.
先malloc一塊大內存, 然後自己管理內存,最後一次釋放.
核心就是使用sym_sbrk 實現自己的malloc函數.

void *sym_sbrk(struct sym_table_entry *s, int increment)


DEBUG_DUMP 是comm.h中的一個宏定義
#ifdef NODEBUG
#define DEBUG_DUMP(...)
#else
#define DEBUG_DUMP  trace
#endif


#define trace(...) (fprintf(stderr, "[%s %d %s] ", __FILE__, __LINE__, __func__), \
                fprintf(stderr, __VA_ARGS__), fflush(stderr))






代碼如下
sym.h
  1 #ifndef SYMBOL_TABLE_H_
  2 #define SYMBOL-TABLE_H_
  3
  4 #include
  5 #include
  6 #include
  7 #include "comm.h"
  8
  9
 10 enum sym_type {
 11   S_INT ,
 12   S_STR ,
 13   S_PTR ,
 14   S_FLOAT,
 15 } ;
 16
 17 struct   sym
 18 {
 19   int type;
 20   char *name;
 21   union {
 22     void *pdata ;
 23     int  idata ;
 24     float fdata;
 25   } ;
 26 } ;
 27
 28
 29 struct sym_table_entry
 30 {
 31     struct sym  *symlist ;
 32     int  sym_size ;
 33     int  idx ;
 34     char *sym_data ;
 35     char *lim ;
 36     char *end_data_segment  ;
 37 };
 38
 39 /*
 40     memory:   sym_table_entry | symlist | sym_data
 41
 42 */
 43
 44 struct sym_table_entry   *sym_table_alloc(int sym_size, int seg_size)
 45 {
 46          struct sym_table_entry *p;
 47          int asize  ;
 48          asize = sizeof(struct  sym) * sym_size  ;
 49
 50
 51          p = malloc(sizeof(struct sym_table_entry)+ asize + seg_size) ;
 52          p->sym_size   =  sym_size ;
 53
 54          p->symlist   =  (char *)p + sizeof(struct sym_table_entry) ;
 55          p->sym_data  =  (char *)p + sizeof(struct sym_table_entry)    + asize ;
 56
 57          p->end_data_segment    = p->sym_data ;
 58          p->idx    = 0;
 59          p->lim    =  p->sym_data + seg_size ;
 60
 61          return p;
 62 }
 63
 64 void sym_table_free(struct sym_table_entry  *p)
 65 {
 66          free(p) ;
 67 }
 68
 69
 70 void *sym_sbrk(struct sym_table_entry *s, int increment)
 71 {
 72          int m ;
 73          char *pos;
 74          if  ((s->lim - s->end_data_segment) < increment) {
 75
 76                  DEBUG_DUMP("%s\n", "sym_sbrk error");
 77                  return NULL ;
 78          }
 79
 80          pos = s-> end_data_segment ;
 81          s->end_data_segment  += increment ;
 82          return pos ;
 83 }
 84
 85 void *sym_xalloc(struct sym_table_entry *s, int size)
 86 {
 87          void *p ;
 88          p = sym_sbrk(s, size) ;
 89          if  (p == NULL) {
 90                  DEBUG_DUMP("%s\n", "alloc error");
 91                  exit(-1);
 92
 93          }
 94
 95          return p;
 96 }
 97
 98
 99 struct sym  *sym_find(struct sym_table_entry *s, const char *name)
100 {
101          int i;
102          struct sym *p;
103          for (i=0; i< s->idx; i++) {
104                  p =&(s->symlist[i]) ;
105                  if (strcmp(p->name, name) ==0) {
106                          return p;
107                  }
108
109          }
110          return NULL;
111 }
112
113 int sym_put(struct sym_table_entry *s, const char *name,  int type, void *data, int d_size)
114 {
115          int x, l;
116          struct sym *p;
117          int new = 0;
118
119          if  (s->idx >= s->sym_size) {
120                  fprintf(stderr, "%s\n", "symbol table is full");
121                  return -1;
122          }
123
124          p = sym_find(s, name) ;
125          if  (p  == NULL) {
126                  l = strlen(name) + 1 ;
127                  p = &(s->symlist[s->idx]) ;
128                  p->type = type;
129                  p->name = sym_xalloc(s, l);
130                  strcpy(p->name, name) ;
131                  new = 1;
132          } else if (p->type != type) {
133                  fprintf(stderr, "dismatch data type \n");
134                  exit(-1);
135          }
136
137
138          switch (type)  {
139          case  S_INT:
140                  p->idata = *(int *)data ;
141                  s->idx += new ;
142                  break ;
143          case  S_STR:
144                  p->pdata  = sym_xalloc(s, d_size +1) ;
145                  memcpy(p->pdata, data, d_size +1);
146                  s->idx += new ;
147                  break ;
148          case S_PTR:
149                  p->pdata = data ;
150                  s->idx += new ;
151                  break ;
152          case S_FLOAT:
153                  p->fdata = *(float *) data ;
154                  s->idx += new ;
155                  break ;
156          default:
157                  printf("error\n");
158                  exit(-1) ;
159          }
160
161          return 0;
162 }
163
164 #endif
165



做一個簡單的測試.

  1 #include
  2 #include "sym.h"
  3
  4 int test()
  5 {
  6          struct sym_table_entry *sym ;
  7          int x ;
  8          char *str ="hell world this is ";
  9          sym = sym_table_alloc(100,1024) ;
 10          x =3 ;
 11          sym_put(sym,"aaa", S_INT, &x, 4);
 12          sym_put(sym,"bbb", S_INT, &x, 4);
 13          sym_put(sym,"ccc", S_INT, &x, 4);
 14          sym_put(sym,"ccc", S_INT, &x, 4);
 15          sym_put(sym,"ee", S_STR, str, strlen(str));
 16          sym_put(sym,"ff", S_STR, str, strlen(str));
 17          printf("size:%d %s\n", sym->idx , sym_find(sym,"ff")->idata );
 18          sym_table_free(sym);
 19          return 0;
 20 }
 21
 22 int main(int argc, char *argv[])
 23 {
 24          test();
 25          exit(0);
 26 }

                                                                                                     
阅读(5885) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~