双击安装完成即可直接使用! 目前为止windows下使用lex 最便捷的 方案!
自带编辑器EditPlusPortable,图形化界面编辑与编译操作。同时附带lex与yacc官方文档!
关于Lex和Yacc在windows下使用,网上搜了很多博客论坛,发现现有的介绍绝大部分属于以下两类:
- 使用不同版本的VS来配置环境进行开发;
- 单独对lex和Yacc进行了封装,但仍需要在命令行环境下使用。
这两者对于习惯图形化界面一键操作的同学来说,都不十分便捷。
而现在介绍的这一软件包,完美解决了问题,安装完成便是lex与Yacc的集成开发环境,图形化界面操作,编辑完成后,一键编译!全方位服务到家!
————————————————————————————————————————————
文章目录
0. 前言
为了与网络上目前资源形成区分,本文主要是详细介绍win下lex+yacc集成开发环境的安装与使用,对于lex与yacc的语法不做介绍。选用示例代码亦是入门级代码。
1.【使用界面】
2. 【安装方法】
2.1 下载安装包
软件安装包下载地址:软件包下载地址_CSDN
若下载地址失效可以 私信
或 邮件
联系我(悬停此处显示邮箱地址)
2.2 双击进行安装
2.2.1
点击 `Next`
点击 `I agree`
2.2.2 目标文件夹要避免 “Program Files
”
点击 next
2.3 安装完成
3. 【使用方法】
3.1 编辑Lex
(1)打开 `LexEditor.exe` 进入软件(如无响应,请以管理员方式运行)
(2)点击 `New` > `Lex` 新建一份Lex文档
(3)开始编辑
(4)保存为后缀为 `.l` 的文件
3.2 编辑Yacc
Yacc文档的新建与编辑类似Lex。
3.3 仅编译Lex
此处先给出一份"Lex代码示例_1"
//lex_try.l
%{
#include <stdio.h>
#include <stdlib.h>
int num_num = 0;
int num_id = 0;
%}
INTEGER [-+]?[1-9][0-9]*
ID [a-zA-Z][a-zA-Z_0-9]*
SPACE [ \n\t]
%%
{INTEGER} {num_num++;printf("(num = %d)\n", atoi(yytext));/*打印数字值*/}
{ID} {num_id++;printf("(id = %s)\n", yytext);}
{SPACE} {/*什么也不做,滤掉白字符和其它字符*/}
%%
int main()
{
yylex();
printf("num = %d, id = %d\n", num_num, num_id);
//因为此法分析为一循环,打印总数字数仅当使用文件操作时可读出
return 0;
}
int yywrap()//此函数必须由用户提供,或者声明
{
return 1;//返回1报告文件结尾0标记,为0则继续扫描
}
在编辑完成之后,点击 tools
按顺序进行如下操作:
- 点击
Lex File Compile
(形状为:扳手1) - 点击
Lex Build
(形状为:扳手2) - 点击
Execute exe directly
(形状为:扳手5)
此时即完成了对于Lex文档的编译。
同时,自动生成了 “yy.lex.c” 这一词法分析的c文件。
3.4 Lex和Yacc程序链接并编译-执行
首先根据编辑 Yacc
与Lex
文档(文件放置于同一目录下)
然后,务必根据如下顺序进行操作:
- 通过IDE中的
Yacc Compile
按钮编译yacc程序。(形状为:扳手3) - 通过
Lex File Compile
来编译Lex程序。 - 通过单击
Lex + Yacc Build
按钮来构建程序。(形状为:扳手4) - 单击执行按钮
Execute exe directly
(形状为:扳手5)
此处给出一份已实现的简单计算器的Lex与Yacc代码
:
Lex代码:
%{
#include <stdlib.h>
void yyerror(char *);
#include "y.tab.h"
%}
%%
[0-9]+ { yylval = atoi(yytext); return INTEGER; }
[-+*/\n] return *yytext;
[ \t\n] ;/* 去除空格 */
. yyerror("无效字符");
%%
int yywrap(void) {
return 1;
}
Yacc代码:
%{
#include <stdlib.h>
#include <stdio.h>
int yylex(void);
void yyerror(char *);
%}
%token INTEGER
%left '+' '-' //规定左结合与优先级
%left '*' '/'
%%
program:
program expr '\n' { printf("%d\n", $2); }
|
;
/* 先理解expr,再递归理解program。
* 首先program可以为空,也可以用单单的expr加下“/n”回车符组成
* 结合起来看program定义的就是多个表达式组成的文件内容 */
expr:
INTEGER { $$ = $1; }
| expr '*' expr { $$ = $1 * $3; }
| expr '/' expr { $$ = $1 / $3; }
| expr '+' expr { $$ = $1 + $3; }
| expr '-' expr { $$ = $1 - $3; }
;
/* 可以由单个INTEGER值组成,也可以有多个INTERGER和运算符组合组成。
* 以表达式“1+4/2*3-0”为例,1 4 2 3 都是expr
* 就是expr+expr/expr*expr-expr说到底最后还是个expr。
* 递归思想正好与之相反,逆推下去会发现expr这个规则标记能表示所有的数值运算表达式 */
%%
int main(void) {
yyparse();
return 0;
}
//不知道为什么yyerror()放在main()函数前面就无法编译通过
void yyerror(char *s) {
printf("%s\n", s);
}
4. 【不使用图形界面的CMD替代方法】
这一部分不作为重点,可以参看互联网上的其他资源。仅简单罗列(未做验证)
4.1 仅编译Lex
- 在IDE中单击直接执行CMD按钮。
- 通过键入命令lex .l来编译Lex File。
- 在CMD中通过gcc / cc命令构建Lex文件,例如gcc lex.yy.c -o <程序的可执行名称>
- 通过键入<程序的可执行名称> .exe执行程序
- -o <程序的可执行名称> 参数是可选的,可以通过直接由gcc lex.yy.c进行构建来跳过所述参数,然后通过键入a.exe直接执行程序
4.2 Lex和Yacc程序链接并编译-执行
- 单击IDE中的“执行CMD”按钮。
- 通过键入命令yacc -dy <filename.y>编译Yacc文件
- 通过键入命令lex .l来编译Lex File。
- 在CMD中通过gcc / cc命令构建Lex文件,例如gcc lex.yy.c y.tab.c -o <程序的可执行名称>
- 通过键入<程序的可执行名称> .exe执行程序
- -o <程序的可执行名称> 参数是可选的,可以通过直接通过gcc lex.yy.c y.tab.c进行构建来跳过所述参数,然后通过键入a.exe直接执行程序
5. 【附带官方文档】
在安装路径下:
Bision文档:.\Bison\doc\bison\2.4.1\bison-2.4.1\bision.pdf
Lex文档:.\Lex\doc\flex\2.5.4a\flex-2.5.4a\flex.pdf
——————————————————————————————————————
6. 尾声
1. 感慨
- lex与yacc真是伟大,直接简化了多少分析的过程,我自己也写过NFA确定化和DFA最小化,也算是做过确定机的编程了,但是和lex比起来,实在差的太远了。
- 网上的教程,包括博客,水文也是越来越多了,大量的重复和冗余,干货越来越少。在思考c语言中正则表达式时,查询注释的完美匹配,仅有一篇博客写的比较到位(注释正则式详解),而搜寻有关c语言中带前后缀数字的正则匹配时,资料几乎为0.。。。。win下lex和yacc安装也就不说了,大量都是vs的配置方法。
- (关于c语言的词法分析)目前还没有找到非常完备的实现,自己通过整合资料和思考,实现了注释、字符串的完美匹配,关于数字还有很多的不足(包括其验证,难道真的要拆分开不同进制吗),关于这一部分欢迎私信交流和探讨。
2. 版权
- 学习lex与yacc的过程中,参看了很多的博客及示例代码,因内容太多与琐碎,难免疏漏。文中所引用代码如有侵权请联系本人。参考文档
- 本文为原创博客,转载务必注明出处。