设计词法分析之基于lex实现词法分析

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

词法分析程序

一、设计目的

通过编写并上机调试一个词法分析程序,掌握在对程序设计语言的源程序进行扫描的过程中,将其分解成各类单词的词法分析方法。

二、设计要求

要求将用模拟语言书写的源程序进行词法分析,输出源程序清单,Token文件和错误信息文件,若有错误,必须输出错误在源程序中行号和列号,并将符号表和字符串以文件的形式写出来。

三、设计说明

基于Parser Genarator的词法分析器构造方法。Lex输入文件由3个部分组成:定义集(definition),规则集(rule)和辅助程序集(auxiliary routine)或用户程序集(user routine)。这三个部分由位于新一行第一列的双百分号分开,因此,Lex输入文件的格式如下

{definitions}

%%

{rules}

%%

{auxiliary routines}

而且第一部分用“%{”和“%}”括起来。

第一和第三个部分为C语言的代码和函数定义,第二个部分为一些规则。

3.1正规式定义

定义正则表达式如下

ID = letter letter*

NUM = digit digit*

Letter = a|…|z|A|…|Z

D igit = 0|…|9

Keyword = else|if|int|return|void|while

Special symbol = +|-|*|/|<|<=|>|>=|==|!=|=|;|,|(|)|[|]|{|}|/*|*/

White space = “ ”

Enter = \n

在lex中的构造

letter [A-Za-z]

digit [0-9]

id ({letter}|[_])({letter}|{digit}|[_])*

error_id ({digit})+({letter})+

num {digit}+

whitespace [ \t]+

enter [\n]+

3.2转换规则定义

在Lex中的规则定义构造

定义识别保留字规则

"int"|"else"|"return"|"void"|"if"|"while"

{Upper(yytext,yyleng);

printf("%d 行 ",lineno);

printf("%s reserved word\n",yytext);}//保留字

定义识别数字规则

{num}

{printf("%d 行 ",lineno);

printf("%s NUM\n",yytext);}//数字

定义识别专用符号规则","|";"|"("|")"|"{"|"}"|"*"|"/"|"+"|"-"|">"|"<"|">="|"<="|"=="|"!="|"="|"/*"|"*/" {printf("%d 行 ",lineno);

printf("%s special symbol\n",yytext);}//特殊符号

定义识别标识符规则

{id}

{printf("%d 行 ",lineno);

printf("%s ID\n",yytext);}//标识符

定义识别错误的字符串规则

当开头为数字的后面为字母的字符串时,是错误的标识符。

{error_id}

{printf("error:%s\n",yytext);}//以数字开头的字符自动报错

定义忽略空格规则

{whitespace}

{/* skip whitespace */}//忽略空格

定义忽略回车规则

{enter}

{lineno++;}//遇到回车自动加行号忽略

3.3辅助程序

辅助程序集中包括

主函数main ()和辅助函数toupper()。

3.3程序代码实现

%{

#include

#include

#include

int yywrap();

int lineno=1;

%}

delim [ \t]

ws {delim}+

letter [A-Za-z]

digit [0-9]

id {letter}({letter}|{digit})*

number {digit}+

error_id ({digit})+({letter})+

enter [ \n]

spchar ("{"|"}"|"["|"]"|"("|")"|";"|"="|",")

ariop ("+"|"-"|"*"|"/")

relop ("<"|"<="|">"|">="|"=="|"!=")

comment \/\*(\*[^/]|[^*])*\*\/

reswd (int|else|return|void|if|while)

%%

{ws} {}

{comment} {}

{enter} {lineno++;}

{reswd} {fprintf(yyout,"%d行\tkeywod\t%s\n",lineno,yytext);} {spchar} {fprintf(yyout,"%d行\tspchar\t%s\n",lineno,yytext);} {id} {fprintf(yyout,"%d行\tidentifier\t%s\n",lineno,yytext);} {number} {fprintf(yyout,"%d行\tnumber\t%s\n",lineno,yytext);} {error_id} {fprintf(yyout,"%d行\terror_id\t%s\n",lineno,yytext);} {ariop} {fprintf(yyout,"%d行\tari_op\t%s\n",lineno,yytext);} {relop} {fprintf(yyout,"%d行\trel_op\t%s\n",lineno,yytext);}

%%

相关文档
最新文档