词法分析 flex 应用

来源:互联网 发布:怎么样才能学好编程 编辑:程序博客网 时间:2024/06/05 11:51

 代码:
%{
#include<stdio.h>
#include<stdlib.h>
void print();                            //输出token序列;
void main(int argc,char*argv[]);         //主函数;
struct token{                            //二元组;
char*idproperty;    //token属性值;
char*idname;    //识别的token名字;
}entity[100];     //定义100个这样的token,大小可改变;
char*filename;                           //保存结果的文件名;
int errnum=0;     //错误token的数目;
int value;     //属性值int型;
int linenum=1;     //行数;
int count=0;     //token的个数;
int flag=0;
FILE*fpin;     //测试文件指针;
FILE*fpout;     //结果文件指针;
%}

newline              [/n]
whitespace           [/t]+
nondigit [_a-zA-Z]
digit [0-9]
wrongid              ({digit}+){nondigit}({nondigit}|{digit})*
identifier {nondigit}({digit}|{nondigit})*
unsigned_suffix u|U
long_suffix l|L
integer_suffix {unsigned_suffix}{long_suffix}?|{long_suffix}{unsigned_suffix}?
nonzero_digit [1-9]
octal_digit [0-7]
hex_digit [0-9a-fA-F]
dec_constant {nonzero_digit}{digit}*
octal_constant 0{octal_digit}*
hex_constant 0(x|X){hex_digit}*
integer_constant ({dec_constant}|{octal_constant}|{hex_constant}){integer_suffix}?|/'{c_char_sequence}/'
simple_escape_sequence [/'/"/?///a/b/f/n/r/t/v]
hex_escape_sequence //x{hex_digit}+
octal_escape_sequence //{octal_digit}{1,3}
escape_sequence {simple_escape_sequence}|{octal_escape_sequence}|{hex_escape_sequence}
c_char [^/'///n]|{escape_sequence}
c_char_sequence {c_char}+
character_constant [L]?/'{c_char_sequence}/'
floating_suffix [fFlL]
digit_sequence {digit}+
sign [+-]
exponent_part [eE]{sign}?{digit_sequence}
fractional_constant {digit_sequence}?/.{digit_sequence}|{digit_sequence}/.
floating_constant {fractional_constant}{exponent_part}?{floating_suffix}?|{digit_sequence}{exponent_part}{floating_suffix}?
s_char [^/"///n]|{escape_sequence}
s_char_sequence {s_char}+
string_literal [L]?/"{s_char_sequence}?/"

%%
"public" |
"protect" |
"private" |
"super"  |
"void" |
"end"  | 
"else" |
"new"   |
"const"  |
"if"  | 
"then"  |  "interfance"|
"implements" |
"while"  |
"for"   |
"read"  | 
"write"  | 
"switch" |
"static" |
"return" |
"finally" |
"main"   |{value=0;print();}
{string_literal}    {value=1;print();}
{wrongid}   {value=8;print();}
{integer_constant}   {value=2;print();}
{floating_constant} {value=6;print();}
{identifier}   {value=7;print();}

"+"|"-"|"*"|"/"          {value=3;print();}
"<>"  | 
">="  | 
"<="  | 
"=="  | 
"!="  |

"="|"#"|"<"|">"          {value=4;print();}
"("|")"|","|";"  |
"{" |"}"|
"."                   {value=5;print();}




{newline}   {linenum+=1;}
{whitespace}   {;}
" "    {;}
.    {value=9;print();}
%%
int yywrap()
{  
fclose(fpin);
return 1;
}

void print()
{
count+=1;
if(flag!=1){
if((fpout=fopen(filename,"a"))==NULL){
printf("cannot write the file /n");
exit(0);
}
}
if(value<=7){
switch(value){


case 0:entity[count-1].idproperty="是关键字";break;
case 1:entity[count-1].idproperty="是字符串";break;
case 2:entity[count-1].idproperty="是整型变量";break;
case 3:entity[count-1].idproperty="是算术运算符";break;
case 4:entity[count-1].idproperty="是关系运算符";break;
case 5:entity[count-1].idproperty="是界符";break;
case 6:entity[count-1].idproperty="是float型变量";break;
case 7:entity[count-1].idproperty="是标示符";break;
}
entity[count-1].idname=yytext;
fprintf(fpout,"%d < %s , %s > /n",count,entity[count-1].idname,entity[count-1].idproperty);
}else{
errnum+=1;
switch(value){
case 8:entity[count-1].idproperty="Mixed number and letter:";break;
case 9:entity[count-1].idproperty="Unkown operator:";break;
}
entity[count-1].idname=yytext;
fprintf(fpout,"%d [line:%d]:%s/"%s/" /n",count,linenum,entity[count-1].idproperty,entity[count-1].idname);
}
if(flag!=1)fclose(fpout);
}

void main(int argc,char*argv[])
{
if(argc==1){
printf("************ 请输入,验证词法********* /n");
flag=1;
fpin=stdin;
fpout=stdout;
}
if(argc==2)argv[2]="defresult.txt";
filename=argv[2];
if(flag!=1){
if((fpin=fopen(argv[1],"r"))==NULL){
printf("cannot open the file /n");
exit(0);
}
}
yyin=fpin;
yylex();
if(flag!=1){
if((fpout=fopen(filename,"a"))==NULL){
printf("cannot write the file /n");
exit(0);
}
}
fprintf(fpout,"/n");
fprintf(fpout,"%d symbol(s) found. /n %d error(s) found. /n",count,errnum);
fprintf(fpout,"======================================================================= /n");
if(flag!=1)fclose(fpout);
yywrap();


}

在windows下运行:
把上面代码保存为flex.k 下载flex.exe 在DOS下运行 (要到flex.exe的根目录.文件要和flex在同一个目录中)输入:flex flex.k 执行
生成一个lex.yy.c 文件 用vc(或其他C语言编译器)编译 执行 在debug中找到
可执行文件 执行输内容如:




在Linux下运行:(本人Ubuntu9.10)
1.下载flex并安装
2.  执行 flex ab.txt(保存文件名)
3. gcc lex.yy.c(用gcc编译.c文件)
4. 看是否生成a.out文件。执行 ./a.out
5.输入内容进行验证那。

原创粉丝点击