编译原理-用FLEX构造词法分析程序

实验内容:

★★ 输入一个C 源程序文件, 用FLex 实现以下任务

a) 添加行号。
b) 将文件中每个非空的空白符号序列替换为单个空格。
c) 将文件中所有关键字转换为大写字母。
d) 将文件中所有标识符转换为小写字母,且以下划线开头。
e) 将文件中所有指数形式的常量转换为小数形式。
例如: 2.5e3 被转换为 2500
3.7e-2 被转换为 0.037
f) 将转换后的文件存入另一个文件。


实现代码:
%{
#include<stdio.h>
FILE* f1;
int n =0;
%}
keywords auto|break|case|char|const|continue|defaultdo|double|else|enum|extern|float|for|goto|if|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|union|unsigned|void|volatile|while
id [a-zA-Z][a-zA-Z0-9]*
number [0-9]
enumber {number}+(\.{number}+)?(e([+-])?{number}+)?
space [\ \t]+
%%

{keywords} {
		int i = 0;
		while(i<yyleng && yytext[i]>='a' && yytext[i]<='z')
		{
		yytext[i]-=32;
		i++;
	   	 }
		fprintf(f1,"%s",yytext);
		}

{id} {
	int i =0 ;
	while(i<yyleng && yytext[i]>='A' && yytext[i]<='Z')
	{
	yytext[i]+=32;
		i++;	
	}
	fprintf(f1,"_%s",yytext);
	}

{enumber} {
	float f = atof(yytext);	
	fprintf(f1,"%f",f);	
}

{space} {fprintf(f1," ");}

[^\n] {fprintf(f1,"%s",yytext);}

\n {
	fprintf(f1,"%s%5d  ",yytext,n++);
	}
%%

int yywrap(void)
{
  return 1;
}

main()
{
  f1 = fopen("bingo.txt","a+");
  fprintf(f1,"%5d  ",n++);
  yylex();
  fprintf(f1,"\n");
  fclose(f1);
}



测试文件:

#include <stdio.h>
#include <stdlib.h>
int main() 
{ 
	/*
	 测试指数形式转换
	 float f1 = 0.15e1;
	 float f2 = 3.5e-2;
 	 float f3 = 0e0;
 	 float f4 = 25e3;
 	 float f5 = -5.123e-1
	*/
	int day,month,year,sum,leap; 
	printf("\nplease input year,month,day\n"); 
	scanf("%d,%d,%d",&year,&month,&day); 
	switch(month)/*先计算某月以前月份的总天数*/ 
	{ 
  		case 1:sum=0;break; 
  		case 2:sum=31;break; 
  		case 3:sum=59;break; 
  	 	case 4:sum=90;break; 
  	 	case 5:sum=120;break; 
  		case 6:sum=151;break; 
  		case 7:sum=181;break; 
  		case 8:sum=212;break; 
  		case 9:sum=243;break; 
  		case 10:sum=273;break; 
  		case 11:sum=304;break; 
   		case 12:sum=334;break; 
   		defaultrintf("data error");break; 
	} 
	sum=sum+day;  /*再加上某天的天数*/ 
	if(year%400==0||(year%4==0&&year%100!=0))/*判断是不是闰年*/ 
		 leap=1; 
 	else 
 		 leap=0; 
	if(leap==1&&month>2)/*如果是闰年且月份大于2,总天数应该加一天*/ 
		  sum++; 
	printf("It is the %dth day.",sum);

 } 


用FLEX执行后的文件:

    0  #_include <_stdio._h>
    1  #_include <_stdlib._h>
    2  INT _main() 
    3  { 
    4   /*
    5   测试指数形式转换
    6   FLOAT _f1 = 1.500000;
    7   FLOAT _f2 = 0.035000;
    8   FLOAT _f3 = 0.000000;
    9   FLOAT _f4 = 25000.000000;
   10   FLOAT _f5 = -0.512300
   11   */
   12   INT _day,_month,_year,_sum,_leap; 
   13   _printf("\_nplease _input _year,_month,_day\_n"); 
   14   _scanf("%_d,%_d,%_d",&_year,&_month,&_day); 
   15   SWITCH(_month)/*先计算某月以前月份的总天数*/ 
   16   { 
   17    CASE 1.000000:_sum=0.000000;BREAK; 
   18    CASE 2.000000:_sum=31.000000;BREAK; 
   19    CASE 3.000000:_sum=59.000000;BREAK; 
   20    CASE 4.000000:_sum=90.000000;BREAK; 
   21    CASE 5.000000:_sum=120.000000;BREAK; 
   22    CASE 6.000000:_sum=151.000000;BREAK; 
   23    CASE 7.000000:_sum=181.000000;BREAK; 
   24    CASE 8.000000:_sum=212.000000;BREAK; 
   25    CASE 9.000000:_sum=243.000000;BREAK; 
   26    CASE 10.000000:_sum=273.000000;BREAK; 
   27    CASE 11.000000:_sum=304.000000;BREAK; 
   28    CASE 12.000000:_sum=334.000000;BREAK; 
   29    _defaultrintf("_data _error");BREAK; 
   30   } 
   31   _sum=_sum+_day;  /*再加上某天的天数*/ 
   32   IF(_year%400.000000==0.000000||(_year%4.000000==0.000000&&_year%100.000000!=0.000000))/*判断是不是闰年*/ 
   33    _leap=1.000000; 
   34    ELSE 
   35     _leap=0.000000; 
   36   IF(_leap==1.000000&&_month>2.000000)/*如果是闰年且月份大于2.000000,总天数应该加一天*/ 
   37   _sum++; 
   38   _printf("_it _is _the %_dth _day.",_sum);
   39  
   40   } 


感受:

啊,好久没发博客了啊。

今天突然有一种感觉:当一个程序员也挺不错的。

之前一直不能正视自己,一直在想自己以后(应该?或许?肯定?)不会是一个程序员把,因为我感觉要是整天编程不是太无聊了。

今天产生的新想法产生的原因挺多的吧,可能是这个行业可以靠自己的努力赢得自己的一席之地(前几天听某个老师说时才有所体会),可能是我还有一些想法需要通过它来实现,总之这应该不是我的三分钟热度之词..

要当一个程序员,对我来说真的是任重而道远,因为之前一直无法真正投入到这里面,即使到现在也还是不行,但是态度却转变了很多。

看看自己之前发过的博客,完全不知道自己在做什么啊,好像做了一点就觉得自己好吊的样子,哈哈...悲剧,看了自己都好害臊啊。

努力的人真的是好多,当自己开始有一点点努力的时候才会发现,之前自己还是“井底之蛙”时,去上一个晚自习就感觉自己好了不起了,甚至觉得就我这样,谁还能比我更努力,哈哈....现在感觉那时自己真....

正如贺老曾经说的,大一时不知道自己不知道,大二时知道自己不知道。既然知道了就努力把。

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值