消防劳士应急灯灯信号信绿黄可以反过来接吗

关于lex生成的代码编译问题
关于lex生成的代码编译问题
发布时间: 9:22:21
编辑:www.fx114.net
本篇文章主要介绍了"关于lex生成的代码编译问题
100CSDN]",主要涉及到关于lex生成的代码编译问题
100CSDN]方面的内容,对于关于lex生成的代码编译问题
100CSDN]感兴趣的同学可以参考一下。
我用lex写的一个很简单的.L文件生成的.c文件编译后遇到很多错误,
tjs.cpp(390)&:&error&C2146:&syntax&error&:&missing&';'&before&identifier&'YY_PROTO'
怎么解决?检测l文件中是否有表达式错误,这就是lex的局限性,必须要生成cpp文件后才能检测是否写正确你不把源码放上来,这样是看不出什么的唉
帮你找了下面的文章你看看吧。
--&&LEX的使用方法
Lex&是一种生成扫描器的工具。扫描器是一种识别文本中的词汇模式的程序。这些词汇模式(或者常规表达式)在一种特殊的句子结构卸ㄒ澹?飧鑫颐且换岫?鸵?致邸?/P&
一种匹配的常规表达式可能会包含相关的动作。这一动作可能还包括返回一个标记。当&Lex&接收到文件或文本形式的输入时,它试图将文本与常规表达式进行匹配。它一次读入一个输入字符,直到找到一个匹配的模式。如果能够找到一个匹配的模式,Lex&就执行相关的动作(可能包括返回一个标记)。另一方面,如果没有可以匹配的常规表达式,将会停止进一步的处理,Lex&将显示一个错误消息。
Lex&和&C&是强耦合的。一个&.lex&文件(Lex&文件具有&.lex&的扩展名)通过&lex&公用程序来传递,并生成&C&的输出文件。这些文件被编译为词法分析器的可执行版本。
Lex&的常规表达式
常规表达式是一种使用元语言的模式描述。表达式由符号组成。符号一般是字符和数字,但是&Lex&中还有一些具有特殊含义的其他标记。&下面两个表格定义了&Lex&中使用的一些标记并给出了几个典型的例子。
用&Lex&定义常规表达式
字符&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&含义&
A-Z,&0-9,&a-z&&&&&&&&&构成了部分模式的字符和数字。&
.&&&&&&&&&&&&&&&&&&&&&&&&&&匹配任意字符,除了&\\n。&
-&&&&&&&&&&&&&&&&&&&&&&&&&&用来指定范围。例如:A-Z&指从&A&到&Z&之间的所有字符。&
[&]&&&&&&&&&&&&&&&&&&&&&&&&一个字符集合。匹配括号内的任意&字符。如果第一个字符是&^&那么它表示否
&&&&&&&&&&&&&&&&&&&&&&&&&&&定模式。例如:&[abC]&匹配&a,&b,&和&C中的任何一个。&
*&&&&&&&&&&&&&&&&&&&&&&&&&&匹配0个或者多个上述的模式。&
+&&&&&&&&&&&&&&&&&&&&&&&&&&匹配1个或者多个上述模式。&
?&&&&&&&&&&&&&&&&&&&&&&&&&&匹配0个或1个上述模式。&
$&&&&&&&&&&&&&&&&&&&&&&&&&&作为模式的最后一个字符匹配一行的结尾。&
{&}&&&&&&&&&&&&&&&&&&&&&&&&指出一个模式可能出现的次数。&例如:&A{1,3}&表示&A&可能出现1次或3次。&
\\&&&&&&&&&&&&&&&&&&&&&&&&&&用来转义元字符。同样用来覆盖字符在此表中定义的特殊意义,只取字符的
&&&&&&&&&&&&&&&&&&&&&&&&&&&本意。&
^&&&&&&&&&&&&&&&&&&&&&&&&&&否定。&
|&&&&&&&&&&&&&&&&&&&&&&&&&&表达式间的逻辑或。&
"&一些符号&"&&&&&&&&字符的字面含义。元字符具有。&
/&&&&&&&&&&&&&&&&&&&&&&&&&&向前匹配。如果在匹配的模版中的“/”后跟有后续表达式,只匹配模版
&&&&&&&&&&&&&&&&&&&&&中“/”前面的部分。如:如果输入&A01,那么在模版&A0/1&中的&A0&是匹配的。
(&)&&&&&&&&&&&&&&&&&&&&&&&&将一系列常规表达式分组。&
常规表达式举例
常规表达式&&&&&&&&&&含义
joke[rs]&&&&&&&&&&&&匹配&jokes&或&joker。
A{1,2}shis+&&&&&&匹配&AAshis,&Ashis,&AAshi,&Ashi。
(A[b-e])+&&&&&&&&&&匹配在&A&出现位置后跟随的从&b&到&e&的所有字符中的&0&个或&1个。
Lex&中的标记声明类似&C&中的变量名。每个标记都有一个相关的表达式。(下表中给出了标记和表达式的例子。)使用这个表中的例子,我们就可以编一个字数统计的程序了。我们的第一个任务就是说明如何声明标记。
标记声明举例
标记&&&&&&&&&&&&&&&&&&&相关表达式&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&含义
数字(number)&&&&&([0-9])+&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&1个或多个数字
字符(chars)&&&&&&&&[A-Za-z]&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&任意字符
空格(blank)&&&&&&&&&"&"&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&一个空格
字(word)&&&&&&&&&&&&(chars)+&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&1个或多个&chars
变量(variable)&&&&&(字符)+(数字)*(字符)*(数字)*
Lex&编程可以分为三步:
以&Lex&可以理解的格式指定模式相关的动作。&
在这一文件上运行&Lex,生成扫描器的&C&代码。&
编译和链接&C&代码,生成可执行的扫描器。&这是&&编译原理与实践&&书中配套的源代码的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&&&&&\\n
whitespace&&[&\\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<}
"+"&&&&&&&&&&&&&{return+}
"-"&&&&&&&&&&&&&{return−}
"*"&&&&&&&&&&&&&{return×}
"/"&&&&&&&&&&&&&{return&OVER;}
"("&&&&&&&&&&&&&{return&LPAREN;}
")"&&&&&&&&&&&&&{return&RPAREN;}
";"&&&&&&&&&&&&&{return;}
{number}&&&&&&&&{return#}
{identifier}&&&&{return&ID;}
{newline}&&&&&&&{lineno++;}
{whitespace}&&&&{/*&skip&whitespace&*/}
"{"&&&&&&&&&&&&&{&char&c;
&&&&&&&&&&&&&&&&&&do
&&&&&&&&&&&&&&&&&&{&c&=&input();
&&&&&&&&&&&&&&&&&&&&if&(c&==&EOF)&
&&&&&&&&&&&&&&&&&&&&if&(c&==&\'\\n\')&lineno++;
&&&&&&&&&&&&&&&&&&}&while&(c&!=&\'}\');
&&&&&&&&&&&&&&&&}
.&&&&&&&&&&&&&&&{return&ERROR;}
TokenType&getToken(void)
{&static&int&firstTime&=&TRUE;
&&TokenType&currentT
&&if&(firstTime)
&&{&firstTime&=&FALSE;
&&&&lineno++;
&&&&yyin&=&
&&&&yyout&=&
&&currentToken&=&yylex();
&&strncpy(tokenString,yytext,MAXTOKENLEN);
&&if&(TraceScan)&{
&&&&fprintf(listing,"\\t%d:&",lineno);
&&&&printToken(currentToken,tokenString);
&&return&currentT
这里有点不同的就是,作者用了另外一个getToken函数来代替yylex作为外部输出函数.其中getToken里面也使用了lex默认的输出函数yylex(),同时还做了一些其它的事情.不过我建议大家不要像作者那样另外写自己的结果输出函数,因为在后面,需要和yacc搭配工作的时候,yacc生成的语法分析程序只认名字叫yylex()的词法结果输出函数.
if&(firstTime)
&&{&firstTime&=&FALSE;
&&&&lineno++;
&&&&yyin&=&
&&&&yyout&=&
其中的yyin,yyout,source,listing都是FILE*类型.yyin就是要lex生成的词法扫描程序要扫描的文件,yyout就是基本输出文件(其实我们通常都不用yyout,即使要生成一些输出信息,我们都是自己通过fprintf来输出).
"{"&&&&&&&&&&&&&{&char&c;
&&&&&&&&&&&&&&&&&&do
&&&&&&&&&&&&&&&&&&{&c&=&input();
&&&&&&&&&&&&&&&&&&&&if&(c&==&EOF)&
&&&&&&&&&&&&&&&&&&&&if&(c&==&\'\\n\')&lineno++;
&&&&&&&&&&&&&&&&&&}&while&(c&!=&\'}\');
&&&&&&&&&&&&&&&&}
其中,作者的这个Tiny&C是以{}来包括注释信息.作者并没有写出注释信息的正则表达式,但是它可以通过检索"{",然后用lex内部函数input()一一检查&{&后面的字符是不是&}&来跳过注释文字.(C语言的/*&*/注释文字正则表达式十分难写,所以很多时候我们都用这种方法直接把它的DFA(扫描自动机)写出来).C/C++&的注释这样子写是没有毛病的&\/\*([^\*]|\*[^/]|\n|\r)*\*\/&,&就是遇到一大段注释的时候往往就得分配内存啦,&在内存紧张的环境下就不大好啦&,&这个倒是不算很复杂,&字符串常量的正则如果要严格写起来就麻烦大啦,&我自己搞的一个简单脚本的都得写成:
ESC_CHAR1 [\'\"\\\/bfnrtv]
HEX_ESC_CHAR x[0-9a-fA-F][0-9a-fA-F]
OCT_ESC_CHAR [0-7]{1,2}|[0-3][0-7]{2}
UNI_ESC_CHAR u[0-9a-fA-F]{4}
ESC_CHAR {ESC_CHAR1}|{HEX_ESC_CHAR}|{OCT_ESC_CHAR}|{UNI_ESC_CHAR}
DBL_CHAR [^\"\\\n\r]|\\{ESC_CHAR}
SIG_CHAR [^\'\\\n\r]|\\{ESC_CHAR}
STR_L1 \"({DBL_CHAR})+\"
STR_L2 \'({SIG_CHAR})+\'
STR_LITERAL {STR_L1}|{STR_L2}
bison&&&&flex&&都可以定制&skeleton&文件,&函数名啊,&变量名这些只要稀饭就可以随便改改啦
一、不得利用本站危害国家安全、泄露国家秘密,不得侵犯国家社会集体的和公民的合法权益,不得利用本站制作、复制和传播不法有害信息!
二、互相尊重,对自己的言论和行为负责。
本文标题:
本页链接:> 博客详情
编译器就是将“高级语言”翻译为“机器语言(低级语言)”的程序。一个现代编译器的主要工作流程:源代码 (source code) → 预处理器 (preprocessor) → 编译器 (compiler) → 目标代码 (object code) → 链接器 (Linker) → 可执行程序 (executables) 编译器是软件开发中的核心部件,其作用是其他 任何软件所不能取代的。 编译器在工作过程中,往往完成如下的任务: 1、读取源代码并且获得程序的结构描述 2、分析程序结构,并且生成相应的目标代码 在构造专业的编译器的时候,常常需要使用到和. 正是因为这两个工具,使得我们编写编译器,解释器等工具的时候工作变得非常简单。 通过使用lex和yacc生成的词法和语法代码比程序员手写代码要方便很多,代码规范,甚至效率有时比手工高。
编译器工作原理
lex负责词法解析,而yacc负责语法解析,其实就是lex负责根据指定的正则表达式,将输入的字符串匹配成一个一个的token,同时允许用户将当前匹配到的字符串进行处理,并且允许返回一个标识当前token的标识码。而yacc则负责进行语法解析,将一个个的token最终形成一个完整的语法。
lex与yacc合建编译程序
三、lex与yacc介绍
在UNIX早期时代,编写一个编译器是一件非常耗时的工作。人们为了简化开发过程,贝尔实验室开发了Lex和YACC程序来解决以上的任务,根据用户描述的语言,生成能够解决问题的C/C++语言代码,供开发者使用。
Lex将源代码文件分解为各种词汇,用来分析词法,例如if、int、16。
Yacc找到这些词汇的组成方式,用来分析语法,例如int i = 10。
GNU软件协会开发了Flex和Bison,其功能与Lex和Yacc基本兼容,并且在Lex和Yacc提供的功能的基础 上进行了各种扩展。
在构造专业的编译器的时候,常常需要使用到lex和yacc. 正是因为这两个工具,使得我们编写编译器,解释器等工具的时候工作变得非常简单。 Lex 代表 Lexical Analyzar。Yacc 代表 Yet Another Compiler Compiler。
Lex 和 Yacc 是 UNIX 两个非常重要的、功能强大的工具。事实上,如果你熟练掌握 Lex 和 Yacc 的话,它们的强大功能使创建 FORTRAN 和 C 的编译器如同儿戏,使用这两个工具开发的软件很多,下面简单举几个使用它们开发的软件。 开发编译器(gcc) 、开发解释器(php解析)、 sql解析器(mysql和PostgreSQL的sql解析)、 lex程序本身 、go的语法分析器 、自然语言处理、 文本分析、 Lua 第一版等众多的软件都是lex和yacc的杰作。
开发工具 windows下方法:Parser Generator+VC6.0、Parser Generator+Cygwin、记事本+Cygwin
linux下方法:vim+flex+bosin+gcc
Parser Generator作为当前最好用的Windows环境LEX/YACC工具而被广泛应用,之所以推荐它是因为它生成的c文件可以在vc++下通过编译。 Parser Generator的地址,下载之后,解压缩,然后安装。
六、Lex与Yacc语法通用样式
/* 定义段 */
/ * Flex、Bison代码段(规则) * /
/ * 辅助代码段,C语言 */
分为三段,段与段之间以%%分隔
七、Lex与Yacc编译命令
flex -o&由lex生成文件.c& &lex词法分析文件.l&
bison -o&yacc生成文件.c& &yacc语法分析文件.y& -d & & &# 注意-d,用于产生对应的头文件
gcc test2yy.c test2ll.c -o test2
关于lex与yacc的语法,由于篇隔限制,这里不作过多的介绍,可以去自学一下。
ps:一些实例代码,已上传到云端,希望能帮助到大家的学习,点击这里,有问题大家一起讨论。
人打赏支持
码字总数 0
支付宝支付
微信扫码支付
打赏金额: ¥
已支付成功
打赏金额: ¥阅读排行榜
评论排行榜您所在位置: &
&nbsp&&nbsp&nbsp&&nbsp
编译原理实践词法分析程序的自动生成器LEX.ppt 27页
本文档一共被下载:
次 ,您可全文免费在线阅读后下载本文档。
下载提示
1.本站不保证该用户上传的文档完整性,不预览、不比对内容而直接下载产生的反悔问题本站不予受理。
2.该文档所得收入(下载+内容+预览三)归上传者、原创者。
3.登录后可充值,立即自动返金币,充值渠道很便利
需要金币:100 &&
编译原理实践词法分析程序的自动生成器LEX
你可能关注的文档:
··········
··········
由于各种高级程序设计语言的单词形式基本上可以用一组正规式来描述,人们就希望能否构造一个自动生成系统,只要给出程序设计语言的各类单词描述以及识别出各类单词后应输出的结果,这种自动系统便能自动产生此程序设计语言的词法分析程序Lex就是这样一个工具,他将正规式转换为一个NFA,进而转换为相应的DFA,这个DFA可以识别该正规式所表示的语言的句子 LEX有一个重要的元字符约定是用大括号指出正则表达式的名字。在前面已经提到过可以为正则表达式起名,这些名字也可使用在其他的正则表达式中,而为了将正则表达式名和普通的字符序列区分开来,将正则表达式放在大括号中。例如,无符号整数定义为:num=[0-9]+其中,num为正则表达式名。 在有符号的整数的定义中,可以引用正则表达式名num:signedNum=(+|-)?{num}注意:在定义正则表达式名时并不写大括号,只有在使用正则表达式名时才加上大括号。编译原理实践 --词法分析程序的自动生成器LEX LEX简单的介绍1LEX(lexicalananlyzergenerator)一个词法分析程序的自动生成器.LEX是1972年贝尔实验室首先在UNIX上实现的.2FLEX(fastlexicalananlyzergenerator)是对LEX的扩充,它可在MS-DOS下运行.我们这里实际使用的是FLEX,但仍称呼为LEX.LEX简单的介绍3LEX能根据给定的正则表达式自动生成相应的词法分析程序.LEX的输入是用LEX语言写的源程序,生成一个用C语言描述的词法分析程器,所以LEX本身就相当与LEX语言写的编译程序.LEX生成的目标程序包含一个状态转换矩阵和一个控制执行程序.LEX使用流程使用LEX的流程如图:LEX源程序LEXYYLEX.CYYLEX.CC编译器YYLEX.EXEYYLEX.EXE字符串源程序符号串源程序LEX源程序是使用LEX语言编写的词法规则说明,经过LEX翻译后形成目标文件YYLEX.C;再用C编译器对YYLEX.C进行翻译,生成目标程序YYLEX.EXE,它就是词法分析程序,用YYLEX.EXE就可以将字符串源程序转换成符号串源程序.用LEX语言表达正则表达式LEX的输入是LEX源程序.首先介绍如何表示正则表达式.LEX表示正则表达式时采用一些元字符*+()\[]|{}““等,表示方法如下.(1)对于单个的字母a,就直接表示成a,如a,+,-等.(2)[abc]表示字符a,b,或c中的任一个,如[01]表示0或1(3)[a-d]表示字符a,b,c或d中的任一个.(4)[^ab]表示除了a或b外的任一个字符.用LEX语言表达正则表达式(5).表示除了换行符之外的任一个字符.(6)”text”表示双引号里的每个字符(包括元字符)都按字符处理,如”ab[01]”就是表示ab[01]是字符串,其中的[和]不是元字符(7)\转义字符(8){xxx}名字xxx表示的正则表达式。(9)r|s表示正则表达式r或正则表达式s。(10)rs表示正则表达式r与正则表达式s的连接。用LEX语言表达正则表达式(11)(r)表示()内的优先级高于括号外。(12)r*表示正则表达式r可重复零次或多次。(13)r+表示正则表达式r可重复一次或多次。(14)r?表示r是一个可选的正则表达式。(15)r{m,n}其中m,n是正整数,表达正则表达式r的m~n次重复。(16)r{m}表示正则表达式r的m次重复。(17)r{m,}表示正则表达式r的m到多次的重复。(18)^行的开始,$行的结尾用LEX语言表达正则表达式例:1)二进制数(0|1)*2)以aa或bb开头的由a和b任意组成的字符串(aa|bb)(a|b)*或(aa|bb)[ab]*3)任何一个从0~9的数字:[0-9]4)长度不超过8的小写字符串[a-z]{1,8}用LEX语言表达正则表达式5)无符号整数[0-9]+6)可带小数点的有符号数(“+”|”-”)?[0-9]+(“.”[0-9]+)?7)可带指数的有符号数(“+”|”-”)?[0-9]+(“.”[0-9]+)?(E(“+”|”-”)?[0-9]+)?8)标识符:字母或_开头,后跟字母数字、下划线等字符[a-zA-Z_]([a-zA-Z_]|[0-9])*9)空白区[\t\n]+用LEX语言表达正则表达式LEX有个特征,在方括号(表示字符类)中,大多数的元字符都丧失了其特殊状况,且不必用引号括起来。甚至如果可以首先将连字符列出来的话,则也可以将其看作字符。因此,可将前一个数字的正则表达式(“+”|”-”)写作[-+],但不能写成[+-],这是因为元字符“-”用于表示字符的一个范围。又例如:[.”?]表示了句号、引号和问号3个字符中的任一个字符,此时,这三个字符在方括号中都丧失了它们元字符的含义。
正在加载中,请稍后...

我要回帖

更多关于 防爆应急灯 的文章

 

随机推荐