形式語言:現代工程師可以用程式語言、不需要用紙帶打洞來寫程式都要感謝它

科學

Written by:

《讓電腦讀懂你的話:形式語言》系列將為大家初探語言學,與後續引響電腦科學的重要理論──喬姆斯基的轉換生成語法。此為第四集。

 


電腦如何判讀高階語言?形式語言

如果你想要學編譯器的相關原理,必修形式語言的邏輯。

1950 年代的電腦程式都還是機器語言,也就是所有的指令只能用 0 與 1 的排列組合來表示,這使得寫程式、除錯、修改程式都相當浪費時間。

美國電腦科學家約翰·巴克斯(John Backus)當時在 IBM 工作,後來向老闆提出:應該開發比較接近人類語言的高階語言,更方便編程。

要怎麼讓電腦辨識人類的語言特性呢?

這就要用到形式語言啦!在數學、邏輯和電腦科學領域中,形式語言(Formal language)是用精確的數學或機器、可處理的公式定義的語言。

形式語言的研究始於 20 世紀初,而把形式語言用於模擬自然語言是 1950 年代左右。

當時,許多數理語言學家致力於用數學方法研究自然語言的結構,尤其是 1946 年第一台電腦 ENIAC 出現以後,人們很快想到能用電腦來作自然語言的機械翻譯。

可是這項工作在取得一些初步的成功以後便停滯不前,翻譯的質量很難提高,主要是因為當時對自然語言結構的理解太表面化。

1956 年,喬姆斯基發表了用形式語言方法研究自然語言的第一篇文章,稱為「轉換生成文法」。

轉換生成文法繼續發展喬姆斯基先前提出的普遍文法理論 (Universal Grammar)。喬姆斯基認為,若普遍文法是正確的話,人類的大腦應該能夠系統性地生產文法正確的字句。

因此他嘗試利用轉換生成文法,來描述生產正確文法字句的過程。

1957 年,IBM 的約翰.巴克斯等人發明了高階語言 Fortran 語言與編譯器。人們發現巴克斯使用的語法幾乎就是喬姆斯基發表的文法理論。

從而成了形式語言被廣泛應用於程式語言的濫觴,使程式語言設計成為現代電腦科學的一個重要分支。

在數學或電腦科學當中,形式語言就是「一個符號字串的集合、加上其所對應規則的集合。」

(In mathematics and computer science, a formal language is a set of strings of symbols together with a set of rules that are specific to it.)

所以我們在分析語言時,需要將語言以數學模型的抽象形式表達。比如機器翻譯、語音識別等,然後利用計算機去針對該數學模型求解。

來看看語言要如何用數學式來表達吧!

 

什麼是語言?字串所成的集合

a, b, 3, *, %, w, 0… 這些符號都叫做一個「符號」或「字元」。把字元集合起來可以變成「字串」,比如變成:abcde,這就叫「含有五個字元的字串」。

喬姆斯基對語言的定義方法是:給定一組符號(有限多個),稱為字母表,以 ∑ 表示之。

又以 ∑* 表示由 ∑ 中字母組成的所有字串的集合。則 ∑* 的每個子集都是 ∑ 上的一個語言。

例如,若令 ∑ 為 26 個字母加上空格和標點符號,則每個英語句子都是 ∑* 中的一個元素,所有合法的英語句子的集合是 ∑* 的一個子集,最後構成一個語言。

喬姆斯基的語言定義方法為人們所公認,一直沿用下來。

 

將上述理論以數學表達:

假設 ∑ 為一個有限的非空符號所成的集合,稱為符號集 (alphabet)。

∑ 的次方定義成:

  1. 1 = ∑
  2. n+1  = { xy | x ∈ ∑, y ∈ ∑n }

\sum^{n} 表示佈於 \sum 的 n 個符號或字母的串連 (concatenation) )

—舉例—

