private void UpdateSymbolsAfterRuleRemoved( RuleStrRep rule, ref bool grammaticals_changed, ref bool terminals_changed )
        {
            // LeftHandSide
            if( this.grammaticals[rule.Lhs] <= 1 )
            {
                this.grammaticals.Remove(rule.Lhs);
                grammaticals_changed = true;

                if( this.terminals.ContainsKey(rule.Lhs) )
                    terminals_changed = true;
            }
            else
            {
                this.grammaticals[rule.Lhs] -= 1;
            }

            // RightHandSide
            for( int i = 0; i < rule.Rhs.Count; ++i )
            {
                string symbol = rule.Rhs[i];

                if( this.terminals[symbol] <= 1 )
                {
                    this.terminals.Remove(symbol);
                    terminals_changed = true;
                }
                else
                {
                    this.terminals[symbol] -= 1;
                }
            }
        }
        private RuleStrRep ParseRule( string str )
        {
            var new_rule = new RuleStrRep();

            new_rule.Lhs = str.Substring(0, 1);

            for( int i = 3; i < str.Length; ++i )
                new_rule.Rhs.Add(str.Substring(i, 1));

            return new_rule;
        }
        private void UpdateSymbolsAfterRuleAdded( RuleStrRep rule, ref bool grammaticals_changed, ref bool terminals_changed )
        {
            // LeftHandSide is a grammatical.
            if( this.grammaticals.ContainsKey(rule.Lhs) )
            {
                this.grammaticals[rule.Lhs] += 1;
            }
            else
            {
                this.grammaticals.Add(rule.Lhs, 1);
                grammaticals_changed = true;

                if( this.terminals.ContainsKey(rule.Lhs) )
                    terminals_changed = true;
            }

            // Count all RightHandSide symbols as terminals.
            for( int i = 0; i < rule.Rhs.Count; ++i )
            {
                string symbol = rule.Rhs[i];

                if( this.terminals.ContainsKey(symbol) )
                {
                    this.terminals[symbol] += 1;
                }
                else
                {
                    this.terminals.Add(symbol, 1);
                    terminals_changed = true;
                }
            }
        }
        private void LoadGrammar( Grammar grammar )
        {
            this.terminals.Clear();
            this.grammaticals.Clear();
            this.rules.Clear();

            try
            {
                // Check symbol names
                foreach( var tr in grammar.Terminals )
                    if( tr.Name.Length != 1 )
                        throw new ArgumentException(string.Format("Terminal's name '{0}' is not simple.", tr.Name));

                foreach( var gr in grammar.Grammaticals )
                    if( gr.Name.Length != 1 && gr.Name != "S'" )
                        throw new ArgumentException(string.Format("Grammatical's name '{0}' is not simple.", gr.Name));

                foreach( var rule in grammar.Rules )
                {
                    var rule_rep = new RuleStrRep();

                    rule_rep.Lhs = rule.LeftHandSide.Name;
                    if( this.grammaticals.ContainsKey(rule.LeftHandSide.Name) )
                        this.grammaticals[rule.LeftHandSide.Name] += 1;
                    else
                        this.grammaticals[rule.LeftHandSide.Name] = 1;

                    foreach( var symbol in rule.RightHandSide )
                    {
                        rule_rep.Rhs.Add(symbol.Name);
                        if( symbol is GrammaticalSymbol )
                        {
                            if( this.grammaticals.ContainsKey(symbol.Name) )
                                this.grammaticals[symbol.Name] += 1;
                            else
                                this.grammaticals[symbol.Name] = 1;
                        }
                        else
                        {
                            if( this.terminals.ContainsKey(symbol.Name) )
                                this.terminals[symbol.Name] += 1;
                            else
                                this.terminals[symbol.Name] = 1;
                        }
                    }

                    this.rules.Add(rule_rep);
                }
            }
            finally
            {
                // Update gui
                this.UpdateRulesList();
                this.UpdateGrammaticals();
                this.UpdateTerminals();
            }
        }