為什麼語法分析不能只看 Pattern,而忽略 Semantic?

在語法分析中,Pattern(形式模式)可以幫助我們辨認可能存在的結構。然而,表面形式上的相似,並不足以證明兩個語言表達具有相同的句法結構。

一個 Pattern 首先只能提供一個 Candidate Parse(候選句法分析)。

例如,對於:

A + B + C
A + [B + C]
B 和 C 是否真的構成一個 Constituent(句法成分)?
B 和 C 之間存在什麼句法關係?
它們之間存在什麼語義關係?
C 所陳述的對象究竟是 B,
還是其他成分?

如果這些問題尚未得到解決,那麼 [B + C]仍然只是一個候選結構。

這正是 Semantic Analysis(語義分析)在語法分析中具有重要作用的原因。

1. Pattern 可以辨認形式,但不能自行證明結構

假設我們已知一種結構:

A + [B + C]
X + Y + Z
X + [Y + Z]
Relation(Y, Z)
=
Relation(B, C)

兩個表達可以具有相似的表面形式,卻在以下方面存在差異:

Constituency(成分關係)

Syntactic Relations(句法關係)

Semantic Roles(語義角色)

  • Semantic Relations(語義關係)

因此:

Same Surface Pattern
≠
Same Structure

Pattern 的作用是幫助我們提出可能的分析,而不是直接證明結構。

2. 從 Compiler 看:Parser 接受,不代表程式已經有效

在 Compiler(編譯器)中,結構與語義之間的區別非常明確。

考慮一個假設的表達式:

"hello" - 5
Expression
→ Expression "-" Expression

那麼 Parser(語法分析器)仍然可能成功建立一棵 Abstract Syntax Tree – AST(抽象語法樹):

Subtract
├── String("hello")
└── Integer(5)

在句法層面,結構已經建立:

Operator: -
Left: String("hello")
Right: Integer(5)

但分析並沒有結束。

接下來,Semantic Analysis(語義分析)與 Type Checking(型別檢查)還需要判斷這些成分是否滿足運算符的限制。

假設 -只接受數值:

Subtract(Number, Number) → Number
Subtract(String, Integer)
Tokens
↓
Parser
↓
AST
↓
Semantic Analysis
↓
Type Checking
↓
Valid / Invalid

因此:

Syntactically Constructible
≠
Semantically Valid

3. 為什麼這種對照對自然語言分析有用?

自然語言不是程式語言,也不存在一套由規格文件完整定義的 Type System(型別系統)。

但是,兩者共享一個方法論上的問題:

從一串線性排列的單位中,判斷哪些成分彼此組合,以及它們之間存在什麼關係。

一個自然語言句子可能存在多個 Candidate Parses(候選句法分析):

Input
│
├── Parse A
│
├── Parse B
│
└── Parse C

某一個 Parse 符合已知 Pattern,只能說明:

我們有理由考慮這種分析。

它不能直接證明:

這就是句子的實際結構。

還需要繼續檢查:

Constituency
↓
Syntactic Relations
↓
Semantic Relations

尤其當某種層次分析會遺失或改變句子的重要語義關係時,就有理由重新檢查該分析。

4. 一個例子:我送他回國

考察:

我送他回國。
他 + 回國
他回國。
我 + 送 + [他回國]
Subject
├── 我
└── Predicate
├── Verb: 送
└── Object: 他回國

從純粹的表面形式來看,這種分析似乎具有一定可能性。

但是,考察句子的 Semantic Relations,就會發現問題。

5. 「送誰?」與「誰回國?」

可以分別檢查兩個關係。

送誰?

送誰?
→ 他

第一個語義關係是:

送(我, 他)
我 = 施事
他 = 與「送」直接相關的對象

誰回國?

誰回國?
→ 他

第二個關係是:

回國(他)
送(我, 他回國)
送(我, 他)
回國(他)

也就是:

送
├── 我
└── 他
│
└── 回國

他同時參與兩個關係。

6. 兼語:一個成分同時參與兩個關係

在傳統漢語語法分析中,這類現象涉及兼語(pivot)。

可以表示為:

我送他回國
│ │ │ │
│ │ │ └── Predicate
│ │ └──── 兼語
│ └─────── Verb
└───────── Subject

關鍵在於他:

他
/ \
/ \
ObjectOf SubjectOf
↓ ↓
送 回國

進一步表示:

Sentence
├── Subject: 我
└── Predicate
├── Verb: 送
├── 兼語: 他
│ ├── ObjectOf → 送
│ └── SubjectOf → 回國
└── Predicate: 回國

他一方面與送發生關係,另一方面又與回國形成主體—陳述關係。

這正是「兼語」分析試圖描述的核心現象。

這裡最重要的並不是是否一定要採用「兼語」這個術語,而是:

一個句法分析必須能夠保存並解釋句中實際存在的重要關係。

7. 為什麼 [他回國] 還不足以解釋整個句子?

在:

他回國。
他 + 回國
我送他回國。
我 + 送 + [他回國]
送誰?
→ 他

這一關係。

因此:

Possible Constituent
≠
Correct Constituent in Every Context

一個詞語序列能在環境 A 中形成某個句法成分,並不代表它在環境 B 中必然具有相同的結構。

8. Semantic Relations 可以限制 Candidate Parse

分析過程可以表示為:

Input
↓
Pattern Recognition
↓
Candidate Parse
↓
Constituency
↓
Syntactic Relations
↓
Semantic Relations
↓
Interpretation

假設 Candidate Parse 提出:

Relation(A, C)
Relation(B, D)

