/// <summary> /// Computes the FIRSTS set for this rule body /// </summary> /// <returns><c>true</c> if there has been modifications</returns> public bool ComputeFirsts(RuleChoice next) { // If the choice is empty : Add the ε to the Firsts and return if (parts.Count == 0) { return(setFirsts.Add(Epsilon.Instance)); } Symbol symbol = parts[0].Symbol; // If the first symbol in the choice is a terminal : Add terminal as first and return var terminal = symbol as Terminal; if (terminal != null) { return(setFirsts.Add(terminal)); } // Here the first symbol in the current choice is a variable Variable variable = symbol as Variable; bool mod = false; // keep track of modifications // foreach first in the FIRSTS set of the variable foreach (Terminal first in variable.Firsts) { // If the symbol is ε if (first == Epsilon.Instance) { // Add the Firsts set of the next choice to the current Firsts set mod |= setFirsts.AddRange(next.setFirsts); } else { // Symbol is not ε : Add the symbol to the Firsts set mod |= setFirsts.Add(first); } } return(mod); }
/// <summary> /// Append the specified choice /// </summary> /// <param name="choice">A choice</param> public void Append(RuleChoice choice) { parts.AddRange(choice.parts); }