软件学报
JOURNAL OF SOFTWARE
1999年　第10卷　第9期　Vol.10　No.9　1999



用LR算法分析汉语的语法关系*
周会平　王挺　陈火旺
摘要　为了获取汉语词语之间的语法关系，以达到准确分析汉语的目的，文章给出了一种基于词组的扩充的LR分析方法.
关键词　机器翻译，依存文法，上下文无关文法，中间语言，LR算法.
中图法分类号　TP18
Using LR Algorithm to Analyze the Grammar Relations of Chinese
ZHOU Hui-ping,WANG Ting,CHEN Huo-wang
(Department of Computer Science Changsha Institute of Technology Changsha 410073)
Abstract　In order to obtain the grammar relations between the words in Chinese sentences and analyze Chinese correctly, the authors present an extended LR algorithm based on phrases in this paper.
Key words　Machine translation, dependency grammar, context-free grammar, interlingua, LR algorithm.
　　汉语是孤立语，语法现象非常灵活.例如，汉语的名词除了作主语和宾语外，还可以作谓语和定语.动词和形容词既可以作谓语、状语，也可以作主语、宾语.这种语言现象导致了一个句子可以包含多个谓词（动词和形容词），而且汉语的语法没有提供任何标志来描述它们之间的关系.因此，如何确定汉语句子中各词语之间的关系是汉语分析中一个非常令人头疼，也的确是非常困难的问题.
　　语法关系来源于依存文法中的依存关系，用于描述词语之间内在的联系.语法关系树和语义网之间也存在着比较简单的对应关系.我们采用一种扩充的LR算法来分析汉语词间的语法关系，目前,这种算法正应用于一个基于中间语言的汉英翻译系统(interlingua-based Chinese-English natural-language translation,简称ICENT)［1］中，并取得了比较满意的结果.
1　词间的语法关系
　　依存文法(dependency grammar)是由Tesniere［2］于1959年提出的一种语法理论.1965年,Gaifman［3］对它进行了形式化，并正式在语言学界提出来.依存文法直接描述单个词之间的关系，依存关系描述了中心词与修饰词、动词与施受对象之间的关系.如果用箭头表示依存关系，则句子“依存文法直接描述单个词之间的关系”的结构如图1所示.
　　从图1可以看出，“描述”是句子的中心词，直接依存于它的词有3个，其中，“文法”是它的主语，“关系”是宾语，“直接”是修饰词.直接依存于“文法”的词只有“依存”，是它的修饰词.

图1　句子“依存文法直接描述单个词
之间的关系”各词之间的依存关系
　　传统的依存文法只描述了词与词之间的依存关系，没有任何语法信息.直接用它来表示和分析汉语句子，其结果显得太粗，忽略了太多的信息.我们对它进行了改进，在其中加入一些语法功能函数来描述词之间的语法关系.我们将它写成
fA(X，A),
其中X,A是句子中的两个词法结构，函数fA描述X和A之间的语法关系，可以是sent, pred-obj, man-pred等值.这样,对句子“依存文法直接描述单个词之间的关系”就可以描述如下：
　　(1) att-obj（依存，文法）　(2) man-pred（直接，描述）　(3) quan-obj（单个，词）
　　(4) obj-dir（3，之间）　　 (5) obj-aux（4，的）　　　　(6) att-obj（5，关系）
　　(7) pred-obj（2，6）　　　 (8) agent-pred（1，7）　　　(9) end（8）
　　改进后的语法关系树清楚地描述了句子中各词语之间的关系以及它们在句子中的语法功能，使句子的框架一目了然.加入的语法功能函数和系统的中间语言结构对词汇的语法功能的描述是一一对应的，便于从语法关系的表示到中间语言结构的直接转换.ICENT通过适当改写上下文无关文法使系统在得到分析树的同时获得句子词间的语法关系. 
2　扩充的LR分析方法
　　LR算法原本是为程序语言设计的，它根据一张分析表的内容决定推理机下一步的动作：移进或者归约.分析表可以从一组上下文无关短语通过算法自动生成.传统的LR算法只能处理简单的上下文无关文法，对于分析表中的歧义无能为力.分析表的歧义是指,在分析表的某一项中同时包含移进和归约或包含多个归约动作.之后，Tomita［4］对基于上下文无关文法的LR分析算法进行了扩充，使它能够处理移进归约歧义,也就是在碰到移进归约歧义时，复制分析栈，让每个分析栈去完成分析表中的一个动作，保留多种可能性，生成多个结果.为了方便书写规则，ICENT的分析器对所使用的上下文无关文法没有任何限制，可以有左递归.例如，对于如下的一个包含歧义的文法，其分析如表1所示.
　　(1) START→S　　　(2) S→pron VP　　　(3) S→VP　　　　　(4) VP→verb S
　　(5) VP→LOC VP　　(6) VP→VP noun　　 (7) VP→verb aux　 (8) LOC→ noun direc
表1　歧义文法生成的分析表

