词法分析的各类用途2
一. 目的:
使我们明白词法分析的作用不仅仅在于写词法分析器,它还有很多其他用途。
二. 内容:
写一个lex程序,它读入一个c语言文件,将其中所有的float关键字都替换成double关键字。
三.要求:
输入为一个C语言源文件;输出为新的C语言源文件,该文件在原输入的基础上将float关键字替换成double关键字。
注意:必须是float关键字,如果是afloat或者floata这样的id不可以被替换为adouble和doublea。
在cygwin下用flex和gcc工具将实验调试通过,并写出测试例测试正确性。
四.源代码:
4.l:
%{
#include <stdio.h>
#define LT 1
#define LE 2
#define GT 3
#define GE 4
#define EQ 5
#define NE 6
#define WS 15
<strong>#define DOUBLE 16
#define FLOAT 17</strong>
#define WHILE 18
#define DO 19
#define ID 20
#define NUMBER 21
#define RELOP 22
#define NEWLINE 23
#define ERRORCHAR 24
int yylval;
%}
delim [ \t \n]
ws {delim}+
letter [A-Za-z]
digit [0-9]
id {letter}({letter}|{digit})*
number {digit}+(\.{digit}+)?(E[+-]?{digit}+)?
%%
{ws} {return (WS);/* 此时词法分析器没有动作,也不返回,而是继续分析。
<strong>float {return (FLOAT);}
double {return (DOUBLE);}</strong>
while {return (WHILE);}
do {return (DO);}
{id} {yylval = installID (); return (ID);}
{number} {yylval = 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);}
. {yylval = ERRORCHAR; return ERRORCHAR;}
/*.匹配除换行之外的任何字符,一般可作为最后一条翻译规则。*/
%%
int installID () {
/* 把词法单元装入符号表并返回指针。*/
return ID;
}
int installNum () {
/* 类似上面的过程,但词法单元不是标识符而是数 */
return NUMBER;
}
int yywrap (){
return 1;
}
void writeout(int c){
switch(c){
case ERRORCHAR: fprintf(yyout, "%s", yytext);break;
case WS: fprintf(yyout, "%s", yytext);break;
<strong>case DOUBLE: fprintf(yyout, "%s", yytext);break;
case FLOAT: fprintf(yyout, "double", yytext);break;</strong>
case RELOP: fprintf(yyout, "%s", yytext);break;
case WHILE: fprintf(yyout, "%s", yytext);break;
case DO: fprintf(yyout, "%s", yytext);break;
case NUMBER: fprintf(yyout, "%s", yytext);break;
case ID: fprintf(yyout, "%s", yytext);break;
case NEWLINE: fprintf(yyout, "\n");break;
default:break;
}
return;
}
int main (int argc, char ** argv){
int c,j=0;
if (argc>=2){
if ((yyin = fopen(argv[1], "r")) == NULL){
printf("Can't open file %s\n", argv[1]);
return 1;
}
if (argc>=3){
yyout=fopen(argv[2], "w");
}
}
while (c = yylex()){
writeout(c);
j++;
if (j%5 == 0) writeout(NEWLINE);
}
if(argc>=2){
fclose(yyin);
if (argc>=3) fclose(yyout);
}
return 0;
}<strong>
</strong>
五.结果及分析:
处理前的t1.c:
#include<stdio.h>
void main()
{
int i,j;
<strong>float a,b;
double c;
int afloat,floatb;</strong>
i=1;
j=i;
a=b=0;
while((j+i)<100)
{
a+=b;
b++;
}
}
处理后的t2.c:
#include<stdio.h>
void main()
{
int i,j;
<strong>double a,b;
double c;
int afloat,floatb;</strong>
i=1;
j=i;
a=b=0;
while((j+i)<100)
{
a+=b;
b++;
}
}
输入t1.c,输出为t2,c,词法分析器将文件t1.c文件中的float关键字替换成double关键字,并在t2,p中输出。注意上述t2.c中的输出结果:t1.c中的float关键字在t2.c中变为double关键字,而ID afloat,floatb中的float则未被替换。