Lex教程
1. Lex: 一种词法生成器
lex全称lexical analyzar
英文描述是 a scanner generator简单的来说,他讲一串字符串,拆分成单独的单词,并根据指定的正则来调用相应的宏,换句话说就是我们常说的保留字,lex就是去扫描里面有没有符合保留字的词,所以说是scanner,这个最中生成的c程序.
-
根据正则规则,将输入的语法进行分割
-
yylex():
- 将输入的流文件和正则规则进行匹配
- 如果发现有匹配成功的,触发相关的动作
-
lex文件的结构
-
# 第一部分 definition 初始化定义相关参数 选填 # 第二部分 %% Rules 必填 #第三部分 %% user subroutines 用户定义的子程序 选填
-
rule的规则: <reg.exp>
- reg.exp: 从这一行开始到出现第一个未转义的空格结束
- action: 当行c命令,多行的命令使用{}包起来
- 未被匹配到字符串会被复制一份输出出去
-
-
lex的正则表达式:
- 运算符:
\ [ ] ˆ - ? . * | ( ) $ / { } % < >
- 字母和数字匹配他们本身
.
点匹配所有字符串,除了换行- [] 中括号里包含一些列的字符
- 里面可以是任意字符串
-
表示一个范围
^
表示否定,[^0-9]
表示开始不能以数字开头- 使用引号字符时需要使用在转义字符
\
\n
,\t
代表换行, 缩进()
表示一组数据|
表示或关系*
表示0个或更多+
表示一个或者更多?
表示0个或一个
- 运算符:
-
在匹配的结果中有多个结果符合筛选条件时,lex会优先选择匹配字符最长的
-
在匹配结果有多个并且字符数量一致的情况下,第一个出现的优先
-
与自定义程序间进行通讯:
-
yytext
这是一个字符串数组,里面装着匹配好的数据[a-z][a-z0-9_]* printf("ident: %s\n", yytext);
-
yyleng
匹配到的字符长度//Counting the number of words in a file and their total size: [a-zA-Z]+ {nwords += 1; size += yyleng;}
-
-
lex中关于资源的处理:
- 未被lex匹配到的资源,都会复制一份到编译后的c程序里面
- 任何不适定格写的,并且不是在%{ ... %}包裹的,都会被赋值进编译好的c程序中(lex.yy.c).
-
lex中内置的变量和函数:
-
变量
yyin FILE* 类型。 它指向 lexer 正在解析的当前文件。 yyout FILE* 类型。 它指向记录 lexer 输出的位置。 缺省情况下,yyin 和 yyout 都指向标准输入和输出。 yytext 匹配模式的文本存储在这一变量中(char*)。 yyleng 给出匹配模式的长度。 yylineno 提供当前的行数信息。 (lexer不一定支持。) -
函数:
yylex() 这一函数开始分析。 它由 Lex 自动生成。 yywrap() 这一函数在文件(或输入)的末尾调用。 如果函数的返回值是1,就停止解析。 因此它可以用来解析多个文件。 代码可以写在第三段,这就能够解析多个文件。 方法是使用 yyin 文件指针(见上表)指向不同的文件,直到所有的文件都被解析。 最后,yywrap() 可以返回 1 来表示解析的结束。 yyless(int n) 这一函数可以用来送回除了前n? 个字符外的所有读出标记。 yymore() 这一函数告诉 Lexer 将下一个标记附加到当前标记后。
-