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); }
public object Clone() { cSet <T> _retSet = new cSet <T>(); _retSet.UnionWith(this); return(_retSet); }
private cLexem(string a_name, eLexType a_type) { cf_firstCache = null; cf_EpsilonCount = 0; cf_Name = a_name; cf_type = a_type; if (a_name == cc_Epsilon) { cf_type = eLexType.Epsilon; } }
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); }
public static cSet <cConfiguration> cm_Goto(cSet <cConfiguration> a_listConfiguration, cLexem a_lexem) { cSet <cConfiguration> _validConfigurations = new cSet <cConfiguration>(); foreach (cConfiguration _configuration in a_listConfiguration) { if (_configuration.cf_Production.cp_RightPart.Count > _configuration.cf_Position) { if (_configuration.cf_Production.cp_RightPart[_configuration.cf_Position] == a_lexem) { cConfiguration _newConfiguration = cConfiguration.cm_GetConfiguration(_configuration.cf_Production, _configuration.cf_Position + 1, _configuration.cf_Terminal); _validConfigurations.Add(_newConfiguration); } } } return(cm_Closure(_validConfigurations)); }
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); }
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 bool cm_addItemGroup(List <cSet <cConfiguration> > a_items, cSet <cConfiguration> a_item, cLexem a_lexem, cSet <cConfiguration> a_set, Dictionary <cSet <cConfiguration>, Dictionary <cLexem, cSet <cConfiguration> > > a_goto) { bool _notSubset = true; foreach (cSet <cConfiguration> _set in a_items) { if (_set.IsSupersetOf(a_set)) { _notSubset = false; cm_addToGoto(a_goto, a_item, a_lexem, _set); break; } } if (_notSubset) { a_items.Add(a_set); cm_addToGoto(a_goto, a_item, a_lexem, a_set); } return(_notSubset); }
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); }
private KeyValuePair <List <cSet <cConfiguration> >, Dictionary <cSet <cConfiguration>, Dictionary <cLexem, cSet <cConfiguration> > > > cm_Items(cLexem a_root) { List <cSet <cConfiguration> > _retList = new List <cSet <cConfiguration> >(); cConfiguration _rootConfiguration = cConfiguration.cm_GetConfiguration(a_root.cp_ListProducts[0], 0, cLexem.cc_StopLexem); cSet <cConfiguration> _rootClosure = cConfiguration.cm_Closure(new cSet <cConfiguration>() { _rootConfiguration }); Dictionary <cSet <cConfiguration>, Dictionary <cLexem, cSet <cConfiguration> > > _gotoResults = new Dictionary <cSet <cConfiguration>, Dictionary <cLexem, cSet <cConfiguration> > >(); _retList.Add(_rootClosure); bool _added = false; int _lastChecked = 0; do { _added = false; for (; _lastChecked < _retList.Count; _lastChecked++) { cSet <cConfiguration> _currentItem = _retList[_lastChecked]; cSet <cLexem> _currentChecked = cm_getAllPossibleGotoLexems(_currentItem); foreach (cLexem _lexem in _currentChecked) { cSet <cConfiguration> _possibleItem = cConfiguration.cm_Goto(_currentItem, _lexem); if (cm_addItemGroup(_retList, _currentItem, _lexem, _possibleItem, _gotoResults)) { _added = true; } } } } while (_added); return(new KeyValuePair <List <cSet <cConfiguration> >, Dictionary <cSet <cConfiguration>, Dictionary <cLexem, cSet <cConfiguration> > > >(_retList, _gotoResults)); }
//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]; } }
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; }
DataTable cm_fillDataTable(cProductInfo[] a_data) { cm_checkProducts(a_data); Dictionary <cLexem, int> _dicJump = new Dictionary <cLexem, int>(); for (int k = 0; k < a_data.Length; k++) { if (!_dicJump.ContainsKey(a_data[k].cp_Root.Key)) { _dicJump.Add(a_data[k].cp_Root.Key, a_data[k].cp_Root.Value); } } DataTable _retDT = new DataTable("table"); _retDT.Columns.Add("i", typeof(int)); _retDT.Columns.Add("terminals", typeof(string[]) /*typeof(object)*/); _retDT.Columns.Add("jump", typeof(int)); _retDT.Columns.Add("accept", typeof(bool)); _retDT.Columns.Add("stack", typeof(bool)); _retDT.Columns.Add("return", typeof(bool)); _retDT.Columns.Add("error", typeof(bool)); _retDT.Columns.Add("action", typeof(string)); int _count = a_data.Length; bool _warning = false; for (int k = 0; k < _count; k++) { cProductInfo _info = a_data[k]; // Проверка LL(1) if (k == 0 || a_data[k - 1].cp_Root.Key != _info.cp_Root.Key) { _warning = _info.cp_Root.Key.cm_HasEpsilonProduct(); } foreach (cLexem _lex in _info.cp_ArrDirLexems) { if (cf_follow[_info.cp_Root.Key].ContainsKey(_lex)) { if (_warning) { throw new Exception("Невозможно однозначно определить переход из-за " + cLexem.cc_Epsilon + "-порождающей продукции в " + _info.cp_Root.Key + "."); } if (_lex.cp_Type != eLexType.Epsilon) { _warning = true; } } else if (_lex.cp_Type == eLexType.Epsilon) { if (_warning) { throw new Exception("Невозможно однозначно определить переход из-за " + cLexem.cc_Epsilon + "-порождающей продукции в " + _info.cp_Root.Key + "."); } _warning = true; } } int _i = _info.cp_Root.Value; cSet <string> _terminals = new cSet <string>(); foreach (cLexem _lex in _info.cp_ArrDirLexems) { if (_lex.cp_Type == eLexType.Terminal) { _terminals.Add(_lex.cf_Name); } } int _jump = _info.cp_ArrLexems[0].Value; bool _accept = false; bool _stack = false; bool _return = false; bool _error = false; if (k == _count - 1 || a_data[k + 1].cp_Root.Key != _info.cp_Root.Key) { _error = true; } string _action = ""; //_terminals.Sort(); _retDT.Rows.Add(_i, _terminals.ToArray(), _jump, _accept, _stack, _return, _error, _action); KeyValuePair <cLexem, int>[] _arrLexems = _info.cp_ArrLexems; int _lexCount = _arrLexems.Length; for (int j = 0; j < _lexCount; j++) { cLexem _lexem = _arrLexems[j].Key; _i = _arrLexems[j].Value; // ERROR _error = true; // TERMINALS switch (_lexem.cp_Type) { case eLexType.Epsilon: _terminals = new cSet <string>(); //foreach (cLexem _lex in _info.cp_ArrDirLexems) // _terminals.Add(_lex.cf_Name); break; case eLexType.Terminal: _terminals = new cSet <string>(); _terminals.Add(_lexem.cf_Name); break; case eLexType.NonTerminal: _terminals = new cSet <string>(); foreach (cLexem _lex in _lexem.cp_LeadLexems) { if (_lex.cp_Type == eLexType.Epsilon) { if (j == _lexCount - 1) { _retDT.Rows.Add(_i + 1, new string[0], 0, false, false, true, true, ""); } _error = false; } else { _terminals.Add(_lex.cf_Name); } } break; case eLexType.Action: _terminals = new cSet <string>(); break; } // JUMP if (_lexem.cp_Type == eLexType.NonTerminal) { _jump = _dicJump[_lexem]; } else { // Не последний терминал или действие //if (j < _lexCount - 1) _jump = _i + 1; // Последний терминал или действие //else // _jump = 0; } // ACCEPT _accept = _lexem.cp_Type == eLexType.Terminal; // STACK // Не последний нетерминал правой части _stack = (_lexem.cp_Type == eLexType.NonTerminal && j < _lexCount - 1); // RETURN // Крайний правый терминал или действие _return = ((_lexem.cp_Type != eLexType.NonTerminal) && j == _lexCount - 1); // ACTION _action = ""; if (_lexem.cp_Type == eLexType.Action) { _action = _lexem.cf_Name; } //_terminals.Sort(); _retDT.Rows.Add(_i, _terminals.ToArray(), _jump, _accept, _stack, _return, _error, _action); } } // Сортировка строк DataTable _oldDT = _retDT; _retDT = _oldDT.Clone(); foreach (DataRow _dr in _oldDT.Select(null, "i")) { _retDT.Rows.Add(_dr.ItemArray); } return(_retDT); }
private bool cm_addToGoto(Dictionary <cSet <cConfiguration>, Dictionary <cLexem, cSet <cConfiguration> > > a_goto, cSet <cConfiguration> a_item, cLexem a_lexem, cSet <cConfiguration> a_gotoItem) { bool _retVal; if (!a_goto.ContainsKey(a_item)) { a_goto.Add(a_item, new Dictionary <cLexem, cSet <cConfiguration> >()); } if (!a_goto[a_item].ContainsKey(a_lexem)) { a_goto[a_item].Add(a_lexem, a_gotoItem); _retVal = true; } else { _retVal = false; throw new Exception("Попытка заменить значение в дереве Goto при построении списка пунктов"); } return(_retVal); }
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); }