当前位置: 首页 > news >正文

深入浅出理解编译器:前端视角

一、编译器究竟是什么?

在前端开发的世界里,我们经常会听到 “编译器” 这个词。就拿 Babel 来说,在它的官网上,最显眼的一句话就是:“Babel is a JavaScript compiler”。那什么是 JavaScript 编译器呢?又该如何去学习和理解编译器呢?让我们一起来揭开它的神秘面纱。

编译器,简单来说,就是一种电脑程序,它的主要工作就是把用某种编程语言写的源代码,转换成另一种编程语言。比如说,Babel 就可以把 ES6、ES7 或者 JSX 这些新的语法转换成 ES5 或者其他指定版本,就像是给代码做了一次 “变形记”。

其实,在我们日常的前端开发中,有很多工具都用到了编译器的技术,比如 Less/Saas 用于处理样式,TypeScript/coffeeScript 用于处理脚本,还有 Eslint 用于代码检查等等。正是因为有了这些工具,前端工程化才能发展得越来越好。

二、编译器的基本思路

(一)词法分析 (Lexical Analysis)

目的

词法分析的主要任务就是把我们写的文本代码分割成一个个小小的 “token”,就像是把一句话拆分成一个个的单词。比如说,“init、main、x、;、=、3” 这些都可以是 token。同时,它还会把那些注释、空格、回车等对代码运行没有实际作用的字符去掉,让代码变得更加 “纯粹”。

生成方式

生成 token 主要有两种办法:

  • 正则表达式:这种方法需要写大量的正则表达式,而且这些正则之间还可能会有冲突,维护起来比较麻烦,性能也不是很高。所以,正则表达式一般只适合一些简单的模板语法,对于真正复杂的语言就不太合适了。而且有些语言可能还没有自带的正则引擎呢。
  • 自动机:自动机就像是一个智能的小机器,可以很好地生成 token。其中,有穷状态自动机(finite state machine)是一个很重要的概念。它在有限个输入的情况下,会在不同的状态之间转移,最终达到一个终止状态。有穷状态自动机又可以分为 “确定有穷状态自动机”(DFA - Deterministic finite automaton)和 “非确定有穷自动机”(NFA - Non-deterministic finite automaton)。DFA 在输入一个状态时,只会得到一个固定的状态,可以认为是一种特殊的 NFA;而 NFA 当输入一个字符或者条件时,会得到一个状态机的集合。JavaScript 正则采用的就是 NFA 引擎。

(二)语法分析 (Syntactic Analysis)

我们平时说的编译原理,其实就是把一种语言转换为另一种语言。编译原理研究的是形式语言,这种语言不需要知道太多的背景知识,而且没有歧义。和自然语言不一样,自然语言很难处理,因为很难分清哪些是名词、动词、形容词。比如说 “进口汽车”,这里的 “进口” 到底是动词还是形容词呢?所以,我们要解析一门语言,前提是这门语言有严格的语法规定。

在 1956 年,乔姆斯基把文法按照规范的严格性分成了 0 型、1 型、2 型和 3 型共 4 种。一般的计算机语言用的是 2 型文法,也叫上下文无关文法(CFG)。因为 0 型和 1 型文法定义太宽松,会增加解析的难度,降低效率;而 3 型文法限制又太多,不利于语言设计的灵活性。

语法分析的目的就是把词法分析得到的 token 流,结合文法规则,通过一定的算法生成一颗抽象语法树(AST)。AST 在前端领域非常重要,比如说 Babel 插件的原理就是:es6 代码通过 Babylon.parse 生成 AST,然后用 babel-traverse 处理得到新的 AST,最后再生成 es5 代码。

从生成 AST 的效率和实现难度来看,主要有两种解析算法:自顶向下的分析方法和自底向上的分析方法。自底向上算法可以分析的文法范围比较广,但是实现起来比较难;自顶向下算法实现相对简单,能解析的文法范围也不错,所以一般的编译器都会采用深度优先索引的方式。

(三)代码转换(Transformation)

当我们得到 AST 之后,通常会先把它转换成另一种 AST,这样可以生成更符合我们预期的 AST,这个过程就叫做代码转换。代码转换有很多优势:

  • 易移植:它和具体的机器没有关系,所以可以作为中间语言,为生成多种不同型号的目标机器码服务。
  • 机器无关优化:可以对中间码进行优化,提高代码的质量。
  • 层次清晰:把 AST 先映射成中间代码,再映射成目标代码,这样可以让编译算法更加清晰。

对于一个编译器来说,在转换阶段通常有两种形式:

同语言的 AST 转换和 AST 转换为新语言的 AST。

一般的做法是,对之前的 AST 从上至下进行解析(称为 traversal),然后有一个映射表(称为 visitor),把对应的类型做相应的转换。

(四)代码生成 (Code Generation)

