Lex和Yacc使用学习笔记(一)

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情
 

概述

使用LexYacc构造编译器过程如下图所示:

 

Yacc 读入bas.y 中的语法描述而后生成一个剖析器,即y.tab.c 中的函数 yyparseb as.y 中包含的是一系列的标记声明。Lex 读入bas.l 中的正则表达式的说明,包含文件 y.tab.h,然后生成词汇解释器,即文件lex.yy.c 中的函数yylex

最终,这个解释器和剖析器被连接到一起,而组成一个可执行程序,bas.exe。我们从main 函数中调用yyparse 来运行这个编译器。函数yyparse 自动调用yylex 以便获取每一个标志。

Lex

       在第一阶段,编译器读入源代码然后把字符串转换成对应的标记。使用正则表达式,我们可以为Lex设计特定的表达式以便从输入代码中扫描和匹配字符串。在Lex上每一个字符串对应一个动作。通常一个动作返回一个代表被匹配的字符串的标记给后面的剖析器使用。

每一个正则表达式代表一个有限状态自动机 (FSA) 我们可以用状态和状态之间的转换来代表一个FSA 。其中包括一个开始状态以及一个或多个结束状态或接受状态。

lex 把正则表达式翻译成模拟FSA 的一个计算机程序。通过搜索计算机生成的状态表,很容易使用下一个输入字符和当前状态来判定下一个状态。

Lex使用后缀名l的文件,文件结构如下:

... 定义 ...

%%

... 规则 ...

%%

... 子程序 ...

定义段由替代式,C代码,和开始状态构成。

定义段中的C代码被简单地原样复制到生成的C文件的顶部,而且必须用%{%}括起来。

替代式简化了正则表达式规则。例如,可以按如下方式定义数字和字母:

digit [0-9]

letter [A-Za-z]

替代式中定义的在规则段中使用时需要添加花括号{},如{letter}

规则段指定正则表达式已经对配置的这个表达式所做的处理。

子程序端中定义代码会直接拷贝到目标源文件中去。

 

Lex中使用的模式匹配的正则表达式的符号表

表意字符

匹配字符

.

除换行外的所有字符

/n

换行

*

0次或无限次重复前面的表达式

+

1次或更多次重复前面的表达式

?

0次或1次出现前面的表达式

^

行的开始

$

行的结尾

a|b

a或者b

(ab)+

1次或玩多次重复ab

"a+b"

字符串a+b本身(C中的特殊字符仍然有效)

[]

字符类

 

正则表达式举例:

表达式

匹配字符

abc

abc

abc*

ab abc abcc abccc ...

abc+

abc abcc abccc ...

a(bc)+

abc abcbc abcbcbc ...

a(bc)?

a abc

[abc]

a,b,c中的一个

[a-z]

az中的任意字符

[a/-z]

a,-,z中的一个

[-az]

-,a,z中的一个

[AZaz09]+

一个或更多个字母或数字

[ /t/n]+

空白区

[^ab]

a,b 外的任意字符

[a^b]

a, ^, b 中的一个

[a|b]

a, |, b 中的一个

a|b

a, b 中的一个

