软件设计师笔记之程序语言和语言程序处理基础知识
作者:互联网
目录
程序语言和编译相关知识,主要在编码阶段应用,我们需要掌握程序语言相关知识,本章需要掌握以下几个方面的知识点与考点。
汇编、编译、解释系统 | 基础知识和基本工作原理 |
程序设计语言的基本成分 | 数据、运算、控制和传输,程序调用的实现机制 |
各类程序设计语言的主要特点和适用情况 | 过程式程序语言、面向对象程序设计语言、函数式程序设计语言、逻辑程序设计语言的基本特点、脚本语言的特点 |
汇编、编译、解释系统的基础知识和基本工作原理 | 文法、有限自动机、正规式 |
程序设计语言的基本成分 | 语句的作用、语句的语义、程序的控制结构、函数调用的参数传递 |
各类程序设计语言的主要特点和适用情况 | 各种程序语言的特点比较 |
总结以上我们本章需要掌握:编译与解释、文法、正规式、有限自动机、表达式、传值与传址、多种程序语言特点。
一、汇编、编译、解释系统基础
本节将针对软件设计师考试当中需要掌握的编译原理知识进行笔记梳理。编译原理是计算机专业课程中难的课程之一。
1. 解释与编译
在计算机中,程序语言分为低级语言和高级语言,如汇编语言便是一种低级语言,而平时我们所使用的一般都属于高级语言如:Java、python、C#、Delphi等,。使用高级语言开发的程序是不能直接运行的,需要经过一系列的处理,才能运行。这个过程,根据其处理方式的不同,可分为:解释型和编译型,这是语言处理的两种基本方式
解释型 | 接受所输入的用程序语言编写的源程序,然后直接解释执行;这类语言中的典型代表是BASIC |
编译型 | 将用某种程序语言编写的源程序直接翻译成为另一种语言(目标语言程序),而且两者在逻辑上等价,如:C语言 |
编译过程包括词法分析、语法分析、语义分析、中间代码生成、代码优化和目标代码生成等阶段,以及符号表管理与出错处理模块。
解释过程在词法、语法和语义分析方面与编译程序的工作原理基本相同,但是在运行用户程序时,它直接执行源程序或源程序的内部形式。
这两种语言处理程序的根本区别是:在编译方式下,机器上运行的是与源码程序等价的目标程序,源程序和编译程序都不再参与目标程序的执行过程;而在解释方式下,解释程序和源程序(或其某种等价表示)要参与到程序的运行过程中,运行程序的控制权在解释程序。
在编译方式下,词法、语法和语义分析是必须要进行的工作,而生产中间代码和优化则是可以进行也可以不进行。
2. 编译过程
所谓编译过程,就是使用编译程序将高级语言源程序翻译为等价的机器语言程序的过程。一般来说,编译程序分为以下几个部分:词法分析、语法分析、语义分析、中间代码生成、代码优化、目标代码生成以及贯穿始终的表格管理与出错处理。
在对用高级程序设计语言编写的程序进行执行时,首先是将源代码翻译成目标代码,然后在连接成可执行的二进制代码。因此在翻译阶段,目标代码生成阶段的工作与目标机器的体系结构密切相关。
3.语言及文法的概念
(难点但不是考点)
语言是按照一定规则排列的符号和集合。要形式化地描述一个语言,就需要借助文法的概念。文法就是用来描述语言的语法结构的形式规则。根据乔姆斯基的分类法,文法可以分成四种类型
要根据这样的定义来对文法进行判断,总是让许多人无从下手,其实只要掌握一些规律,就能够更好地完成这一任务(听说这个知识点考查概率在不断降低,若完成本节学习,仍有疑问,可考虑先将主要精力投入其它章节学习)。
四种文法之间的关系是随着型号的增加,对语言的限制条件就越来越大
条件如下:
0型文法 : 产生式左右两边都可以出现任意符号串
1型文法 : 产生式的左边可以有终结符的出现,产生式右边是任意符号串
2型文法 :产生式的左边是非终结符,产生式的右边是任意符号串
3型文法 :产生式的左边是非终结符,产生式的右边非终结符的位置要么在最左边要么在最右边而且最多只能有一个
如: A-->aB | d A-->Ba | d
4. 词法分析
词法分析是整个分析过程的一个子任务,它把构成源程序的字符串转换成语义上关联的单词符号(包括关键字、标识符、常数、运算符和分界符等)的序列。词法分析可以借助于有限自动机的理论与方法进行有效的处理。
(1)有限自动机
有限自动机是一种自动识别装置,能够准确地识别正规集。它与3型文法对应,可以分为确定的有限自动机和不确定的有限自动机两种。
确定的有限自动机(DFA)
M=(S,∑, δ,S0,Z)
1)S是一个有限集,每个元素为一个状态
2)∑是一个有穷字母表,每个元素为一个输入字符
3)δ是转换函数:是一个单值对照
4)S0属于S,是其唯一的初态
5)Z是一个终态集(可空)
有限状态自动机可以形象地用状态转换图表示,设有限状态自动机:
DFA = ({S, A, B, C, f}, {1, 0},δ,S, {f})
其中:δ(S, 0) = B, δ(S, 1) = A, δ(A, 0) = f, δ(A, 1) = C, δ(B, 0) = C, δ(B, 1) = f,δ(C, 0) = f, δ(C, 1)= f
不确定的有限自动机(NFA)
M=(S,∑, δ,S0,Z)
1)S是一个有限集,每个元素为一个状态
2)∑是一个有穷字母表,每个元素为一个输入字符
3)δ是转换函数,是多值对照
4)S0,属于S,是非空初态集
5)Z是一个终态集(可空)
与确定的有限自动机相同点:不确定有限自动机同样可以用状态转换图表示,不同点:在图中一个状态结点可能有一条以上的边到达其它状态结点。
从定义的角度来区分NFA与DFA,我们发现:DFA是单值对照,NFA是多值对照(其实也就对应着上面所述的“NFA图中一个状态结点可能有一条以上的边到达其它状态结点”);NFA可以转换为等价的DFA。
(2)正规式
对于字母表∑而言,正规则式和它所表示的正规集的递归定义是:
空集是正规表达式。
任何属于∑的α,都是其正规式。
假定U和V都是∑上的正规式,那它们的或、连接、闭包都是正规式。
通常在正规表达式中,一元运算符 ”*” 具有高的优先级,”·”连接运算具有次优先级,”|”运算符具有低优先级,这三个运算都是左结合(左结合性的运算符由左向右运算,右结合性的运算符由右向左运算)的。每一个正规表达式R都对应一个有限自动机M,使M所接受的语言就是正规表达式的值。经过以下步骤可以从一个正规表达式R构造出相应的有限自动机M。
运算符的优先级从高到低顺序排列为:“*”、“·”、“|”
若两个正规式表示的正规集相同,则认为二者等价,两个等价的正规集U和V记作U=V。
直到所有的边都以Σ中的字母或ε标记为止。由此产生了一个带ε–转移的非确定有限自动机,然后可以通过上面介绍的方法,把该自动机转换成确定有限状态自动机。
下面举一个例子说明自动机理论在词法分析程序中的应用。C语言中对标识符的规定为由“_”或以字母开头的由“_”、字母和数字组成的字符串,该标识符的定义可以表示为下面的正则表达式:(_|a)(_|a|d)*
式中的a代表字母字符{A,…,Z,a,…,z},d代表数字字符{0,1,…,9}。利用前面的方法构造出如图所示的有限自动机。
该自动机所接受的语言就是C语言中的标识符。
在有限自动机的状态转换过程中,需要执行相关的语义动作。例如当识别到一个标识符时,需要在符号表中添加该标识符,并且向语法分析程序输送表示该标识符的单词。
5. 语法分析
语法分析的任务是识别由词法分析给出的单词符号序列是否为给定文法的正确句子(程序),语法分析可以分为自底向上分析和自顶向下分析两大类。
(1)自底向上分析
自底向上分析也称为移进——归约分析法。它的基本思想是:对输入符号串自左向右进行扫
描,并将输入符号逐一移进一个后进先出的栈中,边移进边分析;一旦栈顶符号串形成某个句型的可归约串时,就用某产生式的左部非终结符来替代(这称之为归约)。一直重复这个过程,直到栈中只剩下文法的开始符号。
(2)自顶向下分析
自顶向下分析法也称为面向目标的分析方法,也就是从文法的开始符号出发尝试推导出与输入的单词串相匹配的句子。
6.语法推导树
一棵语法树具有以下特征:
1)每个结点都有一个标记,此标记是 V 的一个符号;
2)根的标记是 S ;
3)若一个结点 n 至少有一个它自己除外的子孙,并且标记 A ,则 A 肯定在 VN中;
4)如果结点 n 的直接子孙,从左到右的次序是结点 n₁ ,n₂ ,... ... ,nk,其标记分别是 A₁ ,A₂ ,... ... ,Ak,那么 A -> A₁ ,A₂ ,... ... ,Ak,一定是P中的一个产生式。
二、程序设计语言基础
程序设计语言基础主要包括程序当中的数据、运算、控制、传输以及程序调用的实现机制等相关内容。本节主要对表达式的转化和程序调用的实现机制的知识点进行笔记。
1. 数据类型
计算机系统中,会把数据分为不同的类型,常见的数据类型包括:整型,长整型,字符型,浮点型等。
数据类型的出现是为了把数据分成所需内存大小不同的数据,编程的时候需要用大数据的时候才需要申请大内存,就可以充分利用内存。
要求源程序中的数据必须具有类型的目的主要有以下几个方面:
第一是方便为数据合理分配存储单元;
第二是规定了数据类型,就知道了其占用的字节数,从而也就规定了数据对象的取值范围及能够进行的运算;
第三是对参与表达式求值的数据对象可以进行合法性检查,比如浮点数就不能进行自加操作。
2. 表达式
表达式是程序语句的基本组成,体现了程序控制和数据改变的方法。表达式可分为前缀表达
式、中缀表达式与后缀表达式。
(1)中缀表达式
中缀表示法是日常通用的用法,但是在程序语言中使用中缀表示法会产生以下问题:
- 由于中缀表示法仅适合于二元操作符,一种语言不能只使用中缀表示法,而必须结合中缀与前缀表示法,但这种混合使用会使翻译过程相对复杂。
- 当一个以上的中缀操作符出现在表达式中时,如果不使用括号就有可能产生二义性。
(2)前缀表达式(波兰式)
在前缀表达式中,是以从左到右的顺序先写操作符后写操作数,如果操作数本身是一个具有操作数的操作,则对其使用同样的规则。例如,公式(a+b)*(a-b),使用前缀表达式表示将变为 * + a b– a b。函数调用可以看做一种前缀表达式,因为一般是把操作符函数名写在它的参数的左边,像f(a,b)这样。
以前缀表示的表达式可以在一次扫描后计算出值,前提是要明确知道每个操作符的参数的数
目。用以下的算法通过使用一个执行栈,计算给定的前缀表达式P。
如果P的下一项是一个操作符,将它压入栈,并把参数计数器设置为该操作符所需要的参数的数目n。
如果P的下一项是一个操作数,把它压入栈。
如果栈顶操作数的个数为n,则把操作符作用于这n个操作数,得出的结果替换该操作符和它所有的参数,作为操作数压入栈。
前缀表达式的计算方法意味着在每个操作数压入栈后都必须检查操作数的数目是否满足近栈顶的操作符的要求,而后缀表达式就无需做这种检查。
(3)后缀表达式(逆波兰式)
后缀表示法类似于前缀表示法,不同之处在于操作符跟在操作数之后。前面的公式使用后缀表示法时表示为“ a b + a b– * ” 。由于这一点不同,在计算后缀表达式的时候,当扫描到操作符时,栈中已压入了它的操作数。因此计算后缀表达式的算法如下。
如果P的下一项是操作数,将它压入栈。
如果P的下一项是n元操作符(即需要参数个数为n的操作符),那么它的参数就是栈顶的n项,把该操作符作用于这n项,得到的结果作为操作数替代栈顶的n项。
由于后缀表达式的计算是直接的,并且易于实现,因此它是很多翻译器产生表达式代码的基
础。
在考试中,通常形式是给出一个表达式的中缀表达形式(或前缀、后缀),再将其转换为前缀或后缀表达形式。
3.程序调用的实现机制
在过程式程序设计语言中,我们通常将程序看做层次结构:从主程序开始执行,然后进入各层次的过程执行,后返回主程序,而过程通常有四个要素。
当用户调用一个过程时,就将通过参数来传递信息。形式参数就是过程定义中用于命名所传递的数据或其他信息的标识符(即过程定义中函数名后括号中所带的参数);而实际参数是在调用点表示向被调用过程传递的数据或其他信息的表达式。多数语言中,形参与实参的对应关系是按位置来进行的,因此在调用时,实参的个数、类型与顺序应该与形参一致。常见的参数传递方式有两种:传值与引用(传址)两种调用方式。
传递方式 | 主要特点 |
---|---|
传值调用 | 形参取的是实参的值,形参的改变不会导致调用点所传的实参的值发生改变 |
传址调用 | 形参取的是实参的地址,即相当于实参存储单元的地址引用,因此其值的改变同时就改变了实参的值 |
在函数调用时,数据传递的方向是从实参到形参。只是采用传值传递方式时,传递的是数值,
这个数值只要是确定的即可,可以是常理、变量或表达式等。而采用传址传递方式时,传递的是地址,因此实参必须有地址。
注:传值调用中,形参取的是实参的值,形参的改变不会导致调用点所传的实参的值发生改变;而引用(传址)调用中,形参取的是实参的地址,即相当于实参存储单元的地址引用,因此其值的改变同时就改变了实参的值。
标签:语言,编译,程序处理,基础知识,程序语言,操作符,实参,自动机,表达式 来源: https://blog.csdn.net/qq_40791253/article/details/89278917