美文网首页专业课程
使用lex编写一个词法分析器

使用lex编写一个词法分析器

作者: YAOPRINCESS | 来源:发表于2020-05-09 13:46 被阅读0次

    1、编译步骤

    • vim lexical.lex
    • flex lexical.lex //生成lex.yy.c文件
    • gcc -o lexical.exe lex.yy.c -lfl //生成可执行文件 -lfl链接flex的库函数
    • touch test.txt //创建测试文件
    • //选择一:使用文件读写
      • vim test.txt //写入要测试的语句
      • touch out.txt //结果输出到该文件里
      • ./lexical.exe test.txt out.txt //运行程序
      • cat out.txt //查看结果
    • //选择二:直接运行程序边写边分析
      • ./lexical.exe
    vim lexical.lex
    flex lexical.lex    //生成lex.yy.c文件
    gcc -o lexical.exe  lex.yy.c    -lfl    //生成可执行文件   -lfl链接flex的库函数
    touch   test.txt    //创建测试文件
    //选择一:使用文件读写
    vim test.txt    //写入要测试的语句
    touch   out.txt //结果输出到该文件里
    ./lexical.exe   test.txt    out.txt //运行程序
    cat out.txt //查看结果
    //选择二:直接运行程序边写边分析
    ./lexical.exe
    

    2、程序源码

    • lexical.lex
    %{
    #include<stdio.h>
    #define LT 1
    #define LE 2
    #define GT 3
    #define GE 4
    #define EQ 5
    
    #define ADD 6
    #define DEC 7
    #define MUL 8
    #define DIV 9
    
    #define SEM 10
    
    #define LB 11
    #define RB 12
    #define BLB 13
    #define BRB 14
    
    #define WHILE   18
    #define DO  19
    #define IF  20
    #define THEN    21
    #define ELSE    22
    #define FOR 23
    #define ID      24
    #define NUMBER  25
    
    #define REAL8   26
    #define REAL10  27
    #define REAL16  28
    
    #define INT8    29
    #define INT10   30
    #define INT16   31
    
    #define NEWLINE 40
    #define ERRORCHAR 41
    
    int yylval;
    %}
    
    delim   [ \t\n]
    whitespace  {delim}+
    digit   [0-9]
    letter  [A-Za-z_]
    id  {letter}({letter}|{digit})*
    number  {digit}+(\.{digit}+)?([eE][+-]?{digit}+)?
    
    int8    (0([0-7])+)
    int10   ([1-9]|[1-9]([0-9])+|0)
    int16   (0[xX]([A-Fa-f0-9])+)
    
    real8   (0([0-7])+\.([0-7])*)
    real10  (([1-9]|[1-9]([0-9])+)\.[0-9]+|0\.([0-9])+)
    real16  0[xX]([A-Fa-f0-9])+\.([A-Fa-f0-9])*
    
    %%
    {whitespace}    {;}
    (while|WHILE)   {return (WHILE);}
    (do|DO)     {return (DO);}
    (if|IF)         {return (IF);}
    (then|THEN)         {return (THEN);}
    (else|ELSE)         {return (ELSE);}
    (for|FOR)         {return (FOR);}
    
    {id}        {return (ID);}
    
    
    {int8}      {return (INT8);}
    {int10}     {return (INT10);}
    {int16}     {return (INT16);}
    
    {real8}     {return (REAL8);}
    {real10}    {return (REAL10);}
    {real16}    {return (REAL16);}
    
    "<"     {return (LT);}
    "<="             {return (LE);}
    ">"             {return (GT);}
    ">="             {return (GE);}
    "="             {return (EQ);}
    "+"             {return (ADD);}
    "-"             {return (DEC);}
    "*"             {return (MUL);}
    "/"             {return (DIV);}
    ";"             {return (SEM);}
    "("             {return (LB);}
    ")"             {return (RB);}
    "{"     {return (BLB);}
    "}"     {return (BRB);}
    
    .       {return (ERRORCHAR);}
    
    %%
    int yywrap(){
        return 1;
    }
    
    void writeout(int c){
        switch(c){
            case ERRORCHAR:fprintf(yyout,"(ERRORCHAR,\"%s\")",yytext);
                break;
    case INT10:fprintf(yyout,"(INT10,\"%s\")",yytext);
                            break;
    
     case INT16:fprintf(yyout,"(INT16,\"%s\")",yytext);
                            break;
    
                case INT8:fprintf(yyout,"(INT8,\"%s\")",yytext);
                            break; 
            case WHILE:fprintf(yyout,"(WHILE,\"%s\")",yytext);
                            break; 
            case DO:fprintf(yyout,"(DO,\"%s\")",yytext);
                            break; 
            case IF:fprintf(yyout,"(IF,\"%s\")",yytext);
                            break; 
            case THEN:fprintf(yyout,"(THEN,\"%s\")",yytext);
                            break; 
            case ELSE:fprintf(yyout,"(ELSE,\"%s\")",yytext);
                            break; 
            case FOR:fprintf(yyout,"(FOR,\"%s\")",yytext);
                            break; 
            case ID:fprintf(yyout,"(ID,\"%s\")",yytext);
                            break; 
            //case NUMBER:fprintf(yyout,"(NUMBER,\"%s\")",yytext);
                    //      break;
            case RB:fprintf(yyout,"(RB,\"%s\")",yytext);
                            break; 
            case LB:fprintf(yyout,"(LB,\"%s\")",yytext);
                            break; 
            case SEM:fprintf(yyout,"(SEM,\"%s\")",yytext);
                            break; 
            case DIV:fprintf(yyout,"(DIV,\"%s\")",yytext);
                            break; 
            case MUL:fprintf(yyout,"(MUL,\"%s\")",yytext);
                            break; 
            case DEC:fprintf(yyout,"(DEC,\"%s\")",yytext);
                            break; 
            case ADD:fprintf(yyout,"(ADD,\"%s\")",yytext);
                            break; 
            case EQ:fprintf(yyout,"(EQ,\"%s\")",yytext);
                            break; 
            case GE:fprintf(yyout,"(GE,\"%s\")",yytext);
                            break; 
            case GT:fprintf(yyout,"(GT,\"%s\")",yytext);
                            break; 
            case LE:fprintf(yyout,"(LE,\"%s\")",yytext);
                            break; 
            case LT:fprintf(yyout,"(LT,\"%s\")",yytext);
                            break; 
            case BLB:fprintf(yyout,"(BLB,\"%s\")",yytext);
                break;
            case BRB:fprintf(yyout,"(BRB,\"%s\")",yytext);
                break;
            case NEWLINE:fprintf(yyout,"\n");
                break; 
            case REAL8:fprintf(yyout,"(REAL8,\"%s\")",yytext);
                            break; 
            case REAL10:fprintf(yyout,"(REAL10,\"%s\")",yytext);
                            break; 
            case REAL16:fprintf(yyout,"(REAL16,\"%s\")",yytext);
                            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;
    }
    

    3、测试及输出文件

    • test.txt

      0 92+data> 0x3f 00 while a+acc>xx do x=x-1;
      a=6.2+a*0X88.80;
      if a>b then a=b else a=b-1+c;
      
    • out.txt

      (INT10,"0")(INT10,"92")(ADD,"+")(ID,"data")(GT,">")
      (INT16,"0x3f")(INT8,"00")(WHILE,"while")(ID,"a")(ADD,"+")
      (ID,"acc")(GT,">")(ID,"xx")(DO,"do")(ID,"x")
      (EQ,"=")(ID,"x")(DEC,"-")(INT10,"1")(SEM,";")
      (ID,"a")(EQ,"=")(REAL10,"6.2")(ADD,"+")(ID,"a")
      (MUL,"*")(REAL16,"0X88.80")(SEM,";")(IF,"if")(ID,"a")
      (GT,">")(ID,"b")(THEN,"then")(ID,"a")(EQ,"=")
      (ID,"b")(ELSE,"else")(ID,"a")(EQ,"=")(ID,"b")
      (DEC,"-")(INT10,"1")(ADD,"+")(ID,"c")(SEM,";")
      

    相关文章

      网友评论

        本文标题:使用lex编写一个词法分析器

        本文链接:https://www.haomeiwen.com/subject/unkknhtx.html