系列文章目录
flex&bison系列第一章:flex Hello World
flex&bison系列第二章:写一个简单的单词统计工具Word Counter
flex&bison系列第三章:写一个简单的计算器Calculator
LLVM系列
在此记录下基于flex写一个Hello World的过程,以备查阅。
flex是用来生成程序的工具,比如用来生成编译器程序(一般指编译器的前端部分)。它所生成的程序能够处理结构化的输入。在这里,为简单起见,我们可以把“结构化的输入”理解为有一定组织结构的文本,我们用flex对文本进行处理时,应提前了解一下正则表达式和编译原理相关的知识(如词法分析器、自动机等)。
本章,我们就来利用flex写一个简单的Hello World程序。
我用的操作系统是macOS 11.6.4:
System Version: macOS 12.5 (21G72)
Kernel Version: Darwin 21.6.0
Model Name: MacBook Pro
Model Identifier: MacBookPro15,1
Processor Name: 8-Core Intel Core i9
Processor Speed: 2.3 GHz
Number of Processors: 1
Total Number of Cores: 8
Memory: 16 GB
用到的工具有Clang (Xcode)、flex。
关于安装Xcode, 可参考这个简易教程:
How to download Xcode DMG or XIP file? - Stack Overflow
安装后确认信息如下(示例):
% clang -v
Apple clang version 14.0.0 (clang-1400.0.29.100)
Target: x86_64-apple-darwin21.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
对于其它工具,可借助brew (https://brew.sh) 进行安装(示例):
# Install flex
brew install flex
# Upgrade flex
brew upgrade flex
macOS已经自带flex工具,所以无需自己安装了。
这个Hello World程序要做的事很简单,具体如下:
首先,我们要写一个简单的flex脚本文件(示例):
/*
* hello-world.l
*/
%option noyywrap
%{
%}
%%
World printf("Hello World");
%%
int main(int argc, char** argv)
{
yylex();
}
一个flex文件一般分为三部分,用符合“%%”隔开:
<第一部分>
%%
<第二部分>
%%
<第三部分>
我们的例子中,比较重要的是第二部分:
World printf("Hello World");
这一行代码包含两个部分:
World
,它其实是一个匹配字符串,意思是用“World”去匹配输入的数据。printf("Hello World");
,这是匹配成功后的“行动”,意思是如果匹配成功,则打印“Hello World”。运行如下命令即可生成C代码(示例):
flex hello-world.l
其生成的C代码文件名为“lex.yy.c”。
我们可以用clang对以上生成的C代码进行编译(示例):
# Set up C++ standard library and header path for clang
export SDKROOT=$(xcrun --sdk macosx --show-sdk-path)
# Build with clang
clang lex.yy.c -o hello-world
# Or, build with gcc
gcc lex.yy.c -o hello-world
以上命令会生成一个名为“hello-world”的可执行程序。
可以用如下命令运行Hello World程序(示例):
./hello-world
接下来,程序会等待用户的输入。我们可以随意打一个字符,然后按回车键,可以看到如下输出(示例):
abc
abc
World
Hello World
123
123
注意到,当我们输入单词“World”时,程序会输出“Hello World”;而当输入其它单词时,则仅输出原来的单词而已。
我们基于flex,用C++写了一个Hello World,并且编译运行成功。完整源码示例请参看:
https://github.com/wuzhanglin/flex-bison-examples