public ProductionExpressionBuilder(string str) { expression = new ProductionExpression() { TypeConventer.ToTerminal(str) }; }
private void getFollow() { Productions[0].Left.Follow.Add(TypeConventer.ToTerminal(Tokens.LexEnd)); while (true) { bool loop = false; for (var i = 0; i < Productions.Count; i++) { var left = Productions[i].Left; var right = Productions[i].Right; foreach (var proe in right) { var flag = true; for (var j = proe.Count - 1; j >= 0; j--) { if (proe[j] is NonTerminal nontJ) { int x = vndic[nontJ]; if (flag) { int before = nontJ.Follow.Count; nontJ.Follow.UnionWith(left.Follow); if (!Productions[x].HasEpsilonExpression) { flag = false; } int after = nontJ.Follow.Count; if (after > before) { loop = true; } } for (int k = j + 1; k < proe.Count; k++) { if (proe[k] is NonTerminal nontK) { var from = nontK.First; var to = nontJ.Follow; int before = to.Count; foreach (var it1 in from) { if (it1 != Terminal.Epsilon) { to.Add(it1); } } int after = to.Count; if (after > before) { loop = true; } if (!Productions[vndic[nontK]].HasEpsilonExpression) { break; } } else if (proe[k] is Terminal termK) { int before = nontJ.Follow.Count; nontJ.Follow.Add(termK); int after = nontJ.Follow.Count; if (after > before) { loop = true; } break; } else { continue; } } } else { flag = false; } } } } if (!loop) { break; } } }
public void Append(string str) { expression.Add(TypeConventer.ToTerminal(str)); }