夯实基础,编译器原理前端部分浅析

简介: 如果说计算机网络、操作系统、数据结构这些是编程必学基础,我能理解,现在连编译器原理都是必备基础了吗?是的,我们太习惯于从高级语言学起了,反而忘了C、C++、Java 这些高级语言是如何一层一层解析直至被计算机读懂的。正本清源,我们对编译器的认知,应该提到和操作系统、数据库、浏览器、编程语言、算法这些编程基础技能同一水平。

image.png

编译器同样重要



如果说计算机网络、操作系统、数据结构这些是编程必学基础,我能理解,现在连编译器原理都是必备基础了吗?是的,我们太习惯于从高级语言学起了,反而忘了C、C++、Java 这些高级语言是如何一层一层解析直至被计算机读懂的。正本清源,我们对编译器的认知,应该提到和操作系统、数据库、浏览器、编程语言、算法这些编程基础技能同一水平。


计算机很笨,只能认识 0 和 1,而人呢,脑子的存储能力又非常有限,很难记住大量无规律的东西。在这两者之间就需要一个“翻译官”,让人与计算机能“沟通”,它的名字是“语言处理器”。语言处理器由三部分组成,分别是:编译器、汇编器、解释器。其中编译器是离高级语言最近的一个部分。


编译器是处理完整程序并将源代码转换为可由计算机处理器执行的机器代码的程序。


说白了,编译器本质上就是一个程序,它可以阅读以某一种语言(通常是源语言)编写的程序,并把该程序翻译成为一个等价的、用另一种语言(目标语言)编写的程序。编译器还有一个很重要的任务就是报告他在翻译的过程中发现的源程序中的错误。

对于很多程序员而言,编译器就是一个黑匣子,当你打开这个黑匣子的时候,会发现它由两部分组成,分别是:前端(分析)部分和后端(综合)部分


前端部分的工作主要包括:词法分析、语法分析、语义检查、生成中间代码。这个过程相对于后端,相对简单一点,之所以简单的原因是它所有操作都有了成型的理论支撑。

后端部分的主要工作内容:对中间代码优化,生成目标机器语言,以及对目标语言优化。


image.png


