示例#1
0
        private ail.net.parser.EarleyParser.Item AddItem(ail.net.parser.EarleyParser.CoreItem xi_core_item, // core_item
                                                         ail.net.parser.EarleyParser.Chart xi_orig_chart,   // original chart recognition started
                                                         ail.net.parser.EarleyParser.Chart xi_master_chart, // chart to add to
                                                         ail.net.parser.EarleyParser.Item xi_lptr_item,     // l-ptr
                                                         ail.net.parser.EarleyParser.EFlags xi_action,      // action introduced this item
                                                         int xi_error_cost,                                 // error cost
                                                         bool xi_check_existence)
        {
            // no args assertion!!!
            ItemKey key;

            key.CoreItem      = xi_core_item;
            key.OriginalChart = xi_orig_chart;
            key.Lptr          = xi_lptr_item;

            ail.net.parser.EarleyParser.Item result = xi_check_existence ? (ail.net.parser.EarleyParser.Item)xi_master_chart.Items[key] : null;

            if (result == (object)null)
            {
                result = new ail.net.parser.EarleyParser.Item();
#if PRINT_STATS
                result.Id = xi_master_chart.Items.Count;
#endif
                result.CoreItem      = xi_core_item;
                result.OriginalChart = xi_orig_chart;
                result.MasterChart   = xi_master_chart;
                result.Lptr          = xi_lptr_item;
                result.Rptrs         = new Hashtable();
                result.Flags         = (uint)xi_action;

                xi_master_chart.Items.Add(key, result);

                // update optimization lists
                if (result.CoreItem.Dot == result.CoreItem.Rule.Rhs.Count ||
                    ((ail.net.parser.GrammarSymbol)result.CoreItem.Rule.Rhs[0]).Id == (int)ail.net.parser.Token.EType.eEpsilon)
                {
                    result.MasterChart.CompleterItems.Add(result);
                    ExecuteCompleter = (xi_action & ail.net.parser.EarleyParser.EFlags.ePredictor) != 0 || (xi_action & ail.net.parser.EarleyParser.EFlags.eScanner) != 0;
                }
                else // if(result.CoreItem.Dot < result.CoreItem.Rule.Rhs.Count)
                {
                    if (((ail.net.parser.GrammarSymbol)result.CoreItem.Rule.Rhs[result.CoreItem.Dot]).IsNonTerminal())
                    {
                        if (!PredictedNonTerminals[((ail.net.parser.GrammarSymbol)result.CoreItem.Rule.Rhs[result.CoreItem.Dot]).Id])
                        {
                            result.MasterChart.PredictorItems.Add(result);
                        }

                        ExecutePredictor = (xi_action & ail.net.parser.EarleyParser.EFlags.eCompleter) != 0 || (xi_action & ail.net.parser.EarleyParser.EFlags.eScanner) != 0;
                    }
                    else
                    {
                        result.MasterChart.ScannerItems.Add(result);
                    }
                }
            }

            ail.net.framework.Assert.NonNullReference(result, "result");
            return(result);
        }
示例#2
0
        private ail.net.parser.EarleyParser.Chart Scan(ail.net.parser.EarleyParser.Chart xi_chart)
        {
            // SCANNER:
            //  if [A -> ... • a ..., j] is in S(i) and a = x(i)+1, add [A -> ... a • ..., j] to S(i+1)
            // no args assertion!!!
            ail.net.parser.EarleyParser.Chart result = null;

            if (xi_chart != (object)null)
            {
                for (int i = 0; i < xi_chart.ScannerItems.Count; i++)
                {
                    ail.net.parser.EarleyParser.Item item = (ail.net.parser.EarleyParser.Item)xi_chart.ScannerItems[i];

                    ail.net.parser.GrammarSymbol symbol = (ail.net.parser.GrammarSymbol)item.CoreItem.Rule.Rhs[item.CoreItem.Dot]; // item.CoreItem.Dot is inside rhs.count

                    if (symbol.Id == Lexer.Token.Type)
                    {
                        if (result == (object)null)
                        {
                            result = AddChart();
                        }

                        AddItem((ail.net.parser.EarleyParser.CoreItem)CoreItemTable[item.CoreItem.Id + 1],
                                item.OriginalChart,
                                result,
                                item,
                                ail.net.parser.EarleyParser.EFlags.eScanner,
                                GetErrorCost(item),
                                true);
                    }
                }
            }

            return(result);
        }
