• flex&bison系列第一章:flex Hello World


    系列文章目录

    flex&bison系列第一章:Flex Hello World

    LLVM系列



    前言

    在此记录下基于flex写一个Hello World的过程,以备查阅。

    flex是用来生成程序的工具,比如用来生成编译器程序(一般指编译器的前端部分)。它所生成的程序能够处理结构化的输入。在这里,为简单起见,我们可以把“结构化的输入”理解为有一定组织结构的文本,我们用flex对文本进行处理时,应提前了解一下正则表达式和编译原理相关的知识(如词法分析器、自动机等)。

    本章,我们就来利用flex写一个简单的Hello World程序。

    一、开发环境

    1. 操作系统

    我用的操作系统是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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2. 安装工具

    用到的工具有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
    
    • 1
    • 2
    • 3
    • 4
    • 5

    对于其它工具,可借助brew (https://brew.sh) 进行安装(示例):

    # Install flex
    brew install flex
    
    # Upgrade flex
    brew upgrade flex
    
    • 1
    • 2
    • 3
    • 4
    • 5

    macOS已经自带flex工具,所以无需自己安装了。

    二、Hello World

    这个Hello World程序要做的事很简单,具体如下:

    1. 当检查到“World”这个单词时,输出“Hello World”
    2. 否则,输出原来的单词即可

    首先,我们要写一个简单的flex脚本文件(示例):

    /*
     * hello-world.l
     */
    
    %option noyywrap
    
    %{
    %}
    
    %%
    World    printf("Hello World");
    %%
    
    int main(int argc, char** argv)
    {
      yylex();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    一个flex文件一般分为三部分,用符合“%%”隔开:

    <第一部分>
    
    %%
    
    <第二部分>
    
    %%
    
    <第三部分>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    我们的例子中,比较重要的是第二部分:

    World    printf("Hello World");
    
    • 1

    这一行代码包含两个部分:

    1. World,它其实是一个匹配字符串,意思是用“World”去匹配输入的数据。
    2. printf("Hello World");,这是匹配成功后的“行动”,意思是如果匹配成功,则打印“Hello World”。

    三、编译

    1. 生成C代码

    运行如下命令即可生成C代码(示例):

    flex hello-world.l
    
    • 1

    其生成的C代码文件名为“lex.yy.c”。

    2. 编译

    我们可以用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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    以上命令会生成一个名为“hello-world”的可执行程序。

    四、运行

    可以用如下命令运行Hello World程序(示例):

    ./hello-world
    
    • 1

    接下来,程序会等待用户的输入。我们可以随意打一个字符,然后按回车键,可以看到如下输出(示例):

    abc
    abc
    World
    Hello World
    123
    123
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    注意到,当我们输入单词“World”时,程序会输出“Hello World”;而当输入其它单词时,则仅输出原来的单词而已。

    总结

    我们基于flex,用C++写了一个Hello World,并且编译运行成功。完整源码示例请参看:
    https://github.com/wuzhanglin/flex-bison-examples

  • 相关阅读:
    Day 10 - C# 与 C++ opencv图像数据转换
    importlib.metadata.version无法在pyinstaller打包后正常工作?
    设计模式-Factory
    A Philosophy of Software Design读书笔记——信息隐蔽和泄露
    让无数人头疼的网络攻击到底是什么?究竟隐藏了哪些不为人知的秘密?
    CONTAINER: Few-Shot Named Entity Recognition via ContrastiveLearning
    opencv+vs studio环境配置
    小白学java进阶工程师路线图
    对称(镜像)二叉树
    【STM32】学习笔记(TIM定时器)
  • 原文地址:https://blog.csdn.net/Zhanglin_Wu/article/details/126114017