C编译器剖析_1.4 UCC编译器预览_UCC的使用

C编译器剖析_1.4 UCC编译器预览_UCC驱动 在上一小节,通过以下四条命令,我们有意地给ucc传递不同的参数来依次调用预处理器、编译器、汇编器和连接器。当然实际使用ucc命令时,我们不会绕这么大一个圈子,直接用”ucc  hello .c -o hello”即可得到可执行程序hello。 iron@ubuntu:demo$ ucc -E hello.c -o hello.i iron@ubuntu:demo$ ucc --dump-a 阅读详情

1.4.1  UCC的使用

    通过第1.3节的例子ucc\examples\sc,我们对如何根据语言的文法来编写语法分析器,建立语法树,之后在语法树的基础上生成中间代码有了一个感性的直观认识。当然,光有这些中间代码,C程序员还不能得到其所要的计算结果。C编译器还要由中间代码产生汇编代码。在剖析UCC编译器前,让我们先熟悉一下UCC编译器的使用。UCC编译器的大部分代码都是用标准C语言并调用C标准库来编写,可在Linux或Windows系统上生成32位的x86汇编代码,这些代码需要32位的函数库的支持才能在相应系统中运行。在后续的章节中,为节省篇幅,我们主要以32位Ubuntu系统为例来讨论。在VMware等虚拟机上安装32位Ubuntu系统不算太复杂,这里不再画蛇添足。需要在ucc/makefile第1行和ucc/driver/linux.c第7行配置UCC的安装目录UCCDIR,比如” /home/iron/bin”。如果ucc的源代码被解压到” /home/iron/src/ucc”目录,则经过以下步骤就可构建并安装UCC到” /home/iron/bin”中。

    iron@ubuntu:ucc$ pwd

    /home/iron/src/ucc

    iron@ubuntu:ucc$ make -s

    iron@ubuntu:ucc$ make -s install

    iron@ubuntu:ucc$ make -s test

    为了使用户能方便地使用ucc命令,我们还需要设置一下环境变量PATH,具体的操作如下所示,由” cd ~ ”进入当前用户主目录,在gedit打开的.bashrc文件末尾添加一行”exportPATH=$PATH:/home/iron/bin”, 其中”/home/iron/bin”即为前文所设定的UCCDIR,保存后退出,重新打开一个终端,即可使用ucc命令。

    iron@ubuntu:ucc$  cd ~

    iron@ubuntu:~$  gedit  .bashrc

    接下来,我们用一个简单的例子来解释一下UCC的大致工作流程。编写以下C代码,存为文件”hello.c”。这份代码用于求阶乘,其中有if语句、while语句、库函数调用及递归函数。

#include <stdio.h>

int f(int n){

         if(n < 1){

                   return 1;

         }else{

                   return n *f(n-1);

         }

}

int main(){

         int i = 1;

         while(i <= 10){

                   printf("f(%d)= %d\n",i,f(i));

                   i++;

         }

         return 0;

}

    C源代码hello.c需要先经过预处理器(C  PreProcessor)预处理。预处理器会根据预设的include目录去查找并包含头文件,并对宏定义进行展开,如果找不到对应的头文件,则报错,这类错误是预处理报的错,还未到编译器阶段。

    预处理器后的结果hello.i,才是作为编译器的输入,诚如UCC的原作者在”ucc\doc\UCC User Manual.txt”中所言” Before reporting bugs: ……. , send the prepocessed files towenjunw@yahoo.cn” ,编译器看到的是preprocessed后的文件。有时侯,编译器可能报出数以百计的语法错误,其原因可能仅是宏定义时出了点差错,这时打开预处理后的文件看看,就能很清楚哪里出问题了。

    编译器会对hello.i进行词法分析、语法分析、语义检查和中间代码生成,经过前面几节的准备,我们对这些概念应有点感觉了,这几个阶段被称为编译器的前端,它们与具体的机器无关。C编译器再根据中间代码生成不同硬件平台的汇编语言,这部分工作被称为编译器的后端,与具体的机器相关,因为不同机器的机器指令是各不相同的。当然,编译器还有“优化”这样的重点戏需要完成,这也是编译相关研究的当前热点。而中间代码实际上起到了连结前端和后端的桥梁作用。

    有了汇编代码hello.s后,还需要借助汇编器assembler根据汇编语言来“装配”成机器码,由此产生了目标代码hello.o,其中为.o代表的是object,译为“目标”,与面向对象的object是同一个英文单词。既然不同硬件平台的机器代码是不同的,那能不能定义一套中间代码,我们假设有一个虚拟的机器,其机器代码正好就是我们的中间代码。这样,程序员所编写的高级语言被编译成中间代码,再把这些中间代码送给用软件实现的虚拟机来解释执行,各个平台上预先写好各自的中间代码虚拟机,那生成的中间代码就可以跨平台了。这一定让你想起了Java和” Write Once , RunAnywhere”那让人热血沸腾的Slogan。当然,与运行平台相关的工作及优化的重头戏就交给了Java 虚拟机。”天之道损有余 而补不足”,所以总体而言,上帝是公平的。正如在星际争霸里的人族、神族和虫族一样,如果参数太失衡,就不好玩了。Java得到跨平台的代价是牺牲了一部分的运行效率,但在程序员比CPU和内存贵的今天,这种牺牲还是有经济上的意义的。生成中间代码之后解释执行,比”生成机器代码之后直接运行速度更低”的原因,就好比有一本英语原版书,翻译的方法可以有口译和笔译,口译的方式每次都要找口译员帮你解释一下,讲完你可能就忘了;而笔译的好处是笔译员翻译一遍后,你就有了一份中文版的书,以后就不用再麻烦笔译员了。Java虚拟机采取的加速方案有即时编译Just InTime,如果运行时发现有些中间代码要被多次解释执行,那我们干脆就在动态运行时,把相应的中间代码翻译成机器代码吧,这就是所谓的”即时”。当然,道理很简单,做起来很难。

     目标模块hello.o还需要携手函数库和其他的目标代码才能得到可执行程序hello,这个工作被称为Linking,即连接,也有写为链接的,哪个是错误字,已经傻傻分不清楚了,权当IT世界的通假字吧,这个工作由连接器Linker完成。在此阶段出现的错误有,全局变量(或函数)重复定义,全局变量(或函数)未定义等。

