王朝网络
分享
 
 
 

Flex with c++ 入门示例

王朝c/c++·作者佚名  2006-01-09
宽屏版  字体: |||超大  

Flex with c++ 入门示例

凡是学过《编译原理》的大概对Flex都不陌生吧。

flex - fast lexical analyzer generator,这是GNU对其的定义,它的意思说Flex就是fast LEX,但是它是不是比AT&T的LEX好呢?我不知道。

首先,我们先开始我们的第一个事例吧,我们需要统计一个文档有多少行,有多少个字符。但是我又不想自己写函数,那么好,让Flex来帮我写吧

这是一个c++的例子,c的例子大家很容易在网上找到。C++稍微得麻烦点。因为即使是Flex的最新版本,它出的时候c++ standrad 也还在制定中,所以,由于namespace std的问题,编译的时候会遇到一些麻烦。

首先,用acmkdir新建一个目录,名为test,acmkdir具体怎么用,请参见我以前的文章《利用GNU 开发工具套件开发c++应用程序》(

http://www.blogcn.com/User5/snnn/blog/4919807.html)。

然后在src目录下写入test.l

%{

int num_lines = 0, num_chars = 0;

%}

%%

\n ++num_lines; ++num_chars;

. ++num_chars;

%%

该文件一共分为三部分

前面用%{和%}括起来的是c/c++格式的变量声明,语句等,或者直接就是"#include "something"

中间两个%% ,%%是模式定义,使用的是正则表达式的方式对左面的模式进行匹配,如果匹配,就执行右面的语句。

最后在%%之后你还可以写你自己的c/c++函数,比如,你可以在这放一个main(){}

然后用flex生成

flex -+ test.l

注意,参数-+代表生成c++格式的源文件(lex.yy.cc),而不是c文件(lex.yy.c)

找了个死奴来帮我写代码,

去喝杯咖啡如何?

还是算了吧,在我刚起身的时候才发现,它生成一个31734字节的源文件只用了几ms,如果这个文件是要我自己来写的话。。。

要不要打开lex.yy.cc来看看呢?

1500多行,还是算了吧,相信它,它是不会出错的。

然后新建一个cpp文件,这是我的test.cpp文件

more test.cpp

/*! \file test.cpp

* \brief test.cpp

* \date 30 Nov 2004 22:05:31

* \author snnn119@hotmail.com

*/

/*

** Copyright (C) 2004 cyper sun <snnn119@hotmail.com>

**

** This program is free software; you can redistribute it and/or modify

** it under the terms of the GNU General Public License as published by

** the Free Software Foundation; either version 2 of the License, or

** (at your option) any later version.

**

** This program is distributed in the hope that it will be useful,

** but WITHOUT ANY WARRANTY; without even the implied warranty of

** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

** GNU General Public License for more details.

**

**

**

*/

#if HAVE_CONFIG_H

# include <config.h>

#endif

#include <FlexLexer.h>

#include <fstream.h>

extern int num_lines,num_chars;

int main(int argc,char** argv){

if(argc == 1){

printf("usage:%s [file]",argv[0]);

return 1;

}

ifstream* pmyFile = new ifstream();

pmyFile->open(argv[1],ios::out);

if(pmyFile->fail()){

printf("error while open the file"

;

return 1;

}

FlexLexer* lexer = new yyFlexLexer(pmyFile);

while(lexer->yylex()!=0);

printf("total lines:%d\ntotal chars:%d\n",num_lines,num_chars);

delete pmyFile;

delete lexer;

return 0;

}

注意这里的一点多态, yyFlexLexer是派生自 FlexLexer的派生类。 FlexLexer是一个抽象基类,它们都是在<FlexLexer.h>中定义的。

下面我简单的介绍下这两个类

------------------------------------------------------------------------------------------------------------------

Class FlexLexer:

这是一个抽象类

const char* YYText()

returns the text of the most recently matched token, the equiva-

lent of yytext.

返回最近一次匹配,同c格式下的yytext

int YYLeng()

returns the length of the most recently matched token, the

equivalent of yyleng.

返回最近一次匹配的长度,同c格式下的 yyleng

int lineno() const

returns the current input line number (see %option yylineno), or

1 if %option yylineno was not used.

返回最近一次匹配的行号,或者1,如果你在option中关闭了此项。 同c格式下的 yylineno

还有一些Member function如:

yy_create_buffer(),yy_flush_buffer(),yy_delete_buffer(),yyrestart()等等,具体用法请去读源代码。(sorry,there is no doc any more).

------------------------------------------------------------------------------------------------------------------

Class yyFlexLexer:

继承自 FlexLexer

yyFlexLexer( istream* arg_yyin = 0, ostream* arg_yyout = 0

这是它的构造函数,用一个iistream* arg_yyin 代替以前的yyin作输入,ostream* arg_yyout 作输出。也就是说它的输入和输出也可以是多种多样的,文件,cin等等。

如果你不特别指定,默认的输入和输出流依然是cin和cout

virtual int yylex()

对输入进行分析,在<FlexLexer.h>中定义,在lex.yy.cc中实现

virtual void LexerOutput( const char* buf, int size

将buf中size个字节写出到输出流。

其他的函数还是请参考<FlexLexer.h>

------------------------------------------------------------------------------------------------------------------

好了,然后修改src/Makefile.am,告诉它我们要编译什么

bin_PROGRAMS = test

test_SOURCES = test.cpp lex.yy.cc

INCLUDE =(all_include)

test_LDFLAGS = (all_libraries)

然后就是configure.ac了,检测目标机器上flex/lex是否存在

只需加入一行

AC_PROG_LEX

ok,编译

理论上来讲这样就行了,可是在我的机子上没有能通过,我的gcc 3.4坏了,现在用的是

gcc --version

gcc (GCC) 3.3.1 (cygming special)

它提示istream重定义

你可以在lex.yy.cc中找到那句对istream的前向声明,替换成#include <istream.h>

然后编译,运行,

./test test.l

total lines:25

total chars:145

注意,把程序命名为test是个坏习惯,因为在unix/linx系统上已经存在一个名为test的系统工具。

如果你需要查询某个特定的模式(比如邮件地址,标记)在某个文件中的出现次数,那么稍微改下test.l中的那两个正则表达式就行了

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
>>返回首页<<
推荐阅读
 
 
频道精选
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有