SLR(1)分析法详解与代码实现:解决文法E->E+T|T T->T*F|F F->(E)|d的分析表构建问题

在学习编译原理SLR(1)分析法的过程中,构建分析表是至关重要的一步。很多初学者经常在添加归约状态时遇到问题,本文将针对这一问题进行详细分析,并提供C#代码实现。

问题描述

给定文法:

E->E+T|TT->T*F|FF->(E)|d

构建SLR(1)分析表时,发现添加的归约状态与正确答案不符。

错误分析

错误的原因是在添加归约状态时,将归约状态添加到了终结符对应的列,而不是非终结符的Follow集对应的列。

代码实现与优化

以下代码实现了SLR(1)分析表的构建,并对添加归约状态的部分进行了优化:

1. SLRAnaly()函数c#public void SLRAnaly(){ Table tnode = new Table();

SLRAna = new Table[proitemset.Count][];    for (int i = 0; i < proitemset.Count; i++)        SLRAna[i] = new Table[Echar.Count + Nchar.Count];

// 初始化分析表    for (int i = 0; i < proitemset.Count; i++)        for (int j = 0; j < Echar.Count + Nchar.Count; j++)            SLRAna[i][j] = tnode;

// 添加接受状态    tnode = new Table('A', 0);    SLRAna[1][FindID(Echar, '#')] = tnode;

// 添加归约状态    for (int i = 0; i < Gy_itemset.Count; i++)    {        SLRNode item = SLRobjNum[proitemset[Gy_itemset[i]].Container[0]];        char left = item.Left[0];        List<char> follow = GetFollow(left);        foreach (char c in follow)        {            // 只在终结符对应的列添加归约状态            if (isFinalsymbol(c))            {                int CID = FindID(Echar, c);                SLRAna[Gy_itemset[i]][CID] = new Table('r', Find_pro(item));            }        }    }

// 添加移进状态和GOTO状态    for (int i = 0; i < Pindex; i++)    {        if (isFinalsymbol(dfa[i].symbol))        {            int CID = FindID(Echar, dfa[i].symbol);            SLRAna[dfa[i].from][CID] = new Table('S', dfa[i].to);        }        else        {            int CID = FindID(Nchar, dfa[i].symbol);            SLRAna[dfa[i].from][CID + Echar.Count] = new Table('N', dfa[i].to);        }    }}

2. GetFollow()函数c#public List GetFollow(char c){ List follow = new List(); if (c == 'E') follow.Add('#'); foreach (SLRNode node in SLRproNum) { int index = node.Right.IndexOf(c); if (index != -1 && index < node.Right.Length - 1) { char next = node.Right[index + 1]; if (isFinalsymbol(next)) follow.Add(next); else { List first = GetFirst(next); if (first.Contains('#')) { first.Remove('#'); follow.AddRange(first); follow.AddRange(GetFollow(node.Left[0])); } else { follow.AddRange(first); } } } else if (index != -1 && index == node.Right.Length - 1) { // 处理空串的情况 if (node.Left[0] != c) follow.AddRange(GetFollow(node.Left[0])); } } follow = follow.Distinct().ToList(); return follow;}

总结

通过以上代码的修改,就可以正确地构建SLR(1)分析表。在学习SLR(1)分析法的过程中,一定要注意添加归约状态的位置,并仔细处理空串的情况,避免出现错误

SLR(1)分析法详解与代码实现:解决文法E->E+T|T  T->T*F|F  F->(E)|d的分析表构建问题

原文地址: https://www.cveoy.top/t/topic/f0Ly 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录