或者 [A + B]中的某個成分仍然與該 constituent 外部的成分存在直接而重要的依存關係,那麼就需要重新檢查:

  • constituent boundary(成分邊界);
  • 結構類型;
  • dependency(依存關係);
  • 或正在使用的分析模型。

Semantic 並不取代 Syntax(句法)。

更準確地說:

Semantic Relations 可以對相互競爭的 Candidate Parses 形成限制,並提供選擇分析的證據。

9. Semantic Constraints 與 Type Constraints

在這裡,可以進一步與電腦科學中的型別系統進行對照。

在具有型別的程式語言中:

Function : InputType → OutputType
sqrtNumber → Number
sqrt(25)
sqrt("hello")
重要(Event / Proposition) ✓
好聽(Auditory Entity) ✓
PredicateX
Number - Number
String - Number
Semantic Mismatch
INVALID
Semantic Mismatch
↓
Context / Coercion / Metonymy
↓
Alternative Interpretation

這是 Compiler 類比最重要的限制之一。

11. Semantic 也不能取代 Syntax

Pattern 不充分,並不意味著可以完全拋開 Syntax,只根據語義判斷句法結構。

一句話「能夠理解」,不能證明任何一種層次分析都是正確的。

從某個:

Meaning M
Meaning M
→
Structure X

除非還存在相應的結構證據。

完整的分析需要同時考慮:

Surface Evidence
+
Structural Evidence
+
Syntactic Relations
+
Semantic Relations

因此,更合適的關係是:

Syntax ↔ Semantics
Syntax → Semantics only
Semantics → Syntax only
我送他回國。
送(我, 他)
回國(他)

一個完整的分析必須能解釋這兩個關係。

如果某個 Parse 只能解釋:

回國(他)
送(我, 他)
送(我, 他)
Candidate Parse
↓
Preserve Syntactic Relations?
↓
Preserve Semantic Relations?
↓
Explain the Interpretation?

13. Pattern 仍然非常重要

指出 Pattern 不充分,並不等於否定 Pattern 的價值。

Pattern 可以用來:

  • 辨認可能存在的結構;
  • 搜尋相似語料;
  • 建立 Candidate Parse;
  • 歸納語法規則;
  • 發現異常形式;
  • 比較不同結構在 Corpus(語料庫)中的分布。

在 Compiler 中,Grammar Rule(語法規則)同樣極為重要。

沒有 Grammar,Parser 甚至不知道應該建立什麼結構。

但是:

Grammar
↓
Parse

並不是整個分析流程。

同樣,在自然語言分析中:

Pattern
↓
Candidate Structure

也只是分析的一個階段。

真正的問題出現在:

Pattern = Proof
Pattern
=
Evidence for a Candidate Analysis

14. 從 Pattern Matching 到 Grammatical Analysis

整個過程可以概括為:

Linguistic Data
↓
Pattern Recognition
↓
Candidate Structures
↓
Hierarchical Analysis
↓
Syntactic Relations
↓
Semantic Relations
↓
Context / Prosody
↓
Grammatical Analysis

這並不意味著自然語言分析必須像 Compiler 一樣嚴格按照這一順序執行。

它是一個方法論模型,而不是自然語言的正式演算法。

它的主要作用,是避免一種過快的推論:

我以前看過這個 Pattern
↓
所以我已經知道這句話的結構

更合理的推論是:

我以前看過這個 Pattern
↓
所以我得到了一個 Candidate Parse
↓
現在需要檢驗它

15. 三個必須區分的命題

整個問題可以濃縮為三個命題。

Pattern ≠ Structure

Pattern ≠ Structure
Structure ≠ Semantic Validity
Possible Parse ≠ Established Analysis
Source
↓
Lexer
↓
Tokens
↓
Parser
↓
AST
↓
Semantic Analysis
↓
Type Checking

自然語言並不存在一條與之完全相同的固定 Pipeline(處理流程)。

但這種分層思維仍然具有方法論價值:

Utterance
↓
Units
↓
Patterns
↓
Candidate Structures
↓
Syntactic Relations
↓
Semantic Relations
↓
Interpretation

兩者的共同點不是:

自然語言的運作方式等同於程式語言。

而是:

一個形式結構還需要接受其內部關係的檢驗。

Compiler 使這個問題更加直觀:即使 AST 在句法上可以成功建立,如果 operand(運算元)的型別不符合 operator(運算符)的要求,Semantic Analysis 仍然可能拒絕它。

自然語言遠比這種情況靈活,但方法論上的問題仍然存在:

這棵樹可以建立。
但是這棵樹內部所表示的關係,
真的能夠解釋這句話嗎?

17. 結論

Pattern 是語法分析的重要工具。它能幫助我們辨認可能存在的結構,並產生可以進一步檢驗的 Candidate Parses。

但是:

Pattern
Structure
我送他回國。
他 + 回國
[他回國]
送(我, 他)
回國(他)

就會發現他同時與送和回國建立關係。

這正是理解兼語結構的關鍵,也說明為什麼表面 Pattern 不能取代關係分析。

更完整的分析過程應當是:

Pattern
↓
Candidate Structure
↓
Hierarchical Structure
↓
Syntactic Relations
↓
Semantic Relations
↓
Interpretation

因此:

Pattern ≠ Structure
Structure ≠ Semantic Validity
Possible Parse ≠ Established Analysis

下一篇將直接把這套方法應用到他學習很好與他唱歌很好聽。

問題將不再只是「這句話能不能說」,而是進一步檢查:學習與唱歌是否具有相同的句法性質、很好與很好聽究竟在語義上陳述哪一個成分,以及兩個表面上相似的 Pattern 是否真的足以支持相同的語法分析。