示例#3
0
        private void Predict(ail.net.parser.EarleyParser.Chart xi_chart)
        {
            // PREDICTOR:
            //  if [A -> ... • B ..., j] is in S(i), add [B -> • a(lpha), i] to S(i) for all rules B -> a(lpha)
            // no args assertion!!!
            if (xi_chart != (object)null)
            {
                for (int i = xi_chart.PredictedK; i < xi_chart.PredictorItems.Count; i++, xi_chart.PredictedK++)
                {
                    ail.net.parser.EarleyParser.Item item = (ail.net.parser.EarleyParser.Item)xi_chart.PredictorItems[i];

                    ail.net.parser.GrammarSymbol symbol = (ail.net.parser.GrammarSymbol)item.CoreItem.Rule.Rhs[item.CoreItem.Dot]; // item.CoreItem.Dot is inside rhs.count

                    if (symbol.IsNonTerminal() && !PredictedNonTerminals[symbol.Id])
                    {
                        foreach (ail.net.parser.EarleyParser.CoreItem core_item in (ArrayList)PredictTable[symbol.Id])
                        {
                            AddItem(core_item,
                                    xi_chart,
                                    xi_chart,
                                    null,
                                    ail.net.parser.EarleyParser.EFlags.ePredictor,
                                    GetErrorCost(item),
                                    Charts.Count == 1); // only check for initial chart, because items were introduced
                                                        // by pseudo-prediction in BuildInitialSet
                        }

                        PredictedNonTerminals[symbol.Id] = true; // marked as predicted
                    }
                }
            }
        }
示例#4
0
 private void SetRptr(ail.net.parser.EarleyParser.Item xi_item, ail.net.parser.EarleyParser.Item xi_rptr_item)
 {
     // no check for args!!!
     // check if item already has this rptr
     if (!xi_item.Rptrs.Contains(xi_rptr_item))
     {
         xi_item.Rptrs[xi_rptr_item] = xi_rptr_item; //!!!
     }
 }
示例#5
0
        private int SetErrorCost(ail.net.parser.EarleyParser.Item xi_item, int xi_value)
        {
            // no args assertion!!!
            ail.net.framework.Assert.Condition(xi_value <= ail.net.parser.EarleyParser.kMaxErrorCost, "ail.net.parser.EarleyParser.SetErrorCost: xi_value <= ail.net.parser.EarleyParser.kMaxErrorCost");

            uint result = (((uint)xi_value) << 24) & (uint)ail.net.parser.EarleyParser.EFlags.eErrorMask;

            xi_item.Flags &= ~(uint)ail.net.parser.EarleyParser.EFlags.eErrorMask;
            xi_item.Flags |= result;

            return((int)result);
        }