C编译器剖析_4.2 语义检查_表达式的语义检查(4)_函数调用 4.2.4 函数调用的语义检查      在这一小节中,我们来讨论一下函数调用的语义检查,语法上,函数调用对应的表达式属于后缀表达式PostfixExpression,UCC编译器exprchk.c的函数CheckFunctionCall()完成了对函数调用的语义检查,如图4.2.18所示。在阅读这份代码时,需要对语法分析后为函数调用构造的语法树有较好认识,请先参照”图3.1.21后缀运算符对应 阅读详情

相关推荐

C编译器剖析_5.1 中间代码生成及优化_简介

本节对UCC编译器的中间代码生成及优化进行简介,给出基本块BasicBlock、三地址码、控制流图CFG的相应数据结构,介绍有条件跳转、无条件跳转和间接跳转等概念。

SheIsC的专栏 4907

C编译器剖析_2.5 UCC编译器的符号表管理

这一节,我们准备初步讨论一下UCC编译器的符号表管理,与符号表管理相关的代码主要在ucl\symbol.h和ucl\symbol.c中。UCC编译器内部需要对用到的所有符号进行分类,并建立相应的数据结构来记录与符号相关的信息。图2.5.1第25行的结构体struct symbol用于记录与符号相关的信息,这些信息如图第7至23行所示。第8行的kind用于区别不同类别的符号,其取值范围如图第1至5行

SheIsC的专栏 3111

Ucc: Unicorn系统静态文件编译器实战指南

本文还有配套的精品资源,点击获取 简介:Unicorn系统的静态文件编译器Ucc是一个高效的工具,专门用于优化JavaScript代码,提升性能、减少资源消耗、增强安全性和简化部署。它包括源代码、文档、测试套件、示例和构建脚本等部分,是一个完整的设计用于编译和压缩JavaScript资源的系统。通过Ucc,开发者可以实现性能提升、资源减少、安全性增强和部署简化。 ...

weixin_36078669的博客 1430

中文编译器 ucc

UCC是由清华学生开发的一块简单c语言编译器,结构清晰,方便学习!

ucc-c-compiler:用C实现的C编译器

