上下文无关文法

1.上下文无关文法定义

  文法:它描述语言语法结构的一组形式规则。

   上下文无关文法:它定义的语法范畴(或语法单位)是完全独立于这种范畴可能出现的环境。例如,在程序设计语言中,当碰到一个算术表达式时,我们完全可以“就事论事”处理,而不必考虑它所处的上下文。然而,在自然语言中,随便一个词,甚至一个字的意思在不同的上下文中都有可能有不同的意思。幸运的是,当今的程序设计语言都是上下文无关的

。  

  好像有点抽象,来个例子

  

  "→"表示箭头左边的由箭头右边的定义

  把He gave me a book与上述规则进行对照,看其中的语法范畴是否处于适当的位置,如果你了解英语的话,你应该可以确认这是一个正确的句子。做科学研究都有一个过程从现象得出一般结论,再用实验验证这个一般性结论。有了这个语法规则我们可以造出很多这种英文句子(简单假设,英文语法远比这复杂)。如果我们要造一个句子表达我们自己的意思,利用这个规则,很容易。

  

    

  根据上述规则,句子无需考虑上下文,就可以判断正确性(符合<主语><谓语><间接宾语><直接宾语>的规则)。

  其中,He,me等为终结符号,<主语>、<谓语>、<间接宾语>等为非终结符号。

  这个文法最终要定义<句子>语法结构,所以<句子>在这里称为开始符号;<谓语>→<动词>这种书写形式称之为产生式。

  归纳一下:上下文无关语法G包括四个部分:一组终结符号,一组非终结符号,一个开始符号,以及一组产生式。

  说明一下:终结符号是组成语言不可再分的基本符号,在程序语言中就是保留字、标识符、常数等;非终结符号是一个给定的语法概念,是一个类(或集合)记号,而是不是某个个体记号;开始符号是一个特殊的非终结符号,是语言中我们最终想得到的字符串(在程序语言中,我们最终感兴趣的是“程序”这个语法范畴,其他的语法都是构造“程序”的基石);产生式(也称产生规则或者简称规则)是语法范畴的一种书写规则。 

  你想嘛,gave这个单词,拆分为一个个字母,就不再是gave了,没有什么特别的含义;而非终结符号就是诸如gave的动词的集合。

    额,有个细节好像忽略了,产生式的形式:

    A→α

    箭头左边是一个非终结符,称之为产生式的左部,箭头右边称之为右部。

    A是一个非终结符,α是由 非终结符号和终结符号的并集 的闭包 中的元素 组成的符号串

 

  形式化的上下文无关文法定义:

 一个四元数组G=(VN,VT,S,P)

    VN:非空有限的非终结符集合

    VT:非空有限的终结符集

    S:开始符号

    P:产生式集合

    其中,VN∩VT=∅,S∈VN

    P中产生式一般形式为A→α|β,其中A∈VN,α,β∈(VN∪VT)*

 

  通常用大写字母表示非终结符,小写字母表示终结符,α、β、γ等代表由 终结符和非终结符号的并集的闭包 中的元素 组成的符号串。

  例如:E→i|EAE    A→+|*

  是上下文无关语法,E、A是非终结符,E是开始符,而i,+和*是终结符

2.用上下文无关语法定义一个语言

  一个上下文无关语法如何定义一个语言呢,主要思想是从文法的开始符号出发,反复连续使用产生式,对非终结符进行替换和展开。

   例如:

   算术表达式的定义可以写为:

   E→i

   E→E+E

   E→E*E

   E→(E)

   E代表算术表达式,i代表变量。这四个产生式的后三个是递归的。

     我们可以定义如下文法G

   E→E+E|E*E|(E)|i

   开始符号为E,从E出发E=>(E)=>(E+E)=>(E*E+E)=>(i*E+E)=>(i*i+E)=>(i*i+i)

   符号"=>"表示仅推导一步

   

   我们定义αAβ=>αγβ为αAβ直接推导出αγβ,仅当A→γ是一个产生式,且α,β∈(VN∪VT)

   如果a1=>a2=>a3=>...=>an,我们称这个序列是从a1到an的一个推导。若存在一个从a1到an的推导,则称之为a1可推导出an。用a1=>an表示从a1出发经过零步或若干步,可推导出an

    假设G是一个文法,S是它的开始符号,如果S=>α则称α是一个句型。仅含终结符号的句型是句子。文法G所产生的句子全体是一个语言记为L(G)。

   L(G)={α|S+=>α&α∈VT*}

 

   例如:文法G1

    S→bA

    A→aA|a

    从符号S出发我们可以推出,S=>bA=>ba

    S=>bA=>baA=>baa

    .

      .

    .

    S=>bA=>baA=>...=>ba...a

    归纳得出所有以b开头后头跟一个或者多个a的字符串L(G1)={ban|n>=1}

posted @ 2018-06-22 14:59  nemo99  阅读(5127)  评论(0编辑  收藏  举报