词法分析器flex中文手册
flex资料
![flex资料](https://img.taocdn.com/s3/m/3adefc83d4d8d15abe234eda.png)
LEX介绍LEX(Lexical Analyzer Generator)即词法分析器生成工具是1972年贝尔实验室的M.E.Lesk和E.Schmidt在UNIX操作系统上首次开发的。
GNU同时推出了和LEX完全兼容的FLEX(Fast Lexical Analyzer Genrator)。
下面用到的例子都是基于flex的。
LEX工作原理:LEX通过对源文件的扫描,经过宏替换将规则部分的正则表达式转换成与之等价的DFA,并产生DFA的状态转换矩阵(稀疏矩阵);利用该矩阵和源文件的C代码产生一个名为int yylex()的词法分析函数,将yylex()函数拷贝到输出文件lex.yy.c中。
函数yylex()以在缺省条件下的标准输入(stdin)作为词法分析的输入文件。
输入文件(扩展名为.l)LEX输出文件lex.yy.cLex源文件格式为:定义部分%%规则部分%%用户附加的C语言代码例1:int num_chars=0,num_lines=0;/*定义两个全局变量,一个及字符数,一个记行数.注意:该语句不能顶行*/%%\n ++num_chars++; ++num_lines;. ++num_chars;%%int main(){yylex();printf(“%d,%d”, num_chars,num_lines);}int yywrap()/*文件结束处理函数,当yylex()读到文件结束标记EOF时,调用该函数时会,用户必须提供该函数,否则会提示编译出错*/{return 1;//返回1表示文件扫描结束,不必再扫描别的文件}lex 的输入文件分成三个段,段间用%% 来分隔。
由于必须存在一个规则段,第一个%% 总是要求存在模式LEX的模式是机器可读的正则表达式。
表意字符匹配字符. 除换行外的所有字符\n 换行* 0 次或无限次重复前面的表达式+ 1 次或更多次重复前面的表达式? 0 次或1 次出现前面的表达式^ 行的开始$ 行的结尾a|b a 或者b(ab)+ 1 次或玩多次重复ab"a+b" 字符串a+b 本身(C 中的特殊字符仍然有效)[] 字符类[^ab] 除a,b 外的任意字符[a^b] a, ^, b 中的一个[az] 从a 到z 中的任意字符[a\-z] a,-,z 中的一个[a-z] a, z 中的一个<EOF> 匹配文件结束标记表1 :简单模式匹配在方括号([])中,通常的操作失去了本来含意。
词法分析器flex中文手册
![词法分析器flex中文手册](https://img.taocdn.com/s3/m/7b497e863186bceb19e8bbd8.png)
FLEX 中文手册这是flex手册的部分中文翻译,仅供参考•一些简单的例子•输入文件的格式•模式•如何匹配输入•动作•生成的扫描器•开始条件•文件结尾规则•与yacc一起使用一些简单的例子首先给出一些简单的例子,来了解一下如何使用flex。
下面的flex输入所定义的扫描器,用来将所有的“username”字符串替换为用户的登陆名字:%% username printf("%s", getlogin());默认情况下,flex扫描器无法匹配的所有文本将被复制到输出,所以该扫描器的实际效果是将输入文件复制到输出,并对每一个“username”进行展开。
在这个例子中,只有一个规则。
“username”是模式(pattern),“printf”是动作(action)。
“%%”标志着规则的开始。
这里是另一个简单的例子:int num_lines = 0, num_chars = 0;%% \n ++num_lines; ++num_chars; . ++num_chars;%% int main(void){yylex();printf("# of lines = %d, # of chars = %d\n", num_lines, num_chars);}该扫描器计算输入的字符个数和行数(除了最后的计数报告,并未产生其它输出)。
第一行声明了两个全局变量,“num_lines”和“num_chars”,可以在yylex()函数中和第二个“%%”后面声明的main()函数中使用。
有两个规则,一个是匹配换行符(“\n”)并增加行数和字符数,另一个是匹配所有不是换行符的其它字符(由正规表达式“.”表示)。
一个稍微复杂点的例子:/* scanner for a toy Pascal-like language */%{/* need this for the call to atof() below */#include <math.h>%}DIGIT [0-9] ID [a-z][a-z0-9]*%%{DIGIT}+ {printf( "An integer: %s (%d)\n", yytext,atoi( yytext ) );}{DIGIT}+"."{DIGIT}* {printf( "A float: %s (%g)\n", yytext,atof( yytext ) );}if|then|begin|end|procedure|function {printf( "A keyword: %s\n", yytext );}{ID} printf( "An identifier: %s\n", yytext );"+"|"-"|"*"|"/" printf( "An operator: %s\n", yytext );"{"[^}\n]*"}" /* eat up one-line comments */[ \t\n]+ /* eat up whitespace */. printf( "Unrecognized character: %s\n", yytext );%%int main(int argc, char **argv){++argv, --argc; /* skip over program name */if ( argc > 0 )yyin = fopen( argv[0], "r" );elseyyin = stdin;yylex();}这是一个类似Pascal语言的简单扫描器的初始部分,用来识别不同类型的标志(tokens)并给出报告。
Flex
![Flex](https://img.taocdn.com/s3/m/4f5b3ac09ec3d5bbfd0a7460.png)
Flex 简明中文教程本书特色用通俗易懂的语言,不要求华丽的语句(部分可能由用词错误)介绍难懂的语法,通过图片讲解每一个操作步骤,让初学者快速入门,让懂一点皮毛的人快速提高语言尽量精简,不说废话,句句重点注重从实际例子中讲解,不让学习枯燥无味涵盖Flex全部基础知识写作目的介于现在市面上,甚少的书介绍Flex,好不容易看见一本还是英语的,使好的想学Flex 的人感到无从下手,本人通过自己对Flex的一段时间研究编写了一本简明教程,希望大家喜欢联系作者由于此书使本人兴趣来了写的,肯定存在诸多不完善的地方,由的地方可能不使说很清楚,望大家批评指正qq:403617596email:yanming4036@编者:严铭版权声明:此教程由个人制作,可以随便转载,但不可以用作商业用途Flex是Adobe公司推出的一系列开发工具和技术,使开发人员开发和可部署升级的富媒体技术(简称RIAs),Flex使一种年轻的,现代的开发技术,基于标准的语言,运行在客服端、支持公共模板、支持高级数据处理的技术。
RIAs能支持在客户端开发就向web开发一样,这样就减轻了服务器端的负担。
本节将简单介绍Flex的特点,让大家对Flex有一个大致的了解。
1.1.1Flex的技术特点Flex可以在企业内部,和web服务器上创建和运行,是公认的最强大,最完整的RIA 开发技术,使企业、个人开发富有个性的web应用程序。
彻底改变人与web的交互能力。
1.1.2Flex的开发环境搭建可以直接到Adobe公司的官方网站下载。
Adobe buildler3.0(由于你看到书的时间不同可能是4.0或者更加高了),安装办法就不用多说了哈。
另外还可以在Eclipse下面装一个叫Flex builder3 bate plugin的插件(推荐使用第一种开发环境,本书基于Adobe builder3.0讲解)。
1.1.3 Flex开发语言介绍开发Flex可以使用两种语言来写,可能对熟悉flash的人一定听说过ActionScript 吧,对,Flex可以用基于ActionScript3.0来开发,另外还有就使一种基于脚本和xml 的语言——Mxml。
Flex词法分析工具
![Flex词法分析工具](https://img.taocdn.com/s3/m/d914ef150740be1e650e9a28.png)
词法分析器生成工具flex1.FLEX简介单词的描述称为模式(Lexical Pattern),模式一般用正规表达式进行精确描述。
FLEX通过读取一个有规定格式的文本文件,输出一个如下所示的C语言源程序。
+------------+ +------------+ +----------------+| 输入文件*.l |------>|flex工具 |------>|输出文件lex.yy.c |+------------+ +------------+ +----------------+FLEX的输入文件称为LEX源文件,它内含正规表达式和对相应模式处理的C语言代码。
LEX 源文件的扩展名习惯上用.l表示。
FLEX通过对源文件的扫描自动生成相应的词法分析函数int yylex(),并将之输出到名规定为lex.yy.c的文件中。
实用时,可将其改名为lexyy.c。
该文件即为LEX的输出文件或输出的词法分析器。
也可将int yylex()加入自已的工程文件中使用。
2. LEX源文件的格式LEX对源文件的格式要求非常严格,比如若将要求顶行书写的语句变成非顶行书写就会产生致命错误。
而LEX本身的查错能力很弱,所以书写时一定要注意。
下面以统计单词出现的次数的源程序count.l做说明,count.l的内容如下:%{#include "stdio.h"#include "stdlib.h"int num_num=0,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;}定义部份由C语言代码、模式的宏定义、条件模式的开始条件说明三部份组成。
FLEX 5000 安全頻率輸入模組 使用手冊说明书
![FLEX 5000 安全頻率輸入模組 使用手冊说明书](https://img.taocdn.com/s3/m/988b5ad46429647d27284b73f242336c1eb9308e.png)
FLEX 5000 安全頻率輸入模組型號 5094-IJ2IS、5094-IJ2ISXT2Rockwell Automation 出版物 5094-UM004A-ZC-P - 2021 年11 月FLEX 5000 安全頻率輸入模組使用手冊使用者重要資訊進⾏本產品的安裝、設定、操作或維護前,請閱讀本文件及其他資源一節內有關本設備安裝、設定和操作的文件。
使用者除了必須瞭解所有相關法規、法律條文與標準外,還需熟知安裝與配線說明。
舉凡安裝、調整、運作、使用、組裝、拆卸及維護等作業,均需由受訓合格的⼈員依照相關法規進⾏。
若以製造商未提及之方式使用本設備,將可能損害到製造商為本設備所提供的保護措施。
不論任何情況,Rockwell Automation Inc. 對於使用或應用此裝置而產生的間接或連帶損壞,均不負擔任何法律或賠償責任。
本⼿冊中的範例和圖表皆僅供說明之用。
由於個別安裝會有許多不同的變數及條件,Rockwell Automation, Inc. 無法對依照範例及圖⽰指⽰進⾏的實際使用狀況負責或提供賠償。
關於本⼿冊中所述之資訊、電路、設備或軟體部分,Rockwell Automation Inc. 概不承擔任何專利責任。
在取得 Rockwell Automation Inc. 書面同意之前,禁止重製本⼿冊部分或全部內容。
在整本⼿冊中,我們會在必要時使用註記,讓您瞭解安全注意事項。
這些標籤也可能位在設備上方或內側,以提供特定預防措施資訊。
以下圖⽰可能會出現在本文件的文字中。
Rockwell Automation 瞭解本出版物及業界目前所使用的部分詞彙,並不符合技術中包容性語⾔的發展趨勢。
我們正積極與業界同仁合作,找出這類詞彙的替代方案,並對產品和內容進⾏變更。
在我們實施這些變更時,請原諒我們在內容中使用此類詞彙。
警告:指出可能在危險環境中導致爆炸的做法或情況之相關資訊,爆炸可能會進而導致⼈員受傷或死亡、財物損失或經濟損失。
Flex中文帮助第1-2章.pdf-
![Flex中文帮助第1-2章.pdf-](https://img.taocdn.com/s3/m/562eded9ad51f01dc281f14c.png)
译者声明1.请大家在转载和使用时保持本文的完整性。
2.本文所有资料均来自Flex官方文档,其英文版权归Adobe公司所有。
3. 文中某些内容根据译者的理解稍作改动,因此与原版英文在文字上不完全一致。
同时,由于译者水平有限,翻译不妥之处请大家多多见谅。
重庆大坪刘刚第一章Flex是如何工作的该部分文档的内容是为用户提供关于Adobe®Flex 工作机制的一个快速综述。
通过本章节的学习,你可以创建你的第一个Flex 应用程序,并将它与你以前所熟悉的Web开发技术进行比较,以领会Flex的内涵和精髓。
第一节构建并运行Flex应用程序Flex是一个提供开发设计和运行支持的架构,它可以使开发人员创建利用Adobe® Flash® Player 9作为前台的“富客户端互联网应用程序/rich Internet applications/RIA”,以满足用户更为直观和极具交互性的在线体验。
开发Flex应用程序的典型步骤如下(通常是这样):1. 选取一系列预先定制好的、用于设计应用程序界面的组件(如表格、按钮等等)2. 布置组件以设计用户界面。
3. 使用样式和主题来增强视觉方面的设计。
4. 添加动态行为(例如程序部件之间的相互作用)。
5. 定义并连接所需的数据库服务。
6. 将源代码编译成SWF文件,然后在Flash Player中运行。
一个典型的Flex应用程序包括如下元素:1. Flex frameworkAdobe® Flex 2 framework包含了创建RIA所需要的所有组件,它们是:用于应用程序布局规划的容器;针对用户界面和从用户处获取数据的控制(例如文本框和按钮);广泛支持的数据绑定、数据格式化、以及有效值验证;事件驱动的开发模式。
Flex framework被包含在公用组件库(SWC)文件中。
2. MXML每个Flex应用程序至少包含有一个MXML文件,它被作为该程序的主文件。
使用flex
![使用flex](https://img.taocdn.com/s3/m/fe168227a22d7375a417866fb84ae45c3b35c219.png)
使⽤flexFlex如何处理⼆义性模式:1、词法分析器匹配输⼊时匹配尽可能多的字符串2、如果两个模式都可以匹配的话,匹配在程序中更早出现的模式上下⽂相关的记号flex提供起始状态(start state)的概念,可以动态地开启和关闭针对特定模式的识别,对于处理上述上下⽂相关的情况⽐较有⽤。
Flex词法分析器中的⽂件IO操作除⾮另⾏制定,否则flex词法分析器总是读取标准输⼊。
词法分析器总是通过名为yyin的⽂件句柄读取输⼊。
[root@typhoeus79 flex2]# more fb2-1.l%option noyywrap%{#include <string.h>int chars = 0;int lines = 0;int words = 0;%}%%[a-zA-Z]+ { words++; chars += strlen(yytext); }\n { lines++; chars++; }[ \t] {}. { chars++; }%%int main(int argc, char**argv){if(argc>1){yyin=fopen(argv[1],"r");if(yyin == NULL){perror(argv[1]);return 1;}}yylex();printf("chars=%d,words=%d,lines=%d\n",chars,words,lines);return 0;}对应的Makefile:[root@typhoeus79 flex2]# more Makefilefb2-1:lex.yy.ogcc -o fb2-1 lex.yy.o -lfllex.yy.o:fb2-1.lflex fb2-1.lgcc -Wall -c -g lex.yy.cclean:rm -rf lex.yy.* fb2-1读取多个⽂件flex提供yyrestart(f)例程,它使词法分析器读取标准输⼊输出⽂件f。
Flex中文帮助No4章A
![Flex中文帮助No4章A](https://img.taocdn.com/s3/m/6d7406791711cc7931b71667.png)
译者声明1.请大家在转载和使用时保持本文的完整性。
2.本文所有资料均来自Flex官方文档,其英文版权归Adobe公司所有。
3. 文中某些内容根据译者的理解稍作改动,因此与原版英文在文字上不完全一致。
同时,由于译者水平有限,翻译不妥之处请大家多多见谅。
重庆大坪刘刚第四章Flex编程入门教程本章节将提供一系列的课程教授你如何开发Flex应用程序。
第一节创建你的第一个应用程序本节将向你展示如何使用Adobe Flex Builder编译和运行一个简单的Flex应用程序。
其中涉及的重点内容包括Flex Builder项目的概念。
在Flex Builder中,所有的程序都被包含在项目/projects里。
创建一个项目在Flex Builder中创建一个Flex应用程序之前,你必须首先要创建一个项目。
当创建好项目文件时,主MXML程序文件就已经准备好。
然后你就可以在项目中添加各种资源,如MXML组件文件、ActionScript文件等等。
其主要操作步骤有:1. 启动Flex Builder并从主菜单中选择File > New > Flex Project,出现新项目向导/New Flex Project wizard。
2. 在打开的屏幕中,选择基础数据选项/Basic data option并点下一步/Next。
接下来会询问你指定保存项目文件的目录。
3. 在项目名称栏中输入Lessons。
在项目内容区域,确保使用默认目录选项/Use Default Location option被选定。
默认的目录是C:\Documents and Settings\your_user_name\My Documents\Flex Builder 2。
Flex Builder将在该目录下创建Lessons文件夹。
4. 点击完成/Finish。
Flex Builder创建好新的项目并在导航视图中进行显示。
新建项目向导将自动生成项目配置文件,存放被编译SWF文件的输出目录,以及主程序文件Lessons.mxml。
Bison-Flex笔记
![Bison-Flex笔记](https://img.taocdn.com/s3/m/9f215c003c1ec5da50e27084.png)
Bison-Flex笔记Bison-Flex 笔记FLEX什么是 FLEX ,它是一个自动化工具,可以按照定义好的规则自动生成一个 C 函数 yylex() ,也成为扫描器( Scanner )。
这个 C 函数把文本串作为输入,按照定义好的规则分析文本串中的字符,找到符合规则的一些字符序列后,就执行在规则中定义好的动作( Action )。
例如在规则中可以这样定义:如果遇到一个换行字符 \n ,那么就把行计数器的值加一。
Flex 文件就是一个文本文件,内容包括定义好的一系列词法规则。
文件的命名习惯上以小写字母 l(L) 来作为文件后缀。
如果为了清晰,也可以用 .flx 或者 .flex 作为文件的后缀名。
Flex 文件完成后,就执行下列命令: $ flex example.flex这个命令执行后将生成一个 C 文件,默认文件名为 lex.yy.c 。
这个 C 文件主要内容就是函数 yylex() 的定义。
如果要直接将这个文件编译成为一个可执行程序,还有一些要注意的地方。
如果在 Flex 文件中没有提供 main() 函数的定义,那么这个 C 文件中不会有main() 函数。
此时单独编译这个 C 文件的时候,一定要加上 -lfl 的连接库参数;若提供了 main() 函数,就不必要提供这个连接库参数了。
连接库 libfl 提供了一个缺省的 main 函数。
缺省的 main() 函数中只是简单地调用 yyflex() 函数,而自己提供的 main() 函数则可以根据需要加入许多其他的处理代码。
Flex 文件词法规范定义文件给出了单词构成规则。
词法文件在习惯上用字母 l( 即 L 的小写 ) 来作为后缀。
Flex 文件由三个部分组成。
或者说三个段。
三个段之间用两个 %% 分隔。
定义段 (definitions)%%规则段 (rules)%%用户代码段 (user code)定义段 (definitions section)定义段包含着一些简单名字的定义 (name definitions) ,旨在简化扫描器的规范。
从lexyacc说到编译器(二):flex的使用
![从lexyacc说到编译器(二):flex的使用](https://img.taocdn.com/s3/m/a4fb1df66394dd88d0d233d4b14e852458fb3917.png)
从lexyacc说到编译器(二):flex的使用二、flex的使用看了第一篇的关于正则表达式的说明后,下面我们就来通过它,使用flex这个词法分析工具来构造我们的编译器的词法分析器.关于lex的教程应该是很多,这里我就简单地介绍一下,然后着重后面的lex和yacc的配合使用以及其技巧.所以,如果你不看了后还是不太明白lex或者yacc的使用,请你自己上网去查查,这方面的教程是很多的.我知道的一篇常见的就是Yacc 与 Lex 快速入门Lex 与 Yacc 介绍它的作者就是Ashish Bansal.Flex就是fast lex的意思.而lex就是Lexical Analyzar的意思.flex 可以在cygwin或者gnupro中找到.它是unix的一个工具,属于GNU 组织产品.网上也可以找到单独可以在windows下用的版本.我们一般把我们的词法扫描程序要扫描的一些单词(token)用正则表达式写好,然后作为lex的输入文件,输入命令flex xxx.l(xxx.l就是输入文件),lex经过处理后,就能得到一个名字叫lex.yy.c的C源代码.这个C源代码文件,就是我们的词法扫描程序.通常lex为我们生成的词法分析器的C源代码都是十分复杂而且庞大的,我们一般根本不会去查看里面的代码(放心好了,flex这个东西不会出错的)下面让我们看看几个我已经使用过的几个lex输入文件.这是一个前段时间我为GBA上的一个RPG游戏写的脚本引擎所使用的lex输入文件(部分)例2.1%{/* need this for the call to atof() below */#include <stdio.h>#include <stdlib.h>#include <math.h>#include "globals.h"%}digit [0-9]number ("-"|"+")?{digit}+hexnumber "0x"({digit}|[a-fA-F])+letter [a-zA-Z]identifier ({letter}|_)({number}|{letter}|_)* newline [\n]whitespace [ \t]+string \"[^"]*\"comment "#"[^#]*"#"%%{string} { return VM_STRING; } "Logo" { return VMIN_LOGO; } "FaceIn" { return VMIN_FACEIN; } "FaceOut" { return VMIN_FACEOUT; } "LoadTile" { return VMIN_LOAD_TILE; } "CreateRole" { return VMIN_CREATE_ROLE; } "ReleaseRole" { return VMIN_RELEASE_ROLE;} "CreateMap" { return VMIN_CREATE_MAP; } "ReleaseMAP" { return VMIN_RELEASE_MAP;} "ShowBitmap" { return VMIN_SHOWBITMAP; } "CreateDialog" { return VMIN_CREATE_DIALOG; }"ReleaseDialog" { return VMIN_RELEASE_DIALOG;}"Fight" { return VMIN_FIGHT; }"Delay" { return VMIN_DELAY; }"PressA" { return VMIN_PRESS_A; }"PressB" { return VMIN_PRESS_B; }"PressR" { return VMIN_PRESS_R; }"PressL" { return VMIN_PRESS_L; }"PressStart" { return VMIN_PRESS_START; }"PressSelect" { return VMIN_PRESS_SELECT;}{number} { return VM_NUMBER; }{whitespace} { /* skip whitespace */ }{identifier} { return VM_ID; }{newline} ;. ;%%int yywrap(){return 1;}这里的lex输入文件一共有三个部分,用%%分开.第一部分中的%{和}%中的内容就是直接放在lex输出C代码中的顶部.我们通过它可以来定义一些所需要的宏,函数和include一些头文件等等.我的这个lex输入文件中也没什么特别的东西,就是常规的C源文件的include头文件%{/* need this for the call to atof() below */#include <stdio.h>#include <stdlib.h>#include <math.h>#include "globals.h"%}第一部分中,除了前面的%{和}%包含的部分,下面的就是正则表达式的定义.看了第一篇的正则表达式,这样你就能够在这里派上用场了.让我们来看看我这里定义的正则表达式:digit [0-9]number ("-"|"+")?{digit}+hexnumber "0x"({digit}|[a-fA-F])+letter [a-zA-Z]identifier ({letter}|_)({number}|{letter}|_)*newline [\n]whitespace [ \t]+string \"[^"]*\"comment "#"[^#]*"#"digit就不用说了,就是0-9的阿拉伯数字定义,第一篇文章中也举了这个例子.number就是digit的1到无限次的重复,再在其前面加上”+”和”-“符号.注意:“a”: 即使a是元字符,它仍是字符a\a: 当a是元字符时候,为字符aa?: 一个可选的a,也就是说可以是a,也可以没有aa|b: a或b(a): a本身[abc]: 字符a,b或c中的任一个[a-d]: a,b,d或者d中的任一个[^ab]: 除了a或b外的任何一个字符.: 除了新行之外的任一个字符{xxx}: 名字xxx表示的正则表达式这里需要特别说明的就是newline [\n]newline就是新行,这里我使用了[]把\n换行号括起来.因为如果我直接用\n表示的话,那么按照上面的规则,那就会看成\和n两个字符,所以我使用了[\n].有些时候newline也被写成[\n]|[\r\n].因为在文本文件中,一般换行一次,那么就是一个\n(0xA),可是在二进制文件中,换行有时候又是\r\n(0xD,0xA)一共两个字符号.第二部分就是定义扫描到正则表达式的动作.这些动作其实就是C代码,它们将会被镶嵌在lex输出的C文件中的yylex()函数中.上面的例子的动作其实十分平常,就是返回一个值.我们在外部使用这个lex为我们生成C代码的时候,只需要使用它的int yylex()函数.当我们使用一次yylex(),那么就会自动去扫描一个匹配的正则表达式,然后完成它相应的动作.这里的动作都是返回一值,那么yylex就会返回这个值.通常默认yylex返回0时候,表示文件扫描结束,所以你的动作中最好不要返回0,以免发生冲突.当然,动作中也可以不返回一值,那么yylex就会完成这个动作后自动扫描下一个可以被匹配的字符串,一直到扫描到文件结束.当扫描到一个可以被匹配的字符串,那么这个时候,全局变量yytext 就等于这个字符串请大家一定记住这些正则表达式的顺序.如果出现一个字符串,可以同时匹配多个正则表达式,那么它将会被定义在前面的正则表达式匹配.所以我一般把字符串string定义在最前面.如果文件中的字符没有被lex输入文件中任何一个字符匹配,那么它会自动地被标准输出.所以大家一定要记住在每个正则表达式处理完毕后,一定要加上{newline}和.这两个正则表达式的动作.好,让我们看看lex为我们输出C文件中提供一些常量Lex 变量例2.2这是<<编译原理与实践>>书中配套的源代码的lex输入文件.大家可以参考一下,作者为它自己定义的一个Tiny C编译所做的词法扫描器./****************************************************//* File: tiny.l *//* Lex specification for TINY *//* Compiler Construction: Principles and Practice *//* Kenneth C. Louden *//****************************************************/%{#include "globals.h"#include "util.h"#include "scan.h"/* lexeme of identifier or reserved word */char tokenString[MAXTOKENLEN+1];%}digit [0-9]number {digit}+letter [a-zA-Z]identifier {letter}+newline \nwhitespace [ \t]+%%"if" {return IF;} "then" {return THEN;} "else" {return ELSE;} "end" {return END;} "repeat" {return REPEAT;} "until" {return UNTIL;} "read" {return READ;} "write" {return WRITE;} ":=" {return ASSIGN;} "=" {return EQ;} "<" {return LT;} "+" {return PLUS;} "-" {return MINUS;} "*" {return TIMES;} "/" {return OVER;} "(" {return LPAREN;} ")" {return RPAREN;} ";" {return SEMI;} {number} {return NUM;} {identifier} {return ID;}{newline} {lineno++;} {whitespace} {/* skip whitespace */} "{" { char c;do{ c = input();if (c == EOF) break;if (c == ‘\n‘) lineno++;} while (c != ‘}‘);}. {return ERROR;}%%TokenType getT oken(void){ static int firstTime = TRUE;TokenType currentToken;if (firstTime){ firstTime = FALSE;lineno++;yyin = source;yyout = listing;}currentToken = yylex();strncpy(tokenString,yytext,MAXTOKENLEN); if (TraceScan) {fprintf(listing,"\t%d: ",lineno); printToken(currentToken,tokenString);}return currentT oken;}这里有点不同的就是,作者用了另外一个getToken函数来代替yylex作为外部输出函数.其中getToken里面也使用了lex默认的输出函数yylex(),同时还做了一些其它的事情.不过我建议大家不要像作者那样另外写自己的结果输出函数,因为在后面,需要和yacc搭配工作的时候,yacc生成的语法分析程序只认名字叫yylex()的词法结果输出函数.if (firstTime){ firstTime = FALSE;lineno++;yyin = source;yyout = listing;}其中的yyin,yyout,source,listing都是FILE*类型.yyin就是要lex 生成的词法扫描程序要扫描的文件,yyout就是基本输出文件(其实我们通常都不用yyout,即使要生成一些输出信息,我们都是自己通过fprintf 来输出)."{" { char c;do{ c = input();if (c == EOF) break;if (c == ‘\n‘) lineno++;} while (c != ‘}‘);}其中,作者的这个Tiny C是以{}来包括注释信息.作者并没有写出注释信息的正则表达式,但是它可以通过检索“{”,然后用lex内部函数input()一一检查 { 后面的字符是不是 } 来跳过注释文字.(C语言的/* */注释文字正则表达式十分难写,所以很多时候我们都用这种方法直接把它的DFA(扫描自动机)写出来).本文就是通过简单地举出两个比较实际的例子来讲解flex输入文件的.再次说明,如果你是第一次接触lex,那么请看看前面我推荐的文章,你可以在IBM的开发者网上查到.下一篇关于yacc于BNF文法的说明也是如此.请大家先参考一下其它标准的教程.。
flex生成词法分析器
![flex生成词法分析器](https://img.taocdn.com/s3/m/6d48c9266bd97f192279e97a.png)
(一)实验题目:flex生成词法分析器(二)实验目的:掌握词法分析程序生成器flex的用法(三)实验内容:例程一:Count.l:%{int num_lines = 0;num_chars = 0;%}%%\n ++num_lines; ++num_chars;. ++num_chars;%%main( argc, argv )int argc;char **argv;{++argv, --argc; /* skip over program name */if ( argc > 0 )yyin = fopen( argv[0], "r" );elseyyin = stdin;yylex();printf( "# of lines = %d, # of chars = %d\n",num_lines, num_chars ); }int yywrap(){return 1;}分析文件:abc.txt:运行结果:例程二:Sample1.l:/* scanner for a toy Pascal-like language */%{/* need this for the call to atof() below */#include <math.h>%}DIGIT [0-9]ID [a-z][a-z0-9]*%%{DIGIT}+ { printf( "An integer:%s(%d)\n",yytext, atoi( yytext ) ); } {DIGIT}+"."{DIGIT}* { printf( "A float: %s (%g)\n", yytext,atof( yytext ) ); }if|then|begin|end|procedure|function { printf( "A keyword: %s\n", yytext ); }{ID} printf( "An identifier: %s\n", yytext ); "+"|"-"|"*"|"/" printf( "An operator: %s\n", yytext );"{"[^}\n]*"}" /* eat up one-line comments */[ \t\n]+ /* eat up whitespace */. printf( "Unrecognized character: %s\n", yytext );%%main( argc, argv )int argc;char **argv;{++argv, --argc; /* skip over program name */ if ( argc > 0 )yyin = fopen( argv[0], "r" );elseyyin = stdin;yylex(); /*调用词法分析器*/}int yywrap(){return 1;}运行结果:。
JFlex 词法分析说明
![JFlex 词法分析说明](https://img.taocdn.com/s3/m/01e588c88762caaedd33d4be.png)
JFlex 的词法分析说明使用JFlex这个项目中使用JFlex 的目的是为我们的计算器创建一个词法分析器。
这个词法分析器,或者叫扫描器,将为我们计算器检查输入,而且确认所有的字符归类是有效的。
用于JFlex 的词法分析说明文件可以分成三个部分。
每个部分由%%分开。
用户代码段%%参数设置和声明段%%词法规则段用户代码段这个段中的所有内容将被拷贝到生成的词法类的类声明之前。
在这个段中,常见的是package 和import 语句。
我们的词法说明在这个段中引入(import)了两个类,sym 和java_cup.runtime.*,如下所示:import java_cup.runtime.*;import sym;在我们的例子中,sym 类(与处理器一起)由CUP产生。
参数设置和声明段这个段含有参数,词法状态,和宏定义。
设置参数将包含额外的代码,它们将被包括在产生的扫描器类。
参必须另开新行,以%开头。
可以包含的参数很多。
在随JFlex 来的手册中可以得到一个可以包含的参数列表。
在我们的词法说明中用到的参数如下:%class Lexer%line%column%cup第一个参数,class Lexer,告诉JFlex 把生成的类命名为Lexer并把代码写到名为Lexer.java的文件。
参数Line打开行计数,使你可以用变量yyline存取输入的当前行号。
参数column有类似的作用,除了它是通过变量yycolumn存取当前列号。
最后一个参数,cup,把JFlex设置成一个特殊模式,使它与CUP产生的处理器兼容,我们使用的就是。
然后,你可以声明扫描器用到的成员变量和函数。
可以加入的代码是Java 代码,并放在%{和}%之间。
它们将被拷贝到生成的词法类源代码中。
在我们的词法说明中,声明了两个成员函数。
这些函数创建java_cup.runtime.Symbol对象。
第一个仅仅记录当前记号的位置信息。
第二个还包含了记号的值。
词法分析器生成器flex中文手册
![词法分析器生成器flex中文手册](https://img.taocdn.com/s3/m/230b665f4afe04a1b071defe.png)
词法分析器生成器flex中文手册FLEX 中文手册这是flex 手册的部分中文翻译,仅供参考, 一些简单的例子, 输入文件的格式模式,, 如何匹配输入, 动作, 生成的扫描器, 开始条件, 文件结尾规则, 与yacc 一起使用一些简单的例子首先给出一些简单的例子,来了解一下如何使用flex 。
下面的flex 输入所定义的扫描器,用来将所有的“username”字符串替换为用户的登陆名字:%% username printf("%s", getlogin()); 默认情况下,flex 扫描器无法匹配的所有文本将被复制到输出,所以该扫描器的实际效果是将输入文件复制到输出,并对每一个“ username”进行展开。
在这个例子中,只有一个规贝U。
“ user name”是模式(pattern) ,“printf ”是动作(action) 。
“%%”标志着规则的开始。
这里是另一个简单的例子:int num_lines = 0, num_chars = 0; %% \n ++num_lines; ++num_chars; .++num_chars;%% int main(void)yylex();printf("# of lines = %d, # of chars = %d\n", num_lines, num_chars);该扫描器计算输入的字符个数和行数( 除了最后的计数报告,并未产生其它输出) 。
第一行声明了两个全局变量,“ num_lines ”和“num_chars”,可以在yylex()函数中和第二%%”后面声明的main() 函数中使用。
有两个规则,一个是匹配换行符( “ n”) 并增加行数和字符数,另一个是匹配所有不是换行符的其它字符(由正规表达式“ .”表示)。
一个稍微复杂点的例子:/* scanner for a toy Pascal-like language */ %{/* need this for the call to atof() below */#include <math.h>%}DIGIT [0-9] ID [a-z][a-z0-9]*%%{DIGIT}+ {printf( "An integer: %s (%d)\n", yytext,atoi( yytext ) );{DIGIT}+"."{DIGIT}* {printf( "A float: %s (%g)\n", yytext,atof( yytext ) );if|then|begin|end|procedure|function {printf( "A keyword: %s\n", yytext );{ID} printf( "An identifier: %s\n", yytext );"+"|"-"|"*"|"/" printf( "An operator: %s\n", yytext );"{"[A}\n]*"}" /* eat up on e-li ne comme nts */ [ \t\n]+ /* eat up whitespace */ . printf( "Unrecognized character: %s\n", yytext );%%int main(int argc, char **argv)++argv, --argc; /* skip over program name */if ( argc > 0 )yyin = fopen( argv[0], "r" );elseyyin = stdin;yylex();}这是一个类似Pascal 语言的简单扫描器的初始部分,用来识别不同类型的标志(tokens) 并给出报告。
Flex操作手册
![Flex操作手册](https://img.taocdn.com/s3/m/0e80216c1711cc7931b716ae.png)
系统Flex编码规范参考对系统平台涉及到Flex部分的建议Qinmao2010-2-9目录1.架构目录 (5)1.1.主要文件结构 (5)1.2.SRC文件结构 (5)1.3.UTILS文件结构 (5)2.ACTIONSCRIPT (6)2.1.文件结构 (6)2.2.样式 (6)2.2.1.行与换行 (6)2.2.2.变量声明 (6)2.2.3.括号 (7)2.2.4.换行与空格 (7)2.3.注释 (8)2.3.1.文档注释 (8)2.3.2.执行注释 (8)3.MXML (9)3.1.文件结构 (9)3.2.样式 (9)3.2.1.行与换行 (9)3.2.2.属性 (9)3.2.3.脚本 (9)3.3.注释 (10)3.3.1.文档注释 (10)3.3.2.执行注释 (10)4.JAVA (11)4.1.文件结构 (11)5.命名 (11)5.1.一般规则 (11)5.2.语言 (11)5.3.包 (11)5.4.类 (12)5.5.接口 (12)5.6.方法 (12)5.7.变量 (12)5.8.常量 (12)5.9.命名空间 (12)6.配置文件 (12)6.1.F LEX配置文件 (12)7.插件安装 (15)7.1.安装文件 (15)【内部资料注意保密】版本:v1.0武汉市精建工程科技有限公司信息部二〇一〇年二月1.架构目录1.1. 主要文件结构bin-debug:调试生成文件html-template:libs:存放swc插件包src:开发文件目录1.2. src文件结构assets:图片,css,资源文件business:业务逻辑文件controller:前端控制文件events:事件文件model:模型文件utils:工具文件views:自定义组件Main.mxml:项目的主运行文件1.3. utils文件结构line:关于线工具文件2.A ctionScript2.1. 文件结构ActionScript文件包含以下组成部分:定义包Import 描述(flash包,mx包,com.adobe包,公司组件,第三方包,属于该文件的工程包)对类的注释属性的声明属性的注释方法方法注释2.2. 样式2.2.1.行与换行如果一段描述不能放在一行中,依据下列规则将其拆分成多行:从逗号后换行;在运算符之前换行;最好在较高级别代码处换行;换行后与上一行对齐;如果上一条规则不适用,加入两个缩进2.2.2.变量声明每行只有一个声明。
Flex
![Flex](https://img.taocdn.com/s3/m/d751287202768e9951e73858.png)
flexfast lexical analyz er generator名称NAMEfex-快速的词法分析程序产生器大纲SYNOPSISflex[-bcdfhilnpstvwBFILTV78+?-C[aefFmr]-ooutput-Ppre-fix-Sskeleton] [--help--version][filename...]概述OVERVIEW这个手册描述flex,一个通过在文本上进行模式匹配并生产程序的工具。
这个手册包括教程和参考两部分。
描述工具的一个简要的概述一些简单的例子输入文件的格式模式由flex使用的扩展的正则表达式输入是如何被匹配的用于判断哪些内容被匹配的规则动作如何指定当模式被匹配时该做什么生产扫描关于Flex扫描器的详细资料如何控制输入源开始条件介绍扫描器的环境和最小的扫描器多输入缓存如何操作双输入源;如何从string而不是文件进行扫描文件结束符规则匹配输入的结束符的特殊的规则各种宏动作可以使用的宏的概述用户可使用到的各种值动作可以用的各种值的概述关于Yacc的接口联合使用flex的扫描器和yacc的分析器选项Flex命令行的选项和“%option"指令性能考虑怎么让扫描器跑得最快生产C++扫描器可以生产C++扫描器class的能力与lex和posix不兼容的地方和AT&T lex和POSIX lex标准不同的地方诊断关于那些由flex生成(或是扫描器生成的)的意义不是很明显的错误消息文件Flex使用的文件不足和BUG已知的关于flex的问题参考其他文档和相关工具作者包括联系的信息描述DESCRIPTIONflex是一个用来生成扫描器的工具,生成扫描器可以识别文本中的词汇模式。
flex从输入文件中或是从标准输入设备中(如果没给出输入文件名)读取信息来生成一个扫描器。
信息以正则表达式和C代码对的形式组成,这种形式称为规则(rule)。
flex生成C源代码文件,lex.yy.c,其中定义了一个例程yylex()。
flex词法分析器
![flex词法分析器](https://img.taocdn.com/s3/m/afe2f0d980eb6294dd886cfe.png)
实验项目二语法和语义分析器一、实验类型本实验为验证性实验。
二、实验目的1.掌握 Yacc 的基本用法,并能够根据语言给出语法规则的定义,最后生成语言的解析器;2.使用Yacc实现一个高级计算器程序。
三、准备工作和预备知识在进一步阐述以前,让我们复习一下什么是语法。
在上一节中,我们看到Lex 从输入序列中识别标记。
如果你在查看标记序列,你可能想在这一序列出现时执行某一动作。
这种情况下有效序列的规范称为语法。
Yacc 语法文件包括这一语法规范。
它还包含了序列匹配时你想要做的事。
为了更加说清这一概念,让我们以英语为例。
这一套标记可能是:名词, 动词, 形容词等等。
为了使用这些标记造一个语法正确的句子,你的结构必须符合一定的规则。
一个简单的句子可能是名词+动词或者名词+动词+名词。
(如I care. See spot run.)所以在我们这里,标记本身来自语言(Lex),并且标记序列允许用Yacc 来指定这些标记(标记序列也叫语法)。
用Yacc 来创建一个编译器包括四个步骤:1. 通过在语法文件上运行Yacc 生成一个解析器。
2. 说明语法:o编写一个 .y 的语法文件(同时说明C 在这里要进行的动作)。
o编写一个词法分析器来处理输入并将标记传递给解析器。
这可以使用Lex 来完成。
o编写一个函数,通过调用yyparse() 来开始解析。
o编写错误处理例程(如yyerror())。
3. 编译Yacc 生成的代码以及其他相关的源文件。
4. 将目标文件链接到适当的可执行解析器库。
终端和非终端符号终端符号 : 代表一类在语法结构上等效的标记。
终端符号有三种类型:命名标记: 这些由%token标识符来定义。
按照惯例,它们都是大写。
字符标记 : 字符常量的写法与C 相同。
例如, -- 就是一个字符标记。
字符串标记 : 写法与C 的字符串常量相同。
例如,"<<" 就是一个字符串标记。
lexer 返回命名标记。
FLEX 中文手册
![FLEX 中文手册](https://img.taocdn.com/s3/m/e9d3680d844769eae009ed07.png)
FLEX 中文手册一些简单的例子 输入文件的格式 模式 如何匹配输入 动作 生成的扫描器 开始条件 文件结尾规则 与 yacc 一起使用一、一些简单的例子首先给出一些简单的例子,来了解一下如何使用 flex。
下面的 flex 输入所定 义的扫描器,用来将所有的“ username”字符串替换为用户的登陆名字: %% username printf("%s", getlogin()); 默认情况下,flex 扫描器无法匹配的所有文本将被复制到输出,所以该扫描 器的实际效果是将输入文件 复制到输出,并对每一个“username”进行展开。
在这个例子中,只有一个规 则。
“username”是模式 (pattern),“printf”是动作(action)。
“%%”标志着规则的开始。
这里是另一个简单的例子:int num_lines = 0, num_chars = 0;%% \n ++num_lines; ++num_chars; . ++num_chars; %% int main(void){ yylex(); printf("# of lines = %d, # of chars = %d\n", num_lines, num_chars); }该扫描器计算输入的字符个数和行数(除了最后的计数报告,并未产生其它 输出)。
第一行声明了两 个全局变量,“num_lines”和“num_chars”,可以在 yylex()函数中和第二个 “%%”后面声明的 main()函数中 使用。
有两个规则,一个是匹配换行符(“\n”)并增加行数和字符数,另一个 是匹配所有不是换行符的 其它字符(由正规表达式“.”表示)。
一个稍微复杂点的例子: /* scanner for a toy Pascal-like language */ %{/* need this for the call to atof() below */ #include <math.h>%} DIGIT [0-9] ID [a-z][a-z0-9]* %%{DIGIT}+ {printf( "An integer: %s (%d)\n", yytext, atoi( yytext ) ); }{DIGIT}+"."{DIGIT}* {printf( "A float: %s (%g)\n", yytext, atof( yytext ) ); }if|then|begin|end|procedure|function {printf( "A keyword: %s\n", yytext ); }{ID} printf( "An identifier: %s\n", yytext ); "+"|"-"|"*"|"/" printf( "An operator: %s\n", yytext ); "{"[^}\n]*"}" /* eat up one-line comments */ [ \t\n]+ /* eat up whitespace */ . printf( "Unrecognized character: %s\n", yytext ); %% int main(int argc, char **argv){ ++argv, --argc; /* skip over program name */ if ( argc > 0 ) yyin = fopen( argv[0], "r" ); else yyin = stdin; yylex(); }这是一个类似 Pascal 语言的简单扫描器的初始部分, 用来识别不同类型的标 志(tokens)并给出报告。
Flex中文帮助No3章
![Flex中文帮助No3章](https://img.taocdn.com/s3/m/2e3b724d33687e21af45a97a.png)
<!-- Flex controls exist in a container. Define a Panel container. -->
<mx:Panel title="My Application">
<!-- TextInput control for user input. -->
1. 大小/Sizes,即组件或应用程序的高度和宽度。
2. 样式/Styles,即一组特性,如字体、排列方式、颜色等。它们都是通过层叠样式(CSS)
来进行设置的。
3. 皮肤/Skins,即可以进行改变的组件视觉元素。
4. 行为/Behaviors,即 Flex 组件在视觉或听觉效果方面的变化。
// 定义一个 ActionScript 功能函数
private function duplicate():void {
myText.text=myInput.text;
}
public function showErrorDialog(error:String):void {
// 具体功能实现...
}
]]>
</mx:Script>
...
<mx:WebService id="WeatherService" ...">
应用程序模型
Flex 创建一个应用程序时,你使用组件(容器/containers 和控件/controls)来描述用户
的操作界面。例如,容器可以是一个用来进行数据输入的表格容器,如一个盒框/Box 或一
个栅格/Grid;而控件就是该表格中的元素,如一个按钮/Button 或文本输入栏/Text Input field。
flex词法分析器1
![flex词法分析器1](https://img.taocdn.com/s3/m/04ef153c0b4c2e3f572763fe.png)
实验项目一词法分析器一、实验类型本实验为验证性实验。
二、实验目的1.通过本实验加深对词法分析程序的功能及实现方法的理解;2.使用flex实现词法分析程序。
三、准备工作和预备知识Lex(Lexical Analyzar 词法分析生成器)是Unix下十分重要的词法分析工具。
经常用于语言分析,公式编译等广泛领域。
1.Lex(Lexical Analyzar) 初步示例先看简单的例子:一个简单的Lex文件 exfirst.l 内容:%{#include "stdio.h"%}%%[\n] ;[0-9]+ printf("Int : %s\n",yytext);[0-9]*\.[0-9]+ printf("Float : %s\n",yytext);[a-zA-Z][a-zA-Z0-9]* printf("Var : %s\n",yytext);[\+\-\*\/\%] printf("Op : %s\n",yytext);“.” printf("Unknown : %c\n",yytext[0]);%%在命令行下执行命令flex解析,会自动生成lex.yy.c文件:[root@localhost liweitest]flex exfirst.l进行编译生成parser可执行程序:[root@localhost liweitest]cc -o parser lex.yy.c –ll或者[root@localhost liweitest]gcc lex.yy.c –ll -o parser[注意:如果不加-ll链结选项,cc编译时会出现以下错误,后面会进一步说明。
] /tmp/cciACkbX.o(.text+0x37b): In function `yylex':: undefined reference to `yywrap'/tmp/cciACkbX.o(.text+0xabd): In function `input':: undefined reference to `yywrap'创建待解析的文件 file.txt:titlei=1+3.9;a3=909/6bcd=4%9-333通过已生成的可执行程序,进行文件解析。
JFLex用户手册中文版
![JFLex用户手册中文版](https://img.taocdn.com/s3/m/86cdeea7dd3383c4bb4cd2bd.png)
JFLEX词法分析安装与配置.zip,解压缩到本地目录(c:/jflex)。
jflex-1.4.3.zip1.下载jflex-1.4.3bin\jflex.bat文件,配置JAVA HOME和JFLEX HOME2.找到jflex\jflex\bin\jflex.bat3.把x:\jflex\bin写入系统环境变量path中运行可视化方式直接运行jflex\bin\jflex.bat文件,打开可视化界面操作即可。
命令行方式配置把x:\jflex\bin以及x:\jflex\lib\JFlex.jar配置到系统环境变量的CLASSPATH中。
格式java JFlex.Main<options><inputfiles>运行参数-d<directory><directory>生成文件的输出目录--skel<file>使用外部的骨架文件生成扫描器类,它大多数情况下用于JFLEX的维护和低级别定制。
只有在你知道自己正在作什么时候才使用它。
JFLEX的源码中带有一个骨架文件,预先编写骨架文件才能使用此命令。
--nomin在扫描器生成的过程中,跳过DFA简化步骤。
--jlex完全兼容jlex--dot为NFA,DFA and minimised DFA生成扩展名为.dot的graphviz图型文件。
该参数还在最初阶段,尚未完全实现。
--dump在控制台显示NFA转换表,初始DFA和最简DFA。
--verbose or–v显示生成过程信息。
--quiet or–q仅显示生成错误信息--time显示代码生成耗时信息(不十分精确)--version打印JFLex版本号--info打印系统以及JDK信息。
--pack使用%pack代码生成策略--table使用%table代码生成策略--switch使用%switch代码生成策略--help or-h打印帮助信息,解释运行参数以及Jflex用法。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一个带有范围的字符类别;匹配一个'a',或者一个'b',或者从'j'到'o'的任意字母,或者一个'Z'
'[^A-Z]'
一个反选的字符类别(negated character class),即任意不属于这些的类别。在这个例子中,
表示任意一个非大写字母的字符。 '[^A-Z\n]'
pattern action
模式(pattern)不能有缩进,动作(action)必须在同一行。
参见后面对模式和动作的进一步描述。
最后,用户代码部分将被简单的逐字复制到“lex.yy.c”中,作为随同程序用来调用扫描器或者被扫描器
调用。该部分是可选的,如果没有,输入文件中第二个“%%”也可以省略掉。
在定义部分和规则部分,任何缩进的文本或者包含在“%{”和“%}”中的文本,都会被逐字的复制到输出中(并去掉“%{}”)。“%{}”本身不能有缩进。
在规则部分,在第一个规则之前的任何缩进的或者%{}中的文本,可以用来声明扫描程序的局部变量。其它在规则部分的缩进或者%{}中的文本也会被复制到输出,但是它的含义却不好定义,而且可能会产生编译时错误(这一特点是为了与POSIX相同;参见后面的其它特点)。
}
该扫描器计算输入的字符个数和行数(除了最后的计数报告,并未产生其它输出)。第一声明了两
个全局变量,“num_lines”和“num_chars”,可以在yylex()函数中和第二个“%%”后面声明的main()函数中
使用。有两个规则,一个是匹配换行符(“\n”)并增加行数和字符数,另一个是匹配所有不是换行符的
因为,‘*’操作符的优先级比串联高,串联的优先级比间隔符高(‘|’),所以,该模式匹配字符串“foo”
或者字符串“ba”后面跟随零个或多个r。如果要匹配“foo”或者零个或多个“bar”,可以使用:
foo|(bar)*
如果要匹配零个或者多个“foo”,或者零个或多个“bar”:
(foo|bar)*
除了字符和序列字符,字符类别也可以包含字符类别表达式。这些表达式由‘[:’和‘:]’分隔符封装(并且
if ( argc > 0 )
yyin = fopen( argv[0], "r" );
else
yyin = stdin;
yylex();
}
这是一个类似Pascal语言的简单扫描器的初始部分,用来识别不同类型的标志(tokens)并给出报告。
这个例子的详细介绍将在后面的章节中给出。
输入文件的格式
flex输入文件包括三个部分,通过“%%”行来分开:
文件结尾,当在起始条件s1或s2下匹配。
注意,在字符类别里面,除了转义符(‘\’),字符类别操作符‘-’,‘]’和类别开始处的‘^’,所有其它的
正规表达式操作符不再具有特殊的含义。
上面列出的正规表达式,是按照优先级由高到低排列的。同一级别的具有相同的优先级。例如,
foo|bar*
等同于
(foo)|(ba(r*))
文字串:'[xyz]"foo'
'\x'
如果x是一个'a','b','f','n','r','t'或者'v',则为ANSI-C所解释的\x。否则,为一个文字'x'(
用来转义操作符,例如'*')。 '\0'
一个NUL字符(ASCII代码0)
'\123'
八进制值为123的字符
'\x2a'
十六进制值为2a的字符
这里是另一个简单的例子:
int num_lines = 0, num_chars = 0;
%% \n ++num_lines; ++num_chars; . ++num_chars;
%% int main(void)
{
yylex();
printf("# of lines = %d, # of chars = %d\n", num_lines, num_chars);
这些表达式都指定了与标准C中‘isXXX’函数相对应的字符类别。例如,‘[:alnum:]’指定了‘isalnum()’返
回值为真的字符集,即,任意的字母或者数字。一些系统没有提供‘isblank()’,则flex定义‘[:bland:]’为
一个空格符(blank)或者一个制表符(tab)。
例如,下面的字符类别是等同的:
任意一个非大写字母的字符,或者一个换行符
'r*'
零个或者多个r,其中r是任意的正规表达式
'r+'
一个或者多个r
'r?'
零个或者一个r(也就是说,一个可选的r)
'r{2,5}'
两个到五个r
'r{2,}'
两个或者更多个r
'r{4}'
确切的4个r
'{name}'
“name”定义的展开(参见前面)
' "[xyz]\"foo" ' (这里单引号和双引号之间没有空格)
必须在字符类别的分隔符‘[’和‘]’之中)。有效的表达式包括:
[:alnum:] [:alpha:] [:blank:] [:cntrl:] [:digit:] [:graph:] [:lower:] [:print:] [:punct:] [:space:] [:upper:] [:xdigit:]
%% username printf("%s", getlogin());
默认情况下,flex扫描器无法匹配的所有文本将被复制到输出,所以该扫描器的实际效果是将输入文件
复制到输出,并对每一个“username”进行展开。在这个例子中,只有一个规则。“username”是模式
(pattern),“printf”是动作(action)。“%%”标志着规则的开始。
alnum:[[:alpha:][:digit:] [[:alpha:]0-9] [a-zA-Z0-9]
如果你的扫描器是大小写无关的(使用‘-i’命令行选项),则‘[:upper:]’和‘[:lower:]’等同于‘[:alpha:]’。
关于模式的一些注意事项:
一个反选的字符类别例如上面的“[^A-Z]”将会匹配一个换行符,除非“\n”(或者等同的转义序
其它字符(由正规表达式“.”表示)。
一个稍微复杂点的例子:
/* scanner for a toy Pascal-like language */
%{
/* need this for the call to atof() below */
#include <math.h>
%}
DIGIT [0-9] ID [a-z][a-z0-9]*
FLEX 中文手册
这是flex手册的部分中文翻译,仅供参考
一些简单的例子
输入文件的格式
模式
如何匹配输入
动作
生成的扫描器
开始条件
文件结尾规则
与yacc一起使用
一些简单的例子
首先给出一些简单的例子,来了解一下如何使用flex。下面的flex输入所定义的扫描器,用来将所有的“
username”字符串替换为用户的登陆名字:
%%
{DIGIT}+ {
printf( "An integer: %s (%d)\n", yytext,
atoi( yytext ) );
}
{DIGIT}+"."{DIGIT}* {
printf( "A float: %s (%g)\n", yytext,
atof( yytext ) );
}
if|then|begin|end|procedure|function {
printf( "A keyword: %s\n", yytext );
}
{ID} printf( "An identifier: %s\n", yytext );
"+"|"-"|"*"|"/" printf( "An operator: %s\n", yytext );
"{"[^}\n]*"}" /* eat up one-line comments */
规则的开始处,或者‘$’不出现在规则的结尾,将会失去它的特殊属性,并且被作为普通字符。下面的
例子是非法的:
foo/bar$ <sc1>foo<sc2>bar
注意,第一个可以写作“foo/bar\n”。下面的例子中,‘$’和‘^’将会被作为普通字符:
foo|(bar$) foo|^bar
如果想匹配一个“foo”,或者一个“bar”并且后面跟随一个换行符,可以使用下面的方式(特殊动作‘|’,
'(r)'
匹配一个r;括号用来改变优先级(参见后面)
'rs'
正规表达式r,后面跟随正规表达式s;称作“concatenation”
'r|s'
或者r,或者s
'r/s'
一个r,但是后面要跟随一个s。在文本匹配时,s会被包含进来,以判断该规则是否是最长的匹配,但是在动作执行前会被返回给输入。因此,动作只会看到匹配r的文本。这种模式称作trailing context。(有些'r/s'组合,flex会匹配错误;参见后面的不足和缺陷章节中,关于“危险的尾部相关”的注解)