为什么语法分析不能只看 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 是否真的足以支持相同的语法分析。