这个系列主要用来分享编译原理入门学习的一些总结。本文主要包括编译原理的概述部分,主要分为对编译过程的简要描述和编译原理入门的一些术语介绍。
1.编译原理概述
编译原理(Principle of Comompiler),实质就是把程序员员容易理解的高级语言程序代码流翻译成计算机可执行的机器指令代码流。当你输入一段编程语言(我们称为源语言),编译器会对它进行处理,变成计算机可执行的目标语言。
1.编译过程
把我们的源语言和平时表达的句子进行类比。对于源语言也好句子也好,我们需要知道的是这个语言或者这个句子想表达的意思,即语义。所以我们需要进行语义分析。语义分析之后,我们就可以将其转化为我们的目标语言,生成我们的目标语言句子。
对于一个句子,想搞明白这个句子说了什么,归根结底还是要知道句子的成分,这个时候就需要先确定句子里面每个词语的词性。这就是词法分析(Lexcial Analysis),之后需要识别出句子中的各类短语,也就是语法分析(Syntax Analysis),识别完短语之后我们就可以分析句子的意思了,这就是语义分析(Semantic Analysis)。这也就是对源语言进行分析的过程。
举个例子:比如句子:In the room, he broke a window with a hammer
所以什么是编译器(compiler)?
直接的说,编译器就是一种将程序从一种语言翻译到另一种语言的计算机程序。
词法分析的过程叫做scanning,目的是确定单词类型,确定好之后,就可以转换为token(词法单元)。token一般的形式为<种别码,属性值>。它的类型可以使关键字,标识符,常量,运算符,界限符(比如 ;,),( ,= ,} ,{ )等等。不同种类型会有不同的种别码,同种类型也可能不同比如关键字,每个关键字也会有不同的种别码。种别码是对词素(lexeme)进行分类并赋予其语法含义的编码。
语法分析的过程叫做parsing,其中用到的东西叫语法分析器(parser),这一步主要是从token中识别出各类的短语,并且构造出语法分析树(parse tree)。
接下来就是语义分析,这一步是收集标识符的属性信息,同时进行语义检查。中间表示形式有三地址码(Three-address code),分析可以生成语法结构树/语法树(syntax tree)。
2.编译原理中的一些术语
接下来我们介绍一些基本概念和一些术语。
词素(lexeme):
词素(Lexeme)是指源代码中具有独立意义的最小语法单位。它是由词法分析器(Lexer)生成的,用于构建语法分析树。词素通常与标记符(Token)对应,标记符是将词素分类并赋予语法含义的抽象表示。
词素可以是关键字(如"if"、"while")、标识符(如变量名)、操作符(如"+"、"=")、分隔符(如","、";")、常量(如整数、浮点数、字符串)等。词法分析器的任务是扫描源代码,将连续的字符序列组成一个个词素,并将其传递给语法分析器进行后续处理。
词法分析是编译过程的第一步,它将源代码转换为一系列词素,为后续的语法分析和语义分析提供基础。
空串:{ε}。
文法:用于描述和规定编程语言的语法结构,每一种语言都需要文法来描述,文法相当于语言学的语义分析,即分析每一句话所表示的含义,编译器需要利用文法来完成其语法分析和语义分析。
文法的形式化定义:G=(Vt,Vn,P,S)其中的V是vector。Vt即终结符集合,Vn是非终结符集合,P是产生式集合(比如α→β),S是开始符号。
请注意,Vt∩Vn=∅,Vn∪Vn=文法符号集
推导(Derivations)
规约(Reductions)
句型(sentential form)
句子(sentence)
这里需要指出的是,句子是不包括非终结符的句型。
二义性文法(Ambiguous Grammar):一个文法可以为某个句子生成多棵分析树。(这个时候我们就要设立消歧规则)
注意 对于二义性一般只有充分条件 即:有这个充分条件,可以推出无二义性,但是不满足这个条件也未必有二义性。
正则表达式:是一种用来描述正则语言的更紧凑的表示方法。注意正则表达式的优先级:
有穷自动机(Finite Automata):具有离散的输入信息和有穷数目的内部状态。两种主要的种类是DFA和NFA。
最长子串匹配原则:当输入串的多个前缀与一个或多个模式匹配时,总是选择最长的前缀进行匹配。
DFA(Deterministic finite automata)
NFA(Nondeterministic finite automata)
值得注意的是,每个DFA都有等价的NFA。
(下一部分有穷自动机:编译原理初级·新手村学习(二)-CSDN博客)