语法分析器---预测分析程序

本文档详细介绍了如何设计和实现一个预测分析算法,旨在深入理解自上而下的语法分析方法,特别是自上而下分析条件。实验步骤包括文法的左递归转换、FIRST集和FOLLOW集的计算、预测分析表的构造以及总控程序的建立。此外,还要求编写源代码、调试问题和实验报告。
摘要由CSDN通过智能技术生成

实验二  预测分析算法的设计与实现

(8学时)

一、实验目的

通过预测分析算法的设计与实现,加深对自上而下语法分析方法的理解,尤其是对自上而下分析条件的理解。

二、实验要求  

输入文法及待分析的输入串,输出其预测分析过程及结果。

三、实验步骤

1. 参考数据结构

(1)/*定义产生式的语法集结构*/

typedef struct{

    char formula[200];//产生式

}grammarElement;

grammarElement  gramOldSet[200];//原始文法的产生式集

  (2)/*变量定义*/

     char terSymbol[200];//终结符号

     char non_ter[200];//非终结符号

     char allSymbol[400];//所有符号

     char firstSET[100][100];//各产生式右部的FIRST集

     char followSET[100][100];//各产生式左部的FOLLOW集

     int M[200][200];//分析表

2. 判断文法的左递归性,将左递归文法转换成非左递归文法。(该步骤可以省略,直接输入非左递归文法)。

3.根据文法求FIRST集和FOLLOW集。

1/* First 集的算法*/

begin

if  X为终结符(XÎ)

        在所有产生式中查找X所在的产生式

        if  产生式右部第一个字符为终结符或空(X®a)或X®e)

         then ae加进FIRST(X)

        if 产生式右部第一个字符为非终结符 then

             if产生式右部的第一个符号等于当前字符 then

                跳到下一条产生式进行查找

              if 当前非终结符还没有求其FIRST then

                 查找它的FIRST集并标识此符号已求其FIRST

         求得结果并入到XFIRST

         if  当前产生式右部符号可推出空字且当前字符不是右部的最后一个字符

         then  获取右部符号下一个字符在所有字符集中的位置

         if  此字符的FIRST集还未查找 then

          找其FIRST集,并标其查找状态为1

          把求得的FIRST集并入到XF

预测分析子程序是一种自顶向下的语法分析方法,它使用一个预测分析表来确定每个非终结符号的下一步操作。下面是一个简单的预测分析程序的实现,假设我们的文法为: ``` S -> aAB A -> bA | ε B -> cB | d ``` 其中,S、A 和 B 是非终结符号,a、b、c 和 d 是终结符号。 ```python class Parser: def __init__(self, grammar): self.grammar = grammar self.predictive_table = self.build_predictive_table() def build_predictive_table(self): table = {} for nonterminal in self.grammar.nonterminals: for terminal in self.grammar.terminals + ['$']: productions = self.grammar.get_productions(nonterminal, terminal) if len(productions) == 1: table[(nonterminal, terminal)] = productions[0] elif len(productions) > 1: raise ValueError('Grammar is not LL(1)') return table def parse(self, input): stack = ['$'] input.append('$') i = 0 while stack: symbol = stack.pop() if symbol in self.grammar.nonterminals: production = self.predictive_table[(symbol, input[i])] stack.extend(reversed(production.rhs)) elif symbol == input[i]: i += 1 else: raise ValueError('Unexpected token: {}'.format(input[i-1])) return True class Grammar: def __init__(self, productions): self.productions = productions self.nonterminals = set(p.lhs for p in productions) self.terminals = set(t for p in productions for t in p.rhs if t not in self.nonterminals) def get_productions(self, nonterminal, terminal): return [p for p in self.productions if p.lhs == nonterminal and (len(p.rhs) == 1 and p.rhs[0] == terminal or len(p.rhs) > 1 and p.rhs[0] in self.nonterminals and (nonterminal, terminal) in self.predictive_table[(p.rhs[0], terminal)])] class Production: def __init__(self, lhs, rhs): self.lhs = lhs self.rhs = rhs grammar = Grammar([ Production('S', ['a', 'A', 'B']), Production('A', ['b', 'A']), Production('A', []), Production('B', ['c', 'B']), Production('B', ['d']), ]) parser = Parser(grammar) input = ['a', 'b', 'c', 'd'] parser.parse(input) ``` 在预测分析程序中,我们首先构建了一个预测分析表,它是一个字典,键为一个非终结符号和一个终结符号的二元组,值为一个产生式。然后,我们使用一个栈来模拟语法分析过程。我们从栈中弹出一个符号,如果它是一个非终结符号,则查找预测分析表,获取对应的产生式,并将产生式的右部反转后入栈。如果它是一个终结符号,并且与输入符号相同,则继续处理下一个输入符号。如果它是一个终结符号,但与输入符号不同,则抛出异常。 在上面的代码中,我们还定义了一个 Grammar 类,它表示一个文法。该类包含一个产生式列表、非终结符号集合和终结符号集合。我们还定义了一个 Production 类,它表示一个产生式,包含一个左部和一个右部。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值