panda ID:pandaxcl
79164次访问,排名1150(1)好友0人,关注者2
pandaxcl的文章
原创 61 篇
翻译 0 篇
转载 0 篇
评论 151 篇
pandaxcl的公告

博客文档资源下载在本人的网站下载!!!

我也优先在我的网站论坛上面回答问题

在研究C++自动化编程好久之后,发现C++自动化编程在国内还是一个空白。所谓的C++自动化编程,简单点说就是采用了C++的高级模板技术配合产生式编程技法实现了C++代码的自我配置,自动维护代码之间的种种一致性问题。关于这个问题的讨论,将会在我的网站上面进行细致的讨论。如果有问题,欢迎来我的网站提问哦。看看下面的我的网站的链接。

EMail:pandaxcl@163.com

QQ:56637059

我的网站: http://www.autodev.net

最近评论
huxi043715:博主,在很强阿。你的文章也很容易懂。
wangwei200508:呵呵,谢了
您的这里指到自己硬盘了
<a href="file:///D:/work/lex_yacc/chapter01/lexyacc.rar.png" target="_top">这里</a>
imath:老大我引用了你的 这系列文章,嘿嘿
dlr0987:abc* = ab (c+|e) =ab|abc|abcc.....

pandaxcl:这里要注意那个return i
前置和后置都是为了实现增一的效果;)
特意实现前置和后置都是相同的功能的;)
文章分类
收藏
    相册
    友情连接
    小熊猫
    我的另外一个博客
    我的网站-自动化编程社区
    我的论坛-自动化编程社区论坛
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 Lex和Yacc从入门到精通(3)--一个极其简单的lex和yacc程序收藏

    新一篇: Lex和Yacc从入门到精通(4)-能够使用C++的Lex和Yacc框架 | 旧一篇: C++中模板构造函数和模板转义运算符的妙用

    一个极其简单的lex和yacc程序

    本文版权归熊春雷所有 ,我的邮箱:,欢迎大家和我讨论计算机方面 的问题,在我的博客上 面还写了很多其他的文档,有空来看看哦。如果转载,请保留此版权信息,并注 明出处。谢谢:)

    摘要

    在本章中,将会首先给出一个最基本的lex和yacc联合使用的框架,这个基本框架 最主要的特点就是能够正确的被编译。在我学习lex和yacc的过程中经历了无数次 的痛苦折磨,我发现一个一开始足够简单而且能够被正确编译的例子往往能够使 学习者增加学习的兴趣和信心。因此我的所有的文章都尽可能的采用这种方式进 行描述。我写这些文档的最大的愿望就是希望能够减少新手学习的痛苦。希望自 己能够做到这一点!

    1. 基本的lex文件

    例 3.1. frame.l

    %{
    int yywrap(void);
    %}
    %%
    %%
    int yywrap(void)
    {
    return 1;
    }

    lex文件和yacc文件都是被%%分成了上中下三个部分,在这个程序中的yywrap函数 需要说明一下:

    yywrap

    lex源文件中的yywrap函数是必须的!具体的原因就是因为给了这个函数实 现之后就可以不需要依赖flex库了。具体yywrap的作用会在后面的章节应 用的时候进行解释。通常的做法就是直接返回1,表示输入已经结束了。

    2. 基本的yacc文件

    例 3.2. frame.y

    %{
    void yyerror(const char *s);
    %}
    %%
    program:
    ;
    %%
    void yyerror(const char *s)
    {
    }
    int main()
    {
    yyparse();
    return 0;
    }

    如前所述,yacc文件被%%分成了上中下三个部分,在这个程序中有几个需要说明 的地方:

    program

    这是语法规则里面的第一个非终结符,注意上面的格式哦:“program”后 面紧跟着一个冒号“:”,然后换行之后有一个分号“;”,这表明这个 program是由空串组成的。至于什么是非终结符以及什么是终结符,还有什 么是语法规则都会在后面的章节中进行详细介 绍。

    yyerror

    从字面上就可以看出是一个处理错误的函数,在这里为空的原因是为了保 证代码尽可能的简洁! 实际上这个函数里面的代码通常只有一句输出语句 ,当然如果你喜欢还可以加入纠错代码,使你的解析器具备纠错能力:)

    yyparse

    其实这个函数是yacc生成的,所以你在代码里面可以直接使用。这个时候 你可能会问:“yacc生成了yyparse函数,那么lex是不是也生成了什么函 数呢?”,是的,lex生成的函数为yylex函数。实际上yyparse还间接调用 了yylex函数,可以在生成的C源文件中去核实。

    main

    每一个C/C++程序都必须的装备啊,少了怎么能行呢:)所以这个main函数你 可以放到任何的地方,当然要保证能够调用yyparse就可以了。但是通常的 做法就是将main函数放到yacc文件中。

    从上面的yacc文件中还可以看出被%%分割成为的三个部分,第一部分中要写入 C/C++代码必须用%{和%}括起来;但是第三个部分就可以直接写入C/C++代码了 ,不需要任何的修饰;中间的那一部分就是yacc语法规则了。为了能够让这个 最最简单的yacc源程序能够通过bison的编译必须要提供一个语法规则,这 里给出了一个最简单的规则:一个program就是由空字符串构成的。实际上等于 什么也没有做。呵呵,对啊,本章的目的就是为了能够编译通过lex和yacc源程 序,并且也能够被C/C++编译器编译通过啊。现在是不是已经真的编译通过了呢 ,可以按照下面的编译步骤一步一步的来编译核实。

    提示

    对yacc的描述同样也适用于lex。

    lex就是词法扫描器,yacc就是语法分析器,这是通用的说法;具体的实现有所 不同GNU的lex就是flex,GNU的yacc就是bison。为了统一,所以在后面的文章 中就只会用lex来表达词法扫描器,用yacc来表达语法分析器啦!

    3. 用C语言编译器编译

    下面是编译全过程记录,采用了我在第一章中所制作的lex和yacc转换环境:

    D:\work\lex_yacc\chapter03>dir
    驱动器 D 中的卷是 工作区
    卷的序列号是 54D0-5FC0

    D:\work\lex_yacc\chapter03 的目录

    2006-09-25 20:27 <DIR> .
    2006-09-25 20:27 <DIR> ..
    2006-09-25 20:07 71 frame.l
    2006-09-25 20:20 144 frame.y
    2 个文件 215 字节
    2 个目录 7,785,578,496 可用字节

    D:\work\lex_yacc\chapter03>flex frame.l

    D:\work\lex_yacc\chapter03>dir
    驱动器 D 中的卷是 工作区
    卷的序列号是 54D0-5FC0

    D:\work\lex_yacc\chapter03 的目录

    2006-09-25 20:28 <DIR> .
    2006-09-25 20:28 <DIR> ..
    2006-09-25 20:07 71 frame.l
    2006-09-25 20:20 144 frame.y
    2006-09-25 20:28 36,997 lex.yy.c
    3 个文件 37,212 字节
    2 个目录 7,785,537,536 可用字节

    D:\work\lex_yacc\chapter03>bison -d frame.y

    D:\work\lex_yacc\chapter03>dir
    驱动器 D 中的卷是 工作区
    卷的序列号是 54D0-5FC0

    D:\work\lex_yacc\chapter03 的目录

    2006-09-25 20:28 <DIR> .
    2006-09-25 20:28 <DIR> ..
    2006-09-25 20:07 71 frame.l
    2006-09-25 20:28 19,416 frame.tab.c
    2006-09-25 20:28 74 frame.tab.h
    2006-09-25 20:20 144 frame.y
    2006-09-25 20:28 36,997 lex.yy.c
    5 个文件 56,702 字节
    2 个目录 7,785,517,056 可用字节

    D:\work\lex_yacc\chapter03>

    过程 3.1. 总的来说就是如下的几个步骤:

    1. 将前面的例子frame.lframe.y保存成为相应的文件

    2. flex frame.l

    3. bison frame.y

    4. gcc frame.tab.c lex.yy.c

    提示

    实际上经过flex和bison的转换之后的C/C++源程序是可以直接在VC里面使用的!

    上面的frame.tab.c是由bison编译frame.y产生的,而lex.yy.c则是由flex编译 frame.l产生的。

    好了,一个最简单的lex和yacc程序已经完备了,因此这一章的目的也就已经达到了。 在下一章里面将会对这里的框架例子进行扩充以适应自己特殊的需要,逐步逐步的实 现一个分析C/C++源代码的工具程序,但是每一章的结尾都会尽可能的给出一个可以编 译通过的lex和yacc源程序。本来也想给出一个计算器的源程序作为例子的,但是这样 的资料已经很多了。这些资料往往不能够让自己说清楚问题,在自己的开发中还是会 遇到千奇百怪的问题,因此为了让自己能够有机会解决一个新手在开发新程序中可能 出现的问题,我也就找了一个我没有开发过的程序来让自己一步一步的解决这些问题 。我想这种方式也许是比较好的学习方式吧:)

    本章完!

    后续文章将会在我的博客上 面发布,敬请关注。最好能够有所评论哦:)

    发表于 @ 2006年08月27日 17:45:00|评论(loading...)|编辑

    新一篇: Lex和Yacc从入门到精通(4)-能够使用C++的Lex和Yacc框架 | 旧一篇: C++中模板构造函数和模板转义运算符的妙用

    评论

    #sirguan 发表于2007-01-11 14:24:03  IP: 220.231.22.*
    写得好,很有趣。请问博主是从什么地方第一次接触lex,yacc的。
    #pandaxcl 发表于2007-01-13 22:18:49  IP: 58.60.124.*
    我已经记不得第一次接触lex和yacc是在什么时候了,不过我依稀记得是在使用Linux的时候发现Linux下面的使用程序很多都需要文本解析功能,因为Linux的使用程序的配置文件通常就是文本文件,于是就想:这么多的文本解析应该有一个自动生成工具的,于是借助与我以往的经验,自己想得到的应该别人已经想到了,所以就在网上搜索,于是发现了Lex和Yacc工具,当时真是让我欣喜若狂啊:)
    #sirguan 发表于2007-01-15 09:51:48  IP: 220.231.22.*
    我是看到有人在csdn上提问,有人推荐这个工具,baidu以下就找到了你的,谢谢你奉献这么精彩的文章!以后我也要深入学习以下:D
    #hellojd 发表于2007-08-26 16:47:58  IP: 221.226.128.*
    在执行这个简单程序的时候出现了这样的问题,还请指教。

    D:\fb>g++ lex.yy.c frame.tab.c
    frame.l:2: error: previous declaration of `int yywrap()' with C++ linkage
    lex.yy.c:372: error: conflicts with new declaration with C linkage
    frame.l:9:2: warning: no newline at end of file
    bison.simple: In function `int yyparse()':
    bison.simple:332: error: `yylex' undeclared (first use this function)
    bison.simple:332: error: (Each undeclared identifier is reported only once for
    each function it appears in.)
    frame.y: In function `int main()':
    frame.y:14: error: syntax error before `)' token

    D:\fb>gcc lex.yy.c frame.tab.c
    frame.l:9:2: warning: no newline at end of file
    frame.y: In function `main':
    frame.y:14: error: parse error before ')' token

    D:\fb>
    #pandaxcl 发表于2007-08-26 17:00:32  IP: 222.67.233.*
    这种链接错误,主要是C和C++的链接方式不一致造成的,尝试把yywrap用extern "C"包括起来就可以了;)通常来说,这种问题在混用C和C++代码的时候会出现这种问题;)本系列的文档就是采用了C和C++代码的混用;)原因是直接使用C的话,代码编写过于复杂;)
    #huxi043715 发表于2008-04-25 18:52:31  IP: 219.145.1.*
    博主,在很强阿。你的文章也很容易懂。
    发表评论  


    当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
    Csdn Blog version 3.1a
    Copyright © pandaxcl