在实际处理代码的过程中,我们可能会递归地分析最终生成的 AST,对于每种 type 都有一个对应的函数来处理。最终,我们的目标代码就会在这一步输出。在前端领域,我们的目标代码可能就是 HTML 了。

三、完整链路 (Compiler)

一个完整的编译器过程可以用下面的代码来表示:

input => tokenizer => tokens; // 词法分析
tokens => parser => ast; // 语法分析,生成 AST
ast => transformer => newAst; // 中间层代码转换
newAst => generator => output; // 生成目标代码

 

相关文章:

深入浅出理解编译器:前端视角

一、编译器究竟是什么? 在前端开发的世界里,我们经常会听到 “编译器” 这个词。就拿 Babel 来说,在它的官网上,最显眼的一句话就是:“Babel is a JavaScript compiler”。那什么是 JavaScript 编译器呢?又…...

Minio搭建并在SpringBoot中使用完成用户头像的上传

Minio使用搭建并上传用户头像到服务器操作,学习笔记 Minio介绍 minio官网 MinIO是一个开源的分布式对象存储服务器,支持S3协议并且可以在多节点上实现数据的高可用和容错。它采用Go语言开发,拥有轻量级、高性能、易部署等特点,并且可以自由…...

Ubuntu系统上部署Node.js项目的完整流程

以下是在Ubuntu系统上部署Node.js项目的完整流程,分为系统初始化、环境配置、项目部署三个部分: 一、系统初始化 & 环境准备 bash # 1. 更新系统软件包 sudo apt update && sudo apt upgrade -y# 2. 安装基础工具 sudo apt install -y buil…...

DeepSeek效应初现:Grok-3补刀ChatGPT,OpenAI已在ICU?

嘿,技术小伙伴们!今天咱们聊聊最近在AI界引发轰动的新闻——DeepSeek和xAI相继用R1和Grok-3证明了预训练Scaling Law并非OpenAI的护城河。这意味着什么呢?让我们一探究竟! 开场白 首先,让我们看看最新的“全能冠军”…...

【知识】torchrun 与 torch.multiprocessing.spawn 的对比

转载请注明出处:小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你,欢迎[点赞、收藏、关注]哦~ 来自ChatGPT、DeepSeek 有点干,可仅做了解。 torchrun 和 torch.multiprocessing.spawn 都是在 PyTorch 中用于并行化和分布式训练的工具&a…...

深入了解 K-Means 聚类算法:原理与应用

引言 在数据科学和机器学习的世界中,聚类是一项非常重要的技术,它帮助我们根据数据的相似性将数据划分为不同的组或簇。聚类算法在许多领域中得到了广泛的应用,如图像处理、市场细分、基因研究等。K-Means 聚类算法作为最常见的无监督学习算…...

Rust ~ Collect

背景 Transforms an iterator into a collection 将一个迭代器转换为一个集合 collect() 可以处理任何可迭代的对象,并将其转换为相关的集合 collect() 最基本模式是将一个集合转换为另一个集合: 先获取一个集合,对其调用 iter 方法&#x…...

C# 类型转换

C# 类型转换 引言 在C#编程语言中,类型转换是一种将一个数据类型的变量转换成另一个数据类型的操作。类型转换是编程中常见的操作,特别是在处理不同数据类型的变量时。本文将详细探讨C#中的类型转换,包括隐式转换和显式转换,以及…...

[IP] DDR_FIFO(DDR3 用户FIFO接口)

IP(DDR_FIFO)将DDR3 IP的用户侧复杂接口修改为简易的FIFO接口,用户侧更加简易例化使用MIG 核 IP介绍 c0_xx (连接DDR app接口) 此IP 仅需根据MIG配置进行有限修改,即可使用! 关于IP详细使用说明,参考IP datasheet! 示…...

第三百七十二节 JavaFX教程 - JavaFX HTMLEditor

JavaFX教程 - JavaFX HTMLEditor HTMLEditor控件是一个富文本编辑器,具有以下功能。 粗体斜体下划线删除线字体系列字体大小前景色背景颜色缩进项目符号列表编号列表对齐水平线复制文本片段粘贴文本片段 HTMLEditor类返回HTML字符串中的编辑内容。 创建HTML编辑器…...

蓝桥杯试题:DFS回溯

一、题目要求 输入一个数组n&#xff0c;输出1到n的全排列 二、代码展示 import java.util.*;public class ikun {static List<List<Integer>> list new ArrayList<>();public static void main(String[] args) { Scanner sc new Scanner(System.in);…...

Lua | 每日一练 (4)

&#x1f4a2;欢迎来到张胤尘的技术站 &#x1f4a5;技术如江河&#xff0c;汇聚众志成。代码似星辰&#xff0c;照亮行征程。开源精神长&#xff0c;传承永不忘。携手共前行&#xff0c;未来更辉煌&#x1f4a5; 文章目录 Lua | 每日一练 (4)题目参考答案线程和协程调度方式上…...

每日一题——接雨水

