C语法归约之变量声明和定义(0)

本文深入探讨C语言C99规范下的语法归约,通过实例分析了基本全局变量、结构联合枚举类型的声明和定义以及初始化过程,揭示C语言的编译秘密。
摘要由CSDN通过智能技术生成

0前言

闲来无事,在屋里多看了一眼《编译原理》(2V),有练练手的冲动——采用LR(1)技术,写了一个C语言的语法归约器!之所以用LR(1)是因为gcc,ucc,tcc和lcc跟商量好似的,清一色的用的LL归约技术,书上也是讲的跟天花一样漂亮,那么就说明它已经十分成熟了,如果再使用LL技术实在是炸不出价值来,源码一抓一大把,看看就够了,重写必要性不大!另外,书中的LR技术讲的项集又是大的没谱,工作量太大;如果使用工具yacc生成,又不知道它咋搞的猫腻,所以就没有踩它们的脚印,自己整套方法high起来^!^!至于后期要不要增加编译的其他部分,再说。现在用它来拉拉风!顺便解释下C语言真正机密——归约!

1、C语言C99文法树

C99文法树图,这是C99标准文法,画成图了,方便查阅,便于理解。其中实线是归约方向,虚线箭头不是归约指向,是箭头指向的产生式中此非终结符的产生式,实线箭头相连两头构成一个产生式!(注:图较大,显示太小,请自行右键图片另存为下载该图片查阅或者干脆查看C99文法,都中)
值得提醒一点的是,单纯从文法上讲,它不是树,更准确的说是图,但为了方便理解,中间交织的内容就没有连接,从而看上去还像一颗树
a、表达式(注,为了便于理解运算符优先级,这部分化成了圈)

b、声明,定义,初始化,抽象类型部分(注,图中有opt的,则表示前面的非终结符可选)


c、语句部分(注,图中有opt的,则表示前面的非终结符可选,鉴于图片大小分布,没有展开)

d、外部定义

e、合成总图(几部分的连接不是绝对的对应,比如expression在多处出现,我只是简单链接一条示意了一下,不要钻牛尖哦)

2、实例探究

如果你没有C语言基础,请按照下面步骤执行,一移动鼠标到浏览器的X,二点击关闭,over,(*^__^*) !如果你是初学者,可能会有点好处;前提是下文你得看得懂!如果你是个码农,可能你会看到之前你没有看到的C的另一层面!如果你是个高级工程师且懂得编译,那么你也按照上面两步走或者高手ALT-F4即可!
阅读说明:(对读懂很重要)
0-仅归约过程,无符号表处理,因此不检查ID的冲突和不对typedef的类型归约
1-归约过程输出的是归约栈的整个栈当前状态
2-连续的栈输出,表示curr的多次归约
3-栈顶非终结符是从上步归约而来
     比如:
     declaration-specifiers direct-declarator 
     declaration-specifiers declarator
     其中declarator是从direct-declarator归约而来
     再比如:
     declaration-list type-specifier declaration-specifiers 
     declaration-list declaration-specifiers 
     其中declaration-specifiers是由type-specifier declaration-specifiers 归约而来,等等
4-curr输出当前归约的终结符,next是预取下一个要归约的终结符
5-如果curr输出是ID,STR,CONSTANT,则它的真实值是前面的next输出.比如下面的curr: ID, next ; 那么这个ID就是右上vali
6-要结合上面的文法图或者C99标准来解读
7-任何无语法错误的源程序都要归约成一棵树!根结点就是translation-unit

话说千言万语不如一个好例子。当然不可能在这里穷举所有相关语法的实例,而只在常用重点上举几个例子!看看 C语言是怎么被解析的!
2.1、基本全局变量
示例代码
int vali;
char valc;
short vals;
long vall;
unsigned int valui;
signed int valsi;
/*其余float double double float 
  unsigned char, signed char, unsigned short, signed short
  unsigned long, signed long都一样的归约过程,不多余举例*/
归约树
curr: int  next: vali  
type-specifier 
declaration-specifiers 

curr: ID  next: ;  
declaration-specifiers direct-declarator 
declaration-specifiers declarator 
declaration-specifiers init-declarator 
declaration-specifiers init-declarator-list 

curr: ;  next: char  
declaration 
declaration-list 
//归约char valc;
curr: char  next: valc  
declaration-list type-specifier 
declaration-list declaration-specifiers 

curr: ID  next: ;  
declaration-list declaration-specifiers direct-declarator 
declaration-list declaration-specifiers declarator 
declaration-list declaration-specifiers init-declarator 
declaration-list declaration-specifiers init-declarator-list 

