现在的位置: 首页 > 综合 > 正文

lcc 源代码解析之token.h

2016年08月24日 ⁄ 综合 ⁄ 共 4942字 ⁄ 字号 评论关闭

元旦憋了两天,终究是没能透彻的理解表达式的语法分析,关于这部分等我自己搞明白再分享出来,

又要开工了,每天只有有限的时间区分析代码,再加上还要抽空看看面试题,估计要费一段时间了。

先分享一道小菜,即头文件token.h,这是一个十分重要的头文件,用的也很奇妙,当然,这损失了代码的部分可读性。

/* $Id: token.h,v 1.1 2002/08/28 23:12:47 drh Exp $ */
/*
xx(symbol,	value,	prec,	op,	optree,	kind,	string)
(枚举标示符,  字符值,  单词操作符的优先顺序,  通用操作符,  创建树的函数,  单词集合,  字符串表示)
yy处理单字符单词,xx处理多字符单词和其他
*/
yy(0,         0,     0,      0,    0,      0,      0)
xx(FLOAT,     1,     0,      0,    0,      CHAR,   "float")
xx(DOUBLE,    2,     0,      0,    0,      CHAR,   "double")
xx(CHAR,      3,     0,      0,    0,      CHAR,   "char")
xx(SHORT,     4,     0,      0,    0,      CHAR,   "short")
xx(INT,       5,     0,      0,    0,      CHAR,   "int")
xx(UNSIGNED,  6,     0,      0,    0,      CHAR,   "unsigned")
xx(POINTER,   7,     0,      0,    0,      0,      "pointer")
xx(VOID,      8,     0,      0,    0,      CHAR,   "void")
xx(STRUCT,    9,     0,      0,    0,      CHAR,   "struct")
xx(UNION,    10,     0,      0,    0,      CHAR,   "union")
xx(FUNCTION, 11,     0,      0,    0,      0,      "function")
xx(ARRAY,    12,     0,      0,    0,      0,      "array")
xx(ENUM,     13,     0,      0,    0,      CHAR,   "enum")
xx(LONG,     14,     0,      0,    0,      CHAR,   "long")
xx(CONST,    15,     0,      0,    0,      CHAR,   "const")
xx(VOLATILE, 16,     0,      0,    0,      CHAR,   "volatile")
yy(0,        17,     0,      0,    0,      0,      0)
yy(0,        18,     0,      0,    0,      0,      0)
yy(0,        19,     0,      0,    0,      0,      0)
yy(0,        20,     0,      0,    0,      0,      0)
yy(0,        21,     0,      0,    0,      0,      0)
yy(0,        22,     0,      0,    0,      0,      0)
yy(0,        23,     0,      0,    0,      0,      0)
yy(0,        24,     0,      0,    0,      0,      0)
yy(0,        25,     0,      0,    0,      0,      0)
yy(0,        26,     0,      0,    0,      0,      0)
yy(0,        27,     0,      0,    0,      0,      0)
yy(0,        28,     0,      0,    0,      0,      "long long")
yy(0,        29,     0,      0,    0,      0,      0)
yy(0,        30,     0,      0,    0,      0,      0)
yy(0,        31,     0,      0,    0,      0,      "const volatile")
xx(ID,       32,     0,      0,    0,      ID,     "identifier")
yy(0,        33,     0,      0,    0,      ID,     "!")
xx(FCON,     34,     0,      0,    0,      ID,     "floating constant")
xx(ICON,     35,     0,      0,    0,      ID,     "integer constant")
xx(SCON,     36,     0,      0,    0,      ID,     "string constant")
yy(0,        37,     13,     MOD,  bittree,'%',    "%")
yy(0,        38,     8,      BAND, bittree,ID,     "&")
xx(INCR,     39,     0,      ADD,  addtree,ID,     "++")
yy(0,        40,     0,      0,    0,      ID,     "(")
yy(0,        41,     0,      0,    0,      ')',    ")")
yy(0,        42,     13,     MUL,  multree,ID,     "*")
yy(0,        43,     12,     ADD,  addtree,ID,     "+")
yy(0,        44,     1,      0,    0,      ',',    ",")
yy(0,        45,     12,     SUB,  subtree,ID,     "-")
yy(0,        46,     0,      0,    0,      '.',    ".")
yy(0,        47,     13,     DIV,  multree,'/',    "/")
xx(DECR,     48,     0,      SUB,  subtree,ID,     "--")
xx(DEREF,    49,     0,      0,    0,      DEREF,  "->")
xx(ANDAND,   50,     5,      AND,  andtree,ANDAND, "&&")
xx(OROR,     51,     4,      OR,   andtree,OROR,   "||")
xx(LEQ,      52,     10,     LE,   cmptree,LEQ,    "<=")
xx(EQL,         53,     9,      EQ,     eqtree, EQL,    "==")
xx(NEQ,         54,     9,      NE,     eqtree, NEQ,    "!=")
xx(GEQ,         55,     10,     GE,     cmptree,GEQ,    ">=")
xx(RSHIFT,      56,     11,     RSH,    shtree, RSHIFT, ">>")
xx(LSHIFT,      57,     11,     LSH,    shtree, LSHIFT, "<<")
yy(0,           58,     0,      0,      0,      ':',    ":")
yy(0,           59,     0,      0,      0,      IF,     ";")
yy(0,           60,     10,     LT,     cmptree,'<',    "<")
yy(0,           61,     2,      ASGN,   asgntree,'=',   "=")
yy(0,           62,     10,     GT,     cmptree,'>',    ">")
yy(0,           63,     0,      0,      0,      '?',    "?")
xx(ELLIPSIS,    64,     0,      0,      0,      ELLIPSIS,"...")
xx(SIZEOF,      65,     0,      0,      0,      ID,     "sizeof")
yy(0,           66,     0,      0,      0,      0,      0)
xx(AUTO,        67,     0,      0,      0,      STATIC, "auto")
xx(BREAK,       68,     0,      0,      0,      IF,     "break")
xx(CASE,        69,     0,      0,      0,      IF,     "case")
xx(CONTINUE,    70,     0,      0,      0,      IF,     "continue")
xx(DEFAULT,     71,     0,      0,      0,      IF,     "default")
xx(DO,          72,     0,      0,      0,      IF,     "do")
xx(ELSE,        73,     0,      0,      0,      IF,     "else")
xx(EXTERN,      74,     0,      0,      0,      STATIC, "extern")
xx(FOR,         75,     0,      0,      0,      IF,     "for")
xx(GOTO,        76,     0,      0,      0,      IF,     "goto")
xx(IF,          77,     0,      0,      0,      IF,     "if")
xx(REGISTER,    78,     0,      0,      0,      STATIC, "register")
xx(RETURN,      79,     0,      0,      0,      IF,     "return")
xx(SIGNED,      80,     0,      0,      0,      CHAR,   "signed")
xx(STATIC,      81,     0,      0,      0,      STATIC, "static")
xx(SWITCH,      82,     0,      0,      0,      IF,     "switch")
xx(TYPEDEF,     83,     0,      0,      0,      STATIC, "typedef")
xx(WHILE,       84,     0,      0,      0,      IF,     "while")
xx(TYPECODE,    85,     0,      0,      0,      ID,     "__typecode")
xx(FIRSTARG,    86,     0,      0,      0,      ID,     "__firstarg")
yy(0,           87,     0,      0,      0,      0,      0)
yy(0,           88,     0,      0,      0,      0,      0)
yy(0,           89,     0,      0,      0,      0,      0)
yy(0,           90,     0,      0,      0,      0,      0)
yy(0,           91,     0,      0,      0,      '[',    "[")
yy(0,           92,     0,      0,      0,      0,      0)
yy(0,           93,     0,      0,      0,      ']',    "]")
yy(0,           94,     7,      BXOR,   bittree,'^',    "^")
yy(0,           95,     0,      0,      0,      0,      0)
yy(0,           96,     0,      0,      0,      0,      0)
yy(0,           97,     0,      0,      0,      0,      0)
yy(0,           98,     0,      0,      0,      0,      0)
yy(0,           99,     0,      0,      0,      0,      0)
yy(0,           100,    0,      0,      0,      0,      0)
yy(0,           101,    0,      0,      0,      0,      0)
yy(0,           102,    0,      0,      0,      0,      0)
yy(0,           103,    0,      0,      0,      0,      0)
yy(0,           104,    0,      0,      0,      0,      0)
yy(0,           105,    0,      0,      0,      0,      0)
yy(0,           106,    0,      0,      0,      0,      0)
yy(0,           107,    0,      0,      0,      0,      0)
yy(0,           108,    0,      0,      0,      0,      0)
yy(0,           109,    0,      0,      0,      0,      0)
yy(0,           110,    0,      0,      0,      0,      0)
yy(0,           111,    0,      0,      0,      0,      0)
yy(0,           112,    0,      0,      0,      0,      0)
yy(0,           113,    0,      0,      0,      0,      0)
yy(0,           114,    0,      0,      0,      0,      0)
yy(0,           115,    0,      0,      0,      0,      0)
yy(0,           116,    0,      0,      0,      0,      0)
yy(0,           117,    0,      0,      0,      0,      0)
yy(0,           118,    0,      0,      0,      0,      0)
yy(0,           119,    0,      0,      0,      0,      0)
yy(0,           120,    0,      0,      0,      0,      0)
yy(0,           121,    0,      0,      0,      0,      0)
yy(0,           122,    0,      0,      0,      0,      0)
yy(0,           123,    0,      0,      0,      IF,     "{")
yy(0,           124,    6,      BOR,    bittree,'|',    "|")
yy(0,           125,    0,      0,      0,      '}',    "}")
yy(0,           126,    0,      BCOM,   0,      ID,     "~")
xx(EOI,         127,    0,      0,      0,      EOI,    "end of input")
#undef xx
#undef yy