用C语言编写的AC编译器 依存关系 C标准库 as (使用gnu-as和darwin-as [现在clang-as]进行了测试,但是任何都可以) ld (任何都可以) 使用C89编译器来构建该编译器 特征 编译器实现C89,C99和C11(可通过-std=c89/c99/c11 )。 完全支持系统库,包括与va_list结构的ABI兼容性。 以下列出了一些主要的新增功能: 增加的功能: Microsoft / Plan 9结构扩展 Lambda / Objective-C样式块 函数的尾随返回类型 命名空间检查 标准支持(并非详尽无遗): C89,C99 C11 _Bool , _Noreturn , _Alignof , _Alignas _Generic , _Static_assert 功能支持: 浮点类型 无符号整数 char , short , long和(仅在6

C编译器剖析PDF文档_UCC162.3源代码

包含C编译器剖析PDF文档,及修改少量BUG后的编译器源代码UCC162.3, 欢迎访问对应博客http://blog.csdn.net/sheisc

手把手教你做一个 C 语言编译器.pdf

手把手教你做一个 C 语言编译器.pdf

UCC开源C编译器源代码

UCC是一款小巧并且优秀的开源C编译器代码,可将C源代码直接编译成给予LINUX或WIN平台的可执行程序.

浅谈武术擂台格斗机器人大赛

武术擂台机器人赛是工科类专业的一个跨学科的竞赛项目,它涵盖了机械结构、硬件电路和计算机程序等技术领域。笔者在校期间有幸参加过四次这样的比赛,有成功也有失败,对此深有感悟。本文仅为个人观点,有说得不对的地方,望积极指出,希望能帮助到有需要的人。

weixin_43811044的博客 1万+

【一步到位】Android Studio 实现安卓连接阿里云物联网云平台

最新版本目前是Android Studio Iguana | 2024.1.2,你可以到官网上去找之前的版本,手上有工作项目的不要去轻易尝试,说不定你就编译失败了,失败了也不要担心,解决就可以了。

m0_73799445的博客 1万+

树莓派5新手必看:保姆级ibus中文输入法安装与配置全流程(含.bashrc设置避坑)

本文详细介绍了在树莓派5上安装和配置ibus中文输入法的完整流程,包括系统环境准备、ibus框架安装、图形界面配置及常见问题解决方案。通过清晰的步骤说明和避坑指南,帮助新手快速实现中文输入功能,提升开发效率。

weixin_29159441的博客 531

Sentinel--哨兵系列数据下载地址及流程更新【202310】

哨兵系列数据下载地址及流程更新。哨兵系列卫星作为哥白尼计划的一部分,主要目标便是对地球的观测任务。哥白尼计划由三部分组成:空间部分(哨兵系列太空任务与其他太空机构任务)、测量部分(提供海洋、大陆表面和大气信息的陆基和机载数据收集网络)、数据管理与全球共享。

twg666的博客 3万+

全球第一开源云ERP Odoo操作手册 模块安装和界面汉化指南

Odoo 的功能包含在不同的模块中, 刚创建的数据库除 Odoo 的核心模块外, 其它模块并没有被安装到系统中,你可以根据需要安装它们。本节将介绍安装模块和界面汉化的相关知识。

weixin_44793763的博客 2075

Python爬虫实战:抓取全球船舶AIS定位数据的全流程指南

AIS(Automatic Identification System)自动识别系统是目前全球航运中用于实时跟踪船只位置的主要技术。名称、MMSI编号、呼号实时经纬度船速、航向吃水、目的港状态(航行/停泊/锚泊)航线信息等🛰️海上运输监控:追踪航线,预估到港时间;🛳️船舶管理系统:为物流、港口运营提供决策依据;🌊研究分析:如海洋运输碳排放研究、船只拥堵热力图等;🧠人工智能训练数据集:用于轨迹预测、碰撞预警模型。

2201_76125261的博客 1364

Python爬虫实战:采集菜谱网站数据——以“下厨房”为例

随着互联网的发展,海量优质数据为各类应用提供了坚实基础。菜谱作为用户日常生活中需求极高的内容,丰富多样的菜谱数据不仅方便用户烹饪,也为美食推荐、营养分析等研究提供了数据支持。本文将围绕国内知名菜谱网站“下厨房”(https://www.xiachufang.com)展开,结合最新Python爬虫技术,详细讲解如何高效、规范地采集菜谱数据,包括菜谱名称、食材、步骤、评分、评论等丰富信息。全篇覆盖爬虫原理、框架选型、反爬应对、数据存储和简单分析,是学习爬虫实战的绝佳案例。菜谱标题作者信息菜谱图片。

2201_76125261的博客 1900

RAGFlow 系列教程 第14课:GraphRAG -- 知识图谱增强检索

RAGFlow v0.25.0深度解读了GraphRAG技术,通过构建知识图谱解决传统RAG在多跳推理问题上的局限。系统支持General GraphRAG和Light GraphRAG两种实现,包含四阶段构建流程:实体关系抽取、实体消解、社区检测和图持久化。核心代码位于rag/graphrag目录,采用LLM驱动的抽取机制,结合编辑距离和LLM确认的实体消解策略,以及Leiden社区检测算法。KGSearch模块通过多信号融合检索(实体+关系+N-hop+社区)实现高效查询。该系统将非结构化文本转化为可推

weixin_43674738的博客 101

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

上一篇: C编译器剖析_1.3 由文法到分析器_语句Statement
下一篇: C编译器剖析_1.4 UCC编译器预览_UCC驱动
SheIsC
博客等级 码龄12年 224粉丝 64原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值