protected override List <ProductionInLR0> closure(List <ProductionInLR0> productions) { List <ProductionInLR0> generatedList = new List <ProductionInLR0>(); generatedList.AddRange(productions); for (int i = 0; i < generatedList.Count; i++) { ProductionInLR1 oldProduction = generatedList[i] as ProductionInLR1; string token = generatedList[i].NextTokenOfPoint; if (token != null && inputGrammer.nonTerminalTokens.Contains(token)) { foreach (Production production in inputGrammer[token]) { ProductionInLR1 newProduction = new ProductionInLR1(production, generatedFirst.getFirstFromPart(oldProduction.Values, oldProduction.PointPos + 1, oldProduction.searchTokens)); // 检查项集内是否有同心项(或者完全相同),有则不添加 bool noNeedToAdd = false; foreach (ProductionInLR1 production1 in generatedList) { if (production1.hasSameCoreWith(newProduction)) { noNeedToAdd = true; production1.searchTokens = production1.searchTokens.Union(newProduction.searchTokens).ToList(); } } if (!noNeedToAdd) { generatedList.Add(newProduction); } } } } return(generatedList); }
public LL1Table(InputGrammer inputGrammer) : base(inputGrammer) { generatedFirst = new GenerateFirst(inputGrammer); GenerateFollow generatedFollow = new GenerateFollow(inputGrammer, generatedFirst); if (!checkLeft()) { throw new FailToGenerateLL1Exception("含有左递归或左公因子"); } foreach (Production production in inputGrammer.userProductions) { List <string> firstSetOfRightPart = generatedFirst.getFirstFromPart(production.Values); foreach (string token in firstSetOfRightPart.Where(i => (!inputGrammer.nonTerminalTokens.Contains(i) && i != PublicFunc.EPSILON))) { Item item = new Item(production.Key, token, production.ToString()); checkConflict(item); table.Add(item); } if (firstSetOfRightPart.Contains(PublicFunc.EPSILON)) { foreach (string token in generatedFollow[production.Key].Where(i => !inputGrammer.nonTerminalTokens.Contains(i))) { Item item = new Item(production.Key, token, production.ToString()); checkConflict(item); table.Add(item); } } } }
public GenerateFollow(InputGrammer inputGrammer, GenerateFirst generatedFirst) { foreach (string token in inputGrammer.nonTerminalTokens) { followSet.Add(new Production(token, new List <string>())); } // 加入$符号 GetValuesByKey(inputGrammer.nonTerminalTokens[0], followSet).Add(ENDSYMBOL); int changeTotal; do { changeTotal = 0; foreach (Production production in inputGrammer.userProductions) { List <string> valuesInFollow = GetValuesByKey(production.Key, followSet); for (int i = 0; i < production.Values.Count; i++) { string token = production.Values[i]; if (inputGrammer.nonTerminalTokens.Contains(token)) { List <string> valuesOfTokenInFollow = GetValuesByKey(token, followSet); if (i != production.Values.Count - 1) { bool hasEpsilon = false; if (ExtendElementWithoutEpsilon(generatedFirst.getFirstFromPart(production.Values, i + 1), valuesOfTokenInFollow, ref hasEpsilon)) { changeTotal++; } if (hasEpsilon && ExtendElement(valuesInFollow, valuesOfTokenInFollow)) { changeTotal++; } } else if (ExtendElement(valuesInFollow, valuesOfTokenInFollow)) { changeTotal++; } } } } } while (changeTotal != 0); }
// 检查左递归或左公因子 public bool checkLeft() { foreach (string token in inputGrammer.nonTerminalTokens) { // S->A | B 求First(A)与First(B)的交集是否存在 List <Production> productions = inputGrammer[token]; for (int i = 0; i < productions.Count; i++) { for (int j = i + 1; j < productions.Count; j++) { if (generatedFirst.getFirstFromPart(productions[i].Values).Intersect(generatedFirst.getFirstFromPart(productions[j].Values)).Count() > 0) { return(false); } } } } return(true); }