LCC编译器的源程序分析(14)结构类型的声明

来源:互联网 发布:黑客免杀攻防python 编辑:程序博客网 时间:2024/05/04 14:11
以前都是简单类型的识别和语法分析,现在来分析结构的声明,它是比较复杂的一种数据类型,但结构在编写程序中使用是非常多的。由于程序的方程式就是:
数据结构算法程序
现在面向对象的方程式是:
数据结构算法对象
对象对象程序
由上面的公式,就可以看出程序中的数据结构是非常重要的,无论是面向对象的编程,还是面向过程的编程,有什么样的数据结构,就需要有什么样算法。而在C语言里,使用结构类型来描述现实中需要的抽象模型。例子里的结构声明如下:
struct _iobuf {
 char *_ptr;
 int   _cnt;
 char *_base;
 int   _flag;
 int   _file;
 int   _charbuf;
 int   _bufsiz;
 char *_tmpfname;
 };
typedef struct _iobuf FILE;
这是声明一个文件对象结构。现在就来分析一下LCC编译器是怎么样进行结构的语法分析的。先用调函数decl(dclglobal),然后调用函数specifier,在函数specifier就会处理结构的声明,它的代码如下:
#001 static void decl(Symbol (*dcl)(int, char *, Type, Coordinate *))
#002 {
#003  int sclass;
#004  Type ty, ty1;
#074         case STRUCT:
#075         case UNION:   
#076               p = &type;
#077               ty = structdcl(t);
#078               break;
上面结构定义和联合的识别,这也是比较复杂的类型,所以也调用structdcl来进一步处理结构体。为了仔细地了解结构的语法分析,就需要分析函数structdcl的代码,如下:
#001 //结构声明处理。
#002 static Type structdcl(int op)
#003 {
#004  char *tag;
#005  Type ty;
#006  Symbol p;
#007  Coordinate pos;
#008 
#009  t = gettok();
#010  pos = src;
#011  if (t == ID)
#012  {
#013         tag = token;
#014         t = gettok();
#015  }
#016  else
#017         tag = "";
#018 
#019  //结构的定义开始。
#020  if (t == '{')
#021  {
#022         static char stop[] = { IF, ',', 0 };
#023         ty = newstruct(op, tag);
#024         ty->u.sym->src = pos;
#025         ty->u.sym->defined = 1;
#026 
#027         t = gettok();
#028         if (istypename(t, tsym))
#029         {
#030               //结构成员定义。
#031               fields(ty);
#032         }   
#033         else
#034         {
#035               error("invalid %k field declarations/n", op);
#036         }   
#037 
#038         test('}', stop);
#039  }
#040  else if (*tag && (p = lookup(tag, types)) != NULL
#041         && p->type->op == op)
#042  {
#043         ty = p->type;
#044         if (t == ';' && p->scope < level)
#045               ty = newstruct(op, tag);
#046  }
#047  else
#048  {
#049         if (*tag == 0)
#050               error("missing %k tag/n", op);
#051         ty = newstruct(op, tag);
#052  }
#053 
#054  if (*tag && xref)
#055         use(ty->u.sym, pos);
#056 
#057  return ty;
#058 }
处理struct之后,接着就要处理结构的名称,在这个例子里是_iobuf,它是在第9行里获取到这个记号,然后在第11行里保存_iobuf到变量tag里。tag也有可能是空的情况,比如像下面的语法:
typedef struct  { int a; } A;
上面的语法就是在第17行里处理这种情况的。
在第20行到39行里,主要处理结构字段定义。像结构_iobuf中的定义,就是处理下面的语句:
{
 char *_ptr;
 int   _cnt;
 char *_base;
 int   _flag;
 int   _file;
 int   _charbuf;
 int   _bufsiz;
 char *_tmpfname;
 }
在第23行里创建结构的类型ty,然后在第28行里判断语句是否类型开始的记号,如果不是就是出错的定义。如果是类型,比如像例子里的char,就需要调用函数fields(ty)来处理所有的字段定义。
接着下来就需要去分析fields的代码,下一次再带你去分析它吧。 
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 华为sd卡不可用怎么办 u盘延缓写入失败怎么办 手机提示sd卡不可用怎么办 显示sd卡不可用怎么办 小米手机检测不到sd卡怎么办 小米手机sd卡写入失败怎么办 没有检测到sd卡怎么办 e站图片配额用尽怎么办 内存卡密码忘了怎么办 电脑上酷狗音乐播放失败怎么办 播放失败不支持该文件怎么办 手机山寨云资源失效怎么办 支付密码输错了怎么办 微信密码锁定了怎么办 电脑网易云音乐闪退怎么办 逆战耳机电流声怎么办 肠道感染一直吃药治不好怎么办 如果24小时以后还没到账该怎么办 在游戏平台充值没到账该怎么办 充值豪华黄钻没到账该怎么办 起点签到签满了怎么办 ipad锁屏声音小怎么办 扣扣邮箱文件超大了怎么办 网易邮箱图片已过期怎么办 邮箱里面的文件过期了怎么办 邮箱发的文件过期了怎么办 邮箱发送的文件过期怎么办 小米4s开不开机怎么办 小米平板关机后开不开机怎么办 公司老板跑路了社保怎么办 公司老板跑路社保怎么办 公司被公安局查封社保怎么办 小米四开不了机怎么办 小米的手机后壳裂了怎么办 公司没钱拖欠员工社保怎么办 小米note充不进去电怎么办 公司欠社保没交怎么办 公司不给转社保怎么办 小米note充电特别慢怎么办 小米小米note2充电慢怎么办 小米note充电红灯不闪烁怎么办