private void AddZeroRule() { string newHead = beginToken + "'"; TransRule zeroRule = new TransRule(new TransToken(newHead), new List <TransToken> { new TransToken(beginToken) }, (TransRule thisPlaceholder) => { thisPlaceholder.head.attrVal = thisPlaceholder.body[0].attrVal; }); rules.Insert(0, zeroRule); beginToken = newHead; }
private HashSet <TransToken> GetNextTokenFirsts(TransRule rule, int nextTokenIndex) { HashSet <TransToken> result = new HashSet <TransToken> { }; bool containsEpsilon = true; for (int i = nextTokenIndex; i < rule.body.Count; ++i) { TransToken token = rule.body[i]; containsEpsilon = false; if (terms.Contains(token)) { result.Add(token); break; } foreach (TransToken first in firstSets[token]) { if (first.Equals(new TransToken(""))) { containsEpsilon = true; } result.Add(first); } containsEpsilon |= firstSets[token].Count == 0; if (!containsEpsilon) { break; } } if (containsEpsilon) { result.Add(new TransToken("")); } return(result); }
private Action CreateReduceCallback(int ruleIndex) { return(() => { TransRule rule = parent.rules[ruleIndex]; for (int i = rule.body.Count; i > 0; --i) { stateStack.Pop(); } for (int i = rule.body.Count - 1; i >= 0; --i) { rule.body[i] = tokenStack.Pop(); } rule.ApplyRule(); tokenStack.Push(rule.head); stateStack.Push(GetStateFromGoto(stateStack.Peek(), tokenStack.Peek())); }); }
private TItemState Goto(TItemState itemState, TransToken nextTerm) { HashSet <TItem> resultingSet = new HashSet <TItem> { }; foreach (TItem item in itemState.stateItems) { TransRule rule = parent.rules[item.ruleNum]; if (rule.body.Count == item.dotPos) { continue; } if (rule.body[item.dotPos].token == nextTerm.token) { resultingSet.Add(new TItem(item.ruleNum, item.dotPos + 1)); } } return(new TItemState(resultingSet)); }
// If rule contains body other than one empty symbol, create firsts set for it private bool ComputeBodyFirstSets(Dictionary <TransToken, HashSet <TransToken> > firstSets, TransRule rule) { bool notDone = false; bool containsEpsilon = true; foreach (TransToken token in rule.body) { containsEpsilon = false; if (terms.Contains(token)) { notDone |= firstSets[rule.head].Add(token); break; } foreach (TransToken element in firstSets[token]) { if (element.Equals(new TransToken(""))) { containsEpsilon = true; } notDone |= firstSets[rule.head].Add(element); } if (!containsEpsilon) { break; } } if (containsEpsilon) { notDone |= firstSets[rule.head].Add(new TransToken("")); } return(notDone); }