LLVM理论篇之编译器前端

news2024/9/25 17:11:01

1、简述

LLVM前端通过对源程序的预处理,构成源程序的字符流扫描与分解,将单词序列提取为各类语法短语,生成抽象语法树,最终转换为中间代码。编译器前端包含的这几个过程如下:

(1)预编译

(2)词法分析

(3)语法分析

(4)语义分析

2、预编译

预编译所完成的基本上是对程序源代码的替代和整理工作,经过此类替代整理,生成一个没有宏定义、条件编译指令、特殊符号、用户注释的输出文件。

预编译的主要处理有:

(1)文件包含

这一步主要处理头文件包含问题,也就是#include语句。例如处理#include<stdio.h>时,预编译器会在系统标准路径下搜索stdio.h,并将stdio.h的内容复制到当前文件。文件包含的过程时递归进行的。

(2)宏展开

这一步是主要处理#define定义的宏,用宏定义的字符串替换掉对应的宏名。

(3)条件编译

这一步主要处理#if和#ifdef等条件编译指令,将源代码中的某部分符合条件的代码包含进来,剔除掉不符合条件的代码段。

(4)删除注释

这一步主要处理注释,删除掉注释行(//和/* */)

3、词法分析

词法分析是对源代码从左到右逐个将字符读入编译器,并扫描和分解字符流,从而识别出一个个单词,并确定单词的类型,将识别出的单词转换为统一的语法单元形式,也就是token。包括如下类型:

(1)关键字

关键字是被C语言或者C++本身使用,在程序中有特定含义,不能作为其他用途使用的单词。如int、float、if、for等。

(2)标识符

用来表示各种名字,如变量、数组名、函数名等。

(3)运算符

包括算术运算符+、-、*、\等,逻辑运算符&&、||、!等,以及关系运算符==、>、<等。

(4)分界符

包括,、:、;等符号

(5)常数

分为整型、浮点型、字符型等,如1、5.67、Helllo等

4、语法分析

语法分析的任务是将词法分析生成的单词组合成语法短语,同时分析这些短语是否符合高级程序设计语言中的语法规则。有下面的规则来定义表达式:

(1)标识符是表达式;

(2)常数是表达式;

(3)若表达式1和表达式2都是表达式,那么表达式1+表达式2以及表达式1*表达式2也都是表达式

有下面的规则来定义赋值语句:

(1) <表达式> = n

(2) <表达式> = <表达式>”+“<表达式>

(3) <表达式> = <表达式>”*“<表达式>

(4) <赋值语句> = <标识符>”“<表达式>

根据这个规则,可以将表达式:c=a+b*7 转成下图的语法树:

5、语义分析

语义分析阶段的任务是审查源代码有无语义错误,源代码中有些语法成分,按照语法规则去判断是正确的,但不符合语义规则,比如使用了没有声明的变量。

语义分析主要的任务可归结为以下四类:

(1)完成静态语义审查和处理;

(2)上下文相关性的审查;

(3)类型匹配审查;

(4)类型转换;

比如

int b,c;

c = a * b + 1;

就会审查出a变量没有定义。

再比如

float a,b,c;

c = a + b * 5;

运算符*的两个运算对象分别是b和3,如果b是float变量,3是整型常数,语义分析阶段执行类型审查之后,会自动将整型量转化成float,以完成同类型的数据运算,体现在语法分析所得到的语法树上,即增加一个运算符结点。

6、举例说明

hello.c内容如下:

#include <stdio.h>

#define N 1024

int main()

{

  int a,b,c,d[N];

  a = 2;

  b = 4;

  c = a + b * 3;

  printf("Hello!");

  return c;

}

进行预编译,可以看到结果中对头文件、宏定义和注释按照预编译规则进行相应的处理。

使用

clang -E hello.c -o hello.i

在进行词法分析后会读入源程序的字符流,将其转换成对应的单词序列token。

词法分析指令:

clang -fmodules -fsyntax-only -Xclang -dump-tokens hello.c

结果:

在进行语法分析后会依据语法规则把源代码的单词序列组成语法短语构成的语法树。

clang -fmodules -fsyntax-only -Xclang -ast-dump hello.c

输出就是语法分析的过程和结果:

在进行语义分析后可以检查源代码有无语义错误,若无语义错误,则可以进入编译器中端了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1995903.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【python】实现对文件夹中的图像连续重命名方法

import os import shutildef rename_images(input_folder):# 获取输入文件夹下的所有图片文件&#xff08;假设都是.jpg格式&#xff09;image_files [f for f in os.listdir(input_folder) if os.path.isfile(os.path.join(input_folder, f)) and f.endswith(".jpg"…

性能测试工具LoadRunner

前言&#x1f440;~ 上一章我们介绍了性能测试的一些基本概念&#xff0c;重要的是性能测试的各项指标&#xff0c;今天我们使用性能测试工具LoadRunner简单的完成一次性能测试 性能测试Load Runner LoadRunner是什么&#xff1f; LoadRunner安装 LoadRunner脚本录制 1.录…

振弦式钢筋计的主要应用领域有哪些?

在现代工程建设中&#xff0c;钢筋作为重要的结构材料&#xff0c;其应力状态直接关系到工程结构的安全性和稳定性。因此&#xff0c;对钢筋应力的实时监测成为了保障工程质量的关键环节。振弦式钢筋计作为一种高精度、稳定性好的应力监测仪器&#xff0c;在桥梁、建筑、隧道等…

pg一些常用语句记录

查看数据库大小 pg_size_pretty:将数据库用量展示为KB、MB、GB等样式,查看更直观查看具体某个数据库的大小 select pg_size_pretty(pg_database_size(postgres)); 查看所有数据库的大小 select pg_database.datname, pg_size_pretty (pg_database_size(pg_database.datnam…

Sqli-labs-master靶场--布尔盲注

目录 1、布尔盲注 2、布尔盲注的流程&#xff08;以靶场less-8为例&#xff09; 2.1输入id尝试是否存在注入点 2.1.1通过以上尝试&#xff0c;联想到可能是布尔盲注 2.2猜测数据库长度 2.3获取数据库名 2.3.1python脚本获取 代码&#xff1a; 获取结果为&#xff1a; …

后期调色学习笔记

关于调色曲线的学习&#xff1a; 学习链接&#xff1a;一看就懂的曲线调色教程【手机摄影后期】_哔哩哔哩_bilibili 从左向右就是由暗部越来越到亮部 越靠近右侧的越是亮部

机械学习—零基础学习日志(数学基础汇总1)

零基础为了学人工智能&#xff0c;正在艰苦的学习 我比较推荐&#xff0c;《三个月从零入门深度学习&#xff0c;保姆级学习路线图》的整体学习思路&#xff0c;但因为数学基础太差&#xff0c;而且针对所需的数学系统知识&#xff0c;我依然没有很明确的学习方向。 所以直接…

杀手级的AI LLM产品还有多久面世

AI产品落地&#xff1a;Killer App依然缺席的原因与未来展望 &#x1f680; 在当今科技领域&#xff0c;人工智能&#xff08;AI&#xff09;无疑正处于一个快速发展的阶段。尽管如此&#xff0c;关于AI产品的实际应用和市场落地&#xff0c;仍然存在诸多挑战。本文将探讨当前…

使用 Matplotlib 绘制折线图

使用 Matplotlib 绘制折线图 数据可视化是数据分析的重要组成部分&#xff0c;通过图表&#xff0c;我们可以更直观地理解数据背后的趋势和模式。Matplotlib 是 Python 最基础也是最常用的绘图库之一&#xff0c;非常适合初学者。本文将带你从零开始&#xff0c;逐步创建和自定…

Python Static Typing: 提升代码可靠性与可读性的使用技巧

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storm…

Java毕业设计 基于SSM和Vue的酒店管理系统小程序

Java毕业设计 基于SSM和Vue的酒店管理系统小程序 这篇博文将介绍一个基于SSM框架和Vue开发的酒店管理系统微信小程序&#xff0c;适合用于Java毕业设计。 功能介绍 用户 登录 注册 忘记密码 首页 图片轮播 房间信息 房间详情 预订 收藏 评论 我的 订单信息 酒店管理…

Python 常用内置函数

目录 1、enumerate函数 1.1、for循环中使用 1.2、enumerate指定索引的起始值 1.3、enumerate在线程中的作用 2、Map 函数 2.1、map()函数可以传多个迭代器对象 3、lambda表达式&#xff08;匿名函数&#xff09; 示例 4、sort函数和sorted函数 4.1、sort()函数 4.2、…

vue2学习 -- vuex

文章目录 1. 理解2. 语法2.1 安装使用2.2 getters配置项2.3 四个map方法的使用2.4 vuex模块化 1. 理解 概念&#xff1a;专门在ue中实现集中式状态&#xff08;数据&#xff09;管理的一个ue插件&#xff0c;对vue应用中多个组件的共享状态进行集中式的管理&#xff08;读/写&…

Java基础 1. Java开发环境搭建

Java基础 1. Java开发环境搭建 文章目录 Java基础 1. Java开发环境搭建1.1. 常用的DOS命令1.1.1. 常用的Windows组合键:1.1.2. 常用的DOS命令:1.1.3. 批处理文件 1.2. 通用文本编辑快捷键1.2.1. Sublime Text文本编辑器的安装与使用安装中英文打开方式调整字体大小文件扩展名 1…

LlamaIndex 如何可视化跟踪日志

LlamaIndex 中无论是 RAG 还是 Agent&#xff0c;都是需要和 LLM 进行交互&#xff0c;在这个流程流中包括搜索、Retrieve和推理等多个阶段。提示词在整个流程通过模板进行控制&#xff0c;LlamaIndex 通过整合和调度完成最终任务。 大模型的一个最大特点就是无法保证回答百分…

假如有一个嵌套集合,怎么通过stream流将集合放到一个集合之中?

假如有一个嵌套集合&#xff0c;怎么通过stream流将集合放到一个集合之中&#xff1f; 问题解释&#xff1a;你有一个嵌套的集合&#xff0c;想要通过 Stream 流的方式将其中嵌套的集合放到一个新的集合中。可以使用 flatMap 方法来实现。这种方法非常适合处理嵌套集合的情况。…

2个方法教你如何删除ZIP压缩包密码

zip压缩包设置了加密密码&#xff0c;每次解压文件都需要输入密码才能够顺利解压出文件&#xff0c;当压缩包文件不再需要加密的时候&#xff0c;大家肯定想删除压缩包密码&#xff0c;或是忘记了压缩包密码&#xff0c;想要通过删除操作将压缩包密码删除&#xff0c;就能够顺利…

Basic Pentesting:2-打靶渗透【附代码】(权限提升)

靶机下载地址&#xff1a; https://www.vulnhub.com/entry/basic-pentesting-2,241/https://www.vulnhub.com/entry/basic-pentesting-2,241/ 1. 主机发现端口扫描目录扫描敏感信息获取 1.1. 主机发现 nmap -sn 192.168.7.0/24|grep -B 2 08:00:27:1D:4A:27 1.2. 端口扫描 …

MongoDB学习记录

1、初识Mongo 概述&#xff1a;与关系型数据库不同&#xff0c;MongoDB 的数据以类似于 JSON 格式的二进制文档存储&#xff0c;通常称这种格式为Bson&#xff0c;Bson不仅支持JSON中已有的数据类型&#xff0c;还增加了一些额外的数据类型&#xff0c;例如日期和二进制数据&a…

第二十三天培训笔记

上午 在同步时&#xff0c;对删除和修改都比较慎重&#xff08;监控同步时&#xff09; mysql 主从搭建 前提软件 libaio &#xff0c; rsync 注意&#xff1a;先执行从服务器的脚本&#xff0c;再执行主服务器脚本 master-mysql 配置脚本 2 、其他常⽤函数 &#xff08; …