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); }
private cSet <cLexem> cm_getAllPossibleGotoLexems(cSet <cConfiguration> a_set) { cSet <cLexem> _retSet = new cSet <cLexem>(); foreach (cConfiguration _configuration in a_set) { if (_configuration.cf_Production.cp_RightPart.Count > _configuration.cf_Position) { _retSet.Add(_configuration.cf_Production.cp_RightPart[_configuration.cf_Position]); } } _retSet.Remove(cLexem.cc_EpsilonLexem); return(_retSet); }
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); }
//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]; } }
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); }