本来应该在4月20日写的,由于种种原因没有写,今天将它补起来.这是正式的按君子抉中的计划来写博客的第二天,今天搞那个垂直搜索搞了一上午,以前还感觉搞这个有点激情,现在感觉完全是一种累赘,还得写文档,麻烦啊.下午才干了点真正有点意思的东西-----flex.

   以前从来没有接触过flex,那次听兴旺说要做一个自动的词法分析器,用flex来实现,研究了半天,最后总算明白了.而且今天我才明白原来编程最痛苦的事不是代码怎么写,而是在哪里编写代码.刚开始在网上搜索了半天,都是讲解flex的程序怎么编写,就是没说,写了在哪里进行编译.最后找了半天,明白了.

   先下载flex-2.5.4a-1.exe,然后进行安装,我是安装到了D:\GnuWin32,然后在环境变量的path加上一句:  ;D:\GnuWin32\bin

再到DOS命令下进行测试安装好了没有,输入 flex -V 即可.这个是大写V.之后就是编写.l文件.编写好.l文件之后,在DOS命令行下定位到你的.l文件的目录,让后输入flex test.l 回车即可.这里test.l是你的.l文件的文件名.让后在test.l文件的同一目录就会生成一个 lex.yy.c.这个文件就可以在Visual Studio中进行编译了.下面这个是我改写的词法分析器的flex的.l文件的代码.

      

%{
#include
<stdio.h>
#include
<stdlib.h>
/*保留字*/
#include
<string.h>
char *key[]={" ","auto","break","case","char","const","continue","default","do","double",
"else","enum","extern","float","for","goto","if","int","long","register",
"return","short","signed","sizeof","static","struct","switch","typedef",
"union","unsigned","void","volatile","while"}; 

int IsKeyWord(char *lex) ;/* 判断字符串是否是保留字 */

void print();                            //输出token序列;
void main(int argc,char*argv[]);         //主函数;
struct token{                            //二元组;
      char*idproperty;    //token属性值;
      char*idname;    //识别的token名字;
}entity[1000];     //定义1000个这样的token,大小可改变;
char*filename;                           //保存结果的文件名;
int errnum=0;     //错误token的数目;
int value;     //属性值int型;
int linenum=1;     //行数;
int count=0;     //token的个数;
int flag=0;
FILE
*fpin;     //测试文件指针;
FILE*fpout;     //结果文件指针;
%}
digit         [
0-9]
letter        [_a
-zA-Z]
number        {digit}
+
identifier    {letter}({letter}
|{digit})*
wrongid       ({digit}
+){letter}({letter}|{digit})*
newline       [\n]
whitespace    [\t]
+
allchar             [
^0]|0
string_l            \
"{allchar}?\"
%%
{string_l}        {value
=6;print();}                                            //字符串常量
{identifier}   {value=IsKeyWord(yytext); print();}  //标识符---0 关键字---1
{wrongid}   {value=7;print();}                                        //错误标识符
{number}   {value=2;print();}                                            //数字常量


"++"         |
"--"         |
"->"      |
"&&"    |
"||"    |
"<="    |
"=="       |
"!="    |
">="    |
">>"    |
"<<"    |
"*="    |
"/="    |
"%="      |
"+="    |
"-="    |
"&="    |
"|="    |
"^="                    {value=4;print();}            /*组合运算符*/
"+"            |
"-"            |
"*"            |
"/"         |
 
"!"    |
"%"     |
"&"     |
"|"                   {value=3;print();}                                /*基本运算符*/
","            |
";"            |
"{"            |
"}"            |
"("            |
")"            |
"."            |
"#"            |
"'"              {value=5;print();}                /*分界符*/
{newline}   {linenum
+=1;}
{whitespace}   {;}
" "    {;}
.    {value
=7;print();}                 /*其他不识别*/
%%
int yywrap()
{  
    fclose(fpin);
    
return 1;
}

void print()
{
    count
+=1;
    
if(flag!=1){
       
if((fpout=fopen(filename,"a"))==NULL){
           printf(
"无法打开文件! \n");
           exit(
0);
       }
    }
    
if(value<=6){
       
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="字符串常量";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="错误标识符:";break;
               
case 7:entity[count-1].idproperty="不识别:";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);
}
/* 判断字符串是否是保留字 */

/*    如果不是就返回 0 */

int IsKeyWord(char *lex) 

    
int i;
    
for( i=1;i<=32;i++)
    { 
        
if(strcmp(lex,key[i]) == 0
            
return 1
    } 
    
return 0
}
void main(int argc,char*argv[])
{
    
if(argc==1){
      printf(
"please input the C program(ctrl+z to end) \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();


}


 

 image004 image002