2025-09-29 23:18:247204
然后找到剩余的最长前缀,也就是词素
这两句话比较抽象,举个例子来说明一下
比如 C 语言中有这么一个语句
ifx = 20*30;
那么第一个词素就是 ifx,为什么不是 if 呢?因为 if 不是最长的前缀。然后后面的词素依次是 =,20,*,30和;。
词素、词法分析器、token 的关系如下
词素是 Token 的实例,词法分析器的主要任务就是从源程序中读取字符并产生 token。token 也是有结构的,一般结构如下
在词法分析生成的 token 中,第一个词 token-name 是语法分析期间使用的抽象符号,第二个词 attribute-value 指向的是符号表中关于这个词法单元的条目数。
我们举个例子来看一下词法分析的拆解过程。
比如现在源程序中有一个赋值语句
income = mainjob + sideline // 收入 = 主业 + 副业
这个赋值语句中的字符可以组合成如下词素,并转换成为 token,并传递给语法分析阶段。
首先,income 是一个词素,它会被映射为
然后是赋值符号 = ,它也是一个词素,被映射称为 token 中的 < = >。这个 token 不需要属性值,所以没有第二个词。
mainjob 是一个词素,它被映射成为 token 中的
+也是一个词素,它被映射称为 < + >,没有条目数
sideline 是一个词素,它被映射称为 token 中的
所以,经过词法分析后,上面的源程序会变为
在上面的表达式中, = 和 + 分别表示赋值和加法运算符的抽象符号。用图来表示的话就是
语法分析
编译器的第二个步骤是 语法分析(syntax analysis) 或者称为 解析(parsing)。语法分析器使用由词法分析器生成的各个词法单元的第一个分量来创建树形的中间表示。常用的方法就是 语法树(syntax tree)。编译器的后续步骤都会使用这个语法结构来帮助分析源程序,并生成目标程序。
语义分析
语义分析是由 语义分析器(semantic analyzer) 完成的,它使用语法树和符号表中的信息来检查源程序是否和语言定义的语义一致。语义分析器也收集类型信息,并把这些信息放在语法树或者符号表中,以便后续的中间代码生成器使用。
语义分析会进行类型检查(type checking),这是语义分析器的一个最重要的功能。编译器会检查每个运算符是否具有匹配的运算分量。举个例子比如设计语言要求一个数组的下标是整数,如果你用浮点数作为下标,编译器就会出错。
某些程序设计语言比如 Java 会允许自动类型转换(coercion)。如果整数和浮点数进行运算,编译器会把整数转换为浮点数。
中间代码生成
在源程序的语法分析和语义分析完成后,很多编译器生成一个明确的低级类机器语言的中间表示。我们可以把中间表示形式看作是抽象,中间形式的代码应该具有两个重要的性质:易于生成,并且能够轻松的被翻译。一般常用的一种是 三地址指令(three-address instructions)的中间表示形式。我们后面会细说。
代码优化
代码优化会试图改进代码以便生成更好的目标代码。更好通常情况下意味着更快,但是也可能会有其他目标,比如更短或能耗更低的目标代码。
代码生成
代码生成通过中间代码作为输入,并把它映射为目标语言。如果目标语言是机器代码的话,那么必须要为每个变量分配寄存器或内存位置。解释一下上面的运行结果。
每个指令的第一个运算分量指定了一个目标地址,各个指令中的 F 告诉我们它处理的是 浮点数, 上面代码首先把 id3 装载进 R2 寄存器中,然后把 id2 装载进 R1 寄存器中,再对 R1 目标进行 R1 和 R2 寄存器相加的操作。最后把寄存器 R1 的值存放到 id1 的地址中。
符号表管理
我们上面提到了符号表的概念,它是一个编译器很重要的功能。符号表能够记录源程序中使用变量的名称,并收集和每个名称相关的属性信息。它相当于一个秘书的作用。符号表还记录了每个变量名字的条目。后面我们会详细的介绍符号表。
编译器构造工具
和软件开发一样,写编译器的人可以充分利用现代的软件开发环境进行开发。通常也有 语言编辑器、调试工具、版本管理、测试工具等。除此之外,还需要一些更专业的工具来实现编辑器不同阶段的代码生成。
一些常用的编译器构造工具有
语法分析器生成器:可以根据程序设计语言的语法描述自动生成语法分析器
扫描器生成器:可以根据一个语言的语法单元的正则描述生成词法分析器
语法制导的翻译引擎:用于生成一组遍历分析树并生成中间代码
代码生成器:用于把中间代码转换为目标代码
数据流分析引擎:用于分析输入是如何传递到另一部分的
编译器构造工具:提供用于构造编译器不同阶段的例程
程序设计语言的发展历程
计算机从 20 世纪 40 年代创建至今都只能理解二进制语言,亘古不变。这个 0 、 1 组成的序列能够告诉计算机以什么样的顺序执行怎样的运算。运算本身是很底层的:比如把一个数据从一个位置进行移动;把两个寄存器的内容进行相加、比较两个值,为了避免如此枯燥的运算,我们开发了各种各样的编程语言,但是计算机底层的计算方式一直没变,所以学习哪个技术性价比高,明白了吗?下面我们就来一起认识一下程序设计语言的历程。
高级设计语言
首先被开发出来的是 20 世纪 50 年代的汇编语言,5 年后发生了重要的进步,用于科学计算的 Fortran 被开发出来,用于商业处理的 Cobol 语言和用于符号计算的 Lisp 语言被开发出来;然后接下来的时间,慢慢很多编程语言被开发出来,比如 C、C++、Java、JavaScript、Python 等。后面还有用于数据处理的 SQL 语言。
语言分类
说到给这些编程语言分类,那可是有太多了,不过我们专注一下高频的分类。
如何完成计算任务的语言称为 强制式(imperative)语言,而把程序中指明要进行哪些计算的语言称为 声明式(declarative)语言。C、C++、Java 这些都是强制式语言,它们能够改变程序的状态;声明式比如 HTML Prolog 等。
冯·诺伊曼 语言指的是以冯·诺伊曼计算机体系为基础的编程语言,今天很多编程语言都是冯·诺伊曼语言
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
最后
由于篇幅原因,就不多做展示了 《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门即可获取! 片转存中…(img-ueeiQvzk-1711876935149)]
[外链图片转存中…(img-bGI46mFL-1711876935150)]
[外链图片转存中…(img-Gw6ghDcP-1711876935150)]
[外链图片转存中…(img-mkYtav6x-1711876935150)]
由于篇幅原因,就不多做展示了 《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门即可获取!