专业课程

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

2020-05-09  本文已影响0人  YAOPRINCESS

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

2、程序源码

%{
#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、测试及输出文件

上一篇 下一篇

猜你喜欢

热点阅读