基于LEX的C语言词法分析器
一、LEX语法简介
(一)文件结构
Lex文件结构简单,分为三个部分:
dclarations %% translation rules %% auxiliary procedures //功能函数 //转换规则 //声明 声明段包括变量的声明、符号常量的声明和正则表达式声明。
希望出现在目标C源码中的代码,用%{…%}扩在一起。比如:
%{ #include
digit [0-9]+ alphabet [A-Za-z]+ whitespace [ \\t]+ 功能函数即为正常的C语言代码,遵守C语言代码格式即可。
(二)Lex特性简介
1.Lex依次尝试每一个规则,尽可能地匹配最长的输入流。
2.如果有一些内容根本不匹配任何规则,那么Lex将把它拷贝到标准输出。 二、正则表达式简介
在编写处理字符串的程序或网页时,经常会有查找符合某些复杂规则的字符串的需要。正则表达式就是用于描述这些规则的工具。换句话说,正则表达式就是记录文本规则的代码。
在这里,只用到了字符转义、重复、字符类、反义、贪婪与懒惰等较为基础的语法。以下就简单对涉及到的语法进行介绍。
(一)字符转义
例如,.*在正则表达式中表示匹配所有,因此若要匹配.或*,则需要对其进行转义,即\\.和\\*。
(二)重复
在对数字和标识符等进行匹配时,字符位数不止一位,但遵守相同的规则,因此使用“重复”进行匹配。
例如,对数字进行匹配:[0-9]+,“+”表示至少重复一次,即数字长度至少为1。
例如,对标识符进行匹配,由于C语言标识符必须以下
划线或字母开头,所以规则为:[_|A-Za-z]+(_|[A-Za-z]|[0-9])*。 “[_|A-Za-z]+”表示必须以下划线或字母开头,“(_|[A-Za-z]|[0-9])*”表示之后可以跟字母数字下划线,但是也可以不跟,这就是“+”和“*”所表示的“重复”的不同之处。
(三)字符类与反义
对没有预定义元字符的字符集合,需要在方括号里将其列出,例如,[aeiou]就是对任何一个英文元音字母的匹配,同理,[0-9]代表的含义与元字符\\d完全一致,都是对一位数字进行的匹配。
有时需要查找不属于某个能简单定义的字符类的字符。比如想查找除了数字以外,其它任意字符都行的情况,这时需要用到反义:
对于元字符,其反义即为其大写:\\D,匹配非数字的字符。
更为普遍的表达方式如下:
[^aeiou],匹配除了aeiou这几个字母以外的所有字符。