从上面的头文件中可以看出,这是个类似表的结构,按照列的不同处理不同的部分,

下面来看一下使用的部分,这六个数据结构需要比较熟悉,不然会对代码的理解产生干扰

//使用地:c.h
//作用:声明操作符枚举,使用了表的第一二两列
enum {
#define xx(a,b,c,d,e,f,g) a=b,
#define yy(a,b,c,d,e,f,g)
#include "token.h"
}
//预处理之后就变成了下面的样子,
//建议将这个表处理成以下这个形式,便于代码阅读
enum {
	FLOAT = 1,   
	DOUBLE = 2,
	CHAR = 3,
	SHORT = 4,
	INT = 5,
	UNSIGNED = 6,
	POINTER = 7,
	VOID = 8,
	STRUCT = 9,
	UNION = 10,  
	FUNCTION = 11,  
	ARRAY = 12, 
	ENUM = 13,  
	LONG = 14, 
	CONST = 15, 
	VOLATILE = 16, 
	ID = 32,
	FCON = 34,
	ICON = 35, 
	SCON = 36,
	INCR = 39,
	DECR = 48,
	DEREF = 49,
	ANDAND = 50,
	OROR = 51,
	LEQ = 52,
	EQL = 53,
	NEQ = 54,
	GEQ = 55,
	RSHIFT = 56,
	LSHIFT = 57,
	ELLIPSIS = 64,
	SIZEOF = 65,
	AUTO = 67,
	BREAK = 68,
	CASE = 69,
	CONTINUE = 70,
	DEFAULT = 71,
	DO = 72,
	ELSE = 73,
	EXTERN = 74,
	FOR = 75,
	GOTO = 76,
	IF = 77,
	REGISTER = 78,
	RETURN = 79,
	SIGNED = 80,
	STATIC = 81,
	SWITCH = 82,
	TYPEDEF = 83,
	WHILE = 84,
	TYPECODE = 85,
	FIRSTARG = 86,
	EOI = 127,
	LAST
};

//使用地:enode.c
//作用:创建“创建树的函数指针的数组”,即表中的倒数第三列
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"
};

//使用地:error.c
//作用:创建单词集合数组,倒数第二列
char kind[] = {
#define xx(a,b,c,d,e,f,g) f,
#define yy(a,b,c,d,e,f,g) f,
#include "token.h"
};

//使用地:expr.c
//作用:创建操作符的优先级数组
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"
};

//使用地:output.c
//作用:创建词素的字符串数组
static char *tokens[] = {
#define xx(a,b,c,d,e,f,g) g,
#define yy(a,b,c,d,e,f,g) g,
#include "token.h"
};

抱歉!评论已关闭.