第二章 flex输入输出
flex程序默认总是从标准输入读取, 实际上,词法分析程序都从文件读取输入
flex总是通过名为yyin的文件句柄读取输入, 下面的例子,我们修改单词计数程序,使得它能从文件读取输入
/* even more like Unix wc */
%option noyywrap
%{
int chars = 0;
int words = 0;
int lines = 0;
%}
%%
[a-zA-Z]+ { words++; chars += strlen(yytext); }
\n { chars++; lines++; }
. { chars++; }
%%
main(argc, argv)
int argc;
char **argv;
{
if(argc > 1) {
if(!(yyin = fopen(argv[1], "r"))) {
perror(argv[1]);
return (1);
}
}
yylex();
printf("%8d%8d%8d\n", lines, words, chars);
}
程序中,如果在命令行中提供的文件参数, 那么程序会打开它,修改yyin
yywrap
-lfl库,提供了默认的main主程序和早期lex遗留至今的鸡肋-yywrap
yywarp作用
单lex读取到文件末尾时,会调用yywrap(), 目的是,当有另外一个输入文件时,yywrap可以调整yyin的值并且返回0来重新开始词法分析。如果是真正的文件末尾,那么就返回1来完成分析。
flex默认main程序
int main()
{
while (yylex() != 0) ;
return 0;
}
现在大多flex程序使用“%option noyywrap” 来禁用yywrap,然后写出自己的主程序,所以它们不需要-lfl库
读取多个文件,yyrestart(fp); 如果yylex, yyparse()出现错误, 调用yyrestart()重置调整yyin,重新开始yylex(), 所以开始lex之前,都要调用yyrestart()
main(argc, argv)
int argc;
char **argv;
{
int i;
if(argc < 2) { /* just read stdin */
yylex();
printf("%8d%8d%8d\n", lines, words, chars);
return 0;
}
for(i = 1; i < argc; i++) {
FILE *f = fopen(argv[i], "r");
if(!f) {
perror(argv[i]);
return (1);
}
yyrestart(f);
yylex();
fclose(f);
printf("%8d%8d%8d %s\n", lines, words, chars, argv[i]);
totchars += chars; chars = 0;
totwords += words; words = 0;
totlines += lines; lines = 0;
}
if(argc > 1) /* print total if more than one file */
printf("%8d%8d%8d total\n", totlines, totwords, totchars);
return 0;
}
第二章 flex输入输出的更多相关文章
- 第二章 flex输入输出结构
对于一个词法分析程序,一般读取文件或者终端 一个默认lex程序大致看上去像这样 YY_BUFFER_STATE bp; extern FILE* yyin; ... whatever the prog ...
- 第二章 flex处理二义性
大多数flex程序有二义性,相同的输入可能被多种模式匹配 flex通过下面2个规则来解决 匹配尽可能长的字符 如果2个模式都可以匹配, 匹配更早出现的那个模式 例子 "+" { r ...
- 精通Web Analytics 2.0 (4) 第二章:选择你的网络分析灵魂伴侣的最佳策略
精通Web Analytics 2.0 : 用户中心科学与在线统计艺术 第二章:选择你的网络分析灵魂伴侣的最佳策略 在Web Analytics 2.0的新世界秩序中,您必须跳出"单一真理来 ...
- 学习opencv中文版教程——第二章
学习opencv中文版教程——第二章 所有案例,跑起来~~~然而并没有都跑起来...我只把我能跑的都尽量跑了,毕竟看书还是很生硬,能运行能出结果,才比较好. 越着急,心越慌,越是着急,越要慢,越是陌生 ...
- 第二章排错的工具:调试器Windbg(上)
感谢博主 http://book.51cto.com/art/200711/59731.htm <Windows用户态程序高效排错>第二章主要介绍用户态调试相关的知识和工具.本文主要讲了排 ...
- Android开发艺术探索——第二章:IPC机制(中)
Android开发艺术探索--第二章:IPC机制(中) 好的,我们继续来了解IPC机制,在上篇我们可能就是把理论的知识写完了,然后现在基本上是可以实战了. 一.Android中的IPC方式 本节我们开 ...
- C++第二章复习与总结(思维导图分享)
在完成了第二章的学习后,为了便于日后的复习整理,我制作了一张思维导图,有需要的可以自取. 基本数据类型 基础类型在cppreference网站上有非常完备的介绍,我一句话两句话也说不清,具体网址我会给 ...
- C++ Primer Plus学习:第二章
C++入门第二章:开始学习C++ 进入C++ 首先,以下是一个C++程序: //myfirst.cpp 显示一行文字 #include<iostream> //预处理器编译指令 int m ...
- 【黑金原创教程】【TimeQuest】【第二章】TimeQuest模型角色,网表概念,时序报告
声明:本文为黑金动力社区(http://www.heijin.org)原创教程,如需转载请注明出处,谢谢! 黑金动力社区2013年原创教程连载计划: http://www.cnblogs.com/al ...
随机推荐
- unittest中更多的测试用例
随着软件功能的不断增加,对应的测试用例也会呈指数级增长.一个实现几十个功能的项目,对应的单 元测试用例可能达到上百个.如果把所有的测试用例都写在一个 test.py 文件中,那么这个文件会越来越臃肿, ...
- Linux权限命令
Linux 基础——权限管理命令chmod 一.Linux中的文件权限与目录权限 Linux中定义了3种访问权限,分别是r.w.x.其中r表示对象是可读的,w表示对象是可写的,x表示对象是可执行的 ...
- C#的基础
一:Ref和Out 的区别: 1.使用ref型参数时,传入的参数必须先被初始化.对out而言,必须在方法中对其完成初始化. 2.使用ref和out时,在方法的参数和执行方法时,都要加Ref或Out关键 ...
- poj 2155(未完成)
线段树套线段树模板题 链接:http://poj.org/problem?id=2155 题解: 代码: #include <bits/stdc++.h> using namespace ...
- 为Kubernetes集群部署本地镜像仓库
目录贴:Kubernetes学习系列 经过之前两篇文章:Centos7部署Kubernetes集群.基于kubernetes集群部署DashBoard,我们基本上已经能够在k8s的集群上部署一个应用了 ...
- python--yield and generator(生成器)简述
1.想象一个场景: 设想,我想要100个素数,然后对它们累加求和. 通常的想法是,找一个一次性至少能提供100个素数的工具(函数),让它把这100个素数交给我(用return 一次性返回含 ...
- poj 1797 最大最小路段【dijkstra】 (经典)
<题目链接> 题目大意: Hugo Heavy要从城市1到城市N运送货物,有M条道路,每条道路都有它的最大载重量,问从城市1到城市N运送最多的重量是多少. 解题分析: 感觉这道题用dijk ...
- wireshark实战之局域网抓包分析
Wireshark.它是一款本地监听数据的大杀器,弊端是只能监听本地的数据,有什么办法可以让局域网中的流量都从本机走呢? 第一ARP嗅探,劫持网关,再本地抓包. 第二交换机镜像端口,在路由或者交换机处 ...
- lintcode 单词接龙II
题意 给出两个单词(start和end)和一个字典,找出所有从start到end的最短转换序列 比如: 1.每次只能改变一个字母. 2.变换过程中的中间单词必须在字典中出现. 注意事项 所有单词具有相 ...
- 进程描述和控制(os 笔记二)
进程描述和控制 计算机最初的主要任务之一就是高效的自动化我们的工作,完成用户交付的任务.而这种任务在计算机中的表示就是一个个的进程.从上一篇文章中描述的计算机的发展历史我们能发现,无论是单道批处理 ...