• 编译原理之递归下降语法分析程序(实验)


    一、实验目的

    利用C语言编制递归下降分析程序,并对简单语言进行语法分析。

    编制一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析。

     

    二、实验原理

    每个非终结符都对应一个子程序。

    该子程序根据下一个输入符号(SELECT集)来确定按照哪一个产生式进行处理,再根据该产生式的右端:

    • 每遇到一个终结符,则判断当前读入的单词是否与该终结符相匹配,若匹配,再读取下一个单词继续分析;不匹配,则进行出错处理
    • 每遇到一个非终结符,则调用相应的子程序

     

    三、实验要求说明

    输入单词串,以“#”结束,如果是文法正确的句子,则输出成功信息,打印“success”,否则输出“error”,并指出语法错误的类型及位置。

    例如:

    输入begin a:=9;b:=2;c:=a+b;b:=a+c end #

    输出success

    输入a:=9;b:=2;c:=a+b;b:=a+c end #

    输出‘end' error

     

    四、实验步骤

    1.待分析的语言的语法(参考P90)

    2.将其改为文法表示,至少包含

    –语句

    –条件

    –表达式

    E -> E+T | T
    T -> T*F | F
    F -> (E) | i

    3. 消除其左递归

    E -> TE'
    E' -> +TE' | ε
    T -> FT'
    T' -> *FT' | ε
    F -> (E) | i

    4. 提取公共左因子

    5. SELECT集计算

    SELECT(E->TE) =FIRST(TE')=FIRSI(T)-FIRST(F)U{*}={(, i, *}
    SELECT(E'->+TE')=FIRST(+TE')={+}
    SELECT(E'->ε)=follow(E')=follow(E)={#, )}
    SELECT(T -> FT')=FRIST(FT')=FIRST(F)={(, i}
    SELECT(T'->*FT')=FRIST(*FT')={*}
    SELECT(T'->ε)=follow(T')=follow(T)={#, ), +}
    SELECT(F->(E))=FRIST((E)) ={(}
    SELECT(F->i)=FRIST(i) ={i}

    6. LL(1)文法判断

      其中SELECT(E'->+TE')与SELECT(E'->ε)互不相交,SELECT(T'->*FT')与SELECT(T'->ε)互不相交,SELECT(F->(E))与SELECT(F->i)互不相交,故原文法为LL(1)文法。

    7. 递归下降分析程序

      1 '''
      2     by Rakers
      3 '''
      4 
      5 import re
      6 
      7 types = {'begin':1,
      8          'if':2,
      9          'then':3,
     10          'while':4,
     11          'do':5,
     12          'end':6,
     13          'l(l|d)*':10,
     14          'dd*':11,
     15          '+':13,
     16          '-':14,
     17          '*':15,
     18          '/':16,
     19          ':':17,
     20          ':=':18,
     21          '<':20,
     22          '<=':21,
     23          '<>':22,
     24          '>':23,
     25          '>=':24,
     26          '=':25,
     27          ';':26,
     28          '(':27,
     29          ')':28,
     30          '#':0,
     31          'i':-1
     32         }
     33 
     34 # 当前读到的字符
     35 syn = ''
     36 synIndex = 0
     37 
     38 # 所有字符
     39 syns = []
     40 
     41 kk = 0
     42 
     43 # 语法分析方法
     44 def syntaxAnalysis(strs):
     45     strs += ' '     # 补位
     46     syns = []
     47     index = 0
     48     while index < len(strs):
     49         for key in types.keys():
     50             if index+len(key) < len(strs):
     51                 if strs[index:index+len(key)] == key:
     52 
     53                     if re.match('^[<>:]$', strs[index]) and strs[index+1] == '=':
     54                         key = strs[index:index+2]
     55                     ss = strs[index:index+len(key)]
     56                     # print((ss, types.get(ss)))
     57                     syns.append({ss:types.get(ss)})
     58                     index += len(key)-1
     59                     break
     60                 elif re.match('^[a-zA-Z0-9_]+', strs[index:]):
     61                     ss = re.match('^([a-zA-Z0-9_]+)', strs[index:]).group()
     62                     if not types.get(ss):
     63                         if re.match('[a-zA-Z]+', ss):
     64                             # print((ss, 10))
     65                             syns.append({ss: 10})
     66                         elif re.match('\d+', ss):
     67                             # print((ss, 11))
     68                             syns.append({ss: 11})
     69                         else:
     70                             print((ss, '其他'))
     71                     else:
     72                         # print((ss, types.get(ss)))
     73                         syns.append({ss:types.get(ss)})
     74                     index += len(ss)
     75                     # index += len(strs[index:strs.find(ss, index)])
     76         index += 1
     77     return syns
     78 
     79 
     80 def scaner():
     81     global syn, synIndex
     82     syn = syns[synIndex][list(syns[synIndex].keys())[0]]
     83     synIndex += 1
     84 
     85 
     86 def lrparser():
     87     global kk
     88     if syn == types['begin']:
     89         scaner()
     90         yucu()
     91 
     92         if syn == types['end']:
     93             scaner()
     94             if syn == types['#'] and kk == 0:
     95                 print("语句语法正确!!!")
     96         else:
     97             if kk != 1:
     98                 print("发生错误! 缺少end")
     99             kk = 1
    100     else:
    101         print("发生错误! 缺少begin")
    102         kk = 1
    103     return
    104 
    105 
    106 def yucu():
    107     statement()
    108     while syn == types[';']:
    109         scaner()
    110         statement()
    111     return
    112 
    113 
    114 def statement():
    115     global kk
    116     if syn == types['l(l|d)*']:
    117         scaner()
    118         if syn == types[':=']:
    119             scaner()
    120             expression()
    121         else:
    122             print(":=error!")
    123             kk = 1
    124     else:
    125         print("l(l|d)*error!")
    126         kk = 1
    127     return
    128 
    129 
    130 def expression():
    131     term()
    132     while syn == types['+'] or syn == types['-']:
    133         scaner()
    134         term()
    135     return
    136 
    137 
    138 def term():
    139     factor()
    140     while syn == types['*'] or syn == types['/']:
    141         scaner()
    142         factor()
    143     return
    144 
    145 
    146 def factor():
    147     global kk
    148     if syn == types['l(l|d)*'] or syn == types['dd*']:
    149         scaner()
    150     elif syn == types['(']:
    151         scaner()
    152         expression()
    153         if syn == types[')']:
    154             scaner()
    155         else:
    156             print("语法错误, 缺少')'")
    157             kk = 1
    158     else:
    159         print("表达式错误")
    160         kk = 1
    161     return
    162 
    163 
    164 if __name__ == '__main__':
    165     print('-'*30, 'Rakers语法分析程序', '-'*30)
    166     strs = input('请输入待分析语句:')
    167     syns = syntaxAnalysis(strs)
    168     scaner()
    169     lrparser()

    Rakers 版权所有,侵权必告

  • 相关阅读:
    RfcDestinationManager.UnregisterDestinationConfiguration时报错cannot unregister the given destination configuration
    SVN文件自动加锁-Win7
    linux 命令详解 sort
    Tensorflow的采样方法:candidate sampling(zhuan)
    (转载)机器学习中的目标函数、损失函数、代价函数有什么区别
    tensorflow dropout
    textcnn
    tensorflow学习笔记(三十九):双向rnn
    sklearn one_hot 操作
    sklearn 划分数据集。
  • 原文地址:https://www.cnblogs.com/Rakers1024/p/11940365.html
Copyright © 2020-2023  润新知