接雨水问题详解 问题描述 给定一个非负整数数组 height&#xff0c;表示每个宽度为 1 的柱子的高度图。计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 示例 示例 1&#xff1a; 输入&#xff1a;height [0,1,0,2,1,0,1,3,2,1,2,1] 输出&#xff1a;6 解释&#…...

java常见面试01

为什么重写 equals 还要重写 hashcode &#x1f308; 核心原因&#xff1a; 当两个对象通过equals()判断为相等时&#xff0c;它们的hashCode()必须返回相同的整数值&#xff01;这是Java世界的交通规则哦~&#xff08;交警曼波敬礼.jpg&#xff09; &#x1f9e9; 具体场景…...

算法-二叉树篇27-把二叉搜索树转换为累加树

把二叉搜索树转换为累加树 力扣题目链接 题目描述 给出二叉 搜索 树的根节点&#xff0c;该树的节点值各不相同&#xff0c;请你将其转换为累加树&#xff08;Greater Sum Tree&#xff09;&#xff0c;使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。 提…...

C语言:51单片机 基础知识

一、单片机概述 单片机的组成及其特点 单片机是指在一块芯片上集成了CPU、ROM、RAM、定时器/计数器和多种I/O接口电路等&#xff0c;具有一定规模的微型计算机。 特点&#xff1a; 1、单片机的存储器以ROM、RAM严格分工。 2、采用面向控制的指令系统。 3、单片机的I/O口引脚通…...

olmOCR:使用VLM解析PDF

在PDF解析中&#xff0c;目前主流的开源工具包括Minuer、GOT OCR等。主要都是通过飞桨等OCR套件组装的一套pipeline&#xff0c;或者直接通过VLM解析图像。 #一、 olmOCR是使用VLM进行的端到端的PDF文档解析 二、document-anchoring 与上述的不同在于&#xff0c;olmOCR使用…...

数据结构(初阶)(七)----树和二叉树(堆,堆排序)

八&#xff0c;树与二叉树 树 概念与结构 树是⼀种⾮线性的数据结构&#xff0c;它是由 n&#xff08;n>0&#xff09; 个有限结点组成⼀个具有层次关系的集合。把它叫做树是因为它看起来像⼀棵倒挂的树&#xff0c;也就是说它是根朝上&#xff0c;⽽叶朝下的。 • 有⼀…...

图像分类项目1:基于卷积神经网络的动物图像分类

一、选题背景及动机 在现代社会中&#xff0c;图像分类是计算机视觉领域的一个重要任务。动物图像分类具有广泛的应用&#xff0c;例如生态学研究、动物保护、农业监测等。通过对动物图像进行自动分类&#xff0c;可以帮助人们更好地了解动物种类、数量和分布情况&#xff0c;…...

Kali Linux 2024.4版本全局代理(wide Proxy)配置,适用于浏览器、命令行

1. 网络拓扑介绍&#xff08;不使用虚拟机直接跳到2&#xff09; 虚拟机&#xff1a;VMware 17 Pro&#xff0c;为本机开启桥接模式。 我的究极套娃网络&#xff1a;手机V2rayNG代理端口为10808&#xff0c;开热点 -> 电脑连接wifi -> 虚拟机中运行kali 2. kali 配置…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

边缘计算医疗风险自查APP开发方案

核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

【机器视觉】单目测距——运动结构恢复

ps&#xff1a;图是随便找的&#xff0c;为了凑个封面 前言 在前面对光流法进行进一步改进&#xff0c;希望将2D光流推广至3D场景流时&#xff0c;发现2D转3D过程中存在尺度歧义问题&#xff0c;需要补全摄像头拍摄图像中缺失的深度信息&#xff0c;否则解空间不收敛&#xf…...

2021-03-15 iview一些问题

1.iview 在使用tree组件时&#xff0c;发现没有set类的方法&#xff0c;只有get&#xff0c;那么要改变tree值&#xff0c;只能遍历treeData&#xff0c;递归修改treeData的checked&#xff0c;发现无法更改&#xff0c;原因在于check模式下&#xff0c;子元素的勾选状态跟父节…...

ip子接口配置及删除

配置永久生效的子接口&#xff0c;2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题

分区配置 (ptab.json) img 属性介绍&#xff1a; img 属性指定分区存放的 image 名称&#xff0c;指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件&#xff0c;则以 proj_name:binary_name 格式指定文件名&#xff0c; proj_name 为工程 名&…...

网站指纹识别

网站指纹识别 网站的最基本组成&#xff1a;服务器&#xff08;操作系统&#xff09;、中间件&#xff08;web容器&#xff09;、脚本语言、数据厍 为什么要了解这些&#xff1f;举个例子&#xff1a;发现了一个文件读取漏洞&#xff0c;我们需要读/etc/passwd&#xff0c;如…...

初探Service服务发现机制

1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能&#xff1a;服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源&#xf…...