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