2.2 一个简单的词法分析器示例

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
2014-9-26 8
2.2.3 状态转换图的实现 状态转换图易于用程序实现,最简单的 办法是让每个状态对应一小段程序。对于 图2–5,首先引进一组变量和过程: (1)character: 字符变量,存放最新读入 的源程序字符。 (2)token: 字符数组,存放构成单词符号 的字符串。 (3)getbe( ): 若character中字符为空,则 调用getchar( ),直至character为非空。
2014-9-26 14
case '+': return ('+',null); break; case‘-': return (‘-',null); break; case '*': return ('*',null); break; case '<': getchar ( ); if (character== '=') return(relop,LE); else { retract ( ); return (relop,LT); } break;

2014-9-26 17





(5) 若作为一个主程序,须加一层while循环控制: while (1= =1) { token= ' '; /*对token数组初始化*/ getchar( ); getbe( ); /*滤除空格…*/ if (character!=EOF) { switch (character) … } else break; /* end of if */ } /*end of while */
2014-9-26 18









(6) 考虑不使用retract()、不回退字符,每次情况处 理后多读一个字符留下次直接进行判断处理。பைடு நூலகம்getchar( ); while (1= =1) { token= ' '; /*对token数组初始化*/ getbe( ); /*滤除空格…*/ if (character!=EOF) { switch (character) … /* 去掉每条retract()语句;没有 retract()的case情况加一个getchar();*/ } else break; /* end of if */ } /*end of while */
2014-9-26 16
注意:编程实现过程中, (1)return(…):该程序作为语法分析的子 程序,返回相关信息给语法分析程序; 若单独作为一个主程序,return当作print 相关信息。 (2)getbe():可增加功能:跳过注释、制 表符和换行符等,碰到换行符则 LineNo (记录行号的变量)增加1。 (3)error():利用LineNo,可告诉用户错误 所在的行号,并适当提供纠错信息。 (4)增加功能:识别含“_”的标识符、无 符号小数、无符号数、符号数(负号)。
的字符送入token数组*/
12
}
2014-9-26
retract ( ); /*扫描指针回退一个字符*/ c=reserve ( ); if (c==0) { buildlist ( ); /*将标识符登录到符号表*/ return (id, id在符号表中的入口指针); } else return (保留字码, null) ; break;
2014-9-26
13
case '0': case '1': … case '9': while (digit ( )) { concatenation ( ); getchar ( ); } retract ( ); buildlist ( ); /*将常数登录到常数表中*/ return (num, num的常数表入口指针); break;
2014-9-26
助记符 while if else switch case id num + − * relop relop relop = ;
id在符号表中位置
num在常数表中位置
内码值 — — — — —
— — — LE LT EQ — —
4
2.2.2 C语言子集对应的状态转换图的设计 首先对输入串做预处理。 即剔除多余的空格、注释、制表符和 换行符等。 其次把保留字作为一类特殊标识符处理。 即对保留字不专设对应的状态转换图, 当状态转换图识别出一个标识符时就去查 表,确定它是否为一个保留字。
大多数程序语言的单词符号都可用 状态转换图予以识别。下面构造一个 C 语言子集的简单词法分析器,该 C 语言 子集的所有单词符号及其种别编码和内 码值如下表所示。 由于直接使用整数编码不利于记忆, 故采用一些助记符表示种别编码。
2014-9-26 3
表2.1 C语言子集的单词符号及内码值 单词符号 种别编码 while 1 if 2 else 3 switch 4 case 5 6 标识符 7 常数 + 8 − 9 * 10 <= 11 < 11 == 11 = 12 13 ;
2014-9-26 9
(4)concatenation( ): 将token中字符串与 character中字符连接作为token中的新 字符串。 (5)letter( )和digit( ): 判断character中的字 符是否为字母和数字的布尔函数,若是 则返回true, 否则返回false。 (6)reserve( ): 按token数组中的字符串查 保留字表, 若是保留字则返回其编码, 否则返回0。
2014-9-26 10
(7) retract( ): 扫描指针回退一个字符, 同
时将character置为空白。
(8)buildlist( ): 将标识符登录到符号表或将常数
登录到常数表;若登录表中已存在该标识符
或常数,则返回相关信息。
(9)error( ): 进行出错处理。
(10)getchar():把下一个输入字符读到character中, 读入源程序字符的指针前移一个字符。
2014-9-26 5

对保留字专设对应的状态转换图:

C语言子集对应的状态转换图如下:
6
2014-9-26
空白 字母或数字
开始 0
字母 1 非字母数字 2 * 返回(id, id在符号表中位置)
数字 数字 3 4 * 非数字 + 5 - 6 * < = ; 其它
2014-9-26
或返回(保留字, -)
2014-9-26 19
2014-9-26
20
返回(num, num在常数表中位置) 返回(+, -) 返回(-, -)
7 8
11

其它
返回(*, -)
9 返回(relop, LE) 返回(relop, EQ) 返回(=, -) 返回(; , -) 非法字符错 10 * 返回(relop, LT)

其它
12
13 *
14
15
*
7
注意: (1) 状态 2 识别出一个单词符号后需先 查保留字表 , 若匹配则为保留字 , 否则为标 识符。若为标识符 , 还需查符号表 , 看表中 是否有此标识符。若符号表中无此标识符, 则先将它登录到符号表中,再返回它在符号 表中入口地址作为内码值;若表中有此标识 符,则直接返回其入口地址作为内码值。 (2) 状态 4 识别出一个常数后可以将它 转换成二进制常数再登录到常数表,然后返 回它在常数表中的入口指针作为内码值。
2014-9-26 15
case '=': getchar ( ); if (character=='=') return(relop,EQ); else { retract ( ); return ('=', _ ); } break; case ';': return (';', -); break; default: error ( ); }
2014-9-26 11
C语言子集对应的的词法分析器如下: token= ' '; /*对token数组初始化*/ getchar( ); getbe( ); /*滤除空格*/ switch (character) { case 'a': … case 'z': while (letter ( )‖digit ( )) { concatenation ( ); /*将当前读入 getchar ( );
编 译 原 理 Principle of Compiling
郭 一 晶
厦门大学嘉庚学院
2014-9-26 1
2.2 一个简单的词法分析器示例

2.2.1 C语言子集的单词符号表示 2.2.2 C语言子集对应的状态转换图的设计

2.2.3 状态转换图的实现
2014-9-26
2
2.2.1 C语言子集的单词符号表示
相关文档
最新文档