示例#6
0
        private void Complete(ail.net.parser.EarleyParser.Chart xi_chart)
        {
            // COMPLETER:
            //  if [A -> ... •, j] is in S(i), add [B -> ... A • ..., k] to S(i) for all items [B -> ... • A ..., k] in S(j)
            // no args assertion!!!
            if (xi_chart != (object)null)
            {
                for (int i = xi_chart.CompletedK; i < xi_chart.CompleterItems.Count; i++, xi_chart.CompletedK++)
                {
                    ail.net.parser.EarleyParser.Item completer_item = (ail.net.parser.EarleyParser.Item)xi_chart.CompleterItems[i];

                    ail.net.parser.GrammarSymbol l_symbol = (ail.net.parser.GrammarSymbol)completer_item.CoreItem.Rule.Lhs[0];

                    ail.net.parser.EarleyParser.Chart chart = completer_item.OriginalChart;

                    for (int k = 0; k < chart.PredictorItems.Count; k++)
                    {
                        ail.net.parser.EarleyParser.Item preditor_item = (ail.net.parser.EarleyParser.Item)chart.PredictorItems[k];

                        ail.net.parser.GrammarSymbol r_symbol = (ail.net.parser.GrammarSymbol)preditor_item.CoreItem.Rule.Rhs[preditor_item.CoreItem.Dot]; // preditor_item.CoreItem.Dot is inside rhs.count

                        if (r_symbol.Id == l_symbol.Id)
                        {
                            ail.net.parser.EarleyParser.Item item = AddItem((ail.net.parser.EarleyParser.CoreItem)CoreItemTable[preditor_item.CoreItem.Id + 1],
                                                                            preditor_item.OriginalChart,
                                                                            xi_chart,
                                                                            preditor_item,
                                                                            ail.net.parser.EarleyParser.EFlags.eCompleter,
                                                                            GetErrorCost(preditor_item),
                                                                            true);
                            SetRptr(item, completer_item);

                            // if dot is before non-terminal and that non-terminal is nullable
                            // also add item with dot after that non-terminal
                            while (item.CoreItem.Dot < item.CoreItem.Rule.Rhs.Count &&
                                   ((ail.net.parser.GrammarSymbol)item.CoreItem.Rule.Rhs[item.CoreItem.Dot]).Nullable)
                            {
                                item = AddItem((ail.net.parser.EarleyParser.CoreItem)CoreItemTable[item.CoreItem.Id + 1],
                                               item.OriginalChart,
                                               xi_chart,
                                               item,
                                               ail.net.parser.EarleyParser.EFlags.eCompleter,
                                               GetErrorCost(item),
                                               true);
                                SetRptr(item, completer_item);
                            }
                        }
                    }
                }
            }
        }
示例#7
0
        private bool IsRecognizedItem(ail.net.parser.EarleyParser.Item xi_item)
        {
            ail.net.framework.Assert.NonNullReference(xi_item, "xi_item");

            bool result = false;

            if (xi_item.CoreItem.Rule.Lhs.Count > 0 && xi_item.OriginalChart != (object)null)
            {
                ail.net.parser.GrammarSymbol lhs_symbol = (ail.net.parser.GrammarSymbol)xi_item.CoreItem.Rule.Lhs[0];

                result = xi_item.CoreItem.Dot == xi_item.CoreItem.Rule.Rhs.Count && // dot at the end
                         lhs_symbol.Id == Grammar.StartSymbolId &&
                         xi_item.OriginalChart.Id == 0;
            }

            return(result);
        }
示例#8
0
        private void PopulateRhsStack(Stack xi_stack, ail.net.parser.EarleyParser.Item xi_item)
        {
            // no check for args!!!
            ail.net.parser.EarleyParser.Item item = xi_item;

            for (;;)
            {
                if (item == (object)null || item.CoreItem.Dot == 0)
                {
                    break;
                }

                xi_stack.Push(item);

                item = item.Lptr;
            }
        }
示例#9
0
            public int Compare(object xi_i1, object xi_i2)
            {
                ail.net.parser.EarleyParser.Item i1 = (ail.net.parser.EarleyParser.Item)xi_i1;
                ail.net.parser.EarleyParser.Item i2 = (ail.net.parser.EarleyParser.Item)xi_i2;

                int result = 0;

                if (i1.Id < i2.Id)
                {
                    result = -1;
                }
                else if (i1.Id > i2.Id)
                {
                    result = 1;
                }

                return(result);
            }
