随笔分类 -  编译原理

摘要:0. 引言C++中的句法歧义主要由类似int (a)的代码引起,此类代码共有3种合法的结构解释: 第一种是声明符a两边具有冗余圆括号的对象声明,其等同于int a; 第二种是函数式转型,它是表达式的一种,其等同于(int) a; 第三种是函数类型标识符,其等同于int f(a b)。 既然一种代码可同时解释为声明、表达式和类型,根据排列组合,共可引发声明和表达式、声明和类型、表达式和类型之间的3类歧义,这3类歧义均无法通过句法消解。上述3类两两之间的歧义在C++中都存在对应的句法构造,所幸的是C++中不存在声明、表达式和类型都能同时存在的地方,否则将需要消解3个对象,而不是现在的2个。下面对3 阅读全文
posted @ 2008-02-10 23:31 Goncely 阅读(659) 评论(1) 推荐(0)
摘要:1、libcpp中和宏相关的基础知识libcpp是gcc的C/C++语言预处理器,gcc将C/C++语言预处理器cpp以库的形式独立出来,故取名曰libcpp。libcpp的输出为预处理标记cpp_token序列,为了实现回退机制、预处理指令处理和宏扩展,libcpp分三层输出预处理标记cpp_token序列:a)_cpp_lex_direct:这是预处理标记序列输出的第一层,它直接对程序文件进行词法分析,不处理任何预处理指令,也不提供回退功能,它反映的是真实的程序文本;b)cpp_lex_token:第二层在第一层的基础上实现了回退和预处理指令处理功能,调用这一层的用户看不到符合C/C++标 阅读全文
posted @ 2007-04-14 18:14 Goncely 阅读(531) 评论(0) 推荐(0)
摘要:1 调用接口cp_lexer_get_preprocessor_token: // in cp/ parser.c,C++分析器 => c_lex_with_flags => 标记C++关键字c_lex_with_flags: // in c-lex.c,C语言词法分析 => cpp_get_token // in cpplib => 过滤掉CPP_PADDING类型的标记 => 对各类型做进一步精化处理,构造tree结构2 内存接口 C和C++共用一个cpp_reader *parse_in接口(在c-common.c中定义,cp/decl2.c中有对其的外部声 阅读全文
posted @ 2006-11-14 22:50 Goncely 阅读(288) 评论(0) 推荐(0)
摘要:在gcc中,几乎所有的东西都是用树结构串起来的,从而形成抽象语法树。tree可以看作是指向树节点的指针,所有的树节点都有一个共同的基类:tree_common。在文件coretypes.h中,tree的定义如下:#ifndef USED_FOR_TARGET...typedef union tree_node *tree; ...#else...#define tree union _dont_use_tree_here_ *...#endif可见,当USED_FOR_TARGET宏未被定义的时候,tree是指向联合类型tree_node的指针类型;否则,tree是一个定义为union _do 阅读全文
posted @ 2006-11-14 22:46 Goncely 阅读(467) 评论(0) 推荐(0)
摘要:1、总论任何一个用C写的项目都是由若干文件构成,通常这些文件分为两大类:头文件和实现文件。头文件的后缀为.h,实现文件的后缀为.c。当然,也有一些文件是其他后缀,但这些文件通常也担当着头文件的角色(项目文件、配置文件及其它数据文件除外)。编译器的输入通常是实现文件,每一个实现文件对编译器来说是一个翻译单元,编译器将其翻译为目标代码,通常是一个obj文件。最后由链接器将所有的obj文件连成一个完整的可执行程序。2、头文件第一步,编译器首先对翻译单元进行预处理,包括对头文件和宏进行扩展。对头文件的扩展很简单,把include指令删除,然后把include指令所指定的头文件内容插入当前位置。这也就是 阅读全文
posted @ 2006-03-24 17:07 Goncely 阅读(242) 评论(0) 推荐(0)
摘要:无法根据左递归文法编写出递归下降分析器,因而把左递归文法等价变换为非左递归文法至关重要,以下是变换的算法:1、消除直接左递归原文法: E --> E a1 | E a2 | ... | E an | b1 | b2 | ... | bn消除后: E --> b1 E' | b2 E' | ... | bn E' E'--> a1 E' | a2 E' | ... | an E' | epsilon2、消除间接左递归a) 把所有非终结符号按一定序列排序为E1, E2, ... En;b) for i=1to ndo /*依 阅读全文
posted @ 2006-03-17 17:37 Goncely 阅读(549) 评论(0) 推荐(0)
摘要:对语言进行分类,有利用找出形式各样的语言中的共同特征,为语言设计提供指导。目前流行的形式语言大致可按如下方式分类。1 命令式语言主要的开发语言都是命令式语言,如C, C++, Java, Basic, Pascal。以此种语言编写的程序可以看成是一系列可执行的命令语句的集合,每一条命令语句等价于一个状态转换函数。命令式语言中的控制结构允许程序的流程或者是顺序的,或者是可选的,或者是迭代循环的。执行命令式语言的机器可以是计算机、解释器或者操作系统中的一个虚拟会话,每执行一条命令语句,机器通常变换到一个不同的状态。1.1 简单的命令式语言包括DOS中的批处理文件,数据库查询语言,表达式计算程序,命 阅读全文
posted @ 2006-01-16 09:54 Goncely 阅读(1164) 评论(0) 推荐(0)
摘要:编译器多使用: 词法分析->语法分析->中间代码生成->(代码优化)->目标代码生成的流程。 其中词法分析严重影响着编译器的性能,对词法分析的优化很必要。提高词法分析速度的一个主要途径是使用高效的缓冲管理机制。另一个主要的方面就是实现优化的匹配控制流程。 对于词法分析和语法分析有很多的代码自动生成工具,使用这些工具生成的代码据说速度也很快,一般初学者写出的词法分析和语法分析模块的速度很难超过工具生成的代码。据说GCC的词法分析和语法分析便是使用工具自动生成的。但也有不少牛人嫌工具生成的代码太大太慢,他们喜欢自己手动书写。 语法分析的结果通常是一棵语法树,语法树也是一种中 阅读全文
posted @ 2005-12-24 11:07 Goncely 阅读(168) 评论(0) 推荐(0)
摘要:对于文法G=(V, T, S, P),如果产生式的形式如下:A -> xBA -> x其中A, B属于V,x属于T*,则称为右线性文法;相似的,如果产生式的形式如下:A -> BxA -> x则称为左线性文法。右线性文法和左线性文法统称为正则文法。正则表达式的表达能力等价于正则文法,正则表达式的定义如下:字母表中的任意字母是正则表达式,空串和空集也是正则表达式;如果r, s是正则表达式,那么r|s, rs, r*, (r)也是正则表达式。正则表达式的扩展:r+:一个或多个重复. :任意字符[a-z]:字符范围[^abc]:不在给定集合中的任意字符r?:可选 正则表达式只 阅读全文
posted @ 2005-12-24 10:52 Goncely 阅读(2615) 评论(0) 推荐(0)
摘要:乔姆斯基文法体系共分为4类: 0型文法:也叫短语结构文法或无限制文法,其描述能力相当于图灵机,可使用任何的语法描述形式; 1型文法:也叫上下文有关文法,其描述能力相当于线性有界自动机,语法形式如下: xSy -> xAy 也就是说,S推导出A是和上下文x, y相关的,即S只有在上下文x, y的环境中才能推导出A; 2型文法:也叫上下文无关文法,其描述能力相当于下推自动机,语法形式如下: S -> A S可以无条件的推导出A,和上下文无关,上下文无关文法因此得名; 3型文法:也叫正则文法,等价于正则表达式,其描述能力相当于有穷自动机,语法形式如下: S -> Aa 其中最后一个 阅读全文
posted @ 2005-12-24 10:35 Goncely 阅读(633) 评论(0) 推荐(0)