/// <summary>
    /// Add a new production rule as a sequence of the given symbols.
    /// </summary>
    /// <typeparam name="TInput"></typeparam>
    /// <typeparam name="TOutput"></typeparam>
    /// <typeparam name="T1"></typeparam>
    /// <typeparam name="T2"></typeparam>
    /// <typeparam name="T3"></typeparam>
    /// <typeparam name="T4"></typeparam>
    /// <typeparam name="T5"></typeparam>
    /// <typeparam name="T6"></typeparam>
    /// <typeparam name="T7"></typeparam>
    /// <typeparam name="T8"></typeparam>
    /// <typeparam name="T9"></typeparam>
    /// <param name="lhs"></param>
    /// <param name="s1"></param>
    /// <param name="s2"></param>
    /// <param name="s3"></param>
    /// <param name="s4"></param>
    /// <param name="s5"></param>
    /// <param name="s6"></param>
    /// <param name="s7"></param>
    /// <param name="s8"></param>
    /// <param name="s9"></param>
    /// <param name="func"></param>
    /// <returns></returns>
    public static INonterminal <TInput, TOutput> Rule <TInput, TOutput, T1, T2, T3, T4, T5, T6, T7, T8, T9>(this INonterminal <TInput, TOutput> lhs, ISymbol <T1> s1, ISymbol <T2> s2, ISymbol <T3> s3, ISymbol <T4> s4, ISymbol <T5> s5, ISymbol <T6> s6, ISymbol <T7> s7, ISymbol <T8> s8, ISymbol <T9> s9, Func <T1, T2, T3, T4, T5, T6, T7, T8, T9, TOutput> func)
    {
        var p = new Production <TOutput>(lhs, args => func((T1)args[0], (T2)args[1], (T3)args[2], (T4)args[3], (T5)args[4], (T6)args[5], (T7)args[6], (T8)args[7], (T9)args[8]), s1, s2, s3, s4, s5, s6, s7, s8, s9);

        lhs.Add(p);
        return(lhs);
    }
    /// <summary>
    /// Add a new production rule as a sequence of the given symbols.
    /// </summary>
    /// <typeparam name="TInput"></typeparam>
    /// <typeparam name="TOutput"></typeparam>
    /// <typeparam name="T1"></typeparam>
    /// <typeparam name="T2"></typeparam>
    /// <param name="lhs"></param>
    /// <param name="s1"></param>
    /// <param name="s2"></param>
    /// <param name="func"></param>
    /// <returns></returns>
    public static INonterminal <TInput, TOutput> Rule <TInput, TOutput, T1, T2>(this INonterminal <TInput, TOutput> lhs, ISymbol <T1> s1, ISymbol <T2> s2, Func <T1, T2, TOutput> func)
    {
        var p = new Production <TOutput>(lhs, args => func((T1)args[0], (T2)args[1]), s1, s2);

        lhs.Add(p);
        return(lhs);
    }
    /// <summary>
    /// Add a new production rule as a sequence of the given symbols.
    /// </summary>
    /// <typeparam name="TInput"></typeparam>
    /// <typeparam name="TOutput"></typeparam>
    /// <typeparam name="T1"></typeparam>
    /// <typeparam name="T2"></typeparam>
    /// <typeparam name="T3"></typeparam>
    /// <typeparam name="T4"></typeparam>
    /// <typeparam name="T5"></typeparam>
    /// <typeparam name="T6"></typeparam>
    /// <param name="lhs"></param>
    /// <param name="s1"></param>
    /// <param name="s2"></param>
    /// <param name="s3"></param>
    /// <param name="s4"></param>
    /// <param name="s5"></param>
    /// <param name="s6"></param>
    /// <param name="func"></param>
    /// <returns></returns>
    public static INonterminal <TInput, TOutput> Rule <TInput, TOutput, T1, T2, T3, T4, T5, T6>(this INonterminal <TInput, TOutput> lhs, ISymbol <T1> s1, ISymbol <T2> s2, ISymbol <T3> s3, ISymbol <T4> s4, ISymbol <T5> s5, ISymbol <T6> s6, Func <T1, T2, T3, T4, T5, T6, TOutput> func)
    {
        var p = new Production <TOutput>(lhs, args => func((T1)args[0], (T2)args[1], (T3)args[2], (T4)args[3], (T5)args[4], (T6)args[5]), s1, s2, s3, s4, s5, s6);

        lhs.Add(p);
        return(lhs);
    }