curr: ;  next: short  
declaration-list declaration 
declaration-list 
//归约short vals;
curr: short  next: vals  
declaration-list type-specifier 
declaration-list declaration-specifiers 

curr: ID  next: ;  
declaration-list declaration-specifiers direct-declarator 
declaration-list declaration-specifiers declarator 
declaration-list declaration-specifiers init-declarator 
declaration-list declaration-specifiers init-declarator-list 

curr: ;  next: long  
declaration-list declaration 
declaration-list 
//归约long vall;
curr: long  next: vall  
declaration-list type-specifier 
declaration-list declaration-specifiers 

curr: ID  next: ;  
declaration-list declaration-specifiers direct-declarator 
declaration-list declaration-specifiers declarator 
declaration-list declaration-specifiers init-declarator 
declaration-list declaration-specifiers init-declarator-list 

curr: ;  next: unsigned  
declaration-list declaration 
declaration-list 
//归约unsigned int valui;
curr: unsigned  next: int  
declaration-list type-specifier 

curr: int  next: valui  
declaration-list type-specifier type-specifier 
declaration-list type-specifier declaration-specifiers 
declaration-list declaration-specifiers 

curr: ID  next: ;  
declaration-list declaration-specifiers direct-declarator 
declaration-list declaration-specifiers declarator 
declaration-list declaration-specifiers init-declarator 
declaration-list declaration-specifiers init-declarator-list 

curr: ;  next: signed  
declaration-list declaration 
declaration-list 
//归约signed int valsi;
curr: signed  next: int  
declaration-list type-specifier 

curr: int  next: valsi  
declaration-list type-specifier type-specifier 
declaration-list type-specifier declaration-specifiers 
declaration-list declaration-specifiers 

curr: ID  next: ;  
declaration-list declaration-specifiers direct-declarator 
declaration-list declaration-specifiers declarator 
declaration-list declaration-specifiers init-declarator 
declaration-list declaration-specifiers init-declarator-list 

curr: ;  next: NULL  
declaration-list declaration 
declaration-list 
translation-unit //完成
提示
int vali;归约过程为例子

int->type-specifier->declaration-specifiers(1)
ID->direct-declarator->declarator->init-declarator->init-declarator-list (2)
(1)和(2)->declaration.
由于下面还有变量的定义,因此
declaration->declaration-list


上面其他变量的归约过程基本一样,不多解释!
从语法来讲,void, char, short, int, long, float, double, unsigned, signed,可以任意组合N长的类型说明符,比如long long long long int unsigned char short,这8个当成一个类型也是能正确归约的。当然它没有意义!有没有意义这是类型检测的工作,属于后话,先不说!

2.2、结构联合枚举类型声明和定义
示例代码
struct AA;
union BB;
enum CC;

struct girl {
	int ga, gb, gc;
};

struct boy {
	struct girl bl;
};

struct woman {
	union inner {
		struct girl gg;
		struct boy bb;
	}sex;
};

union type{
	int vali;
	char ch;
	long vall;
};

enum tag{
	FIRST,
	FOLLOW,
	LAST,
	TEST
};
归约树

curr: struct  next: AA  

curr: ID  next: ;  
struct-specifier 
type-specifier 
declaration-specifiers 

curr: ;  next: union  
declaration 
declaration-list 
//归约union BB;
curr: union  next: BB  

curr: ID  next: ;  
declaration-list union-specifier 
declaration-list type-specifier 
declaration-list declaration-specifiers 

curr: ;  next: enum  
declaration-list declaration 
declaration-list 
//归约enum CC;
curr: enum  next: CC  

curr: ID  next: ;  
declaration-list enum-specifier 
declaration-list type-specifier 
declaration-list declaration-specifiers 

curr: ;  next: struct  
declaration-list declaration 
declaration-list 
/*归约struct girl {
int ga, gb, gc;
};*/
curr: struct  next: girl  

