lcc 源码读书笔记1之表达式解析

陆陆续续读可变目标C编译器一书很久了,很容易读了上段忘了下段。本着巩固学习的目的,写作此文。大家如果对编译器感兴趣可以购买此书http://www.china-pub.com/22711

表达式分析主要是把文本表示的表达式转换为一种计算机容易处理的结构,在LCC里边就是树结构。头文件C.H中包含了该结构的描述(所有需要用到的结构都包含在C.H中)

typedef struct tree *Tree;

struct tree {
 int op;              //操作符        
 Type type;       //相应表达式的返回类型
 Tree kids[2];
 Node node;       //用于建立DAG图
 union {
  Value v;
  Symbol sym;

  Field field;
 } u;            //联合用于处理不同类型的操作树
};

下面举一个左结合的表达式和右结合的表达式为例子

expression->assignment-expressionR; R->,assignment-expressionR || 0   //左结合

assignment-expression->condition-expression || unary-expression assign-operator assignment-expression  //右结合

左右结合最大的差别为左结合有继承属性,需要从前一个非终结符继承值,而右结合没有继承属性

下面是第一个表达式的c语言表达

Tree expr(int tok) {
 static char stop[] = { IF, ID, '}', 0 };
 Tree p = expr1(0);    //递归调用第二个表达式

 while (t == ',') {
  Tree q;
  t = gettok();
  q = pointer(expr1(0));             
  p = tree(RIGHT, q->type, root(value(p)), q);    //这儿体现了继承
 }
 if (tok) 
  test(tok, stop);   //错误恢复小模块
 return p;
}

第二个表达式的C语言表述

Tree expr1(int tok) {
 static char stop[] = { IF, ID, 0 };
 Tree p = expr2();

 if (t == '='
 || (prec[t] >=  6 && prec[t] <=  8)
 || (prec[t] >= 11 && prec[t] <= 13)) {
  int op = t;
  t = gettok();
  if (oper[op] == ASGN)
   p = asgntree(ASGN, p, value(expr1(0))); //包含了语义检测,这儿体现了右结合
  else
   {
    expect('=');
    p = incr(op, p, expr1(0));
   }
 }
 if (tok) 
  test(tok, stop);
 return p;
}

LCC的词法分析模块用宏定义设置了token的词性,xx(symbol, value, prec, op, optree, kind, string)

其中prec表示操作符的优先级,op表示该操作符的操作码,是一个枚举值,optree是每个操作符的建树函数,非常易于管理。

static char prec[] = {
#define xx(a,b,c,d,e,f,g) c,
#define yy(a,b,c,d,e,f,g) c,
#include "token.h"
};
static int oper[] = {
#define xx(a,b,c,d,e,f,g) d,
#define yy(a,b,c,d,e,f,g) d,
#include "token.h"
};

Tree (*optree[])(int, Tree, Tree) = {
#define xx(a,b,c,d,e,f,g) e,
#define yy(a,b,c,d,e,f,g) e,
#include "token.h"
};

没想到宏还能这么用,呵呵 :). 表达式的分析就写到这儿,一元,二元表达式都大同小异,有兴趣的朋友可以自己研究

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值