Windows中使用Lex(Win flex-bison)

Lex是Lexical Analyzer Generator(取前三个字母)的缩写,是Unix环境下非常著名的工具,主要功能是生成一个词法分析器(scanner)的C源码,描述规则采用正则表达式(regular expression)

Lex已经广泛地用于描述各种语言的词法分析器

flex (the fast lexical analyser)意思是快速词法分析器

Win-flex bison是flex和bison在Windows平台的一个移植版本,它支持flex(快速词法分析器)和bison(GNU解析器生成器)。

Win-flex bison的下载网址: Win flex-bison download | SourceForge.net 

点击“Download”按钮,开始下载文件“win_flex_bison-latest.zip”,文件大小仅有692KB。

 

解压到自己喜欢的位置。

 

你可以在命令行直接使用win_flex和win_bison,或者在Visual Studio中借助CustomBuildRules使用它们(详见 Win flex-bison / Wiki / Visual Studio custom build rules )

flex/bison文件的例子可参看网页 Win flex-bison - Browse Files at SourceForge.net 

在命令行输入 win_flex --help ,可以获得相关用法:

Usage: win_flex [OPTIONS] [FILE]...

Generates programs that perform pattern-matching on text.

Table Compression:

  -Ca, --align      trade off larger tables for better memory alignment

  -Ce, --ecs        construct equivalence classes

  -Cf               do not compress tables; use -f representation

  -CF               do not compress tables; use -F representation

  -Cm, --meta-ecs   construct meta-equivalence classes

  -Cr, --read       use read() instead of stdio for scanner input

  -f, --full        generate fast, large scanner. Same as -Cfr

  -F, --fast        use alternate table representation. Same as -CFr

  -Cem              default compression (same as --ecs --meta-ecs)

Debugging:

  -d, --debug             enable debug mode in scanner

  -b, --backup            write backing-up information to lex.backup

  -p, --perf-report       write performance report to stderr

  -s, --nodefault         suppress default rule to ECHO unmatched text

  -T, --trace             win_flex should run in trace mode

  -w, --nowarn            do not generate warnings

  -v, --verbose           write summary of scanner statistics to stdout

      --hex               use hexadecimal numbers instead of octal in debug outputs

Files:

  -o, --outfile=FILE      specify output filename

  -S, --skel=FILE         specify skeleton file

  -t, --stdout            write scanner on stdout instead of lex.yy.c

      --yyclass=NAME      name of C++ class

      --header-file=FILE   create a C header file in addition to the scanner

      --tables-file[=FILE] write tables to FILE

Scanner behavior:

  -7, --7bit              generate 7-bit scanner

  -8, --8bit              generate 8-bit scanner

  -B, --batch             generate batch scanner (opposite of -I)

  -i, --case-insensitive  ignore case in patterns

  -l, --lex-compat        maximal compatibility with original lex

  -X, --posix-compat      maximal compatibility with POSIX lex

  -I, --interactive       generate interactive scanner (opposite of -B)

      --yylineno          track line count in yylineno

Generated code:

  -+,  --c++               generate C++ scanner class

  -Dmacro[=defn]           #define macro defn  (default defn is '1')

  -L,  --noline            suppress #line directives in scanner

  -P,  --prefix=STRING     use STRING as prefix instead of "yy"

  -R,  --reentrant         generate a reentrant C scanner

       --bison-bridge      scanner for bison pure parser.

       --bison-locations   include yylloc support.

       --stdinit           initialize yyin/yyout to stdin/stdout

       --nounistd          do not include <unistd.h>

       --wincompat         windows compatibility (uses <io.h> instead of <unistd.h> and _isatty, _fileno functions)

       --noFUNCTION        do not generate a particular FUNCTION

Miscellaneous:

  -c                      do-nothing POSIX option

  -n                      do-nothing POSIX option

  -?

  -h, --help              produce this help message

  -V, --version           report win_flex version

例1

参考网页 Windows环境下lex入门 - 朱迎春 - 博客园 中的例子。

(1)创建文本文件“a.l”(即编写lex程序)

使用文本编辑器创建文件“d:/temp/a.l”,内容如下:

%{

int num_lines = 0, num_chars = 0;

%}

%%

\n      ++num_lines; ++num_chars;

.       ++num_chars;



%%



int main()

{

yyin = fopen("d:/temp/a.l","r");

yylex();

fclose(yyin);

printf("lines = %d, chars = %d\n", num_lines, num_chars);

}



int yywrap()

{

return 1;

}

双百分号“%%”,是lex编译器的专用字符串,用于区分lex程序文件中的声明部分、转换规则(每个规则由模式和动作两部分组成,模式即正则表达式,动作即程序代码)、辅助过程(即C语言编写的函数)。

