编译原理:词法分析实验

实验目的:
(1)熟悉 C 语言的词法规则,了解编译器词法分析器的主要功能和实现技术,掌握典型词法分析器构造方法,设计并实现 C 语言词法分析器;
(2)了解 Flex 工作原理和基本思想,学习使用工具自动生成词法分析器;
(3)掌握编译器从前端到后端各个模块的工作原理,词法分析模块与其他模块之间的交互过程。
实验内容:
根据 C 语言的词法规则,设计识别 C 语言所有单词类的词法分析器的确定有限状态自动机,并使用 Java、C\C++或者 Python 其中任何一种语言,采用程序中心法或者数据中心法设计并实现词法分析器。词法分析器的输入为 C 语言源程序,输出为属性字流。
实验要求:
基于示例实现,对于如下的测试程序
scanner_example.c: int sum(int a, int b) { return a + b; }
输出的属性字流存储在 scanner_example.tokens 文件中,具体内容见下:
[@0,0:2=‘int’,<‘int’>,1:0]
[@1,4:6=‘sum’,,1:4]
[@2,8:8=’(’,<’(’>,1:8]
[@3,10:12=‘int’,<‘int’>,1:10]
[@4,14:14=‘a’,,1:14]
[@5,16:16=’,’,<’,’>,1:16]
[@6,18:20=‘int’,<‘int’>,1:18]
[@7,22:22=‘b’,,1:22]
[@8,24:24=’)’,<’)’>,1:24]
[@9,26:26=’{’,<’{’>,1:26]
[@10,28:33=‘return’,<‘return’>,1:28]
[@11,35:35=‘a’,,1:35]
[@12,37:37=’+’,<’+’>,1:37]
[@13,39:39=‘b’,,1:39]
[@14,41:41=’;’,<’;’>,1:41]
[@15,43:43=’}’,<’}’>,1:43]
[@16,47:46=’’,,2:0]
在这个输出的 token 流中,每行为一个 token,以@开头的数字表示 token 的序号,紧接着的 xx:xx 表示 token 文本对应的开始列和结束列,“=”后面给出了这个范围之内 token 的具体文本,“<>”之内表示 token 的类型,最后一个数字对 xx:xx 表示起始行和起始列。需要说明的是,在这个例子中,运算符等的类型就是其自身,属性流的最后放置了一个“EOF”表示属性字的结束位置。

本实验所用到的工具是flex,关于flex下载安装方法的参考关于flex这一工具的使用方法的参考关于代码写法的参考,代码见下:

%{
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

	int toke=0;
                 int line=0;
                 int len,fin;
                 FILE *fp;
%}
DIGIT [0-9]
OINTEGER [1-9]{DIGIT}*
INTEGER ("+"|"-")?{DIGIT}+
DECIMAL {INTEGER}.{DIGIT}+
FLOAT {INTEGER}.{DIGIT}+("e"(("+"|"-"){OINTEGER})?)?

LETTER [a-zA-Z]
IDENTIFIER ({LETTER}|_)({LETTER}|_|{DIGIT})*
COMMENT ("/*"|"*").*
KEYWORD ("auto"|"break"|"case"|"char"|"const"|"continue"|"default"|"do"|"double"|"else"|"enum"|"extern"|"float"|"for"|"goto"|"if"|"inline"|"int"|"long"|"register"|"restrict"|"return"|"short"|"signed"|"sizeof"|"static"|"struct"|"switch"|"typedef"|"union"|"unsigned"|"void"|"volatile"|"while")
BRACKET ("["|"]"|"("|")"|"{"|"}"|"."|"->"|"++"|"--"|"&"|"*"|"+"|"-"|"~"|"!"|"/"|"%"|"<<"|">>"|"<"|">"|"<="|">="|"=="|"!="|"^"|"|"|"&&"|"||"|"?"|":"|";"|"..."|"="|"*="|"/="|"%="|"+="|"-="|"<<="|">>="|"&="|"^="|"|="|","|"#"|"##"|"<:"|":>"|"<%"|"%>"|"%:"|"%:%:")
TYPEIDENTITY ("%"|"&")[a-z]

%%

{KEYWORD} {
	len=strlen(yytext)-1;
                 fin=len+line;
	fprintf(fp,"[@%d,%d:%d='%s',<'%s'>,1:%d]",toke,line,fin,yytext,yytext,line);
                 toke++;
                 line=fin+2;
}

{TYPEIDENTITY} {
	len=strlen(yytext)-1;
                 fin=len+line;
	fprintf(fp,"[@%d,%d:%d='%s',<'typeidentify'>,1:%d]",toke,line,fin,yytext,line);
                 toke++;
                 line=fin+2;
}

{DECIMAL} {
                 len=strlen(yytext)-1;
                 fin=len+line;
	fprintf(fp,"[@%d,%d:%d='%s',<'decimal'>,1:%d]",toke,line,fin,yytext,line);
                  toke++;
                 line=fin+2;
}

{INTEGER} {
                 len=strlen(yytext)-1;
                 fin=len+line;
	fprintf(fp,"[@%d,%d:%d='%s',<'integer'>,1:%d]",toke,line,fin,yytext,line);
                  toke++;
                 line=fin+2;
}

{FLOAT} {

	char *p = strchr(yytext, 'e');
	if (p && yytext[strlen(yytext)-1] == 'e')
                {
		fprintf(fp,"Error at Illegal floating point number \"%s\".\n",yytext);
		return 0;
	} 
                 else 
                {
                                  len=strlen(yytext)-1;
                                  fin=len+line;
		fprintf(fp,"[@%d,%d:%d='%s',<'float'>,1:%d]",toke,line,fin,yytext,line);
                                   toke++;
                                   line=fin+2;
	}
}

{IDENTIFIER} {
                 len=strlen(yytext)-1;
                 fin=len+line;
	fprintf(fp,"[@%d,%d:%d='%s',<'Identifier'>,1:%d]",toke,line,fin,yytext,line);
                  toke++;
                 line=fin+2;
}

{BRACKET} {
                 len=strlen(yytext)-1;
                 fin=len+line;
	fprintf(fp,"[@%d,%d:%d='%s',<'%s'>,1:%d]",toke,line,fin,yytext,yytext,line);
                  toke++;
                 line=fin+2;
}


{COMMENT} {}

. {}
%%
int main(int argc,char *argv[])
{
    yyin=fopen("scanner_example.c","r");
    fp=fopen("scanner_example.tokens","w");
    yylex();
    fin=line-1;
    fprintf(fp,"\n[@%d,%d:%d='<EOF>',<EOF>,2:0]",toke,line,fin);
    return 0;
}

int yywrap()
{
	return 1;
}
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值