\sum = \left\{ 0, 1 \right\},則 \sum^{2} = \left\{ 00, 01, 10, 11 \right\}

\sum = \left\{ a, b, c, d \right\},則 \sum^{3} 包含的字串個數為 4^{3} = 64,例如 aaaa, abad, bcda 等皆為 \sum^{3} 的字串。

 

我們也可找到由一個符號集,來構成一個語言:

假設 \sum 為一個符號集,若 A \subseteq \sum^{*} 則稱 A 為佈於 \sum 的一個語言。( A is a language over \sum )

—舉例—

\sum = \left\{ a, b, c \right\}

  • L{1} = \left\{ a, ab, ac, bc, abc, acb, cab \right\}
  • L{2} = \left\{ abcba, bcbca \right\}
  • L{3} = \left\{  \right\}
  • L{4} = \left\{a^{i}cb^{i}  \mid i\geqslant 1 \right\}

L{1}, L{2}, L{3}, L{4} 均為佈於 \sum 的語言。

轉換生成文法:生成文法正確的語言

喬姆斯基提出了「轉換生成文法」(Transformational-Generative Grammar) 作為描述形式語言的方法。比如:

  • 語言 ɑ*, 意指包括了 a, aa, aaa, aaaa… 等至少包含一個 a 的字串。
  • 其文法為 {S → ɑ, S → ɑS}

這個文法由兩條規則所產生。

每一步轉換(推導),都用一條轉換規則的右邊、替換它的左邊。

S 是出發點,代表語言 ɑ 中任何一個可能的句子。

例如,句子 ɑɑɑɑɑ 可以這樣推導出來:S → ɑS → ɑɑS → ɑɑɑS → ɑɑɑɑS → ɑɑɑɑɑ。

推導共分五步。前四步用了第二條規則,第五步用了第一條規則。

按這個辦法,可以生成 ɑ* 中的所有句子,即整個 ɑ* 語言。

——A language could be generated by the grammar.

 

note: 文法四要素組成:起始, 非終端, 終端, 產生規則

嚴格來說,喬姆斯基將「轉換生成文法」定義為四個要素:

G 為一個文法,G = \left ( S, N, T, P \right )

(1) T 為終端符號(有限集合),表示不能再以其他符號代替

(2) N 為非終端符號,表示可以再以其他符號來替代。而 N 與 T 須具以下的關係:N∩T=φ

(3) S 為起始符號,表示文法推演之步驟由 S 開始,S ∈ N

(4) P 為文法產生規則的集合

(a) P 中的每個規則,具有 α → β 的形式。

(b) 其中 α ∈ (N U T)* – T*, β ∈ (N U T)*

(c) α ∈ (N U T)*-T*  代表 α 由非終端符號與終端符號所組成的任意長度之字串,但至少包含一個非終端符號。

(d)  β ∈ (N U T)* 代表由 β 非終端符號與終端符號所組成的任意長度之字串。

note: 文法 G 能用來生成語言 l(g)

G = \left ( S, N, T, P \right ) 為一個文法。

可由 S 推導出的所有字串、所成的集合,稱為 G 生成的語言 (Language generated by G),記作 L(G)。

數學式記為:L(G) = \left\{  \alpha \in T^{*} \mid S \overset{*}{\rightarrow} \alpha \right\}

 

文法的分類—喬姆斯基體系中的四型文法

根據 P 中的產生規則 a → β 的特點,可以將形式文法及其產生的形式語言分類,構成形式語言譜系,也被稱為「喬姆斯基譜系」。

在形式語言的理論中,主要研究四類型的文法、和其所生成的語言(也是現在電腦科學程式語言設計的重點研究項目):

 

假設 G = \left ( S, N, T, P \right ) 為一個文法:

(1) 0 型文法 (Type-0 Grammar)

每個推論規則 \alpha \rightarrow \beta 無任何限制。

(2) 1 型文法 (Type-1 Grammar)