移进归约表GOTO表
Statepronverbnounauxdirec#SVPLOC
0sh1sh2
sh3sh4　　　56
78
1　sh2
sh3sh4　　　　7
98
2　　　sh10　　　　　
3sh1sh2
sh3sh4　　　116
78
4　　　　sh12　　　　
5　　　　　acc　　　
6re3re3re3re3re3re3　　　
7　　sh13　　　　　　
8　sh2
sh3sh4　　　　7
148
9re2re2re2re2re2re2　　　
10re7re7re7re7re7re7　　　
11re4re4re4re4re4re4　　　
12re8re8re8re8re8re8　　　
13re6re6re6re6re6re6　　　
14re5re5re5re5re5re5　　　

　　在表1中，状态1碰上动词时就会产生移进歧义.这时，系统将原来的分析栈一分为二，分别保留两种移进的中间结果.用这个分析表分析句子“他看见叶子上爬着蚜虫”,全部移进后的栈状态如下所示.
　　(1) 0―pron―1―verb―2―×
　　(2) 0―pron―1―verb―3―LOC―8―VP―7―noun―13
　　(3) 0―pron―1―VP―7―noun―13
　　(4) 0―S―5―×
　　(5) 0―pron―1―verb―3―VP―7―noun―13
　　(6) 0―pron―1―verb―3―LOC―8―verb―3―×
　　从以上分析过程可以看出，先后5次碰到移进归约歧义，5次对栈进行了复制，共生成了6个分析结果，但其中的3个栈(1，4，6)由于出错而夭折.ICENT采用这种扩充的LR分析方法进行汉语分析以获取多个分析结果，保留汉语句子的歧义性. 
3　通过LR算法获取句子的语法关系
　　LR分析方法只保留了句子中词语之间的层次关系，而没有足够可用的语法信息.例如，两个名词可以归约成一个名词词组，这部分工作LR分析方法可以完成.但在分析汉语句子结构时，我们更需要了解这两个名词之间的语法关系，是偏正还是并列关系.若没有词语之间的语法信息，对句子的分析是不可能的.因此，我们将上下文无关文法、语法关系和LR分析方法结合起来，在获取句子分析树的同时获取句子词语之间的语法关系.
　　要在文法中描述词语之间的语法关系，文法的结构就不能太复杂.ICENT文法规则的形式都是描述两个词法单位之间的关系，如Nounyword→adj noun，这样组成Nounyword的两个词法单位adj和noun之间的关系就很容易描述.但使用这种简单的文法规则必然会导致分析的歧义性非常大，如果任由分析器在分析的过程中不断地产生新的栈，对于一些复杂的句子就会生成相当多的分析树，并有可能产生组合爆炸.因此，系统必须提供一些机制去阻止一些错误分析树的产生.
　　ICENT采用上下文无关文法的形式，并对它进行了扩充，其文法形式是一个六元式
G=(VT,VN,VD,VF,S,Ψ)，
其中VT是终结符集合，是一个非空有限集；VN是非终结符集合，是一个非空有限集，并有VT∩VN=；VD是语法关系集合，是一个非空有限集；VF是布尔函数集合，是一个非空有限集，有accept∈VF；S是开始符号，S∈VN ；Ψ是一个产生式集合，每个产生式的形式是P→〈α,β,γ〉，其中P∈VN，α∈(VT∪VN)+，β∈VD，γ∈VF.β描述了α中各成员之间的语法关系，γ是产生式的约束函数，只有当分析器的当前状态满足该函数时，产生式才是有效的，才能使用该产生式进行归约.
　　ICENT使用算法根据产生式集自动生成了4张表格，第1张是移进归约表格，描述了推理机在当前状态面对下一个终结符要做的动作，是将该终结符移进还是对当前栈顶的元素进行归约，这是一个含歧义的表格，一栏中可以含有多个移进归约动作，推理机通过栈复制来处理分析表的歧义.第2张是GOTO表格，它描述了推理机在当前状态面对当前终结符或非终结符所要进入的下一个状态.这也是一个含歧义的表格，有的状态在面对某些非终结符时可能有多个不同的新状态选择.推理机也是通过栈复制的方式来处理GOTO表的歧义.第3张是规则语法属性表，它描述了推理机在使用某一条规则进行归约时，被归约的各元素之间的语法关系.一条规则可以有多种语法关系，如名词之间的并列和修饰关系.同一条规则如果存在多种不同的语法关系，在系统中就表现为多条不同的规则，并在移进归约表格和规则语法属性表中有多个不同的入口.如规则NP→〈noun noun,and-noun,NULL〉和NP→〈noun noun,att-obj,NULL〉,虽然都是从两个名词归约成一个名词词组，但由于它们的语法属性不同，在ICENT里就是两条不同的规则.第4张表是约束函数表，移进归约表中的每一个归约动作都要满足一定的前提条件才会有效.这些前提条件体现在约束函数表中的函数（函数可以为空，空函数返回真），系统可以任意设置这些函数来调整推理机的动作，阻止对错误分析树的继续分析.
4　例 子
　　本节给出了一个使用LR分析方法来分析扩充后的上下文无关文法来获取汉语句子词语间语法关系的实例.使用的文法由第2节中的歧义文法扩充而来，如下所示.
　　(1) START → 〈S,end,accept〉　 　 　　　(2) S → 〈pron VP,agent-pred,subpron〉
　　(3) S → 〈VP,sent,nosub〉　　　　　　　 (4) VP → 〈verb S,pred-obj,takesent〉
　　(5) VP → 〈LOC VP,loc-pred,NULL〉　　　 (6) VP → 〈VP noun,pred-obj,verbobj〉
　　(7) VP → 〈verb aux,pred-aux,auxfverb〉 (8) LOC→ 〈noun direc,obj-dir,NULL〉
其中语法关系中的end表示分析结束，得到分析树；agent-pred描述被归约的两个元素是主语和谓词结构之间的关系；pred-obj描述谓词结构与宾语之间的关系；loc-pred描述地点状语与谓词结构的关系；obj-dir描述方位词组中中心词与方位词之间的关系.规则里的函数都是系统自定义的，它定义了使用该规则的前提条件，如函数accept给出了接受一个句子的前提条件，只有当它被满足时，非终结符S才能被归约成START.下面是系统使用图5中的文法对句子“他看见叶子上爬着蚜虫”的归约过程.
　　开始系统的栈顶状态初始化为0，表示分析开始.系统的当前词是“他”，词性是pron，推理机的动作是移进，并且从GOTO表中查到当状态0遇到终结符pron时，转入新状态1.移进“他”后的栈状态为：
　　Next Word=“看见”　　(1) 0 - pron - 1
　　推理机的动作和传统LR分析器基本相同，状态1遇动词移进，但在GOTO表中查找要转入的新状态时存在歧义，表中给出了两个状态，分别是2和3.系统对栈进行复制：
　　Next Word=“叶子”　　(1) 0 - pron - 1 - verb - 2
　　　　　　　　　　　　　(2) 0 - pron - 1 - verb - 3
　　第1个栈遇到名词“叶子”时出错，被抛弃，则有：
　　Next Word=“上”　　(1) 0 - pron - 1 - verb - 3 - noun - 4
　　移进“上”和状态12：
　　Next Word=“爬”　　(1) 0 - pron - 1 - verb - 3 - noun - 4 - direc - 12
　　状态12在当前词是动词时使用规则8来归约，系统首先查询规则8的约束函数，为NULL，返回真.规则8的语法关系属性是obj-dir，在归约的同时，系统记录了被归约的各语法结构之间的语法关系：
　　Next Word=“爬”　　(1) 0 - pron -1 - verb - 3 - LOC - 8
　　　　　　　　　　　　　　　　(1) obj-dir（叶子，上）
　　移进“爬”时出现歧义，分别转入状态2和3：
　　Next Word=“着”　　(1) 0 - pron -1 - verb - 3 - LOC - 8 - verb - 2
　　　　　　　　　　　　　　　　(1) obj-dir（叶子，上）
　　　　　　　　　　　　(2) 0 - pron -1 - verb - 3 - LOC - 8 - verb - 3
　　　　　　　　　　　　　　　　语法关系同(1)
　　移进“着”时，第2棵分析树出错，被抛弃：
　　Next Word=“蚜虫”　　(1) 0 - pron -1 - verb - 3 - LOC - 8 - verb - 2 - aux -10
　　　　　　　　　　　　　　　　　(1) obj-dir（叶子，上）
　　状态10在遇到名词时，要用规则7进行归约.系统调用规则7的约束函数auxfverb检查动词“爬”和助词“着”的语法属性，如果它们能组成一个谓词结构，则返回真.归约的同时记录词语之间的语法关系，归约后查询GOTO表出现歧义，分别转入状态7和14：
　　Next Word=“蚜虫”　　(1) 0 - pron -1 - verb - 3 - LOC - 8 - VP - 7
　　　　　　　　　　　　　　　　　(1) obj-dir（叶子，上）
　　　　　　　　　　　　　　　　　(2) pred-aux（爬，着）
　　　　　　　　　　　　　(2) 0 - pron -1 - verb - 3 - LOC - 8 - VP - 14
　　　　　　　　　　　　　　　　　语法关系同(1)
　　状态7在当前词是名词时移进，移进后句子结束，当前词是结束符“＄”.状态14在当前词是名词时归约，归约时约束函数为NULL，之后分别转入状态6和7：
　　Next Word=$　　(1) 0 - pron -1 - verb - 3 - LOC - 8 - VP - 7 - noun - 13
　　　　　　　　　　　　　　(1) obj-dir（叶子，上）
　　　　　　　　　　　　　　(2) pred-aux（爬，着）
　　Next Word=“蚜虫”　　(2) 0 - pron -1 - verb - 3 - VP - 6
　　　　　　　　　　　　　　　　　(1) obj-dir（叶子，上）
　　　　　　　　　　　　　　　　　(2) pred-aux（爬，着）
　　　　　　　　　　　　　　　　　(3) loc-pred（1，2）
　　Next Word=“蚜虫”　　(3) 0 - pron -1 - verb - 3 - VP - 7
　　　　　　　　　　　　　　　　　语法关系同(2)
　　下一步，第1个栈的动作是用规则6进行归约，约束函数是verbobj，归约后状态是7和14.第2个栈的动作是用规则3归约，约束函数是nosub，它检查当前谓词结构是否适合归约成句子结构，结果为假，被抛弃.第3个栈的动作是移进：
　　Next Word=$　　(1) 0 - pron -1 - verb - 3 - LOC - 8 - VP - 7
　　　　　　　　　　　　　　(1) obj-dir（叶子，上）
　　　　　　　　　　　　　　(2) pred-aux（爬，着）
　　　　　　　　　　　　　　(3) pred-obj（2，蚜虫）
　　Next Word=$　　(2) 0 - pron -1 - verb - 3 - LOC - 8 - VP - 14
　　　　　　　　　　　　　　语法关系同(1)
　　Next Word=$　　(3) 0 - pron -1 - verb - 3 - VP - 7 - noun -13
　　　　　　　　　　　　　　语法关系同(1)
　　下一步，第1个栈出错，后两个栈分别用规则5、6进行归约，之后都产生歧义，分别转入状态6和7：
　　Next Word=$　　(1) 0 - pron -1 - verb - 3 - VP - 6
　　　　　　　　　　　　　　(1) obj-dir（叶子，上）
　　　　　　　　　　　　　　(2) pred-aux（爬，着）
　　　　　　　　　　　　　　(3) pred-obj（2，蚜虫）
　　　　　　　　　　　　　　(4) loc-pred（1，3）
　　Next Word=$　　(2) 0 - pron -1 - verb - 3 - VP - 7
　　　　　　　　　　　　　　语法关系同(1)
　　Next Word=$　　(3) 0 - pron -1 - verb - 3 - VP - 6
　　　　　　　　　　　　　　(1) obj-dir（叶子，上）
　　　　　　　　　　　　　　(2) pred-aux（爬，着）
　　　　　　　　　　　　　　(3) loc-pred（1，2）
　　　　　　　　　　　　　　(4) pred-obj（3，蚜虫）
　　Next Word=$　　(4) 0 - pron -1 - verb - 3 - VP - 7
　　　　　　　　　　　　　　语法关系同(3)
　　下一步，第2、4个栈出错，第1、3个栈用规则3归约，然后转入状态11：
　　Next Word=$　　(1) 0 - pron -1 - verb - 3 - S - 11
　　　　　　　　　　　　　　(1) obj-dir（叶子，上）
　　　　　　　　　　　　　　(2) pred-aux（爬，着）
　　　　　　　　　　　　　　(3) pred-obj（2，蚜虫）
　　　　　　　　　　　　　　(4) loc-pred（1，3）
　　　　　　　　　　　　　　(5) sent（4）
　　Next Word=$　　(2) 0 - pron -1 - verb - 3 - S - 11
　　　　　　　　　　　　　　(1) obj-dir（叶子，上）
　　　　　　　　　　　　　　(2) pred-aux（爬，着）
　　　　　　　　　　　　　　(3) loc-pred（1，2）
　　　　　　　　　　　　　　(4) pred-obj（3，蚜虫）
　　　　　　　　　　　　　　(5) sent（4）
　　下一步，两个栈的动作都是用规则4归约，约束函数takesent判断动词结构能否带宾语从句，归约后都产生歧义，分别转入状态7和9：
　　Next Word=$　　(1) 0 - pron -1 - VP - 7
　　　　　　　　　　　　　　(1) obj-dir（叶子，上）
　　　　　　　　　　　　　　(2) pred-aux（爬，着）
　　　　　　　　　　　　　　(3) pred-obj（2，蚜虫）
　　　　　　　　　　　　　　(4) loc-pred（1，3）
　　　　　　　　　　　　　　(5) sent（4）
　　　　　　　　　　　　　　(6) pred-obj（看见，5）
　　Next Word=$　　(2) 0 - pron -1 - VP - 9
　　　　　　　　　　　　　　语法关系同(1)
　　Next Word=$　　(3) 0 - pron -1 - VP - 7
　　　　　　　　　　　　　　(1) obj-dir（叶子，上）
　　　　　　　　　　　　　　(2) pred-aux（爬，着）
　　　　　　　　　　　　　　(3) loc-pred（1，2）
　　　　　　　　　　　　　　(4) pred-obj（3，蚜虫）
　　　　　　　　　　　　　　(5) sent（4）
　　　　　　　　　　　　　　(6) pred-obj（看见，5）
　　Next Word=$　　(4) 0 - pron -1 - VP - 9
　　　　　　　　　　　　　　语法关系同(3)
　　下一步，第1、3个栈出错，第2、4个栈用规则2归约.约束函数subpron判断代词“他”能否作主语，能则返回真.
　　Next Word=$　　(1) 0 - S - 5
　　　　　　　　　　　　　　(1) obj-dir（叶子，上）
　　　　　　　　　　　　　　(2) pred-aux（爬，着）
　　　　　　　　　　　　　　(3) pred-obj（2，蚜虫）
　　　　　　　　　　　　　　(4) loc-pred（1，3）
　　　　　　　　　　　　　　(5) sent（4）
　　　　　　　　　　　　　　(6) pred-obj（看见，5）
　　　　　　　　　　　　　　(7) agent-pred（他，6）
　　Next Word=$　　(2) 0 - S - 5
　　　　　　　　　　　　　　(1) obj-dir（叶子，上）
　　　　　　　　　　　　　　(2) pred-aux（爬，着）
　　　　　　　　　　　　　　(3) loc-pred（1，2）
　　　　　　　　　　　　　　(4) pred-obj（3，蚜虫）
　　　　　　　　　　　　　　(5) sent（4）
　　　　　　　　　　　　　　(6) pred-obj（看见，5）
　　　　　　　　　　　　　　(7) agent-pred（他，6）
　　最后，两个栈都用规则1进行归约，约束函数accept接受两个栈为成功的分析树：
　　Next Word=$　　(1) 0 - Start
　　　　　　　　　　　　　　(1) obj-dir（叶子，上）
　　　　　　　　　　　　　　(2) pred-aux（爬，着）
　　　　　　　　　　　　　　(3) pred-obj（2，蚜虫）
　　　　　　　　　　　　　　(4) loc-pred（1，3）
　　　　　　　　　　　　　　(5) sent（4）
　　　　　　　　　　　　　　(6) pred-obj（看见，5）
　　　　　　　　　　　　　　(7) agent-pred（他，6）
　　　　　　　　　　　　　　(8) end（7）
　　Next Word=$　　(2) 0 - Start
　　　　　　　　　　　　　　(1) obj-dir（叶子，上）
　　　　　　　　　　　　　　(2) pred-aux（爬，着）
　　　　　　　　　　　　　　(3) loc-pred（1，2）
　　　　　　　　　　　　　　(4) pred-obj（3，蚜虫）
　　　　　　　　　　　　　　(5) sent（4）
　　　　　　　　　　　　　　(6) pred-obj（看见，5）
　　　　　　　　　　　　　　(7) agent-pred（他，6）
　　　　　　　　　　　　　　(8) end（7）
　　至此，系统得到了两个正确的分析树，并同时获得了形成两棵树时句子中词语之间的语法关系，它们正是明确一个汉语句子的结构所不可缺少的信息.
5　结　论
　　本文扩充了传统的上下文无关文法，使它能描述汉语词语之间的语法关系，从而使汉语句子的结构一目了然，所生成的每一个句子的中间语言表示结构都不再存在语义和语法上的歧义.系统还在文法中加入约束函数来调整推理机的动作，使系统尽早抛弃一些错误的生成树，减少系统不必要的开销，同时也减少了生成中间语言的歧义.目前，该方法正应用于ICENT系统，并取得了较为理想的结果.
*　本文研究得到国家自然科学基金和国家863高科技项目基金资助.
本文通讯联系人：周会平，长沙410073，长沙工学院计算机系
作者简介：周会平，1972年生，博士生，主要研究领域为人工智能，机器翻译.
　　　　　王挺，1970年生，博士，讲师，主要研究领域为计算语言学，机器翻译.
　　　　　陈火旺，1936年生，教授，博士生导师，中国工程院院士，主要研究领域为人工智能，计算机软件.
作者单位：长沙工学院计算机系　长沙　410073
参考文献：
［1］周会平等.一个基于中间语言的汉英机译系统.计算机科学，1998,25(5):51～55
(Zhou Hui-ping et al. An interlingua-based Chinese-English machine translation system. Computer Science, 1998,25(5):51～55)
［2］Tesniere L. Element de Syntaxe Structurals. Paris: Klincksieck, 1959
［3］Gaifman H. Dependency systems and phrase-structure systems. Information and Control 8, 1965,6(2):303～337
［4］Masaru Tomita. An efficient augmented-context-free parsing algorithm. Computational Linguistics, 1987,13(1～2):31～46
收稿日期：1998-07-18，修改日期：1998-10-09
