zoukankan      html  css  js  c++  java
  • 编译原理 四

    1. 梳理第二章的内容,写一篇理解与总结。


    当我们要描述一种语言时,需要给出这种语言的所有句子,当句子的数目是有限可数时,就要都列出来;当句子
    是一个无穷集,也就是无限不可数时,就要给出可以表示它们的结构的描述方法或者说,句子的组成规则。这种
    规则就是文法。

    从形式上用于描述和规定结构的称为文法(或者说语法)

    一、文法的定义:

    文法G定义为一个四元组(VN,VT,P,S),其中,
    VN为非终结符集合,VT终结符集合;P是产生式结合;S称为识别符或开始符号,也是一个非终结符,至少要在一
    条产生式的左边出现。

    出现了几个名词,终结符、非终结符、产生式、识别符/开始符号等。下面具体聊聊这些名词和文法的定义。

    VN是非终结符集合,非终结符N指的是可以被拆分的字符或串,它采取递归定义:一个非终结符是由终结符和至少
    一个非终结符组成的串,相对应的,终结符就是不可拆分的,语言中要用到的字符。所以VN中所存储的是所有的
    非终结符,VT中存储的是所有的终结符。

    简单点讲:终结符就是推导到终结符时,不可再推导下去;而非终结符可以继续推导下去。

    集合P存储的是所有的产生式。那什么是产生式呢?产生式就是推导规则。比方说 a→b 就是一条规则,即一条产
    生式,可以通过 a 推导出 b。

    对照前面说的非终结符和终结符,就应该可以理解,在产生式左边的只能是非终结符,因为终结符不能再推导下
    去。而右边可以有终结符和非终结符。用数学的集合知识表示就是:

    产生式的形式是α → β,α称为产生式左部,β称为产生式右部,α属于VN,β∈(VN∪VT)*,α∉ε

    最后是S,S是开始符号,也就是最开始的那条产生式左边的非终结符,一切的推导从它开始。比方说

    a → b
    b → c|d
    c → e
    其中,a → b就是最开始的产生式,a就是最开始的非终结符,就是S。S是非终结符,所以S∈VN。
    二、文法与语言的推导

    举个例子:
    G(E):

    E=> E + T | T

    T=>T * F | F

    F=>(E)| i
    求i*i+i的推导式:
    E=>E+T
    =>T+T
    =>T*F+T
    =>F*F+T
    =>i*F+T
    =>i*i+T
    =>i*i+F
    =>i*i+i
    同理从右往左一个个元素的换算就是右推导了。
    三、句型、句子
    对于文法G[S]:
    如果: S=>a,则a称为G的一个句型,
    开始符号是最简单的句型。
    如果:a是G[S]的一个句型,且a属于VT,
    则a称被称为G[S]的一个句子,
    也就是说句子是全部有终结符组成的句型。
    四.语法分析树与二义性
    我们发现从一个句型到另一个句型的推导过程不是唯一的。例如从E+E->i+i,存在两个推导过程:

    E+E->E+i->i+i 最右推导,每个推导过程都是从最右边的非终结符号的替换开始
    E+E->i+E->i+i 最左推导,每个推导过程都是从最左边的非终结符号的替换开始
    当然为了对句子的结构进行一个确定性的分析,我们一般只考虑最左推导或者最右推导。

    前面我们提到过用一种树形的图示来表示这个句型的推导过程,这棵树就被称为”语法分析树“,简称”语法树“。
    对于一个文法,如果它的某些句子对应两棵不同的语法树,这个文法就属于“二义性文法”。
    注意,文法的二义性和我们通常所说的语言的二义性不同,我们可能有两个不同的文法G1,G2,一个是二义性,
    一个是非二义性,但是可能L(G1) = L(G2)。对于程序语言来说,我们常常希望它的文法是非二义性的,但
    是,只要我们能够控制和驾驭文法的二义性,文法二义性的存在也不一定是坏事。

    现在已经证明了,文法二义性是不可判定的。也就是说不存在一个算法,在有限步骤内算出一个文法是不是二义
    性的。我们能做的事儿,就是找一组充分条件来说明非二义性。比如,规定运算符号的优先级和结合性。

    2. 尝试写出PL/0 语言的文法。(或者你认为比较好的语言规则)

    整数n

    标识符i

    表达式e

    条件语句

    赋值语句

    复合语句

    函数

    程序

    ...
    答:
    整数n <整数n>::=int <标识符n>=<无符号整数>|<有符号整数>;
    标识符i <标识符i>::= <字符类型> <字母|数字>;
    表达式e <表达式> ::= [+ | -] <项> { <加法运算符><项>}
    条件语句 <表达式>{语句} ;|<表达式>{句子}
    赋值语句 <标识符>=<无符号整数>|<有符号整数>;
    <复合语句> ::= BEGIN <语句> {;<语句>} END
    函数 <数据类型> <标识符>(形式参数...){句子;...}
    <程序> ::= <分程序>.
    <分程序> ::= [<常量说明部分>] [<变量说明部分>]
    [<过程说明部分>] <语句>
    ...

  • 相关阅读:
    web安全之ssrf
    web安全之sql注入布尔注入
    web安全之sql注入报错型注入
    web安全之sqlload_file()和into outfile()
    浅谈 FHQ-Treap
    (菜鸟都能看懂的)网络最大流最小割,Ford-Fulkerson及Dinic详解
    浅谈最小生成树
    浅谈强连通分量(Tarjan)
    DP-DAY3游记
    关于01背包问题
  • 原文地址:https://www.cnblogs.com/huangwenshuo/p/11588342.html
Copyright © 2011-2022 走看看