从lex&yacc说到编译器(1.正则表达式)

原创 2003年09月29日 00:39:00

lex&yacc说到编译器(1.正则表达式)<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

作者:tangl_99

QQ:8664220

msn:tangl_99@hotmail.com

email:tangl_99@sohu.com

 

学过编译原理的朋友肯定都接触过LEX这个小型的词法扫描工具. 但是却很少有人真正把LEX用在自己的程序里. 在构造专业的编译器的时候,常常需要使用到lexyacc. 正是因为这两个工具,使得我们编写编译器,解释器等工具的时候工作变得非常简单.不过话说回来,会使用lexyacc的人也确实不简单. Lexyacc里面牵涉到一系列的编译原理的理论知识,不是简单地看看书就能搞懂的. 本文只是简单地介绍一下lexyacc的使用方法.相关编译理请查看本科教材.

 

国内大学教材里面对于lexyacc的介绍很少,有些根本就没有,不过在国外的编译原理教材介绍了很多. 按照学科的分类,国内大学本科里面开的<<编译原理>>教程只是讲解编译的原理,并不讲解实践. 而对于实践方面则是另外一门学科<<编译技术>>. 关于编译技术的书籍在国内是少之又少. 前不久, 听说上海交大的计科内部出版过编译技术的教材.可惜我们这些人就无法得见了. 还好,机械工业出版社引进了美国 Kenneth C.Louden所著的经典著作<<编译原理及实践>>,比较详细地介绍lexyacc的使用.

 

Lex属于GNU内部的工具,它通常都是gcc的附带工具. 如果你使用的Linux操作系统,那么肯定系统本身就有lexyacc,不过yacc的名字变成了bison. 如果你使用的Windows操作系统,那么可以到cygwin或者GNUPro里面找得到. 网上也有windows版本lexyacc,大家可以自己去找一找.

 

本文一共有两篇,一篇是介绍lex,另一篇是介绍yacc.  Lexyacc搭配使用, 我们构造自己的编译器或者解释器就如同儿戏. 所以我把本文的名字叫做黄金组合.

 

本文以flex( Fase Lex)为例,两讲解如何构造扫描程序.

Flex可以通过一个输入文件,然后生成扫描器的C源代码.

 

其实扫描程序并不只用于编译器 .比如编写游戏的脚本引擎的时候,我看到很多开发者都是自己写的扫描器,其算法相当落后(完全没有DFA的概念化), 甚至很多脚本引擎开发者的词法扫描器都没有编写,而是在运行过程中寻找token(单词). 在现代的计算机速度确实可以上小型的脚本引擎在运行中进行词法扫描, 但是作为一个合格的程序员, 或者说一个合格的计算机本科毕业生而来说, 能够运用编译原理与技术实践,应该是个基本要求.

 

如果要说到词法分析的扫描器源代码编写, 其实也很简单, C语言的人都会写. 可是Kenneth Louden<<编译原理及技术>里面,花了50多页,原因就是从理论角度,介绍标准的,可扩展的,高效的词法扫描器的编写. 里面从正则表达式介绍到DFA(有穷自动机),再到NFA(非确定性有穷自动机),最后才到代码的编写. 以自动机原理编译扫描器的方法基本上就是现在词法扫描器的标准方法, 也就是Lex使用的方法. Lex,我们甚至不需要自己构造词法的DFA, 我们只需要把相应的正则表达式输入, 然后lex能够为我们自己生成DFA,然后生成源代码,可谓方便之极.

 

本文不讲DFA, lex的输入是正则表达式, 我们直接先看看正则表达式方面知识就可以了.

 

1.正则表达式(regular expression):

 

对于学过编译原理的朋友来说,这一节完全可以不看.不过有些东西还是得注意一下,因为在flex中的正则表达式的使用有些具体的问题是在我们的课本上没有说明的.

先看看例子:

1.1

name      Tangl_99

这就是定义了name这个正则表达式,它就等于字符串Tangl_99.所以,如果你的源程序中出现了Tangl_99这个字符传,那么它就等于出现一次name正则表达式.

 

1.2

digit        0|1|2|3|4|5|6|7|8|9

这个表达式就是说,正则表达式digit就是0,1,2,…,9中的某一个字母.所以无论是0,2,或者是9…都是属于digit这个正则表达式的.

“|”符号表示或者的意思.

那么定义正则表达式 name   Tangl_99|Running,同样的,如果你的源程序中出现了Tangl_99或者Running,那么就等于出现了一次name正则表达式.

 

1.3

one       1*

“*”符号表示零到无限次重复

那么one所表示的字符串就可以是空串(什么字符都没有), 1, 11, 111, 11111, 11111111111, 11111111…等等.总之,one就是由0个或者N1所组成(N可以为任意自然数).

”*”相同的有个”+”符号.请看下面的例子1.4

 

1.4

realone    1+

“+”符号表示”1到无限次重复

那么realoneone不同的唯一一点就是,realone不包含空串,因为”+”表示至少一次重复,那么realone至少有一个1.所以realone所表达的字符串就是1,11,111, 1111, 11111…,等等.

 

1.5

digit      [0-9]