示例#10
0
        private string DecorateItem(ail.net.parser.EarleyParser.Item xi_item)
        {
            ail.net.framework.Assert.NonNullReference(xi_item, "xi_item");

            StringBuilder result = new StringBuilder();

#if PRINT_STATS
            result.Append(xi_item.Id + "  ");

            foreach (ail.net.parser.GrammarSymbol symbol in xi_item.CoreItem.Rule.Lhs)
            {
                result.Append(symbol.Name + " ");
            }

            result.Append("->");

            int i = 0;

            foreach (ail.net.parser.GrammarSymbol symbol in xi_item.CoreItem.Rule.Rhs)
            {
                if (i++ == xi_item.CoreItem.Dot)
                {
                    result.Append(" .");
                }

                if (symbol.Id != (int)ail.net.parser.Token.EType.eEpsilon)
                {
                    result.Append(" " + symbol.Name);
                }
            }

            if (xi_item.CoreItem.Dot == xi_item.CoreItem.Rule.Rhs.Count) // dot at the end
            {
                result.Append(" .");
            }

            result.Append(", [" + xi_item.OriginalChart.Id + "], ");

            if (xi_item.Lptr != (object)null && xi_item.Lptr.OriginalChart != (object)null)
            {
                result.Append(xi_item.Lptr.MasterChart.Id + "." + xi_item.Lptr.Id + ", ");
            }
            else
            {
                result.Append("null, ");
            }

            result.Append("<");

            if (xi_item.Rptrs.Count > 0)
            {
                ArrayList rptrs = new ArrayList(xi_item.Rptrs.Values);

                rptrs.Sort(new ail.net.parser.EarleyParser.ItemComparer());

                StringBuilder str = new StringBuilder();

                foreach (ail.net.parser.EarleyParser.Item item in rptrs)
                {
                    str.Append(item.MasterChart.Id + "." + item.Id + ", ");
                }

                result.Append(str.ToString().Substring(0, str.Length - 2));
            }
            else
            {
                result.Append("null");
            }

            result.Append(">, ");

            if ((xi_item.Flags & (uint)ail.net.parser.EarleyParser.EFlags.eInitAction) != 0)
            {
                result.Append("[i]");
            }
            else if ((xi_item.Flags & (uint)ail.net.parser.EarleyParser.EFlags.ePredictor) != 0)
            {
                result.Append("[p]");
            }
            else if ((xi_item.Flags & (uint)ail.net.parser.EarleyParser.EFlags.eCompleter) != 0)
            {
                result.Append("[c]");
            }
            else if ((xi_item.Flags & (uint)ail.net.parser.EarleyParser.EFlags.eScanner) != 0)
            {
                result.Append("[s]");
            }
            else if ((xi_item.Flags & (uint)ail.net.parser.EarleyParser.EFlags.eErrorScanner) != 0)
            {
                result.Append("[e]");
            }
#endif
            return(result.ToString());
        }
示例#11
0
 private int AddErrorCost(ail.net.parser.EarleyParser.Item xi_item, int xi_value)
 {
     // no args assertion!!!
     return(SetErrorCost(xi_item, GetErrorCost(xi_item) + xi_value));
 }
示例#12
0
 private int GetErrorCost(ail.net.parser.EarleyParser.Item xi_item)
 {
     // no args assertion!!!
     return((int)((((xi_item.Flags & (uint)ail.net.parser.EarleyParser.EFlags.eErrorMask)) >> 24) & 0x00000007));
 }
示例#13
0
        private ail.net.parser.EarleyParser.Chart ErrorScan(ail.net.parser.EarleyParser.Chart xi_chart)
        {
            // error case:
            //  if there is no any item with sybmol after dot equals to input symbol
            //  add to the next Set of items the following:
            //      for each item [A -> a(lpha) * a b(eta), ..., error_num] add to the next set
            //      [A -> a(lpha) * a b(eta), ..., error_num+1] and [A -> a(lpha) a * b(eta), ..., error_num+1],
            //      but only if error_num+1 <= MaxErrorValue
            // no args assertion!!!
            ail.net.parser.EarleyParser.Chart result = null;

            if (xi_chart != (object)null)
            {
                int [] error_costs = new int[xi_chart.Items.Count]; // reserve space for all items in set

                ail.net.framework.Assert.NonNullReference(Semantics, "Semantics");
                Semantics.HandleError(xi_chart, Lexer.Token, error_costs);

                int i = 0;

                for (int k = 0; k < xi_chart.ScannerItems.Count; k++)
                {
                    ail.net.parser.EarleyParser.Item item = (ail.net.parser.EarleyParser.Item)xi_chart.ScannerItems[k];

                    int error_cost = GetErrorCost(item);
                    error_cost += error_costs[i++];

                    // if the error value is less then maximum error value
                    if (error_cost <= ail.net.parser.EarleyParser.kMaxErrorCost)
                    {
                        if (result == (object)null)
                        {
                            result = AddChart();
                        }

                        // deletion of the current input symbol
                        if (result.Token.Type != (int)ail.net.parser.Token.EType.eEndOfStream)
                        {
                            AddItem((ail.net.parser.EarleyParser.CoreItem)CoreItemTable[item.CoreItem.Id],
                                    item.OriginalChart,
                                    result,
                                    item,
                                    ail.net.parser.EarleyParser.EFlags.eErrorScanner,
                                    error_cost,
                                    true);
                        }

                        // insertion of the terminal symbol after the dot to the input string,
                        // it is also changing input operation for other terminal symbols
                        AddItem((ail.net.parser.EarleyParser.CoreItem)CoreItemTable[item.CoreItem.Id + 1],
                                item.OriginalChart,
                                result,
                                item,
                                ail.net.parser.EarleyParser.EFlags.eErrorScanner,
                                error_cost,
                                true);
                    }
                }
            }

            return(result);
        }
