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_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);
        }
Beispiel #3
0
        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));
        }
Beispiel #4
0
        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>());
            }
        }
Beispiel #5
0
        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;
        }
Beispiel #6
0
        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);
        }