Linux bison 命令实战示例

LinuxLinuxBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

在本实验中,我们将探索 bison 命令,这是一个用于编译器和解释器开发的解析器生成工具。Bison 是 YACC 的一个免费软件实现,YACC 是一个强大的工具,用于从上下文无关文法规范生成解析器。我们将首先在 Ubuntu 22.04 环境中安装 bison 包,然后创建一个简单的文法文件并使用 bison 命令生成解析器。最后,我们将学习如何处理生成的解析器中的语法错误。

本实验涵盖以下步骤:

  • bison 命令简介
  • 使用 bison 生成解析器
  • 处理 bison 中的语法错误

Linux 命令速查表



Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL linux(("`Linux`")) -.-> linux/PackagesandSoftwaresGroup(["`Packages and Softwares`"]) linux/PackagesandSoftwaresGroup -.-> linux/software("`Linux Software`") subgraph Lab Skills linux/software -.-> lab-422576{{"`Linux bison 命令实战示例`"}} end

bison 命令简介

在这一步中,我们将探索 bison 命令,这是一个用于编译器和解释器开发的解析器生成工具。Bison 是 YACC(Yet Another Compiler-Compiler)的一个免费软件实现,YACC 是一个强大的工具,用于从上下文无关文法规范生成解析器。

首先,让我们在 Ubuntu 22.04 环境中安装 bison 包:

sudo apt-get update
sudo apt-get install -y bison

示例输出:

Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  m4
Suggested packages:
  bison-doc
The following NEW packages will be installed:
  bison m4
0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
Need to get 1,141 kB of archives.
After this operation, 4,470 kB of additional disk space will be used.
Do you want to continue? [Y/n] Y
...

现在我们已经安装了 bison,接下来让我们创建一个简单的文法文件来生成解析器。在 ~/project 目录下创建一个名为 example.y 的新文件,内容如下:

%{
#include <stdio.h>
%}

%token NUM
%%

input:
    | input line
;

line:
    NUM '\n' { printf("Received number: %d\n", $1); }
;

%%

int main() {
    yyparse();
    return 0;
}

这个文法文件定义了一个简单的类似计算器的语言,可以识别并处理数字。%token NUM 行声明了一个用于数字的标记类型,而 line 规则指定了一个有效的行由一个数字和一个换行符组成。

使用 bison 生成解析器

在这一步中,我们将基于上一步创建的文法文件,使用 bison 命令生成解析器。

首先,让我们从 example.y 文件生成解析器源代码:

bison -d example.y

该命令将生成两个文件:example.tab.cexample.tab.hexample.tab.c 文件包含解析器的实现,而 example.tab.h 包含标记定义。

接下来,我们需要编译解析器源代码并将其与词法分析器(lexer)链接以创建最终的可执行文件。我们将使用 flex 工具生成词法分析器:

sudo apt update
sudo apt-get install -y flex
flex -o example.lex.c example.l
gcc -o example example.tab.c example.lex.c

flex 命令生成 example.lex.c 文件,其中包含词法分析器的实现。gcc 命令编译解析器和词法分析器源代码,并将它们链接以创建最终的 example 可执行文件。

现在,让我们通过运行 example 程序来测试解析器:

./example
123
Received number: 123
456
Received number: 456

如你所见,解析器正确地识别并处理了输入的数字。

处理 bison 中的语法错误

在这一步中,我们将学习如何处理由 bison 生成的解析器中的语法错误。

让我们修改 example.y 文件以包含错误处理:

%{
#include <stdio.h>
%}

%token NUM
%error-verbose

%%

input:
    | input line
    | input error '\n' { yyerrok; }
;

line:
    NUM '\n' { printf("Received number: %d\n", $1); }
    | error '\n' { yyerror("Invalid input"); }
;

%%

void yyerror(const char *s) {
    fprintf(stderr, "%s\n", s);
}

int main() {
    yyparse();
    return 0;
}

主要更改包括:

  1. 添加了 %error-verbose 以提供更详细的错误信息。
  2. inputline 产生式中添加了 error 规则以处理语法错误。
  3. 实现了 yyerror 函数以打印错误信息。

现在,让我们重新生成解析器并测试它:

bison -d example.y
flex -o example.lex.c example.l
gcc -o example example.tab.c example.lex.c

尝试运行 example 程序并输入一些无效的输入:

./example
abc
example.y:12: syntax error, unexpected error, expecting NUM
Invalid input
123
Received number: 123

如你所见,当我们输入 "abc" 而不是数字时,解析器正确地识别并报告了语法错误。

总结

在本实验中,我们探索了 bison 命令,这是一个用于编译器和解释器开发的解析器生成工具。我们首先学习了如何在 Ubuntu 22.04 上安装 bison 包,然后创建了一个简单的文法文件来定义一个类似计算器的语言。接着,我们使用 bison 命令生成了解析器源代码,生成了两个文件:解析器实现和头文件。最后,我们学习了如何处理生成的解析器中的语法错误。

Linux 命令速查表

您可能感兴趣的其他 Linux 教程