方括号中只保留两个操作,连字号(“-”)和抑扬号(“ ^ 。当把连字号用于两个字符中间时,表示字符的范围。当把抑扬号用在开始位置时,表示对后面的表达式取反。Lex中如果两个范式匹配相同的字符串,就会使用匹配长度最长的范式。如果两者匹配的长度相同,就会选用第一个列出的范式。

 

lex中预定义的变量及其功能如下表所示:

名称

功能

int yylex(void)

调用扫描器,返回标记

char *yytext

指针,指向所匹配的字符串

yyleng

所匹配的字符串的长度

yylval

与标记相对应的值

int yywrap(void)

约束,如果返回1 表示扫描完成后程序就结束了,否则返回 0

FILE *yyout

输出文件

FILE *yyin

输入文件

INITIAL

初始化开始环境

BEGIN

按条件转换开始环境

ECHO

输出所匹配的字符串

其中ECHO宏是这么定义的:

#define ECHO fwrite(yytext, yyleng, 1, yyout)

变量yyout是输出文件,默认状态下是stdout。当lex读完输入文件之后就会调用函数yywrap。如果返回1 表示程序的工作已经完成了,否则返回0

 

下面是一个扫描器,用于计算一个文件中的字符数,单词数和行数(类似Unix 中的wc 程序):

%{

int nchar, nword, nline;

%}

%%

/n { nline++; nchar++; }

[^ /t/n]+ { nword++, nchar += yyleng; }

. { nchar++; }

%%

int main(void) {

yylex();

printf("%d/t%d/t%d/n", nchar, nword, nline);

return 0;

}

使用Parser Generator2.07来完成生成工作,使用向导新建只有Alex的工程,注意Target Language的选择,上述例子使用了的是C[Project]->[Rebuild All]就生成了此法分析的C源代码wc.cwc.h文件;新建VC++工程,按照下述步骤配置环境

1.目录设置

VC++中执行以下步骤,每个步骤只执行一次。

1 选择Tools菜单中的Options命令,在屏幕上即会出现Options对话框。

2 选择Directories选项卡。

3 Show Directories for下拉列表框中选择Include Files

4 Directories框中,点击最后的空目录,并填入Parser Generatorinclude子目录的路径。

5 Show Directories for下拉列表框中选择Library Files

6 Directories框中,点击最后的空目录,并填入Parser Generatorlib/msdev子目录的路径。

7 Show Directories for下拉列表框中选择Source Files

8 Directories框中,点击最后的空目录,并填入Parser GeneratorSource子目录的路径。

9 点击OK按钮,Options对话框将接受设置并关闭。

VC++在就可以找到包含文件yacc.hlex.h以及YACCLex的库文件。

2.项目设置

对于每个VC++项目,都需在VC++中执行以下步骤:

1 选择Project菜单中的Settings命令,在屏幕上即会出现Project Settings对话框。

2 Settings for下拉列表框中选择Win32 Debug

3 选择C/C++标签。

4 Category下拉列表框中选择General

5 Preprocessor Definitions框中,在当前文本的最后,输入YYDEBUG

6 选择Link标签。

7 Category下拉列表框中选择General

8 Object/Library Modules框中,在当前文本的后面,输入yld.lib ylmtd.lib ylmtrd.lib ylmtrid.lib

9 Settings for下拉列表框中选择Win32 Release

10 重复第8步的工作,但是*.lib文件选择Release版的,及不带d的。

11 点击OK按钮,Project Settings对话框将接受设置并关闭。

       配置完后编译,运行就可。
LEX词法分析中常见的YY___的用法 这个函数。 阅读详情

相关推荐

LexYacc从入门到精通(4)-能够使用C++的LexYacc框架

能够使用C++的LexYacc框架 本文版权归熊春雷所有 ,我的邮箱:pandaxcl@163.com>,欢迎大家我讨论计算机方面 的问题,在我的博客上 面还写了很多其他的文档,有空来看看哦。如果转载,请保留此版权信息,并注 明出处。谢谢:) 摘要 写这章的目的就是为了能够提供个能够使用C++特色的LexYacc框架,这个

1万+

lex生成lex.yy.c代码流程解析

词法分析器 lex.yy.c流程分析

DavidWu88的专栏 5856

LexYacc使用教程().Windows下使用LexYacc

LexYacc应用方法().Windows下使用LexYacc草木瓜  20070904、序    不想LexYacc系列的最后篇文章竟如此“难产”,已时隔三个月之久。不由慨叹自由可支配时间是如此之少,如此岂不谓新时代的“奴隶”~    罢罢罢,闲话少叙,回归正题,本文主要介绍在Windows下如何去使用LexYacc,以作为本系列文章的终结。    二、方法介绍  

