我们的第一个Flex程序

我们的第一个Flex程序

Unix系统(同样也包括像Linux和BSD这样的类Unix系统)自带了一个字数统计(word count)程序,这个程序可以读入一个文件然后报告这个文件的行数、单词数和字符数。flex使我们能够用仅仅十几行就完成这个wc程序。

    例:字数统计fbh1.l
    /* 正如Unix的wc程序 */
    %{
    int chars = 0;
    int words = 0;
    int lines = 0;
    %}
    %%
    [a-zA-Z]+	{ words++; chars +=	strlen(yytext);	}
    \n	        { chars++; lines++; }
    .	        { chars++; }
    %%
    main(int argc, char **argv)
    {
        yylex();
        printf("%8d%8d%8d\n", lines, words, chars);
    }

这个程序的大部分内容对于C程序员来说是十分熟悉的,因为这些就是C代码。

flex程序包含以下三个部分,各部分之间通过仅有%%的行来分割

  • 声明和选项设置
  • 一系列的模式和动作
  • 被拷贝到生成的词法分析器里面的 C代码,它们通常是一些与动作代码相关的例程。
    在声明部分,%{和%}之间的代码会被原样照抄到生成的C文件的开头部分。在这个例子里面,它只是用来设定了行数、单词数和字符数的变量。
    在第二部分,每个模式处在一行的开头处,接着是模式匹配时所需要执行的C代码。这儿的C代码是用{}括住的一行或者多行语句。(模式必须在行首出现,因为flex认为以空白开始的行都是代码而把它们照抄到生成的C程序中)

这个程序只有三个模式。

  • 第一个模式,[a-zA-Z] + ,用来匹配一个单词。在方括号里面的字符串是一种字符类(character class),能够匹配任意一个大小写字母,而+这个符号表示匹配一个或者多个前面的字符类,也就是一连串的字母,或者说一个单词。相关的动作更新匹配过的单词和字符的个数。在任意一个flex的动作中,变量yytext总是被设为指向本次匹配的输入文本。在这个例子里,我们所需要关心的是有多少个字符,因此我们可以借助这个变量来统计字符数。
  • 第二个模式,\n,用来匹配换行符。相关的动作更新行数和字符数。
  • 第三个模式是一个点号,它在正则表达式中代表任意一个字符(与shell脚本中的?相 似)。关联的动作更新字符数。

末尾的C代码是我们的主程序,它负责调用flex提供的词法分析例程yylex(),并输出结果。在没有任何其他改变的情况下,词法分析器将读取标准输入。我们来运行一下。

$ flex fbh1.l
$ gcc lex.yy.c -lfl
$ ./a.cout
The boy stood on the burning deck
shelling peanuts by the peck
^D
2 12 63
$

首先我们用flex来翻译我们的程序,flex在没有任何错误的情况下默默地完成了翻译,正如Unix的经典设定那样。接着我们编译flex生成的C程序:lex.yy.c;将它与相应的flex 库文件(-Ifl)链接,运行它,然后提供一小段输入以便于程序进行统计。看起来一切运作正常。

注:真正的wc程序对单词的定义和这儿相比有些微小的差别,它的定义是没有空白字符的字符串。一旦我们知道哪些是空白字符,我们只需把匹配单词的那个模式替换成匹配没有空白字符的字符串:

[^ \t\n\r\f\v]+  {  words++;  chars += strlen(yytext);  }

在字符类开始部分的符号^是指匹配任意一个不在字符类里面的字符,而符号+依然意味 着匹配一个或者多个前面的模式。这展示了flex的强大之一,我们很容易在模式上做一些小的改动而让flex去担心它们可能怎样影响生成的代码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值