1.3lex介绍

1.3.1 lex概述

LEX是LEXical compiler的缩写,是UNIX环境下非常著名的工具软件,其主要功能是根据LEX源程序生成一个用C语言描述的词法分析程序。LEX源程序是词法分析程序的规格说明文件,其文件名约定为lex.l,经过LEX编译程序的编译,生成一个C语言程序lex.yy.c。

1.3.2 lex源程序的结构

  • 一个LEX源程序由声明、翻译规则和辅助过程3部分组成,各部分之间用双百分号“%%”隔开。
  • 声明部分可以包括变量的声明、符号常量的声明和正规定义。正规定义中定义的名字可以出现在翻译规则的正规表达式中。希望出现在输出文件lex.yy.c中的C或C++语言声明语句必须用符号“%{”和“%}”括起来。
  • 翻译规则部分是由正规表达式和相应的动作组成的具有如下形式的语句序列:

    1. P1 {动作1}
    2. P2 {动作2}
    3. ……
    4. Pn {动作n}
  • 其中Pi(i=1,2,……,n)是一个正规表达式,描述一种记号的模式;动作i是用C或C++语言描述的程序段,表示当一个符号串匹配模式Pi时,词法分析程序应执行的动作。

  • 辅助过程是对翻译规则的补充。翻译规则部分中某些动作需要调用的过程或函数,如果不是C或C++语言的库函数,则要在此给出具体的定义。这些过程或函数也可以再另一个程序文件中定义,然后再和词法分析程序链接在一起即可。

1.3.3 lex具体用法

这里主要对我们在编写词法分析器时涉及的lex的使用细节、用到的一些lex内置变量和函数等进行说明。具体的用法还需查阅相关文档。

1.3.3.1 转义字符

在书写正规定义式/表达式时,”[]^-?.*+|()$/{}%<>,这些字符具有特殊函数,不能用来匹配自身,如果需要匹配自身,可以通过引号”或转移字符\来指示。

1.3.3.2 “环境”

  • LEX中有环境的概念,利用环境可以很方便地识别字符常量、字符串、单行注释、多行注释等内容。所有不带环境说明的正规表达式都是默认在INITIAL环境下。LEX在运行时,可以根据利用BEGIN语句在环境之间进行转移。在不同环境中识别同一个单词可以执行不同的动作。
  • 以多行注释(以下用MCOM指代其环境)为例,当在INITIAL环境中遇到{时,就说明接下来开始一段多行注释的内容,此时就进入多行注释环境MCOM,在该环境中,不管遇到什么符号,都可以忽略,直到遇到},该符号表示多行注释结束,显然此时应该返回到INITIAL环境中,开始正常的单词和符号的识别。

1.3.3.3 lex匹配原则

  • 由LEX生成的词法分析程序在识别单词符号时,遵循以下匹配原则:
    • 最长匹配原则:当有几条规则都适用时,实施匹配最长输入串的那个规则。
    • 有限匹配原则:当有几条规则都适用,并且匹配长度相同时,则实施排在最前面的那条规则。
  • 也就是说,词法分析程序依次尝试每一条规则,尽可能地匹配最长的输入符号串,并且,排在前面的规则的优先级高于排在其后的规则的优先级。另外,如果有一些内容不匹配任何规则,则LEX将会把它拷贝到标准输出。

1.3.4 flex安装、配置及使用

  • 到官网下载flex的exe安装程序,安装成功后,将其所在目录添加到系统环境变量,即可在命令行中进行调用。
  • 假如我们的LEX源程序是lex.l,那么只需要在命令行,进入到目录中后,键入命令:flex lex.l ,即可获得词法分析程序lex.yy.c。

    1.3.5 转化为C++

    由于我们的编译程序的目标语言是C++,所以需要将LEX输出的lex.yy.c改名为lex.yy.cpp;同时lex自动生成的一些函数接口的声明,需要用extern “C”进行包括,extern “C”的主要作用就是为了能够正确实现C++代码调用其他C语言代码。加上extern “C”后,会指示编译器这部分代码按C语言的进行编译,而不是C++的。