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>()); } }
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); }
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; }