美文网首页专业课程
使用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编写一个词法分析器

    1、编译步骤 vim lexical.lex flex lexical.lex //生成lex.yy.c文件...

  • 词法分析器

    词法分析器 词法分析器又称扫描器。词法分析是指将我们编写的文本代码流解析为一个一个的记号,分析得到的记号(Toke...

  • PHP核心理解-flex和bison入门

    一般词法分析器和语法分析器会一起使用,语法分析器会调用词法分析器来读取输入,词法分析器匹配到特定的模式后,就向语法...

  • 一个编译器最简前端的python实现

    一个编译器的前端通常包括词法分析器和语法分析器。在分析过程中,文本输入词法分析器,根据词法规则解析出词法单元。词法...

  • Lex和Yacc

    Lex和Yacc的分工 Lex用于词法分析,Yacc用于语法分析,二者可以单独使用,亦可配合工作。Yacc和Lex...

  • 龙书 第三章

    词法单元:词法分析器扫描源程序并输出一个由词法单元组成的序列。这些词法单元通常会逐个传送给语法分析器。有些词法单元...

  • 编译原理->词法分析

    词法分析器的作用 词法分析器的主要任务是读入源程序的输入字符、将它们组成词素,生成并输出一个词法单元序列,每个词法...

  • llvm学习日记四:使用lexer

    参考书:《Getting Started with LLVM Core Libraries》 词法分析器使用,参考...

  • 三. Flex进阶:需要了解的一些知识

    参考:词法分析器生成工具flex词法分析器总结--flex&bison词法分析生成器flex的选项 1. Flex...

  • 自己动手制作C 语言编译器(3):词法分析器

    本章我们要讲解如何构建词法分析器。 什么是词法分析器 简而言之,词法分析器用于对源码字符串做预处理,以减少语法分析...

网友评论

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

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