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