與上下文有關文法 (Context-Sensitive Grammar),其文法產生規則必須滿足:

 α → β ∈ P,其中 |α| ≤ |β\

規定文法產生規則,左方的符號長度不得大於右方的符號長度

(3) 2 型文法 (Type-2 Grammar)

與上下文無關文法 (Context-Free Grammar),又稱為 BNF 文法。(Backus Normal Form,由開發 Fortan 語言的 John Backus 和 Peter Naur 首先引入、用來描述電腦語言語法的符號集)

文法產生規則必須滿足:

 α → β ∈ P,其中 α ∈ N,  β ∈ (N U T)* – {λ} (λ表示空字串)

規定文法產生規則,左方僅允許長度為 1 之非終端符號

因為 α 符號可以被 β 字串自由替換,而無需考慮 α 符號出現的上下文,故稱為與上下文無關。由於此語法良好的表達能力,幾乎所有程式語言的語法都是用此語法定義。

(4) 3 型文法 (Type-3 Grammar)

正規文法 (Regular Grammar)。

規定文法產生規則,左方僅允許長度為 1 之非終端符號右方僅允許長度為 1 之終端符號

也被應用為「正規表達式」,通常用來定義檢索模式。

 

從 Type-0 到 Type-3 的四種文法、依次擁有越來越嚴格的產生式規則,同時文法所能表達的語言也越來越少。

Type-0 文法必包含 Type-1、Type-2、Type-3;Type-1 文法必包含 Type-2 和 Type-3… 以此類推。

編譯器在編譯時,會對程式碼中的每一條敘述,按照先後順序均做一次之轉換處理、產生對應之目的碼。

這種轉換處理的工作,必須完全遵守該程式語言所規定的文法規則 (grammar rules)。

不同程式語言的文法規則是不相同的。若撰寫程式時違背了程式語言的文法規則,編譯時會發生文法錯誤之訊息。

 

如何讓電腦判斷一段字串是否屬於合法的句子?

給定一個字串,電腦需要判定這個字串,是否屬於我們給定的一個語法 G 、所產生的語言L(G) 。

也就是說,電腦需要判定一個字串是不是屬於這個集合。

在轉換生成語法理論中,一個句子要麼是「正確的」,要麼是「不正確的」。

換句話說,轉換生成語法的規則是一個算法,會對一個句子的合法度(符合語法 Syntax 的程度)進行判斷,但只會得出「是」或「否」的結果。

當我們在寫程式時遇到 Syntax Error 訊息,代表電腦判斷不過你這個句子屬於它看得懂得語言。

要做到這一步,是一個非常難解的問題。實際上涉及到語法分析的問題——給你一個句子,如果這個句子是屬於這個語言的句子的話,那麼你要給出它被構造而出的過程。

這個構造的過程,與我們在形式系統當中進行證明這是一樣的——假設這個命題是正確的,那你要用我一系列的公式、給出一個證明,說明命題是正確的。

同樣的,如果想判定這個句子是屬於這個語言的(命題是正確的),你也必須要給出一個構造的過程——如何用這個產生式一步一步地推出來(證明過程)。

這就叫識別和判定的過程。

一般來講,要讓機器要能判定喬姆斯基的各種類型語法,是一個難解的問題。

好消息是,科學家的確研究出了幾種不同的機器(事實上是數學模型),能拿來判定語言。但因為機器的能力依其強弱不同,所以能判斷的文法範圍也不同:

(1) Type-0 文法產生的語言,能被圖靈機 (Turing Machine) 所辨識

(2) Type 1 文法所產生的語言可被線性限制自動機 (Linear Bounded Automata) 辨識

(3) Type 2 文法所產生的語言可利用推壓自動機 (Push Down Automata) 辨識

(4) Type 3 文法所產生的語言可利用有限狀態自動機 (Finite State Automata) 辨識

規則越嚴越好判定,需要的機器能力越弱。所以「圖靈機」是裡面最強的機器。