(2)使用win_flex编译文件“a.l”

在命令行窗口输入命令(wincompat参数,命令lex编译器创建Windows兼容的程序),:

D:\Programs\win_flex_bison-latest\win_flex.exe --wincompat --outfile=d:/temp/a.yy.c d:/temp/a.l

正常执行后,生成文件“d:/temp/a.yy.c”,这个文件较大,内容较多。

3使用C语言编译器编译a.yy.c

我使用的C语言编译器是Visual Studio 2022。进入VS2022的开发者命令行窗口,进入目录“d:\temp”执行如下编译命令: cl a.yy.c

命令执行成功后,在目录中生成文件“a.yy.exe”和“a.yy.obj”.

关于进入VS2022的开发者命令行窗口的方法,可参看网页 今日头条 的相关部分。

(4)运行程序文件“a.yy.exe”

在命令行窗口运行命令“a.yy”,结果如下图所示:

该程序的运行结果是,对文件中的行数和字符数进行计数。

例2

参考网页 windows 下使用lex_铿老爷的博客-CSDN博客_lex windows 中的例子。

(1)创建文本文件“a.l”(即编写lex程序)

使用文本编辑器创建文件“d:/temp/b.l”,内容如下:

%{  

    #include <stdio.h>  

    #include <stdlib.h>   

    int count = 0;  

%}   

  

delim [" "\n\t\r]   

whitespace {delim}+   

operator \+|-|\*|\/|:=|>=|<=|#|=|<<|>>|\+\+

reservedWord int|include|main|return|using|if|namespace

delimiter [,\.;\(\)\"\<\>\{\}]

constant ([0-9])+

identfier [A-Za-z]([A-Za-z]|[0-9])*  

%%   

{reservedWord} {count++;printf("%d\t(rw,%s)\n",count,yytext);}  

\"[^\"]*\" {count++;printf("%d\t(ct,%s)\n",count,yytext);}

{operator} { count++;printf("%d\t(op,%s)\n",count,yytext); }  

{delimiter} {count++;printf("%d\t(de,%s)\n",count,yytext);}  

{constant} {count++;printf("%d\t(ct,%s)\n",count,yytext);}  

{identfier} {count++;printf("%d\t(id,%s)\n",count,yytext);}   

{whitespace} { /* do    nothing*/ }

%%



int main()

{

yyin = fopen("d:/temp/input.txt","r");

yylex();

fclose(yyin);

}

int yywrap()

{

return 1;

}

上述程序中使用的“d:/temp/input.txt”文件内容

#include<iostream>

using namespace std;

int main(){

cout<<"Hello World!"<<a + b = i++;

}

(2)使用win_flex编译文件“b.l”

在命令行窗口输入命令(wincompat参数,命令lex编译器创建Windows兼容的程序),:

D:\Programs\win_flex_bison-latest\win_flex.exe --wincompat --outfile=d:/temp/b.yy.c d:/temp/b.l

正常执行后,生成文件“d:/temp/b.yy.c”,这个文件较大,内容较多。

3使用C语言编译器编译b.yy.c

我使用的C语言编译器是Visual Studio 2022。进入VS2022的开发者命令行窗口,进入目录“d:\temp”执行如下编译命令: cl b.yy.c

命令执行成功后,在目录中生成文件“b.yy.exe”和“b.yy.obj”。

(4)运行程序文件“b.yy.exe”

在命令行窗口运行命令“b.yy”,结果如下图所示:

 

但是有个问题,就是在“d:/temp/input.txt”文件的”Hello World”的左边的双引号前面添加空格,就会导致程序的结果不同(不符合预期),这个问题原因还找不到。

小结

通过上面两个例子,可以看出在Windows中使用Lex的步骤为:

  1. 编写lex程序。即扩展名为“.l”的文本文件。
  2. 编译lex程序。即使用win_flex.exe处理lex程序得到扩展名为“.c”的文件。
  3. 得到可执行的程序。即使用C语言编译器,生成扩展名为“.exe”的文件。
  4. 运行可执行程序。

相关网页

lex(计算机领域的词法分析器)_百度百科 ,lex计算机领域的词法分析器

Win flex-bison - Browse Files at SourceForge.net , Win flex-bison Files

Windows环境下lex入门 - 朱迎春 - 博客园 ,Windows环境下lex入门

windows 下使用lex_铿老爷的博客-CSDN博客_lex windows ,windows 下使用lex

今日头条 ,SQLite 3.37.2源码下载及编译(Win10+VS2022)

 

 

  • 7
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Alexabc3000

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值