curr: ID  next: {  

curr: {  next: int  

curr: int  next: ga  
declaration-list struct ID { type-specifier 
declaration-list struct ID { specifier-qualifier-list 

curr: ID  next: ,  
declaration-list struct ID { specifier-qualifier-list direct-declarator 
declaration-list struct ID { specifier-qualifier-list declarator 
declaration-list struct ID { specifier-qualifier-list struct-declarator-list 

curr: ,  next: gb  

curr: ID  next: ,  
declaration-list struct ID { specifier-qualifier-list struct-declarator-list , direct-declarator 
declaration-list struct ID { specifier-qualifier-list struct-declarator-list , declarator 
declaration-list struct ID { specifier-qualifier-list struct-declarator-list 

curr: ,  next: gc  

curr: ID  next: ;  
declaration-list struct ID { specifier-qualifier-list struct-declarator-list , direct-declarator 
declaration-list struct ID { specifier-qualifier-list struct-declarator-list , declarator 
declaration-list struct ID { specifier-qualifier-list struct-declarator-list 

curr: ;  next: }  
declaration-list struct ID { struct-declaration 
declaration-list struct ID { struct-declaration-list 

curr: }  next: ;  
declaration-list struct-specifier 
declaration-list type-specifier 
declaration-list declaration-specifiers 

curr: ;  next: struct  
declaration-list declaration 
declaration-list 
/*归约struct boy {
struct girl bl;
};*/
curr: struct  next: boy  

curr: ID  next: {  

curr: {  next: struct  

curr: struct  next: girl  

curr: bl  next: ID  
declaration-list struct ID { struct-specifier 
declaration-list struct ID { type-specifier 
declaration-list struct ID { specifier-qualifier-list 

curr: ID  next: ;  
declaration-list struct ID { specifier-qualifier-list direct-declarator 
declaration-list struct ID { specifier-qualifier-list declarator 
declaration-list struct ID { specifier-qualifier-list struct-declarator-list 

curr: ;  next: }  
declaration-list struct ID { struct-declaration 
declaration-list struct ID { struct-declaration-list 

curr: }  next: ;  
declaration-list struct-specifier 
declaration-list type-specifier 
declaration-list declaration-specifiers 

curr: ;  next: struct  
declaration-list declaration 
declaration-list 
/*归约struct woman {
union inner {
struct girl gg;
struct boy bb;
}sex;
};*/
curr: struct  next: woman  

curr: ID  next: {  

curr: {  next: union  

curr: union  next: inner  

curr: ID  next: {  

curr: {  next: struct  

curr: struct  next: girl  

curr: gg  next: ID  
declaration-list struct ID { union ID { struct-specifier 
declaration-list struct ID { union ID { type-specifier 
declaration-list struct ID { union ID { specifier-qualifier-list 

curr: ID  next: ;  
declaration-list struct ID { union ID { specifier-qualifier-list direct-declarator 
declaration-list struct ID { union ID { specifier-qualifier-list declarator 
declaration-list struct ID { union ID { specifier-qualifier-list struct-declarator-list 

curr: ;  next: struct  
declaration-list struct ID { union ID { struct-declaration 
declaration-list struct ID { union ID { struct-declaration-list 

curr: struct  next: boy  

curr: bb  next: ID  
declaration-list struct ID { union ID { struct-declaration-list struct-specifier 
declaration-list struct ID { union ID { struct-declaration-list type-specifier 
declaration-list struct ID { union ID { struct-declaration-list specifier-qualifier-list 

curr: ID  next: ;  
declaration-list struct ID { union ID { struct-declaration-list specifier-qualifier-list direct-declarator 
declaration-list struct ID { union ID { struct-declaration-list specifier-qualifier-list declarator 
declaration-list struct ID { union ID { struct-declaration-list specifier-qualifier-list struct-declarator-list 

curr: ;  next: }  
declaration-list struct ID { union ID { struct-declaration-list struct-declaration 
declaration-list struct ID { union ID { struct-declaration-list 

curr: }  next: sex  
declaration-list struct ID { union-specifier 
declaration-list struct ID { type-specifier 
declaration-list struct ID { specifier-qualifier-list 

curr: ID  next: ;  
declaration-list struct ID { specifier-qualifier-list direct-declarator 
declaration-list struct ID { specifier-qualifier-list declarator 
declaration-list struct ID { specifier-qualifier-list struct-declarator-list 

curr: ;  next: }  
declaration-list struct ID { struct-declaration 
declaration-list struct ID { struct-declaration-list 

curr: }  next: ;  
declaration-list struct-specifier 
declaration-list type-specifier 
declaration-list declaration-specifiers 

curr: ;  next: union  
declaration-list declaration 
declaration-list 
/*归约union type{
int vali;
char ch;
long vall;
};*/
curr: union  next: type  

curr: ID  next: {  

curr: {  next: int  

curr: int  next: vali  
declaration-list union ID { type-specifier 
declaration-list union ID { specifier-qualifier-list 

curr: ID  next: ;  
declaration-list union ID { specifier-qualifier-list direct-declarator 
declaration-list union ID { specifier-qualifier-list declarator 
declaration-list union ID { specifier-qualifier-list struct-declarator-list 

curr: ;  next: char  
declaration-list union ID { struct-declaration 
declaration-list union ID { struct-declaration-list 

curr: char  next: ch  
declaration-list union ID { struct-declaration-list type-specifier 
declaration-list union ID { struct-declaration-list specifier-qualifier-list 

curr: ID  next: ;  
declaration-list union ID { struct-declaration-list specifier-qualifier-list direct-de
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值