Debian教程

Debian编译型语言代码

在Debian系统中,编译型语言代码通常用于开发高性能的应用程序和系统工具。C语言是最常用的编译型语言之一,它提供了底层的硬件访问和高效的性能。本教程将介绍如何使用gcc编译器编写简单的C程序,以及使用Flex和Bison工具进行词法分析和语法分析。

编译相关软件包列表:

软件包 流行度 大小 说明
gcc V:166, I:551 47 GNU C 编译器
libc6-dev V:259, I:569 12051 GNU C 库:开发库和头文件
g++ V:53, I:501 14 GNU C++ 编译器
libstdc++-10-dev V:15, I:172 17537 GNU 标准 C++ 库 版本 3(开发文件)
cpp V:331, I:727 30 GNU C 预处理
gettext V:57, I:259 5817 GNU 国际化工具
glade V:0, I:5 1209 GTK 用户界面构建器
valac V:0, I:4 724 使用 GObject 系统类似 C# 的语言
flex V:7, I:74 1243 LEX 兼容的 fast lexical analyzer generator
bison V:7, I:80 3116 YACC 兼容的 解析器生成器
susv2 I:0 16 通过“单一UNIX规范(版本2)”获取(英语文档)
susv3 I:0 16 通过“单一UNIX规范(版本3)”获取(英语文档)
susv4 I:0 16 通过“单一UNIX规范(版本4)”获取(英语文档)
golang I:20 11 Go 编程语言编译器
rustc V:3, I:14 8860 Rust 系统编程语言
haskell-platform I:1 12 标准的 Haskell 库和工具
gfortran V:6, I:63 16 GNU Fortran 95 编译器
fpc I:2 103 自由 Pascal

一、C

可以通过下列方法设置适当的环境来编译使用 C 编程语言编写的程序。

# apt-get install glibc-doc manpages-dev libc6-dev gcc build-essential

libc6-dev 软件包,即 GNU C 库,提供了 C 标准库,它包含了 C 编程语言所使用的头文件和库例程。

参考信息如下:

  • “info libc”(C 库函数参考)
  • gcc(1) 和 “info gcc”
  • each_C_library_function_name(3)
  • Kernighan & Ritchie,“C 程序设计语言”,第二版(Prentice Hall)

二、简单的C程序

一个简单的例子 “example.c” 可以通过如下方式和 “libm” 库一起编译为可执行程序 “run_example”。

<a id="_simple_c_program_gcc"><pre class="screen">$ cat > example.c << EOF
#include <stdio.h>
#include <math.h>
#include <string.h>

int main(int argc, char **argv, char **envp){
        double x;
        char y[11];
        x=sqrt(argc+7.5);
        strncpy(y, argv[0], 10); /* prevent buffer overflow */
        y[10] = '\0'; /* fill to make sure string ends with '\0' */
        printf("%5i, %5.3f, %10s, %10s\n", argc, x, y, argv[1]);
        return 0;
}
EOF
$ gcc -Wall -g -o run_example example.c -lm
$ ./run_example
        1, 2.915, ./run_exam,     (null)
$ ./run_example 1234567890qwerty
        2, 3.082, ./run_exam, 1234567890qwerty

为了使用 sqrt(3),必须使用 “-lm” 链接来自 libc6 软件包的库 “/usr/lib/libm.so”。实际的库文件位于 “/lib/”,文件名为 “libm.so.6”,它是指向 “libm-2.7.so” 的一个链接。

请看一下输出文本的最后一段。即使指定了 “%10s”,它依旧超出了 10 个字符。

使用没有边界检查的指针内存操作函数,比如 sprintf(3) 和 strcpy(3), 是不建议使用,是为防止缓存溢出泄露而导致上面的溢出问题。请使用 snprintf(3) 和 strncpy(3) 来替代.

三、Flex

Flex 是兼容 Lex 的快速语法分析程序生成器。可以使用 “info flex” 查看 flex(1) 的教程。

很多简单的例子能够在 “/usr/share/doc/flex/examples/”下发现。[8]

四、Bison

在 Debian 里,有几个软件包提供 Yacc兼容的前瞻性的 LR 解析 或 LALR 解析的生成器。

兼容 Yacc 的 LALR 解析器生成器列表:

软件包 流行度 大小 说明
bison V:7, I:80 3116 GNU LALR 解析器生成器
byacc V:0, I:4 258 伯克利(Berkeley)LALR 解析器生成器
btyacc V:0, I:0 243 基于 byacc 的回溯解析生成器

可以使用 “info bison” 查看 bison(1) 的教程。需要提供自己的的 "main()" 和 "yyerror()".通常,Flex 创建的 "main()" 调用 "yyparse()",它又调用了 "yylex()".

创建 example.y:

/* calculator source for bison */
%{
#include <stdio.h>
extern int yylex(void);
extern int yyerror(char *);
%}

/* declare tokens */
%token NUMBER
%token OP_ADD OP_SUB OP_MUL OP_RGT OP_LFT OP_EQU

%%
calc:
 | calc exp OP_EQU    { printf("Y: RESULT = %d\n", $2); }
 ;

exp: factor
 | exp OP_ADD factor  { $$ = $1 + $3; }
 | exp OP_SUB factor  { $$ = $1 - $3; }
 ;

factor: term
 | factor OP_MUL term { $$ = $1 * $3; }
 ;

term: NUMBER
 | OP_LFT exp OP_RGT  { $$ = $2; }
  ;
%%

int main(int argc, char **argv)
{
  yyparse();
}

int yyerror(char *s)
{
  fprintf(stderr, "error: '%s'\n", s);
}

创建 example.l:

/* calculator source for flex */
%{
#include "example.tab.h"
%}

%%
[0-9]+ { printf("L: NUMBER = %s\n", yytext); yylval = atoi(yytext); return NUMBER; }
"+"    { printf("L: OP_ADD\n"); return OP_ADD; }
"-"    { printf("L: OP_SUB\n"); return OP_SUB; }
"*"    { printf("L: OP_MUL\n"); return OP_MUL; }
"("    { printf("L: OP_LFT\n"); return OP_LFT; }
")"    { printf("L: OP_RGT\n"); return OP_RGT; }
"="    { printf("L: OP_EQU\n"); return OP_EQU; }
"exit" { printf("L: exit\n");   return YYEOF; } /* YYEOF = 0 */
.      { /* ignore all other */ }
%%

按下面的方法来从 shell 提示符执行来尝试这个:

$ bison -d example.y
$ flex example.l
$ gcc -lfl example.tab.c lex.yy.c -o example
$ ./example
$ ./example
1 + 2 * ( 3 + 1 ) =
L: NUMBER = 1
L: OP_ADD
L: NUMBER = 2
L: OP_MUL
L: OP_LFT
L: NUMBER = 3
L: OP_ADD
L: NUMBER = 1
L: OP_RGT
L: OP_EQU
Y: RESULT = 9

exit
L: exit
广告合作
QQ群号:707632017

温馨提示:

1、本网站发布的内容(图片、视频和文字)以原创、转载和分享网络内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。邮箱:2942802716#qq.com。(#改为@)

2、本站原创内容未经允许不得转裁,转载请注明出处“站长百科”和原文地址。

目录