예제 #1
0
        public static cSet <cConfiguration> cm_Closure(cSet <cConfiguration> a_listConfiguration)
        {
            bool _added = false;

            if (a_listConfiguration != null)
            {
                cSet <cConfiguration> _retList    = a_listConfiguration.Clone() as cSet <cConfiguration>;
                cSet <cConfiguration> _addRetList = new cSet <cConfiguration>();
                do
                {
                    _addRetList.Clear();
                    foreach (cConfiguration _configuration in _retList)
                    {
                        if (_configuration.cf_Production.cp_RightPart.Count > _configuration.cf_Position)
                        {
                            cLexem _lexem = _configuration.cf_Production.cp_RightPart[_configuration.cf_Position];
                            if (_lexem.cp_Type == eLexType.NonTerminal)
                            {
                                List <cLexem> _listTerminals = new List <cLexem>();
                                _listTerminals.AddRange(_configuration.cf_Production.cp_RightPart.GetRange(_configuration.cf_Position + 1, _configuration.cf_Production.cp_RightPart.Count - _configuration.cf_Position - 1));
                                _listTerminals.Add(_configuration.cf_Terminal);
                                cSet <cLexem> _firstTerminals = cm_FirstTerminals(_listTerminals);
                                foreach (cProduction _production in _lexem.cp_ListProducts)
                                {
                                    foreach (cLexem _terminal in _firstTerminals)
                                    {
                                        cConfiguration _newConfiguration = cConfiguration.cm_GetConfiguration(_production, 0, _terminal);
                                        _addRetList.Add(_newConfiguration);
                                    }
                                }
                            }
                        }
                    }
                    _added = _retList.AddRange(_addRetList);
                } while (_added == true);
                return(_retList);
            }
            else
            {
                return(new cSet <cConfiguration>());
            }
        }
예제 #2
0
        List <cLexem> cm_getLeadLexemsInternal(List <cLexem> a_watchedLexems)
        {
            List <cLexem> _retLst = new List <cLexem>();

            if (a_watchedLexems.Contains(this))
            {
                //if (cf_type == eLexType.Terminal || cf_type == eLexType.NonTerminal)
                throw new cNotLL1Exception(this, null, String.Empty);
            }
            else
            {
                a_watchedLexems.Add(this);
                switch (cf_type)
                {
                case eLexType.NonTerminal:
                    foreach (KeyValuePair <cLexem, List <cLexem> > _kvp in cf_listProducts)
                    {
                        if (_kvp.Key.cp_Type != eLexType.Epsilon)
                        {
                            cm_fillNonTerminalLeadingLexList(a_watchedLexems, _kvp.Value, 0, _retLst);
                        }
                        else
                        {
                            _retLst.Add(_kvp.Key);
                        }
                    }
                    if (cf_leadLexems == null)
                    {
                        cf_leadLexems = new cSet <cLexem>();
                        cf_leadLexems.AddRange(_retLst);
                    }
                    break;

                case eLexType.Terminal:
                case eLexType.Epsilon:
                    _retLst.Add(this);
                    break;
                }
            }
            return(_retLst);
        }
예제 #3
0
        public void cm_Init(cParser a_parser)
        {
            cf_valid = false;
            cf_root  = a_parser.cp_Root;

            // Заполнение множества FOLLOW
            cf_follow = new Dictionary <cLexem, cSet <cLexem> >();
            foreach (cLexem _nonTerminal in cp_Lexems)
            {
                if (_nonTerminal.cp_Type == eLexType.NonTerminal)
                {
                    cf_follow[_nonTerminal] = new cSet <cLexem>();
                }
            }

            // 2
            cSet <cLexem> _first = new cSet <cLexem>();

            foreach (cLexem _nonTerminal in cp_Lexems)
            {
                if (_nonTerminal.cp_Type == eLexType.NonTerminal)
                {
                    foreach (List <cLexem> _lstLex in _nonTerminal.cp_ListProducts.Values)
                    {
                        int _count = _lstLex.Count;
                        _first.Clear();
                        for (int i = _lstLex.Count - 1; i >= 0; i--)
                        {
                            cLexem _lex = _lstLex[i];
                            switch (_lex.cp_Type)
                            {
                            case eLexType.NonTerminal:
                                cf_follow[_lex].AddRange(_first);
                                if (!_lex.cm_IsLeadingLexem(cLexem.cc_EpsilonLexem))
                                {
                                    _first.Clear();
                                }
                                _first.AddRange(_lex.cp_LeadLexems);
                                break;

                            case eLexType.Terminal:
                                _first.Clear();
                                _first.Add(_lex);
                                break;

                            case eLexType.Epsilon:
                                _first.Clear();
                                break;
                            }
                        }
                    }
                }
            }

            // 3
            bool _added = true;

            while (_added)
            {
                _added = false;
                foreach (cLexem _nonTerminal in cp_Lexems)
                {
                    if (_nonTerminal.cp_Type == eLexType.NonTerminal)
                    {
                        foreach (List <cLexem> _lstLex in _nonTerminal.cp_ListProducts.Values)
                        {
                            int _count = _lstLex.Count;
                            _first.Clear();
                            bool _break = false;
                            for (int i = _lstLex.Count - 1; i >= 0; i--)
                            {
                                cLexem _lex = _lstLex[i];
                                switch (_lex.cp_Type)
                                {
                                case eLexType.NonTerminal:
                                    cf_follow[_lex].AddRange(_first);
                                    if (!_lex.cm_IsLeadingLexem(cLexem.cc_EpsilonLexem))
                                    {
                                        _break = true;
                                    }
                                    //else
                                    _added = cf_follow[_lex].AddRange(cf_follow[_nonTerminal]) | _added;
                                    break;

                                case eLexType.Action:
                                    break;

                                default:
                                    _break = true;
                                    break;
                                }
                                if (_break)
                                {
                                    break;
                                }
                            }
                        }
                    }
                }
            }
            cf_valid = true;
        }