Beispiel #1
0
        public static cSet <cLexem> cm_FirstTerminals(List <cLexem> a_listLexem)
        {
            cSet <cLexem> _tempSet = new cSet <cLexem>();

            if (a_listLexem.Count > 0)
            {
                int    _pos       = 0;
                cLexem _currLexem = a_listLexem[_pos];
                do
                {
                    _tempSet.Remove(cLexem.cc_EpsilonLexem);
                    _currLexem = a_listLexem[_pos];
                    _tempSet.UnionWith(_currLexem.cp_FirstCache);
                    _pos++;
                } while (_tempSet.Contains(cLexem.cc_EpsilonLexem) && (_pos < a_listLexem.Count));
            }
            cSet <cLexem> _retSet = new cSet <cLexem>();

            foreach (cLexem _lexem in _tempSet)
            {
                if (_lexem.cp_Type != eLexType.NonTerminal)
                {
                    _retSet.Add(_lexem);
                }
            }
            return(_retSet);
        }
Beispiel #2
0
        private cSet <cLexem> cm_First(List <cLexem> a_listLexem)
        {
            cSet <cLexem> _retSet = new cSet <cLexem>();

            if (a_listLexem.Count > 0)
            {
                int    _pos       = a_listLexem.Count - 1;
                cLexem _currLexem = a_listLexem[_pos];
                do
                {
                    _retSet.Remove(cLexem.cc_EpsilonLexem);
                    _currLexem = a_listLexem[_pos];
                    _retSet.UnionWith(_currLexem.cp_FirstCache);
                    _pos--;
                } while (_retSet.Contains(cLexem.cc_EpsilonLexem) && (_pos >= 0));
            }
            return(_retSet);
        }
Beispiel #3
0
        //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];
            }
        }
Beispiel #4
0
        private Dictionary <cLexem, cSet <cLexem> > cm_Follow()
        {
            Dictionary <cLexem, cSet <cLexem> > _retDic = new Dictionary <cLexem, cSet <cLexem> >();

            foreach (cLexem _nonTerminal in cp_Lexems)
            {
                if (_nonTerminal.cp_Type == eLexType.NonTerminal)
                {
                    _retDic[_nonTerminal] = new cSet <cLexem>();
                }
            }

            _retDic[cf_root].Add(cLexem.cc_StopLexem);

            // 2
            foreach (cLexem _nonTerminal in _retDic.Keys)
            {
                foreach (cProduction _production in _nonTerminal.cp_ListProducts)
                {
                    int           _count          = _production.cp_RightPart.Count - 1;
                    List <cLexem> _revListProduct = new List <cLexem>();
                    for (int i = _count; i >= 0; i--)
                    {
                        cLexem _lex = _production.cp_RightPart[i];
                        switch (_lex.cp_Type)
                        {
                        case eLexType.NonTerminal:
                            cSet <cLexem> _first = cm_First(_revListProduct);
                            _first.Remove(cLexem.cc_EpsilonLexem);
                            _retDic[_lex].AddRange(_first);
                            break;

                        default:
                            break;
                        }
                        _revListProduct.Add(_lex);
                    }
                }
            }

            // 3
            bool _added = true;

            while (_added)
            {
                _added = false;
                foreach (cLexem _nonTerminal in _retDic.Keys)
                {
                    foreach (cProduction _production in _nonTerminal.cp_ListProducts)
                    {
                        int           _count          = _production.cp_RightPart.Count - 1;
                        List <cLexem> _revListProduct = new List <cLexem>();
                        bool          _break          = false;      //?
                        for (int i = _count; i >= 0; i--)
                        {
                            cLexem _lex = _production.cp_RightPart[i];
                            switch (_lex.cp_Type)
                            {
                            case eLexType.NonTerminal:
                                cSet <cLexem> _first = cm_First(_revListProduct);
                                if (_first.Contains(cLexem.cc_EpsilonLexem) | (i == _count))
                                {
                                    //_production.cp_Root.cm_First(_first);
                                    //_first.UnionWith(_production.cp_Root.cp_FirstCache);
                                    _first.Remove(cLexem.cc_EpsilonLexem);
                                    _first.UnionWith(_retDic[_nonTerminal]);
                                }
                                _added |= _retDic[_lex].AddRange(_first);
                                break;

                            case eLexType.Action:
                                break;

                            default:
                                _break = true;
                                break;
                            }
                            _revListProduct.Add(_lex);
                            if (_break)
                            {
                                break;
                            }
                        }
                    }
                }
            }

            return(_retDic);
        }