资源描述
实 验 报 告
实验项目名称:用lex构造c子集词法分析器
学时:2学时
一.实验目的和要求
用lex构造c子集词法分析器,能实现识别c子集源程序的单词序列。
二.实验环境
VC/tc dos
三.实验过程
A:lex使用方法
1在“运行“中输入:cmd进入dos环境
2 进入LEX所在文件夹。
(cd 命令若LEX在f盘根目录下
>f:
>cd lex
3 LEX使用步骤:(直接在屏幕显示词法分析结果,不保留的)
1、编写LEX源程序,如“1.L”,将“1.L”与FLEX.EXE保存在同一文件夹下。
2、进入DOS环境FLEX.EXE所在文件夹,运行FLEX.EXE程序。
Ø FLEX 1.L
3、运行FLEX后,产生“LEXYY.C”程序
4、用VC打开“LEXYY.C”程序,编译后产生“LEXYY.EXE”程序。
5、进入DOS环境“LEXYY.EXE”所在文件夹,编写1.c程序,运行“LEXYY.EXE”程序。
>LEXYY.EXE 1.c 的结果。
1.L源程序:实现功能 将所有小写字母转换成大写。
%{
#include <stdio.h>
%}
%%
[a-z] printf("%c",yytext[0]+'A'-'a');
%%
main( argc, argv )
int argc;
char **argv;
{
++argv, --argc; /* skip over program name */
if ( argc > 0 )
yyin = fopen( argv[0], "r" );//yyin存放LEXYY的输入源程序
else
yyin = stdin;
++argv, --argc; /* skip over input name */
if ( argc > 0 )
yyout = fopen( argv[0], "w" );//yyout存放LEXYY的输出程序
else
yyout = stdout;
yylex();
}
int yywrap()
{
return 1;
}
B:构造c子集词法分析器
1、编写c子集的LEX源程序,如“lex.L”,将“lex.L”与FLEX.EXE保存在同一文件夹下。
2、运行FLEX.EXE程序。
3、运行FLEX后,产生“LEXYY.C”程序
4、用VC打开“LEXYY.C”程序,编译后产生“LEXYY.EXE”程序。
5、编写一个c子集源程序A.c (每个人的源程序不相同)
main()
{
int a;real b;
a=2*32;b=3.124;
}
运行“LEXYY.EXE”程序。
>LEXYY.EXE A.c 看词法分析的结果。
四 实验结果
将词法分析的结果抄到实验报告
五:错误分析
由于该词法分析程序是分析c子集,case等关键字不能识别,字符型不能识别,部分运算符号和界符不能识别。编写c源程序需注意c子集范围。
Lex1.L 源程序:
%{
#include <stdio.h>
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
%}
digit [0-9]
number {digit}+
letter [a-zA-Z]
identifier {letter}+
newline [\n]
whitespace [ \t]+
%%
"main" printf("baoliuzi: %s\n", yytext);
"if" printf("baoliuzi: %s\n", yytext);
"else" printf("baoliuzi: %s\n", yytext);
"for" printf("baoliuzi: %s\n", yytext);
"while" printf("baoliuzi: %s\n", yytext);
"do" printf("baoliuzi: %s\n", yytext);
"int" printf("baoliuzi: %s\n", yytext);
"=" printf("yunsuanfu: %s\n", yytext);
"+" printf("yunsuanfu: %s\n", yytext);
"-" printf("yunsuanfu: %s\n", yytext);
"*" printf("yunsuanfu: %s\n", yytext);
"/" printf("yunsuanfu:%s\n", yytext);
"<" printf("yunsuanfu: %s\n", yytext);
">" printf("yunsuanfu: %s\n", yytext);
"(" printf("jiefu: %s\n", yytext);
")" printf("jiefu: %s\n", yytext);
"[" printf("jiefu: %s\n", yytext);
"]" printf("jiefu: %s\n", yytext);
"{" printf("jiefu: %s\n", yytext);
"}" printf("jiefu: %s\n", yytext);
";" printf("jiefu: %s\n", yytext);
":" printf("jiefu: %s\n", yytext);
"'" printf("jiefu: %s\n", yytext);
"\"" printf("yunsuanfu: %s\n", yytext);
"," printf("jiefu: %s\n", yytext);
"==" printf("yunsuanfu: %s\n", yytext);
">=" printf("yunsuanfu: %s\n", yytext);
"<=" printf("yunsuanfu: %s\n", yytext);
"!=" printf("yunsuanfu: %s\n", yytext);
{number} printf("int: %s length:%d\n",yytext,yyleng); //求数字的长度
{identifier} printf("id: %s\n",yytext);
{whitespace} {/* skip whitespace */}
"/*" { char c ;
int done = FALSE;
do
{ while ((c=input())!='*');
while ( (c=input()) == '*');
if (c == '/') done = TRUE;
} while (!done);
}
. {fprintf(yyout,"%s, %s\n", "ERROR",yytext);}
%%
main( argc, argv )
int argc;
char **argv;
{
++argv, --argc; /* skip over program name */
if ( argc > 0 )
yyin = fopen( argv[0], "r" );//yyin存放LEXYY的输入源程序
else
yyin = stdin;
++argv, --argc; /* skip over input name */
if ( argc > 0 )
yyout = fopen( argv[0], "w" );//yyout存放LEXYY的输出程序
else
yyout = stdout;
yylex();
}
int yywrap()
{
return 1;
}
思考题:
1该源程序中只给出了标识符符定义为字母,如何将规则改为识别字母数字的?
2 参照整型变量的定义,怎样将实型变量定义出来?
3 完善定义部分。
附录:
若需要将词法分析器结果作为文件保留起来的,则需要修改程序
LEX使用步骤:(需要将词法分析器结果保留起来的)
1、编写LEX源程序,如“Cffx.l”,将“Cffx.l”与FLEX.EXE保存在同一文件夹下。
2、进入DOS环境FLEX.EXE所在文件夹,运行FLEX.EXE程序。
Ø FLEX cffx.l
3、运行FLEX后,产生“LEXYY.C”程序
4、用VC打开“LEXYY.C”程序,编译后产生“LEXYY.EXE”程序。
5、编写C子集语言源程序,保存为A.TEST,并与“LEXYY.EXE”保存在同一文件夹下。
6、进入DOS环境“LEXYY.EXE”所在文件夹,运行“LEXYY.EXE”程序。
>LEXYY.EXE A.TEST B.TXT
7、打开“B.TXT”,看词法分析的结果。
Cffx.l源程序:
%{
#include <stdio.h>
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
%}
digit [0-9]
number {digit}+
letter [a-zA-Z]
identifier {letter}+
newline [\n]
whitespace [ \t]+
%%
"if" {fprintf(yyout,"%s %s\n", yytext,yytext);}
"else" {fprintf(yyout,"%s %s\n", yytext,yytext);}
"for" {fprintf(yyout,"%s %s\n", yytext,yytext);}
"while" {fprintf(yyout,"%s %s\n", yytext,yytext);}
"do" {fprintf(yyout,"%s %s\n", yytext,yytext);}
"int" {fprintf(yyout,"%s %s\n", yytext,yytext);}
"=" {fprintf(yyout,"%s %s\n", yytext,yytext);}
"+" {fprintf(yyout,"%s %s\n", yytext,yytext);}
"-" {fprintf(yyout,"%s %s\n", yytext,yytext);}
"*" {fprintf(yyout,"%s %s\n", yytext,yytext);}
"/" {fprintf(yyout,"%s %s\n", yytext,yytext);}
"<" {fprintf(yyout,"%s %s\n", yytext,yytext);}
">" {fprintf(yyout,"%s %s\n", yytext,yytext);}
"(" {fprintf(yyout,"%s %s\n", yytext,yytext);}
")" {fprintf(yyout,"%s %s\n", yytext,yytext);}
"[" {fprintf(yyout,"%s %s\n", yytext,yytext);}
"]" {fprintf(yyout,"%s %s\n", yytext,yytext);}
"{" {fprintf(yyout,"%s %s\n", yytext,yytext);}
"}" {fprintf(yyout,"%s %s\n", yytext,yytext);}
";" {fprintf(yyout,"%s %s\n", yytext,yytext);}
":" {fprintf(yyout,"%s %s\n", yytext,yytext);}
"'" {fprintf(yyout,"%s %s\n", yytext,yytext);}
"\"" {fprintf(yyout,"%s %s\n", yytext,yytext);}
"," {fprintf(yyout,"%s %s\n", yytext,yytext);}
"==" {fprintf(yyout,"%s %s\n", yytext,yytext);}
">=" {fprintf(yyout,"%s %s\n", yytext,yytext);}
"<=" {fprintf(yyout,"%s %s\n", yytext,yytext);}
"!=" {fprintf(yyout,"%s %s\n", yytext,yytext);}
{number} {fprintf(yyout,"%s %s\n", "NUM",yytext);}
{identifier} {fprintf(yyout,"%s %s\n", "ID",yytext);}
{whitespace} {/* skip whitespace */}
"/*" { char c ;
int done = FALSE;
do
{ while ((c=input())!='*');
while ( (c=input()) == '*');
if (c == '/') done = TRUE;
} while (!done);
}
. {fprintf(yyout,"%s, %s\n", "ERROR",yytext);}
%%
main( argc, argv )
int argc;
char **argv;
{
++argv, --argc; /* skip over program name */
if ( argc > 0 )
yyin = fopen( argv[0], "r" );//yyin存放LEXYY的输入源程序
else
yyin = stdin;
++argv, --argc; /* skip over input name */
if ( argc > 0 )
yyout = fopen( argv[0], "w" );//yyout存放LEXYY的输出程序
else
yyout = stdout;
yylex();
}
int yywrap()
{
return 1;
}
展开阅读全文