letter     [a-zA-Z]

这里的digit等于例1.2中的digit,也就是说,a|b|c就相当于[a-c].

同理,letter也就是相当于 a|b|c|d|e|f|…|y|z|A|B|C|D…|Z 不过注意的一点就是,你不能把letter写成[A-z],而必须大写和小写都应该各自写出来.

 

1.6

notA        [^A]

“^”表示非,也就是除了这个字符以外的所有字符

所以notA表示的就是除了A以外的所有字符.

下面让我们来看看一些一般高级程序语言中常用的综合例子.

digit        [0-9]

number     {digit}+

letter       [a-zA-Z_]

digit前面多次提起过,就是0-9的阿拉伯数字.number就是所有的数字组合,也就是整数.

Letter前面也提起过,唯一不同的就是多了一个下划线.因为一般我们的C语言中容许有下划线来表示定义的变量名,所以我也把下划线当成英语字母来处理了.

这里number中使用上面定义的digit正则表达式.lex,{digit}就是表示正则表达式digit.

 

newline      [/n]

whitespace   [ /t]+

newline就是提行的意思.这里我们使用的是/n这个符号,它和C语言中表示提行号一致.问题是大家可能要问到为什么要使用[]符号.因为在lex,如果你使用[],那么里面表示的肯定就是单个字符号,而不会被理解成”/””n”两个字符.

Whitespace就是空格符号的意思.一般的高级程序语言中有两种,一种就是简单的空格,还有一种就是/t制表符.使用了”+”符号,就表示了这些空白符号的无限组合.

 

从一个手机号开始-正则表达式

如果图片挂了,请访问:http://www.jianshu.com/p/d989cf2453dd 正则表达式是描述一组字符串特征的模式,用来匹配特定的字符串. –Ken Thompson虽然有...
  • u012524022
  • u012524022
  • 2015年03月17日 13:30
  • 1929

C语言写正则表达式的编译器

看了一个题目,关于正则表达式的编译,反正无业在家,无聊,不如写一个。 思路:1.循环是不现实的,因为要加数量限制,且代码重复率太高,基于语言的发展,也没有可扩充性。 2,递归是可以实现一般功能的,...
  • u011019337
  • u011019337
  • 2013年07月07日 16:57
  • 924

跟我一起写编译器(一)——lex&yacc【转载】

跟我一起写编译器(一)——lex&yacc【原创】 出处http://www.cnblogs.com/lucasysfeng/p/4842310.html    第一节、工欲善其事,必先利其...
  • zdy0_2004
  • zdy0_2004
  • 2015年09月29日 12:02
  • 432

lex yacc 入门教程

声明:原创作品,转载注明出处http://www.cnblogs.com/vestinfo/一、简介推荐书籍《flex&bison》.在UNIX下是flex和bison.网上介绍很多,大部分是写给懂的...
  • Augusdi
  • Augusdi
  • 2017年03月20日 17:07
  • 972

Linux_正则表达式(1.基础正则表达式)

正则表达式(1)正则表达式:用某种模式去匹配一类字符串的公式,它是用一串字符串和元字符构成的字符串。元字符就是描述字符表达式的内容、转换和描述各种操作信息的字符。1.基础的正则表达式 “.”(点号...
  • chenqianleo
  • chenqianleo
  • 2017年05月24日 18:46
  • 200

正则表达式-1.原理理解

正则表达式(regular expression 简称 regex)
  • Sophie_wsy
  • Sophie_wsy
  • 2014年10月16日 09:47
  • 286

[跟我学正则表达式] 1. 介绍

在本章中你将学习到什么是正则表达式以及可以做什么事情。   理解需求 正则表达式( Regular Expression , regex )是一个工具。向所有其他工具一样,正则表...
  • kendyhj9999
  • kendyhj9999
  • 2014年11月12日 13:59
  • 428

1. 正则表达式简介

1. 一个标准的正则表达式分为3个部分:分隔符、表达式和修饰符。1.1 分隔符用来包裹表达式,可以是除了特殊字符意外的任何字符,常用的分隔符是' / '。表达式由一些特殊字符(即元字符)和非特殊字...
  • enlyhua
  • enlyhua
  • 2015年04月14日 22:05
  • 297

1.正则表达式入门

正则表达式入门  正则表达式(Regular Expression)是强大、便捷、高效的文本处理工具; 提供强大的描述和分析文本 能力,配合特定的工具提供的额外支持,正则表达式可以添加、插入、删除、...
  • lszbd
  • lszbd
  • 2017年01月18日 15:59
  • 77

【双11“超级工程”】阿里:从文件分发说到镜像传输 — 蜻蜓,双11背后PB级文件分发重器

本文摘要   2017天猫双11, 交易峰值32.5万/秒,支付峰值25.6万/秒,数据库处理峰值4200万次/秒,成交额1682亿数字的背后是50+神秘技术!其中,阿里集团基础设施蜻蜓,在双11...
  • james570
  • james570
  • 2017年11月14日 13:22
  • 933
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:从lex&yacc说到编译器(1.正则表达式)
举报原因:
原因补充:

(最多只允许输入30个字)