首页 理论教育 编译原理与实践:LEX语言规范

编译原理与实践:LEX语言规范

时间:2023-11-17 理论教育 版权反馈
【摘要】:使用LEX产生词法分析器的关键在于设计LEX源程序。需要注意的是,正规式定义行中不能加注释,它会导致LEX误认为注释也是正规式定义的一部分。如何在LEX中表示正规式,表3-7给出了常用的LEX元字符约定及其描述。关于LEX源程序的构成,下面进一步通过例子来说明。例3.14 以下是统计文件中标识符个数的扫描程序:例3.15 编写一个LEX源文件,使其能够将文本中的十进制数替换成十六进制数,并打印被替换的次数。表3-8一些LEX常用的内部名字

编译原理与实践:LEX语言规范

使用LEX产生词法分析器的关键在于设计LEX源程序。LEX源程序文件包括3个部分,它们是说明部分、翻译规则和辅助程序,由符号“%%”分开,形如:

第一部分是说明部分,出现在第1个%%之前,包括变量声明、常量定义和正规式定义。其中,变量声明、常量定义遵循C语言规范,将在后续的C程序中使用;定义正规式时,先定义它的名字,从新的一行的第1列开始写,后跟所表示的正规式,之间用空格隔开。需要注意的是,正规式定义行中不能加注释,它会导致LEX误认为注释也是正规式定义的一部分。另外,包括在分隔符“%{”和“%}”之间的内容将被直接插到由LEX产生的C代码中,它位于任何过程的外部。

如何在LEX中表示正规式,表3-7给出了常用的LEX元字符约定及其描述。

表3-7 Lex中的元字符约定

例3.12 给出带符号实数的正规式表示,其中可能包含一个小数部分或一个以字母E开头的指数部分:

("+"|"-")?[0-9]+("."[0-9]+)?(E("+"|"-")?[0-9]+)?

例3.13 整数和标识符的正规式可定义如下:

第二部分是规则部分,由一组正规式以及当每个正规式被匹配时所采取的动作组成,动作由C代码实现,它指出当匹配相对应正规式时应执行的动作。形如:

p1 {动作1}

p2 {动作2}

︙(www.xing528.com)

pn {动作n}

其中,pi表示正规式,{动作i}表示匹配pi时词法分析器应执行的程序段。上述规则完全决定了最终所生成的词法分析器的功能,分析器只能识别符合正规式p1、p2、…、pn单词符号。

当最终得到的词法分析器被语法分析器调用时,它将逐一扫描输入串的每个字符,直到发现能与正规式pi匹配的最长前缀为止,并将该字符串截下来放在缓冲区yytext中,然后调用{动作i}。当{动作i}执行完后,词法分析器就识别出了一个单词符号,并将控制返回给语法分析器。若没有返回,词法分析器将继续寻找后续词法单元,直到有一个动作引起控制返回为止。这种重复地搜索词法单元,直到显式返回的方式,便于词法分析器处理空白和注释。当词法分析器被再次调用时,就从剩余的输入串开始识别下一个单词符号。每次词法分析器仅返回一个值(记号)给语法分析器,记号的属性值通过全局变量yylval传递。

第三部分是动作所需要的辅助程序,主要包括一些C代码,将被直接输出到lexyy.c的尾部。这里可定义一些处理正规式的C语言函数、主函数以及yylex()要调用的函数yywrap()等。这些函数也可以分别编译,然后在连接时装配在一起。如果要将LEX输出作为独立程序进行编译,则此处必须得有一个主程序。

关于LEX源程序的构成,下面进一步通过例子来说明。

例3.14 以下是统计文件中标识符个数的扫描程序:

例3.15 编写一个LEX源文件,使其能够将文本中的十进制数替换成十六进制数,并打印被替换的次数。

表3-8列出了LEX常用的内部名字,在与正规式匹配的动作函数或辅助过程中可以使用。

表3-8 一些LEX常用的内部名字

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