草木瓜 2万+

lex编译dos命令_lex.yy.c如何运行

? FLEX 1.L 3、运行 FLEX 后,产生“LEXYY.C”程序 4 、用 VC 打开“LEXYY.C” 程序,编译后产生“LEXYY.EXE”程序。 5、进入 DOS 环境“LEXYY.EXE”......七、结果分析 程序运行命令: 其中 lex.l 即为编写的 Lex 源代码;lex.yy.x 是上步 flexlex.l 源代码进行处理,生成的文件;用 gcc 对 lex.y...

weixin_39700394的博客 1812

编译原理——编写LEX文件:个能识别所有运算式中包含的符号

编写LEX文件:个能识别所有运算式中包含的符号:数字(0-9)+,变量(a-zA-Z)+,运算符:“+,-,*,/,(,)”。 如输入(a+10)*b,输出: OPERATER:( WORD:a OPERATER:+ NUMBER:10 OPERATER:) OPERATER:* WORD:b

m0_59052131的博客 5252

Lex使用指南

Lex使用指南

火雨(Nick) 2万+

LexYacc应用方法().再识LexYacc

LexYacc应用方法().再识LexYacc草木瓜  20070314早在二十世记七十年代之前,编写编译器直是个非常费时的工作。但到了1975这年这切却发生了重大转变,首先Stephen C. Johnson Lesk在贝尔实验室完成了Yacc开发,为了配合yacc更好的协作, Mike LeskEric Schmidt又完成了lex。从而Lexyacc成为计算机编译领

草木瓜 1万+

LexYacc应用方法().初识Lex

 LexYacc应用方法().初识Lex草木瓜  20070301Lex(Lexical Analyzar 词法分析生成器)Yacc(Yet Another Compiler Compiler编译器代码生成器)是Unix下十分重要的词法分析,语法分析的工具。经常用于语言分析,公式编译等广泛领域。遗憾的是网上中文资料介绍不是过于简单,就是跳跃太大,入门参考意义并不大。本文通过循序渐进的

草木瓜 5万+

【PLY】LexYacc简单示例

PLY是流行的编译器构造工具lexyacc的纯python实现。 PLY官方文档:http://www.dabeaz.com/ply/ PLY文档翻译:https://qyliang.blog.csdn.net/article/details/97686897 PLY由两个单独的模块组成lex.py yacc . py 。都可以在名为ply的Python包中找到。 lex.py模块用于将输入的...

土豆洋芋山药蛋的博客 3043

编译原理——Lexyacc的安装

Lexyacc的安装 Linux用户 LexYacc可以直接从终端安装,命令: apt install flex bison 部分系统可能还需要手动安装 gcc make 等工具,请自行测试。 安装完成后,在终端输入以下命令,若可以正确显示出版本号,则安装成功。 gcc --version lex --version yacc --version 如图所示:(图片来源网络)...

budding0828 1万+

lexyacc程序学习(4)——lexyacc使用

个程序通常在每次返回个标记时都要调用yylex()函数。只有在文件结束或者出现错误标记时才会终止。 个由yacc生成的分析器调用yylex()函数来获得标记。yylex()可以由Lex来生成或完全由自己来编写。对于由Lex生成的lexer来说,要yacc结合使用,每当Lex中匹配个模式时都必须返回个标记。因此Lex中匹配模式时的动作般格式为: {pattern} { /* do smthg*/ return TOKEN_NAME; } 于是 Yacc 就会获得返回的标记。当 Yacc

wang_yr的博客 1145

能够使用C++的LexYacc框架

能够使用C++的LexYacc框架<br />写这章的目的就是为了能够提供个能够使用C++特色的LexYacc框架,这个框架同前章的目的样,也是仅仅为了能够提供个什么也不作的框架程序,当时有点不同的就是:这个新的框架使用了C++语法,能够使用所有的C++特色,包括STL的强劲算法容器,还有各式各样的C++库。采用C++的目的就是为了能够快速的编码来完成自己需要完成的任务。<br />在编码词法分析语法分析程序的时候经常会编写些链表容器,实际上这些链表容器在C++语言函数库里面都已经有

