Exemple #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>());
            }
        }
        //private static cSet<cLexem> cm_FirstInList(List<cLexem> a_listLexem)
        //{
        //    cSet<cLexem> _retSet = new cSet<cLexem>();
        //    if (a_listLexem.Count > 0)
        //    {
        //        int _pos = 0;
        //        cLexem _currLexem = a_listLexem[_pos];
        //        do
        //        {
        //            _retSet.Remove(cLexem.cc_EpsilonLexem);
        //            _currLexem = a_listLexem[_pos++];
        //            _currLexem.cm_First(_retSet);
        //        } while (_retSet.Contains(cLexem.cc_EpsilonLexem) && (_pos < a_listLexem.Count));
        //    }
        //    return _retSet;
        //}

        //public cSet<cLexem> cm_First(cSet<cLexem> a_set)
        //{
        //    if (cf_firstCache == null)
        //    {
        //        cSet<cLexem> _retSet = a_set ?? new cSet<cLexem>();
        //        switch (cf_type)
        //        {
        //            case (eLexType.Epsilon):
        //            case (eLexType.Stop):
        //            case (eLexType.Terminal):
        //                _retSet.Add(this);
        //                break;
        //            case (eLexType.NonTerminal):
        //                if (cf_EpsilonCount > 0)
        //                {
        //                    _retSet.Add(cc_EpsilonLexem);
        //                }
        //                bool _added = false;
        //                do
        //                {
        //                    _added = false;
        //                    foreach (cProduction _production in cf_listProducts)
        //                    {
        //                        if (_production.cp_RightPart.Count > 0)
        //                        {
        //                            int _pos = 0;
        //                            cLexem _currLexem = _production.cp_RightPart[_pos];
        //                            do
        //                            {
        //                                _retSet.Remove(cLexem.cc_EpsilonLexem);
        //                                _currLexem = _production.cp_RightPart[_pos++];
        //                                if (_currLexem != this)
        //                                {
        //                                    _currLexem.cm_First(_retSet);
        //                                }
        //                                else
        //                                {
        //                                    break;
        //                                    //if (_retSet.Contains(cLexem.cc_EpsilonLexem))
        //                                    //{
        //                                    //    //    int _countBefore=_retSet.Count;
        //                                    //    //    for
        //                                    //}
        //                                    //else
        //                                    //{
        //                                    //    break;
        //                                    //}
        //                                }
        //                            } while (_retSet.Contains(cLexem.cc_EpsilonLexem) && (_pos < _production.cp_RightPart.Count));
        //                        }
        //                    }
        //                } while (_added);
        //                break;
        //            default:
        //                throw new Exception("Передан некорректный тип в cm_First: " + cf_type.ToString());
        //        }
        //        cf_firstCache = _retSet.Clone() as cSet<cLexem>;
        //        return _retSet;
        //    }
        //    else
        //    {
        //        if (a_set == null)
        //        {
        //            return cf_firstCache.Clone() as cSet<cLexem>;
        //        }
        //        else
        //        {
        //            a_set.AddRange(cf_firstCache);
        //            return a_set;
        //        }
        //    }
        //}

        public static void cm_CacheFirst()
        {
            Dictionary <cLexem, cSet <cLexem> > _firstPerLexem = new Dictionary <cLexem, cSet <cLexem> >();

            foreach (cLexem _lexem in cf_LexemDic.Values)
            {
                _firstPerLexem.Add(_lexem, new cSet <cLexem>());
            }
            _firstPerLexem.Add(cLexem.cc_EpsilonLexem, new cSet <cLexem>());
            _firstPerLexem.Add(cLexem.cc_StopLexem, new cSet <cLexem>());

            bool _added = false;

            do
            {
                _added = false;
                foreach (cLexem _lexem in _firstPerLexem.Keys)
                {
                    switch (_lexem.cf_type)
                    {
                    case eLexType.Epsilon:
                    case eLexType.Stop:
                    case eLexType.Terminal:
                        _added |= _firstPerLexem[_lexem].Add(_lexem);
                        break;

                    case eLexType.NonTerminal:
                        foreach (cProduction _production in _lexem.cf_listProducts)
                        {
                            if (_production.cp_RightPart.Count > 0)
                            {
                                int    _pos        = 0;
                                cLexem _currLexem  = _production.cp_RightPart[_pos];
                                bool   _hasEpsilon = false;
                                do
                                {
                                    _currLexem  = _production.cp_RightPart[_pos];
                                    _hasEpsilon = false;
                                    cSet <cLexem> _currentSet = _firstPerLexem[_currLexem];
                                    _hasEpsilon |= _currentSet.Contains(cLexem.cc_EpsilonLexem);
                                    if (_hasEpsilon)
                                    {
                                        _currentSet = _currentSet.Clone() as cSet <cLexem>;
                                        _currentSet.Remove(cLexem.cc_EpsilonLexem);
                                    }
                                    _added |= _firstPerLexem[_lexem].AddRange(_currentSet);
                                    _pos++;
                                } while (_hasEpsilon && (_pos < _production.cp_RightPart.Count));
                                if (_hasEpsilon)
                                {
                                    _added |= _firstPerLexem[_lexem].Add(cLexem.cc_EpsilonLexem);
                                }
                            }
                        }
                        break;

                    case eLexType.Action:
                        break;

                    default:
                        throw new Exception("Некорректный тип в cm_CacheFirst: " + _lexem.cf_type.ToString());
                    }
                }
            } while (_added);

            foreach (cLexem _lexem in _firstPerLexem.Keys)
            {
                _lexem.cf_firstCache = _firstPerLexem[_lexem];
            }
        }