<!--toc-->
自动机
文法
形式定义
对于一个文法G=(VT,VN,P,S),其中
句型与句子
对于文法中的一个产生式A→α,假如又有α=γBσ,B→β,那么可以有A→γβσ,那么A可以推导出γβσ,γβσ可以归约到A。
我们可以简记推导关系为
A⇒∗α,α∈(VT∪VN)∗,若A可以通过0步或多步推导出α
A⇒+α,α∈(VT∪VN)∗,若A可以通过1步或多步推导出α
A⇒nα,α∈(VT∪VN)∗,若A可以通过n步推导出α
对于一个文法G,S为其开始符号,那么假如有
S⇒∗α,α∈(VT∪VN)∗ 那么称α是G的一个句型,特别的,假如α完全由终结符号构成,即α∈VT∗,那么α是一个G的句子。
若对于一种程序语言L有一个文法G,那么使用该语言写成的所有程序都是该文法的句子,形式表示为:
L(G)={α∣S⇒+α∧α∈VT∗} 乔姆斯基谱系
当我们向文法中的产生式上施加限制,文法的表达能力将会下降,但解析将会更加容易。根据限制的不同,将文法大致分为以下几类:
0型文法:不对产生式施加任何限制
1型文法:上下文有关文法,需满足
∀α→β∈P,∣α∣≤∣β∣∨(α=S∧β=ϵ) 注意该文法允许产生式的左侧附带上下文信息。例如保证某个非终结符只有跟在某个终结符后时才能被翻译αA→...
2型文法:上下文无关文法(表示大部分语言的语法规则,即单词之间如何连接)
∀A→β∈P,A∈VN,β∈(VT∪VN)∗ 上下文无关文法要求产生式的左侧只有一个非终结符。
3型文法:正则文法(表示大部分语言的词法规则,即字符如何构成单词)
∀A→αB∈P,A,B∈VN∧α∈VT∗ 或者
∀A→Bα∈P,A,B∈VN∧α∈VT∗
FIRST与FOLLOW
对于一个上下文无关文法G,文法中每一条产生式P左侧的文法符号A∈AN都有一个FOLLOW集,代表可能跟在该文法符号后的所有终结符,右侧的每一个文法符号α∈(AN∪AT)∗都有一个FIRST集,集合中的元素是所有可能出现在该文法符号开头的终结符。
形式定义
FIRST集:
∀A→α∈P,FIRST(α)={a∣α⇒∗aβ,a∈VT} 特别的,当α⇒∗ϵ时,ϵ∈FIRST(α)
FOLLOW集:
∀A→α∈P,FOLLOW(A)=a∣α⇒∗aβ,a∈VT 自上而下分析
基本原理
例如文法(这里用_来代笔ϵ)
E -> aE | F
F -> bF
自上而下分析即以文法符号为根结点构建分析树,自根结点往下进行,使最终叶子结点对应的字符串符号连接起来恰好是输入字符串。
假设有输入流abbb,那么有最左推导(总是替换产生式最左边的文法符号)
abbb: E
bbb: E -> aE
bbb: E -> F
bb: F -> bF
b: F -> bF
: end
当输入流中的符号被耗尽时,解析完成,这暗示我们的算法最好能稳定的消耗输入流中的符号。
左递归消除
在一些坏情况下,我们可能会遇到下面的文法:
E -> E + E
E -> ident
这时我们的分析程序可能会重复运用第一条产生式,产生死循环。这种情况称为左递归,因此为了分析算法可以停机,我们需要进行左递归消除。
左递归消除的基本思想是将产生左递归的文法符号替换为一个必然会消耗输入的文法符号,在本例中,E可能以ident开头,因此可以将其替换为
E -> ident + E
在一些更复杂的情况下,例如:
P -> A
A -> AR
A -> ident
R -> [A]
可以看到A -> AR中右侧的A产生了左递归,可以看到A只以ident开始,而且后面跟着的都是R,对其进行推导,我们将会得到形如
A -> AR
-> ARR
-> ARRR
-> AR...R
因此我们可以将原式替换为
P -> A
A -> identA'
A' -> RA' | _
R -> [A]