要求:为了能够看到你自己的词汇分析器,请确保你是在一个基于Linux的环境中工作。(对于Windows用户,请查看WSL)
我将使用Linux提供的lex工具,它可以按上述方式安装
编译过程(即把源代码转换为机器码)中涉及的第一步是词法分析。逻辑上的第一步是确保程序只包含有效的字符和符号。一旦确认了这一点,下一步就是解释代码的正确含义。
词法分析器将字符流转换为令牌流。一个标记是指一组有意义的字符。例如:标识符、整数、关键字、空白等。每个程序都要经过一个词汇分析器,词汇分析器是一个定义语言所接受的标记的程序,即什么是有效的。
我对词法分析器的工作方式的解释是。
只要提供输入
--保持2个指针,一个在字符串的开头,另一个指针向右移动,只要有一个词组条件得到满足。
- 当没有匹配的条件时,开始的指针被移动到结束的指针的位置(这标志着在开始和结束的指针之间建立一个标记),结束的指针继续向右移动。
现在让我们建立一个简单的词法分析器来计算给定文本中的字符和词的数量,这将用C语言编写
词法分析器由3个部分组成
1.声明(用C语言编写)
2.规则(Regex和C)。
3.辅助函数(用C语言编写)
声明
声明由头文件、变量定义等组成。它也可能包含正则表达式的模板。
规则
识别字符流中的标记的规则是基于正则表达式决定的。每个正则规则都是以相互排斥的方式一个接一个地写出来的。在空格后,写上所需的C代码的预期动作。
辅助函数
在C语言中执行某些计算的函数或主函数包括在这里
代码
// Declaration enclosed in % { %}
%{
#include<stdio.h>
#include<string.h>
int word = 0;
int chars = 0;
%}
// Rules specified as regex space action enclosed in %%
%%
[a-zA-Z]+ {word += 1; chars += strlen(yytext);}
// yytext stores the latest token encountered, getting its length to get the length of the word
# return 0; // # indicated the end of the input
. ; // on any other character do nothing
%%
// Auxillary functions
// This returns an error if not included, doesnt mean anything but include this function prototype
int yywrap(){return 0;}
int main(){
printf("Enter the input \n");
// this function has an in-built scanf, or can read from a file input
yylex();
printf("The number of words are %d \n" , word);
printf("The number of characters are %d \n ", chars);
return 0;
}
给定一个输入,词法分析器将返回词的数量和包含的字符数量。在通过键盘输入#时,函数yylex()返回。yylex()是lex工具的一个内置函数。
将上述代码粘贴在一个以**.l为扩展名的文件中,即可以是main.l**
执行该命令
lex main.l
它生成了一个C文件,名为lex.yy.c。
lex工具主要负责将正则表达式转换为C语言,这也可以手工完成,但会变得非常复杂😅。
现在我们有了一个C语言文件,只要按常规方法编译就可以了
gcc lex.yy.c // gived an executable a.out