示例#14
0
        private void BuildAstLevel(ail.net.parser.EarleyParser.Item xi_item, ail.net.parser.AstNode xi_root_node)
        {
            ail.net.framework.Assert.NonNullReference(xi_item, "xi_item");
            ail.net.framework.Assert.NonNullReference(xi_root_node, "xi_root_node");

            // populate a rhs stack with items of the current level
            Stack rhs_stack = new Stack();

            PopulateRhsStack(rhs_stack, xi_item);

            // processing all nodes(items) of the level
            while (rhs_stack.Count > 0)
            {
                ail.net.parser.EarleyParser.Item curr_item = (ail.net.parser.EarleyParser.Item)rhs_stack.Pop();

                ail.net.parser.GrammarSymbol symbol = (ail.net.parser.GrammarSymbol)curr_item.CoreItem.Rule.Rhs[curr_item.CoreItem.Dot - 1]; // 'dot-1', because we pushed  items with 'dot' > 0

                if (symbol.IsTerminal())
                {
                    // handle terminal
                    Semantics.HandleTerminal(xi_root_node, curr_item.MasterChart.Token);
                }
                else if (symbol.IsNonTerminal())
                {
                    // handle non-terminal
                    if (curr_item.Rptrs.Count <= 1)
                    {
                        // r-ptr has exactly one element
                        ail.net.framework.Assert.Condition(curr_item.Rptrs.Count == 1,
                                                           "ail.net.parser.EarleyParser.BuildAstLevel: curr_item.Rptrs.Count == 1");

                        ail.net.parser.EarleyParser.Item r_ptr_item = (ail.net.parser.EarleyParser.Item)curr_item.Rptrs[0];

                        ail.net.parser.AstNode new_node = Semantics.HandleNonTerminalBefore(xi_root_node, r_ptr_item);

                        if (new_node != (object)null)
                        {
                            r_ptr_item.Flags |= (uint)ail.net.parser.EarleyParser.EFlags.eMarked;

                            BuildAstLevel(r_ptr_item, new_node);

                            r_ptr_item.Flags &= ~(uint)ail.net.parser.EarleyParser.EFlags.eMarked;
                        }

                        Semantics.HandleNonTerminalAfter(xi_root_node, r_ptr_item);
                    }
                    else
                    {
                        // r-ptr has more than one elements, ambiguity
                        foreach (ail.net.parser.EarleyParser.Item r_ptr_item in curr_item.Rptrs.Values)
                        {
                            if ((r_ptr_item.Flags & (uint)ail.net.parser.EarleyParser.EFlags.eMarked) == 0)
                            {
                                ail.net.parser.AstNode new_node = Semantics.HandleNonTerminalBefore(xi_root_node, r_ptr_item);

                                if (new_node != (object)null)
                                {
                                    r_ptr_item.Flags |= (uint)ail.net.parser.EarleyParser.EFlags.eMarked;

                                    BuildAstLevel(r_ptr_item, new_node);

                                    r_ptr_item.Flags &= ~(uint)ail.net.parser.EarleyParser.EFlags.eMarked;

                                    Semantics.HandleNonTerminalAfter(xi_root_node, r_ptr_item);

                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }