}         // NT_GrammarTranslator

    private static void NT_Rule()
    {
        Rule   rule        = new Rule();
        String nonterminal = "";

        for (;;)
        {
            switch (Syn.Interpret())
            {
            case 0:
                return;

            case 1:
                Lex.GETnonterminalAttr(out nonterminal);
                break;

            case 2: // SEM
                rule.NonTerminal = nonterminal;

                break;

            case 3:
                NT_Alternatives(ref rule);
                break;

            case 4: // SEM
                rules.Add(rule);

                break;
            } // switch
        }     // for
    }         // NT_Rule
    }         // NT_Optional

    private static void NT_Repetition(ref Rule rule)
    {
        for (;;)
        {
            switch (Syn.Interpret())
            {
            case 0:
                return;

            case 1:
                NT_Alternatives(ref rule);
                break;
            } // switch
        }     // for
    }         // NT_Repetition
    public static void StartSem()
    {
        //-----------------------------------|----------------------------------------
        for (;;)
        {
            switch (Syn.Interpret())
            {
            case 0:
                return;

            case 1:
                NT_GrammarTranslator();
                break;
            } // switch
        }     // for
    }         // StartSem
    // *** end of global SYN and SEM declarations from ATG ***



    private static void NT_GrammarTranslator()
    {
        for (;;)
        {
            switch (Syn.Interpret())
            {
            case 0:
                return;

            case 1:
                NT_Rule();
                break;

            case 2: // SEM
                Console.WriteLine("Rules:");
                foreach (Rule r in rules)
                {
                    Console.WriteLine(r);
                }

                break;
            } // switch
        }     // for
    }         // NT_GrammarTranslator
    }         // NT_Alternatives

    private static void NT_Alternative(ref Rule rule)
    {
        String nonterminal = "";
        String terminal    = "";

        Alternative alternative = new Alternative();

        Rule groupRule      = null;
        Rule optionalRule   = null;
        Rule repetitionRule = null;

        for (;;)
        {
            switch (Syn.Interpret())
            {
            case 0:
                return;

            case 1: // SEM
                rule.AddAlternative(alternative);

                break;

            case 2:
                Lex.GETnonterminalAttr(out nonterminal);
                break;

            case 3: // SEM
                alternative.AddSymbol(new Symbol(nonterminal, Symbol.Kind.NONTERMINAL));

                break;

            case 4:
                Lex.GETterminalAttr(out terminal);
                break;

            case 5: // SEM
                alternative.AddSymbol(new Symbol(terminal, Symbol.Kind.TERMINAL));

                break;

            case 6: // SEM
                groupRule             = new Rule();
                groupRule.NonTerminal = symbolNameGenerator.Generate();
                rules.Add(groupRule);
                alternative.AddSymbol(new Symbol(groupRule.NonTerminal, Symbol.Kind.NONTERMINAL));

                break;

            case 7:
                NT_Grouping(ref groupRule);
                break;

            case 8: // SEM
                optionalRule             = new Rule();
                optionalRule.NonTerminal = symbolNameGenerator.Generate();

                // add empty alternative
                optionalRule.AddAlternative(new Alternative());

                rules.Add(optionalRule);
                alternative.AddSymbol(new Symbol(optionalRule.NonTerminal, Symbol.Kind.NONTERMINAL));

                break;

            case 9:
                NT_Optional(ref optionalRule);
                break;

            case 10: // SEM
                repetitionRule             = new Rule();
                repetitionRule.NonTerminal = symbolNameGenerator.Generate();

                rules.Add(repetitionRule);
                alternative.AddSymbol(new Symbol(repetitionRule.NonTerminal, Symbol.Kind.NONTERMINAL));

                break;

            case 11:
                NT_Repetition(ref repetitionRule);
                break;

            case 12: // SEM
                // add recursion to every alternative
                foreach (Alternative a in repetitionRule.GetAlternatives())
                {
                    a.AddSymbol(new Symbol(repetitionRule.NonTerminal, Symbol.Kind.NONTERMINAL));
                }

                // add empty alternative
                repetitionRule.AddAlternative(new Alternative());

                break;
            } // switch
        }     // for
    }         // NT_Alternative