南开大学编译原理第二章课件_第1页
南开大学编译原理第二章课件_第2页
南开大学编译原理第二章课件_第3页
南开大学编译原理第二章课件_第4页
南开大学编译原理第二章课件_第5页
已阅读5页,还剩104页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、1第二章 一个简单的编译器2学习内容m构造一个以语法分析器为核心的编译器将中缀表达式转换为后缀表示形式m利用上下文无关文法描述源语言的语法结构m利用语法制导翻译方法进行表达式转换m构造预测分析器,进行语法分析,并同时进行语法制导翻译3学习内容(续)m构造更复杂的词法分析器消除单字符单词的限制,支持变量m符号表的简单实现方法42.1 概述m语法描述上下文无关文法上下文无关文法,context-free grammar巴科斯巴科斯-瑙尔范式瑙尔范式,Backus-Naur Form,BNFm语义描述:非形式化描述m辅助代码生成:语法制导翻译语法制导翻译,syntax-directed transl

2、ation5构造一个简单的编译器m目标:表达式中缀表示后缀表示9-5+295-2+m过程:m语法制导翻译器:语法分析中间代码生成62.2 语法定义m上下文无关文法:描述语言的语法结构mif (expression) statement else statement对应的文法规则stmtif ( expr ) stmt else stmtm产生式产生式,productionmif, else单词,终结符号,terminalmexpr, stmt单词序列,非终结符号,nonterminal具有形式为具有形式为可可7上下文无关文法m四个部分组成m一组终结符号终结符号,单词,基本符号m一组非终结符号非

3、终结符号(语法变量),语法范畴,语法概念m一组产生式产生式,定义语法范畴产生式:AA一个非终结符,左部左部终结符或/与非终结符串,右部右部1.一个特定的非终结符开始符号开始符号,start symbol8形式化定义m几个概念m:有穷字母表字母表,元素符号m符号串符号串:中符号构成的有穷序列m空字空字:不含任何符号的序列,m*:符号串全体,包括空字m:空集,区分,m*的子集U、V的积积(连接连接)|VUUV且9几个概念(续)mUVVU,(UV)W=U(VW)mV自身的n次积(连接)记为VnmV0=mV的闭包闭包(closure)每个符号串,都是V中符号串有限次连接m正则闭包正则闭包,V+=VV*