由於 Type-3 語言(文法)、也就是正規表達語言,是一個最嚴謹的語言,因此它可以透過一個比較簡單的識別機器來進行判定,也就是上面提到的「有限狀態自動機」。

下一集開始,就讓我們來為大家介紹,什麼是有限狀態自動機吧:)

 

 


  • 後記補充

我們能使用文法來推導出語言,

並判斷一個字串是否屬於該語言:

G 為一個文法,G = \left ( S, N, T, P \right )

(1) S 為起始符號,S \in N

(2) N = \left\{ S, A \right\}

(3) T = \left\{ a, b\right\}

(4) P = \left\{ S \rightarrow bS, S \rightarrow aS, A \rightarrow bA, A \rightarrow b \right\}

找出此文法的語言 L(G) :

G 中 由 S 開始的推導過程為——

其中 n\geqslant 0, m\geqslant 1,所以由 G 所導出的語言為 L(G) = \left \{ b^{n}ab^{m-1} \mid n\geqslant 0, m\geqslant 1 \right \}

判斷:字串 bbabb 是否屬於這個語言?

推導過程:

S 可導出字串 bbabb,故屬於這個語言。

 

我們也可以設計一個文法,來生成所指定的語言。

設計一文法,能生成語言 L= \left \{ a^{i}b^{i}  \mid i, j \geq 1, i \neq j \right \}

設計過程:

假設 L{1} = \left \{ a^{i}b^{i} \mid i, j\geq 1, i > j \right \} , L{2} = \left \{ a^{i}b^{i} \mid i, j\geq 1, i <  j \right \}

G{1} = \left ( S, N{1}, T, P{1} \right ) 為生成 L{1} 的文法

T = \left\{ a, b\right\}, N = \left\{A, B \right\}

  • A 為起始符號,表示 a 出現的個數比 b 出現的個數至少多一個。
  • B 表示 a 出現的個數與 b 出現的個數相同。

因為 a 出現的個數比 b 出現的個數至少多一個可分成兩種情形,一種為剛好多一個、一種為至少多兩個。

  • 剛好多一個: A → aB
  • 至少多二個:A → aA

所以 P{1} 包含以下推論規則:

A → aA, A → aB, B → aBb, B → ab

令 G{2} = \left ( S, N{2}, T, P{2} \right ) 為生成 L{2} 的文法

T = \left\{ a, b \right\}, N = \left\{C, B \right\}

  • C 為起始符號,表示 a 出現的個數比 b 出現的個數至少少一個。
  • B 表示 a 出現的個數與 b 出現的個數相同。

a 出現的個數比 b 出現的個數至少少一個可分成:剛好少一個、至少少兩個,因此 P{2} 包含以下推論規則:

C → Bb, C → Cb, B → aBb, B → ab

欲求的生成語言 L = L{1} \cup L{2} ,其文法 G = \left ( S, N, T, P \right ) 。令:

  • N = N{1} \cup N{2}
  • P = P{1} \cup P{2} \cup \left\{ S \rightarrow A, S \rightarrow C \right\} 
    • P 包含下列推論規則:
    • S → A, A → aA, A → aB, B → aBb, B → ab, S → C, C → Cb, C → Bb

此即為生成語言 L 的文法 G。

One Reply to “形式語言:現代工程師可以用程式語言、不需要用紙帶打洞來寫程式都要感謝它”

  1. egg 說:

    你好,後記補充的地方有部份符號與敘述打錯:
    1. 設計一文法,能生成語言 L = { a^i b^j | i,j >=1, i != j} (b的長度是 j )
    2. 假設 L1 = …, L2 = … 同 1.
    3. 生成 L2 的文法 G2 的中文描述:
    「a 出現的個數比 b 出現的個數至少少一個可分成:剛好多一個、至少多兩個」應該是
    「a 出現的個數比 b 出現的個數至少少一個可分成:剛好少一個、至少少兩個」。

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *