2.1 程序设计语言基础
2.1.1 程序设计语言概述
2.1.1.1 程序设计语言的基本概念
(1) 解释器
- 翻译源程序不生成独立的目标程序
- 解释程序和源程序都要参与到程序的运行过程中
(2) 编译器
- 翻译时将源程序翻译成独立的目标程序
- 机器上运行的是与源程序等价的目标程序
- 源程序和编译程序都不参与目标程序的运行过程
2.1.1.2 程序设计语言的基本成分
(1) 程序的三种基本控制结构:
顺序结构、选择结构、循环结构
(2) 程序的三种基本运算方式:
算式运算、关系运算、逻辑运算
(3) 程序中的数据必须具有类型的作用:
- 便于数据合理分配存储单元
- 便于对参与表达式计算的数据对象进行检查
- 便于规定数据对象的取值范围以及能够进行的运算
(4) 函数:
- 传值调用:将实参值传递给形参,实参可以是变量、常量和表达式;不可以实现实参和形参的双向传递效果。
- 传地址(引用)调用:将实参的地址传递给形参,形参必须有地址,实参不能是常量、表达式;可以实现实参和形参的双向传递效果。
2.2 语言处理程序基础
2.2.1 编译程序基本原理
2.2.1.1 编译、解释程序翻译阶段
- 编译方式:词法分析、语法分析、语义分析、中间代码生成、代码优化、目标代码生成;
- 解释方式:词法分析、语法分析、语义分析;
- 编译器和解释器都不可以省略词法分析、语法分析、语义分析且顺序不可互换,即词法分析、语法分析、语义分析是必须的;
- 编译器方式中间代码生成和代码优化不是必须的,可省略。即编译器方式可以在词法分析、语法分析、语义分析阶段后直接生成目标代码。
2.2.1.2 符号表
- 不断收集、记录和使用源程序中一些相关符号的类型和特征信息,并将其存入符号表中;
- 记录源程序中各个字符的必要信息,以辅助语义的正确性检查和代码生成。
2.2.1.3 词法分析
输入:源程序 输出:记号流
作用:
- 分析构成程序的字符以及由字符按照构成规则构成的符号是否符合程序语言的规定;
- 识别源程序中的记号;
2.2.1.4 语法分析
输入:记号流 输出:语法树(分析树)
作用:
- 语法分析阶段可以发现程序中所有的语法错误;
- 语法分析主要是对各条语句的结构进行合法性分析;
- 分析程序中的句子结构是否正确。
2.2.1.5 语义分析
输入:语法树(分析树)
作用:
- 语义分析阶段主要是进行类型分析和检查;
- 语义分析阶段不能发现程序中所有的语义错误;
- 语义分析阶段可以发现静态语义错误,不能发现动态语义错误,动态语义错误运行时才能发现。
2.2.1.6 目标代码生成
作用:
- 目标代码生成阶段的工作与具体的机器密切相关;
- 寄存器的分配工作处于目标代码生成阶段。
2.2.1.7 中间代码生成
常见中间代码表示方式:后缀式、逆波兰式、三地址码、三元式、四元式和树(图)等。
特点:
- 中间代码与具体的机器无关(不依赖具体的机器);
- 可以将不同的高级语言翻译成同一种中间代码,中间代码可以跨平台;
- 由于与具体机器无关,使用中间代码有利于进行与机器无关的优化处理和提高编译程序的可移植性。
2.2.1.8 正规式(正规表达式)
eg:
正确答案:A
2.2.1.9 有限自动机
有限自动机是此词法分析的一个工具,他能正确的识别正规集。
- 确定的有限自动机(DFA):对于每一个状态来说识别字符后转移的状态是确定唯一的;
- 不确定的有限自动机(NFA):对于每一个状态来说识别字符后转移的状态是不确定的;
- 确定的有限自动机和不确定的有限自动机:输入一个字符,看是否能得出唯一的后继,若能,则是确定的,否则若得出多个后继,则是不确定的。
图示:
左侧箭头 + 圈0表示为自动机的初态,最右侧双圈5表示为自动机的终态,ε表示为空。
eg1:
正确答案:D
eg2:
正确答案:B
推导过程:
- A:有限自动机状态转换为S0 -> S1 -> S0 -> S0 -> S1,最终为中间态,非终态,不能识别;
- B:有限自动机状态转换为S0 -> S1 -> S2 -> S2 -> S2,最终为终态,可以识别;
- C:有限自动机状态转换为S0 -> S1 -> S0 -> S1 ->S0,最终为初态,非终态,不能识别;
- D:有限自动机状态转换为S0 -> S0 -> S1 ->S0 -> S1,最终为中间态,非终态,不能识别。
2.2.1.10 上下文无关文法
上下文无关文法被广泛的应用于表示各种程序设计语言的文法规则。
eg:
正确答案:B
推导过程:
E -> E + T -> E + T * F -> T + T * F -> F + F * F -> F + -F * F -> N + -N * N -> 2 + -3 * 4
2.2.1.11 中缀、后缀(逆波兰式)表达式转换
- 中缀表达式假设为1 + 2 * 3,那么后缀表达式可以转换为123*+;
- 中缀表达式转为后缀表达式所遵循优先级为:括号 > 乘除 > 加减,优先级相同,从右向左;
- 后缀表达式转为中缀表达式可以利用栈来计算;即从左到右,遇到数字直接入栈,遇到符号将栈顶两位进行出站计算,并将计算结果再入栈,直到栈内只有一个数据。
eg:
正确结果:D
推到过程:
(a - b) * (c + d) -> ab- * cd+ -> ab-cd+*
2.2.1.12 语法树中、后序遍历
- 中序遍历即为二叉树的中序序列遍历,后序即为二叉树的后序序列遍历;
- 中序遍历遵循左根右,后序遍历遵循左右根;
eg:
正确答案:C
推到过程:根据后序遍历规则:左右根进行遍历
语法树 -> a_+ -> a_d*+ -> abc-d*+
2.2.2 其他杂项
- 高级语言源程序A经过编译得到机器B上的目标程序B,则对B进行反编译,不能还原出源程序A;
- 脚本语言(弱类型语言)属于动态语言,动态语言都是解释性语言,脚本语言一般通过脚本引擎解释执行,不产生独立保存的目标程序;
- 汇编语言源程序中的指令被翻译成机器代码,汇编语言的指令语句必须具有操作码字段,可以没有操作数;
- 编译过程中为变量分配存储单元所用的地址是逻辑地址,程序运行时再映射为物理地址;
- 递归下降分析法和预测分析法是自顶向下的语法分析法,算符优先分析法、移进-归约分析法和LR分析法是自底向上的语法分析法;
- 语法制导翻译是一种静态语义分析法;
- 计算机执行程序时,内存分为静态数据区、代码区、栈区和堆区。一般栈区在进行函数调用和返回时由系统进行控制和管理,堆区由用户在程序中根据需要申请和释放。
- Java语言的的特征采用即时编译、对象在堆空间分配和自动的垃圾回收处理;
- 全局变量的存储空间在静态数据区分配;