4、3210*VVVVV10四元式定义上下文无法文法m(VT, VN, S, P)mVT:非空有限集,终结符号集合mVN:非空有限集,非终结符号集合mS:开始符号mP :产生式集合(有限集)每个产生式形式A,其中关于A的产生式S至少在某个产生式左部出现一次*)(,NTNVVVA11例2.1 符号约定 expr expr + digitexpr expr digitexpr digitdigit 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9m数字、运算符、黑体字符串黑体字符串终结符m斜体字符串非终结符m左部相同可合并,|“或”的意思expr expr + digit |

5、 expr - digit | digit 候选式候选式12产生式设计练习m首先是“人会做”q我们自己先把语法概念“什么模样”搞清楚m然后是“让计算机会做”符号化q为这个语法概念起个名字,“模样”中的其他语法概念、单词也都有相应的名字q将语法概念放在产生式左部“模样”放在产生式右部都是用名字替换掉语法概念和单词13产生式设计练习mwhile (expression) statementmfor (expression1; expression2; expression3)statmentmint(float, double, char) id1, id2, ;对应的产生式stmt while

6、( expr ) stmt对应的产生式stmt for ( expr ; expr; expr ) stmttype int | float | double | charidlist idlist , id | iddecl type idlist ;14推导m单词串单词串( (string) ):0个或多个单词构成的序列m推导推导( (derive) ) q由开始符号作为推导起点q用产生式右部替换左部非终结符q反复替换,最终得到单词串m语言语言(language)语法所定义的语言可由开始符号推导出的所有单词串的集合15例2.2前面定义的表达式的CFG,可按如下步骤推导出表达式:9 - 5

7、+ 2expr expr + digit expr - digit + digit digit - digit + digit 9 - digit + digit 9 - 5 + digit 9 - 5 + 2 P1 : expr expr + digitP2 : expr expr - digitP3 : expr digitP4 : digit 9P4 : digit 5P4 : digit 2expr expr + digitexpr expr digitexpr digitdigit 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 916例2.2(续)exprd

8、igitdigitexprdigitexpr952-+172.2.1 语法分析树(parse tree)m图示推导过程,推导语法树:q根节点标记为开始符号q每个叶节点用一个T或e标记q每个内部节点用一个NT标记q节点A,孩子节点X1,X2,Xn节点应用了产生式A X1X2Xnq对Ae ,节点A只有一个孩子节点e18例2.4m叶节点从左至右构成树的输出输出(yield)开始符号推导出推导出(生成生成)的单词串m语言语言:语法分析树生成的单词串集合exprdigitdigitexprdigitexpr952-+expr expr + digitexpr expr digit192.2.2 二义性(

9、ambiguity)m多个语法分析树生成相同的单词串多个意义m定义无歧义语法或用附加规则消除歧义20例2.5exprexprexprexprexpr+2-59exprexprexprexprexpr-9+52expr expr + expr | expr expr | 0 | 1 | | 9212.2.3 运算符的结合率m9-5-2(9-5)-2 还是 9-(5-2)?m左结合(left associative):+, -, *, /m右结合(right associative):, =exprdigitdigitexprdigitexpr952-expr expr + digitexpr e

10、xpr digitexpr digitdigit 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 922右结合例asgnvarvarasgnvarasgncba=asgn var = asgn | varvar a | b | c | | z232.2.4 运算符优先级m9+5*2(9+5)*2 还是 9+(5*2)?m运算符优先级:*的优先级比+高m典型的优先级 ( ) * / 左结合 + - 左结合24结合优先级的表达式文法expr expr + term | expr term | termterm term * factor | term / factor |

11、factorfactor digit | ( expr )digit 0 | 1 | 2 | 3 | | 9mexpr、term、factor不同的优先级25Grammar-based compressionx=10011100010001110001111111000s0 s1s3s2s3s4s4s3s1 100s2 s10s3 s4s2s4 11解压推导s0 s1s3s2s3s4s4s3 s1s4s2 s2s4s2 s4s4s4s2 s1s4s10s10s4s10s4s4s4s10 100s410001000s41000s4s4s41000 100111000100011100011111

12、1100026推导练习m7 3 * (4 + 6)exprexpr term term term factor term 7 term 7 term * factor 7 factor * factor 7 3 * factor 7 3 * ( expr ) 7 3 * ( expr + term )7 3 * ( term + term )7 3 * ( factor + term )7 3 * ( 4 + term )7 3 * ( 4 + factor )7 3 * ( 4 + 6 )27推导练习mS S S + | S S * | a给出aa+a*的推导和语法树S S S * S S

13、+ S * a S + S * a a + S * a a + a * 282.3 语法制导翻译m翻译:为生成代码,需保存语言结构的类型、代码位置、代码数量等m属性(attribute):类型、串、内存位置等m语法制导翻译语法制导翻译syntax-directed translationq语法制导定义语法制导定义syntax-directed definition属性与语法结构相关联指明翻译方法q翻译模式翻译模式,translation scheme29怎么设计语法制导翻译程序m首先还是“人会做”q设计文法q程序员自己先理清翻译的方法每个语法结构如何翻译m然后“让计算机会做”q设计文法符号属性

14、,表示翻译结果q把翻译方法转换为语义规则(语义动作)属性的运算,将其附着于产生式q手工编写或利用自动生成工具形成语法分析程序,语义规则(语义动作)嵌入到程序的恰当位置,恰好实现了翻译方法302.3.1 表达式的后缀表示法m表达式E的后缀形式Postfix(E)如何生成:qE为变量或常量:Postfix(E) = EqE = E1 op E2,op二元运算符,E1、E2子表达式:Postfix(E) = Postfix(E1 op E2)= Postfix(E1) Postfix(E2) opqE = (E1):Postfix(E) = Postfix(E1)1.(9 - 5) + 2 9 5

15、- 2 +9 - (5 + 2) 9 5 2 + -312.3.2 语法制导定义m基于语言的上下文无关文法m语法符号一组属性m产生式一组语义规则语义规则(semantic rule)属性值计算规则mCFG+语义规则语法制导定义关联关联32语法制导翻译的基本过程m翻译输入输出映射过程q输入单词串x语法分析树q节点n标记为X,X.aX的属性q计算节点n的X.a的值利用X产生式的语义规则1.“注释语法分析树”(annotated parse tree)332.3.3 综合属性msynthesized attributes:节点属性值由其孩子节点属性值所决定m自底向上(bottom-up)计算34例2

16、.6expr、term都设置属性t字符串型,表示表达式的后缀表示形式expr expr term | expr + term | termterm 0 | 1 | 2 | 3 | | 935翻译方法语义规则9 + 5E : E1 + E29 5 +Post(E) = Post(E1) Post(E2) +expr expr + termexpr.t= expr.t | term.t | +中缀后缀36例2.6(续)Production Semantic Ruleexpr expr1 + term expr.t = expr1.t | term.t | +expr expr1 term expr

17、.t = expr1.t | term.t | -expr term expr.t = term.tterm 0 term.t = 0term 1 term.t = 1. .term 9 term.t = 937例2.6(续)注释语法分析树expr.t =95-expr.t =9expr.t =95-2+term.t =5term.t =2term.t =92+5-938例2.7:机器人移动m描述指挥机器人行动的指令序列,每个指令指挥机器人向一个方向前进一个距离单位seq seq instr | begininstr east | north | west | south39例2.7:机器人移

18、动m命令序列:begin west south east east east north north40机器人移动的语法制导定义Production Semantic Ruleseq begin seq.x := 0 seq.y := 0seq seq1 instr seq.x := seq1.x + instr.dx seq.y := seq1.y + instr.dyinstr east instr.dx := 1 instr.dy := 0instr north instr.dx := 0 instr.dy := 1instr west instr.dx := -1 instr.dy :

19、= 0instr south instr.dx := 0 instr.dy := -141语法分析树m命令序列:begin west southseq.x = -1seq.y = 0seq.x = 0seq.y = 0seq.x = -1seq.y = -1instr.dx = -1instr.dy = 0instr.dx = 0instr.dy = -1beginwestsouth422.3.4 语法制导定义的实现m树的遍历:计算完所有孩子节点的属性,父节点才能计算自身属性m后序遍历,深度优先void visit(node n)for n的每个孩子m(从左至右的顺序)visit(m);利用n

20、的语义规则计算其属性值432.3.5 翻译模式mtranslation schemem同样基于上下文无关文法m语义动作语义动作(semantic action,程序片断)嵌入产生式的右部 rest + term print(+) rest1 m语法分析树添加额外节点m指明了语义动作执行顺序restterm print(+) +rest1442.3.6 执行翻译模式m语义动作的执行顺序非常重要m语法制导定义的特性简单性左部的翻译(后缀字符串)右部终结符的翻译按产生式中顺序连接m用翻译模式实现语法制导定义q语义动作打印额外字符串q按照字符串在语法制导定义中的顺序qrest + term rest1

21、 rest.t := term.t | + | rest1.trest + term print(+) rest1 45例2.8expr expr + term print(+) expr - term print(-) termterm 0 print(0)term 1 print(1)term 9 print(9)46带语义动作的语法分析树m“由左至右”执行语义动作m边进行语法分析,边执行语义动作termtermtermexprexprexpr952-+print(-)print(9)print(5)print(2)print(+)47语法制导定义练习m构造翻译模式,中缀前缀构造9-5*2

22、的注释语法分析树expr print(+); expr + term | print(-); expr term | termterm print(*); term * factor | print(/); term / factor | factorfactor print(num.value); num | ( expr )48Yaccm语法分析器自动生成工具语法分析器源程序语法分析器源程序语法分析器可执行程序语法分析器可执行程序myyacc.y49Yacc程序结构定义段:%C语言代码%定义%规则段:语法规则、翻译模式%用户子程序段50例:简单表达式计算%/*expr.yParserWiz

23、ard generated YACC file.Date: 2005年8月22日*/#include #include %直接复制到语法分直接复制到语法分析程序中析程序中51例:简单表达式计算(续)%include #ifndef YYSTYPE#define YYSTYPE double#endif%token NUMBER%left + -%left * /%right UMINUS%我们要翻译的结果是我们要翻译的结果是什么?表达式值!什么?表达式值!所以类型是所以类型是doubleYYSTYPE是翻译结是翻译结果的类型果的类型运算符优先级运算符优先级复制头文件中复制头文件中52例:简单表

24、达式计算(续)lines:lines expr n printf(%gn, $2); |lines n|;expr:expr + expr $ = $1 + $3; |expr - expr $ = $1 - $3; |expr * expr $ = $1 * $3; |expr / expr $ = $1 / $3; |( expr ) $ = $2; |- expr %prec UMINUS $ = -$2; |NUMBER;表达式的上下文无表达式的上下文无关文法关文法53例:简单表达式计算(续)NUMBER :0 $ = 0.0; |1 $ = 1.0; |2 $ = 2.0; |3 $

25、 = 3.0; |4 $ = 4.0; |5 $ = 5.0; |6 $ = 6.0; |7 $ = 7.0; |8 $ = 8.0; |9 $ = 9.0; ;%54例:简单表达式计算(续)int yygettoken(void)return getchar();int main(void)return yyparse();还没有完整的词法还没有完整的词法分析器,简单地令分析器,简单地令每个字符是一个单每个字符是一个单词词调用语法分析(翻调用语法分析(翻译)器译)器55C+版本%/*expr.yParserWizard generated YACC file.Date: 2016年10月18

26、日*/#include #include using namespace std;%56C+版本(续)%include #ifndef YYSTYPE#define YYSTYPE double#endif/ parser name%name expr/ class definition/ place any extra class members herevirtual int yygettoken();57C+版本(续)/ constructor/ place any extra initialisation code here/ destructor/ place any extra c

27、leanup code here/ place any declarations here/%token NUMBER%left + -%left * /%right UMINUS58C+版本(续)lines:lines expr n cout $2 endl; |lines n|;expr:expr + expr $ = $1 + $3; |expr - expr $ = $1 - $3; |expr * expr $ = $1 * $3; |expr / expr $ = $1 / $3; |( expr ) $ = $2; |- expr %prec UMINUS $ = -$2; |N

28、UMBER;59C+版本(续)NUMBER:0 $ = 0.0; |1 $ = 1.0; |2 $ = 2.0; |3 $ = 3.0; |4 $ = 4.0; |5 $ = 5.0; |6 $ = 6.0; |7 $ = 7.0; |8 $ = 8.0; |9 $ = 9.0; ;60C+版本(续)int YYPARSERNAME:yygettoken()/ place your token retrieving code herereturn getchar();int main(void)int n = 1;expr parser;if (parser.yycreate() n = pa

29、rser.yyparse();return n;612.4 语法分析m确定一个单词串是否可由一个文法生成m构造语法分析树m时间复杂度O(n3)O(n)m自顶向下分析方法,top-down语法树构造由根向叶适合手工编写语法分析器m自底向上分析方法,bottom-up语法树构造由叶向根适用更多文法,自动生成工具622.4.1 自顶向下分析方法m从根节点(标记为开始符号)开始构造语法树,不断重复以下步骤m对标记为NT A的节点n 选择一个关于A的产生式利用产生式右部构造n的孩子节点1.选择下一个没有扩展(构造孩子节点)的节点,对它执行163例:Pascal的类型type simple | id |

30、array simple of typesimple integer | char | num dotdot nummdotdot,”.”64语法分析树构造过程m输入:array num dotdot num of integertype(a)(b)typesimpleofarraytype65语法分析树构造过程m输入:array num dotdot num of integer(c)typesimpleofarraytypenumnumdotdot66语法分析树构造过程(续)typesimpleofarraytypenumnumdotdotsimple(d)67语法分析树构造过程(续)ty

31、pesimpleofarraytypenumnumdotdotsimpleinteger(e)68平凡算法m初始状态,只有一个根节点,标记为开始符号,输入指针指向第一个单词m对于NT节点q选择产生式(尝试、回溯)构造孩子节点q对孩子节点从左至右继续分析m对于T节点q与当前输入单词进行比较q若匹配,输入指针前移,处理下一个节点q不匹配,可能需要回溯或报告错误69扫描输入分析过程type simple | id | array simple of typesimple integer | char | num dotdot num70扫描输入分析过程(续)type simple | id | ar

32、ray simple of typesimple integer | char | num dotdot num71扫描输入分析过程(续)type simple | id | array simple of typesimple integer | char | num dotdot num72扫描输入分析过程(续)type simple | id | array simple of typesimple integer | char | num dotdot num73扫描输入分析过程(续)742.4.2 预测分析m递归下降分析递归下降分析recursive-descent paring递归

33、函数非终结符m预测分析预测分析predictive parsing只需一个超前单词产生式唯一确定75预测分析程序对终结符的处理匹配输入,指针移动procedure match ( t : token ) ;begin if lookahead = t then lookahead : = nexttoken else errorend ;76预测分析程序(续)procedure type ;begin if lookahead is in integer, char, num then simple else if lookahead = then begin match ( ) ; matc

34、h( id ) end else if lookahead = array then begin match( array ); match(); simple; match(); match(of); type end else errorend ;超前单词选择产生式分析孩子节点处理T处理NT,递归type simple | id | array simple of typesimple integer | char | num dotdot num77预测分析程序(续)procedure simple ;begin if lookahead = integer then match ( i

35、nteger ); else if lookahead = char then match ( char ); else if lookahead = num then begin match (num); match (dotdot); match (num) end else errorend ;782.4.4 设计预测分析器m一个超前单词产生式推导出的单词串的第一个单词不同mAqFIRST():推导出的单词串的第一个单词的集合,可包含qFIRST(simple) = integer, char, num FIRST(id) = FIRST(array simple of type) =

36、array mA, A,FIRST()和FIRST()不能相交唯一确定79预测分析器算法m为每个NT A构造一个函数,完成如下工作:m产生式选择q对A,超前符号在FIRST()中选择它q若有冲突预测分析法不适用1.A e,且超前单词不在其他任何产生式右部的FIRST集中选择它80预测分析器算法m产生式的使用依次处理右部符号q对NT,调用对应函数q对T,与超前单词比较,若匹配读取下一单词,否则错误81结合翻译模式m简单方法m首先构造预测分析器m实现语义动作q将语义动作程序段复制到分析器代码中q位置?语义动作位于语法符号X之后程序段中将之放在紧接在处理X的代码之后1.位于产生式开始,复制到函数最前

37、面822.4.5 左递归mleft recursion,导致无限循环m解决方法:改写文法qAA | 改写为qA RR R | m例qexpr expr + term | termqexpr term restrest + term rest | void idlist() if (lookahead = ) idlist(); 一直不变一直不变id , id , 83左递归 vs. 右递归842.5 构造表达式转换的编译器m原始语法:需改写expr expr + term print(+)expr expr - term print(-)expr termterm 0 print(0)term

38、 1 print(1)term 9 print(9)85消除左递归、加入翻译模式expr term restrest + term print(+) rest | - term print(-) rest | term 0 print(0)term 1 print(1)term 9 print(9)869-5+2翻译为95-2+print(2)exprtermterm print(-)term print(+) restprint(5)print(9)restrest25-9+872.5.3 非终结符实现代码非终结符的分析函数exprvoid expr ()term(); rest();exp

39、r term rest88非终结符的分析函数restvoid rest ()if (lookahead = +) match(+); term(); putchar(+); rest();else if (lookahead = -) match(-); term(); putchar(-); rest();rest + term print(+) rest | - term print(-) rest | 89非终结符的分析函数termvoid term ()if (isdigit(lookahead) putchar(lookahead); match(lookahead);else er

40、ror();term 0 print(0)term 1 print(1)term 9 print(9)902.5.4 优化消除rest尾递归void rest ()L: if (lookahead = +) match(+); term(); putchar(+); goto L;else if (lookahead = -) match(-); term(); putchar(-); goto L;91优化rest并入exprvoid expr ()term();while (1)if (lookahead = +) match(+); term(); putchar(+);else if

41、(lookahead = -) match(-); term(); putchar(-);else break;922.5.5 完整程序#include int lookahead;main()lookahead = getchar();expr();putchar(n);void match(int t)if (lookahead = t)lookahead = getchar();else error();932.6 词法分析m2.6.1 去除空白符和注释m2.6.2 常量:, , m2.6.3 标识符与关键字识别qcount = count + increment id = id + i

42、dq单词id不同实例count, increment的区分q关键字(keyword),保留字(reserved)q运算符,, =, ,可以每个运算符作为一类单词942.6.4 词法分析器接口uses getchar ( ) to read characterpushes back c using ungetc (c , stdin)returns token to callertokenvalSets global variable to attribute valuelexan ( )lexical analyzer952.6.5 词法分析器程序#include #include #defi

43、ne NUM 256int lineno = 1;int tokenval = NONE;int lexan()int t;while (1) t = getchar();if (t = | t = t);96词法分析器程序(续)else if (t = n)lineno+;else if (isdigit(t) tokenval = 0;while (isdigit(t) tokenval = tokenval * 10 + t 0;t = getchar();ungetc(t, stdin);return NUM;else tokenval = NONE; return t; 972.7

44、符号表m不同阶段保存(使用)单词的不同信息m2.7.1 接口qinsert(s,t):单词t的实例s(字符串)插入符号表,返回其索引qlookup(s):返回字符串s对应表项的索引,若未找到,返回0m2.7.2 保留字可存入符号表insert(“div”, div) insert(“mod”, mod)982.7.3 一种实现方式 ARRAY symtablelexptr token attributes div mod id idEOSiEOStnuocEOSdomEOSvidARRAY lexemes0123499带有符号表功能的词法分析器int lexan()char lexbuf100

45、;char c;while (1) 从输入字符序列读取一个字符,保存到c;if (c = | c = t) ;else if (c = n) lineno+;else if (isdigit(c) tokenval = c及后续数字组成的数值;return NUM;100带有符号表功能的词法分析器else if (isalpha(c) 将c及后续字母、数字放入lexbuf;p = lookup(lexbuf);if (p = 0) p = insert(lexbuf, ID);tokenval = p;return 符号表项p的token值; else tokenval = NONE;return 字符c对应的整数;101Lcc的符号表m字符串的管理/string.cstatic struct string char *str;int len;struct string *link; *buckets1024;char *stringn(const char *str, int len) int i;unsigned int h;const char *end;struct string *p;assert(str);for (h = 0, i = len, end = str; i 0; i-)/ Hashh = (hlink)/搜索if (len

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论