Skai_CSDN的专栏 2244

YaccLex 快速入门

简介: Lex Yacc 是 UNIX 两个非常重要的、功能强大的工具。事实上, 如果你熟练掌握 Lex Yacc 的话,它们的强大功能使创建 FORTRAN C 的编译器如同儿戏。本文详细的讨论了编写自己的语言编译器所 用到的这两种工具,包括常规表达式、声明、匹配模式、变量、Yacc 语 法解析器代码。最后,本文解释了怎样把 Lex Yacc 结合起来。

红孩儿编程大师 4490

yacc lex c 注释_LexYACC详解

原文:https://www.cnblogs.com/hdk1993/p/4922866.html注:1)修正了原文中有问题的代码;2)补充了YY_INPUT等内容。、简介只要你在Unix环境中写过程序,你必定会邂逅神秘的Lex&YACC,就如GNU/Linux用户所熟知的Flex&Bison,这里的Flex就是由Vern Paxon实现的Lex,Bison则是GNU版本的Y...

weixin_39632397的博客 1463

基于Lex Yacc 的 C 语言编译器

最近由于项目需要,看了点关于编译原理编译器等方面的资料,特别是词法分析语法分析部分,现做下小结。 编译器及其工作流程 编 译器,是将便于人编写,阅读,维护的高级计算机语言翻译为计算机能识别,运行的低级机器语言的程序。编译器将源程序(Source program)作为输入,翻译产生使用目标语言(Target language)的等价程序。源程...

JennyComputer2014的博客 1423

LexYacc入门

原文地址:http://coanor.blog.hexun.com/38241166_d.html   1. 简介 只要你在Unix环境中写过程序,你必定会邂逅神秘的Lex&YACC,就如GNU/Linux用户所熟知的Flex&Bison,这里的Flex就是由Vern Paxon实现的Lex,Bison则是GNU版本的YACC.在此我们将统称呼这些程序为LexYACC.新版本的程序是

雜貨鋪 2107

Lex+YACC or Flex+Bison

1.简介 只要你在Unix环境中写过程序,你必定会邂逅神秘的Lex&YACC,就如GNU/Linux用户所熟知的Flex&Bison,这里的Flex就是由Vern Paxon实现的Lex,Bison则是GNU版本的YACC. 在此我们将统称呼这些程序为LexYACC.新版本的程序是向上兼容的(译注:即兼容老版本),所以你可以用FlexBis...

zzhongcy的专栏 3591

LEXYACC简介

Lex工具 -------     Lex工具是种词法分析程序生成器,它可以根据词法规则说明书的要求来生成单词识别程序,由该程序识别出输入文本中的各个单词。 1、lex程序的结构 -定义部分 -规则部分 -用户子程序部分 其中规则部分是必须的,定义用户子程序部分是任选的。 (1) 定义部分      定义部分起始于"%{"符号,终止于"%}"符号,其间可以是包括include语句、声明语句在内的C语句。 %{ #include "stdio.h" #include "y.tab.h" extern in

xiaoxiaofengqi的专栏 5453

LexYacc从入门到精通(3)--个极其简单的lexyacc程序

个极其简单的lexyacc程序 本文版权归熊春雷所有 ,我的邮箱:pandaxcl@163.com>,欢迎大家我讨论计算机方面 的问题,在我的博客上 面还写了很多其他的文档,有空来看看哦。如果转载,请保留此版权信息,并注 明出处。谢谢:) 摘要 在本章中,将会首先给出个最基本的lexyacc联合使用的框架,这个基本框架

2万+
上一篇: 设计模式轻松讲解
下一篇: Lex和Yacc使用学习笔记(二)
flying2
博客等级 码龄24年 4粉丝 20原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值