编译原理第三章PPT2

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
状态转换图Transition Diagrams
用来描述和识别记号 包括:
还可以用什么 描述记号?
状态States:用圆圈表示 动作Actions:用箭头(边)表示 初态Start State:模式的开始,无源箭头的目标 终态Final State(s):模式的结束,双圈
0
0,1 1
1
2
0
3
1
4
状态转换图的运行(例)
当前状态
0 1 0 1 0,1
1
2
1011
3
4
当前字母
状态转换图的运行(例)
当前状态
0 1 0 1 0,1
1
2
3
4
10Βιβλιοθήκη Baidu1
当前字母
状态转换图的运行(例)
当前状态
0 1 0 1 0,1
1
2
3
4
1011
当前字母
状态转换图的运行(例)
当前状态
0 1 0 1 0,1
{} {return(IF);} {return(THEN);} {return(ELSE);}
一个Lex程序(续)
{id} {yylval=(int) installID( ); return(ID);} {number} {yylval=(int) installNum( ); return(NUMBER);} “<” {yylval=LT; return(RELOP);} “<=” {yylval=LE; return(RELOP);} “=” {yylval=EQ; return(RELOP);} “< >” {yylval=NE; return(RELOP);} “>” {yylval=GT; return(RELOP);} “>=” {yylval=GE; return(RELOP);} %% int installID( ){ } int installNum( ) { }
给出识别正则式所描述语言的状态转换图
a|b
(a|b)* (a|b)+ a(a|b)*a a*ba*ba*ba* (a|b)*a(a|b)(a|b)
词法分析器生成工具Lex
功能:将输入的模式转换成一个状态转换图, 生成代码,并存放到文件lex.yy.c中。
Lex语言:Lex工具的输入表示方法
1
2
3
4
1011
当前字母
状态转换图的运行(例)
当前状态
0 1 0 1 0,1
1
2
3
4
1011
全部输入处理完毕,结 束于终态,本串可接受
词法单元relop的状态转换图
id和关键字的状态转换图
无符号数字的状态转换图
digit+ (.digit+)?(E(+|–)?digit+)?
空白符的状态转换图
a+b*a {printf(“1%s\n”, yytext} (ab)+c? {printf(“2%s\n”, yytext} aa {printf(“3%s\n”, yytext} (a|b)*c {printf(“4%s\n”, yytext}
给出scanner对输入串ababcbacaabaababaa的输出:
a+b*a
(ab)+c? aa
{printf(“1%s\n”, yytext);}
{printf(“2%s\n”, yytext );} {printf(“3%s\n”, yytext );}
(a|b)*c
优先原则:
{printf(“4%s\n”, yytext );}
(1)匹配最长串的规则优先 (2)长度相同时,在前的规则优先
给出scanner对输入串ababcbacaabaababaa的输出:
Step1: a+b*a (ab)+c? (a|b)*c Step2: Step3: a+b*a aa Step 4: a+b*a (ab)+c? Step 5: 输出 2 ababc aba ababc ababc 输出 4 bac 输出1 aaba aaba aa 输出 2 abab aba abab 输出 1 aa
relop的状态转换图的概要实现
TOKEN getRelop( ){ TOKEN retToken = new(RELOP); while(1) { switch(state) { case 0: c = nextChar( ); if ( c == ‘<’ ) state = 1; else if ( c == ‘=’ ) state = 5; else if ( c == ‘>’ ) state = 6; else fail( ) ; break; case 1: . . . ... case 8: retract( ) ; retToken.attribute = GT; return(retToken) ; } } }
//声明
一个Lex程序
delim ws letter digit id number %% {ws} if then else [ \t\n] {delim}+ [A-Za-z] [0-9] {letter} ({letter} | {digit}) * {digit}+(\.{digit}+)? (E[+-]?{digit}+)?
Lex的使用
用Lex语言写一个输入文件,描述要生成的词法 分析器 Lex编译器将lex文件转换成C语言程序 编译C程序,即得词法分析器
Lex程序的结构
declarations
%% translation rules %% auxiliary procedures //辅助过程 //转换规则
匹配失败的处理
int state = 0, start = 0; int fail( ) { start = state; forward = lexeme beginning; switch (start) { case 0: start = 9; break; case 9: start = 12; break; case 12: start = 22; break; case 22: start = 25; break; case 25: recover( ); break; default: /* compiler error */ } return start; }
Lex程序(例)
int num_lines = 0, num_chars = 0;
%%
\n {++num_lines; ++num_chars;} . {++num_chars;} %% main( argc, argv ) int argc; char **argv; { ++argv, --argc; // 跳过程序名 if ( argc > 0 ) yyin = fopen( argv[0], "r" ); else yyin = stdin; yylex( ); printf( "# of lines = %d, # of chars = %d\n", num_lines, num_chars ); }
相关文档
最新文档