zoukankan      html  css  js  c++  java
  • 《编译原理》学习总结(1)

    语法:描述一个程序语言的正确性

    语义:描述一个程序的含义
     
    上下文无关文法是用来描述语法的一种办法,而描述语义的难度太大。
     
    上下文无关文法中的一些概念:
    终结符号
         可以理解为关键字或者一些最小单元的字符,比如while if 0 1 3 之类
    非终结符号
         是终结符号的集合,是自己命名的一个东西比如 digit -> 0 | 1|2|3…|8|9,这里digit称为非终结符号
    产生式
         产生式由两部分组成,左边是非终结符号,右边是非终结符号和终结符号的集合
         比如:digit -> 0 | 1|2|3…|8|9,这一行本身就是产生式
    开始符号
         一段文法的第一行称为开始符号
     
    文法的二义性
    list -> list + digit | list - digit
    list -> digit
    digit -> 0|1|2|3|4|5|6|7|8|9
     
    上面定义了一个文法,然后一个demo:9 - 5 + 3
     
    用语法树来解析,过程如下:
     
    1.先列出来目标内容
    9 - 5 + 3
     
    2.然后把他们都看成某个非终结符号
     
    digit      digit       digit 
    9       -    5     +     3 
     
    3.再往上找关系
    list
    digit      digit       digit 
    9       -    5     +     3  
     
    可以发现,list - digit可以组成list。
         list
      /        
    list        digit
    digit        |          digit 
    9       -    5     +     3   
     
    4.继续
                    list
           /                  
         list           +   digit
      /                       |
    list    -   digit          |
    digit        |             |  
     9       -   5     +     3    
     
    这样就根据一个文法定义,一个语句,生成了唯一的语法书,那么这个语句就没有二义性。
    你可以试试,先将 5 + 3 -> list + digit,这就变成了list了,然后 9 - list,也就是 digit - list 或者是 list - list ,你就会发现文法中并没有这样的定义,也就是不存在这样的语法,这样也就造成了以上的内容只有一种解析结果。
     
    如果从叶子节点开始计算,计算顺序就是 (9 - 5) + 3 是正确的
    如果有二义性,那么有可能出现不同的计算顺序,导致结果出错,所以文法的定义没有二义性很重要
     
    运算符的结合性
    结合性有左结合和右结合。
     
    左结合
    当一个数字左右两边都有运算符的时候,要根据运算符的结合性来决定数字是属于哪一边的
    比如+是左结合
    1+2+3 -> (1+2)+3 因为2左右两边都有+号,+号是左结合的,所以2是属于左边的运算符。
    用文法定义的时候:
    result -> result + digit | result
    digit -> [0-9]
    用语法树来表示
                  result
           result       digit
    result    digit       |
     digit        |         |
      1      +   2   +   3
     
    再看右结合
    a = b = c
    b的左右两边有运算符 = 
    =运算符是右结合的,所以b 是优先属于右边的操作符
    a = (b = c)
     
    文法定义:
    result -> char = result | char
    char-> [a-z]
     
    用语法树表示:
          result
    char     result
    |       char  result
    |         |       char
    a   =   b   =   c 
     
    运算符的优先级
    比如 * / 和 +- 就是两个级别的运算符,设计文法的时候可以将两个独立的分开比如如下的文法
     
    expr -> expr + term | expr - term | term     //expr是加减表达式
    term-> term* factor | term/ factor | factor     //term是乘除表达式
    factor -> digit | expr
    digit -> [0-9]
     
    例子
    1 + 2 * 3 //我们应该优先计算 2 * 3,直接在本子上画个语法树就出来了,我只能说,真的很巧妙!
     
    任意优先级层次的语法
    factor理解为一个因子,不可以被任何运算符分开,因为它就是数字本身了
    高优先级的运算符可以把低优先级的运算符分开
    比如 1 + 2 * 3 
    可以看成 1 + x 但是 * 比+的优先级更高,它可以把x分开
     
    真心觉得这些东西都非常的巧妙,智慧无穷……
     
    原文地址:http://www.cnblogs.com/kross/p/4100317.html
    作者:kross(krossford@foxmail.com)
  • 相关阅读:
    noi.openjudge——2971 抓住那头牛
    P1265 公路修建 洛谷
    P2330 [SCOI2005] 繁忙的都市 洛谷
    P1331 海战 洛谷
    P1464 Function 洛谷
    基于Manhattan最小生成树的莫队算法
    zoj3659
    poj1182
    hdu1325
    hdu3635
  • 原文地址:https://www.cnblogs.com/kross/p/4100317.html
Copyright © 2011-2022 走看看