(图片来源:Introduction to deep learning


编译器前端



下面简要说明一下编译器前端部分的几个处理环节。


(1)词法分析


词法分析是由编译器中的词法分析器来执行的。这通常也被称为Lexer(词法分析器)或者说scanner(扫描器)。

程序源码将作为一个文本流来输入到词法分析器中。词法分析器将源程序的各个单词(比如 begin、end、if、for、while 等)转换成词法单元流并输出到语法分析器中。

编译时词法分析器同时会创建一个符号表,符号表在编译过程的所有阶段都会被频繁的访问和修改。符号表包含了程序员在源代码中使用的名称的信息,例如变量和函数名。


(2)语法分析


语法分析则是由语法分析器来执行,通常也叫parser(语法分析器)。语法分析器从词法分析器输出的 token 序列中识别出各类短语,从而构造语法分析树(syntax tree),并判断源程序在结构上是否正确。

比方说源代码:position = initial + rate * 60 构建出来的语法分析树是这样的:

image.png


(3)语义检查


语义分析使用语法树和符号表中的信息来检查源程序是否和语言定义的语义一致。它同时也收集标识符的属性信息,并把这些信息存放在语法树或符号表中,以便在后面中间代码生成过程中使用。

语义分析的一个重要部分是类型检查。编译器检查每个运算符是否具有匹配的运算分量,比如数组的下标要求必须是一个整数,如果用浮点数作为数组下标,编译器就应该报错。


(4)生成中间代码


编译器的处理过程是从源程序到语法树,再到中间代码,再到目标代码,期间可能构造出一个或多个中间表示,且这些中间表示可以有多种形式。一种常见的中间代码是三地址码,也可以通过四元式、三元式或间接三元式的方式表示。


  • 认识三址码


对于三位址码,每一条赋值指令的右侧只能有一个操作符,总共最多有三个地址(等号右侧只能有一个操作符,比如t1=y+z,这里t1,y,z都是地址,它们指向了地址对应的内存数据)


比如高级语言代码:

x = (y + z)*w


会转换成:

t1 = y + z
t2 = w * t1
x = t2


现在比较流行的一种编译器框架是 LLVM,我们可以大致看看编译前后的代码变化,感受一二。


编译前:

int a = 10;
   int b = 11;
   return a + b;


编译后:

%a = alloca i32, align 4
  %b = alloca i32, align 4
  store i32 0, i32* %retval, align 4
  store i32 10, i32* %a, align 4
  store i32 11, i32* %b, align 4
  %0 = load i32, i32* %a, align 4
  %1 = load i32, i32* %b, align 4
  %add = add nsw i32 %0, %1
  ret i32 %add

小结:在本篇编译器原理前端部分浅析中,有一些关键字,比如语法分析树、符号表、三地址码,这些还能拓展很多,后面有机会再做深入⑧


OK,以上便是本篇分享。点赞关注评论,为好文助力👍

我是掘金安东尼 🤠 100 万人气前端技术博主 💥 INFP 写作人格坚持 1000 日更文 ✍ 关注我,安东尼陪你一起度过漫长编程岁月 🌏


相关文章
|
21天前
|
移动开发 缓存 前端开发
深入理解前端路由:原理、实现与应用
本书《深入理解前端路由:原理、实现与应用》全面解析了前端路由的核心概念、工作原理及其实现方法,结合实际案例探讨了其在现代Web应用中的广泛应用,适合前端开发者和相关技术人员阅读。
|
1月前
|
前端开发 开发者
本文将深入探讨 BEM 的概念、原理以及其在前端开发中的应用
BEM(Block-Element-Modifier)是一种前端开发中的命名规范和架构方法,旨在提高代码的可维护性和复用性。通过将界面拆分为独立的模块,BEM 提供了一套清晰的命名规则,增强了代码的结构化和模块化设计,促进了团队协作。本文深入探讨了 BEM 的概念、原理及其在前端开发中的应用,分析了其优势与局限性,为开发者提供了宝贵的参考。
48 8
|
28天前
|
缓存 前端开发 JavaScript
JavaScript前端路由的实现原理及其在单页应用中的重要性,涵盖前端路由概念、基本原理、常见实现方式
本文深入解析了JavaScript前端路由的实现原理及其在单页应用中的重要性,涵盖前端路由概念、基本原理、常见实现方式(Hash路由和History路由)、优点及挑战,并通过实际案例分析,帮助开发者更好地理解和应用这一关键技术,提升用户体验。
68 1
|
1月前
|
监控 前端开发 jenkins
Jenkins 在前端项目持续部署中的应用,包括其原理、流程以及具体的实现方法
本文深入探讨了Jenkins在前端项目持续部署中的应用,涵盖其基本原理、流程及具体实现方法。首先介绍了Jenkins的基本概念及其在自动化任务中的作用,随后详细解析了从前端代码提交到生产环境部署的全过程,包括构建、测试、部署等关键步骤。最后,强调了持续部署中的代码质量控制、环境一致性、监控预警及安全管理等注意事项,旨在帮助开发者高效、安全地实施持续部署。
60 5
|
2月前
|
编解码 前端开发 JavaScript
前端:Rem 及其转换原理
Rem是一种用于前端开发的相对字体大小单位,它基于根元素的字体尺寸来定义文本大小,有助于实现响应式布局和可维护性。Rem的转换原理是通过相对于HTML根元素的字体大小来设置子元素的字体大小,从而实现统一的比例调整,提高页面的适应性和灵活性。此方法简化了跨浏览器和设备的布局调整,增强了用户体验。
|
3月前
|
移动开发 前端开发 JavaScript
浅谈前端路由原理hash和history
该文章详细解析了前端路由的两种模式——Hash模式与History模式的工作原理及其实现方式,并通过实例代码展示了如何在实际项目中运用这两种路由模式。
|
2月前
|
缓存 JavaScript 前端开发
拿下奇怪的前端报错(三):npm install卡住了一个钟- 从原理搞定安装的全链路问题
本文详细分析了 `npm install` 过程中可能出现的卡顿问题及解决方法,包括网络问题、Node.js 版本不兼容、缓存问题、权限问题、包冲突、过时的 npm 版本、系统资源不足和脚本问题等,并提供了相应的解决策略。同时,还介绍了开启全部日志、使用替代工具和使用 Docker 提供 Node 环境等其他处理方法。
1204 0
|
2月前
|
存储 安全 前端开发
在前端开发中需要考虑的常见web安全问题和攻击原理以及防范措施
在前端开发中需要考虑的常见web安全问题和攻击原理以及防范措施
221 0
|
3月前
|
移动开发 缓存 前端开发
构建高效的前端路由系统:从原理到实践
在现代Web开发中,前端路由系统已成为构建单页面应用(SPA)不可或缺的核心技术之一。不同于传统服务器渲染的多页面应用,SPA通过前端路由技术实现了页面的局部刷新与无缝导航,极大地提升了用户体验。本文将深入剖析前端路由的工作原理,包括Hash模式与History模式的实现差异,并通过实战演示如何在Vue.js框架中构建一个高效、可维护的前端路由系统。我们还将探讨如何优化路由加载性能,确保应用在不同网络环境下的流畅运行。本文不仅适合前端开发者深入了解前端路由的奥秘,也为后端转前端或初学者提供了从零到一的实战指南。
|
4月前
|
开发者 安全 UED
JSF事件监听器:解锁动态界面的秘密武器,你真的知道如何驾驭它吗?
【8月更文挑战第31天】在构建动态用户界面时,事件监听器是实现组件间通信和响应用户操作的关键机制。JavaServer Faces (JSF) 提供了完整的事件模型,通过自定义事件监听器扩展组件行为。本文详细介绍如何在 JSF 应用中创建和使用事件监听器,提升应用的交互性和响应能力。
42 0