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 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 Closure(ail.net.parser.EarleyParser.Chart xi_chart) { // no args assertion!!! if (xi_chart != (object)null) { ExecutePredictor = ExecuteCompleter = true; for (;;) { int count = xi_chart.Items.Count; if (ExecutePredictor) { Predict(xi_chart); } if (ExecuteCompleter) { Complete(xi_chart); } if (xi_chart.Items.Count == count) { break; } } } }
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 IsChartCompleted(ail.net.parser.EarleyParser.Chart xi_chart) { ail.net.framework.Assert.NonNullReference(xi_chart, "xi_chart"); bool result = false; foreach (ail.net.parser.EarleyParser.Item item in xi_chart.Items.Values) { if (IsRecognizedItem(item)) { result = true; break; } } return(result); }
private ail.net.parser.EarleyParser.Chart AddChart() { // create ail.net.parser.EarleyParser.Chart result = new ail.net.parser.EarleyParser.Chart(); result.Id = Charts.Count; result.Items = new Hashtable(); result.PredictorItems = new ArrayList(); // items in predictor list result.CompleterItems = new ArrayList(); // items in completer list result.ScannerItems = new ArrayList(); // items in scanner list result.Token = (ail.net.parser.Token)Lexer.Token.Clone(); Charts.Add(result); // initialize Array.Copy(PredictedNonTerminalsZeroizer, PredictedNonTerminals, PredictedNonTerminalsZeroizer.Length); // zero out ail.net.framework.Assert.NonNullReference(result, "result"); return(result); }
private string DecorateChart(ail.net.parser.EarleyParser.Chart xi_chart) { ail.net.framework.Assert.NonNullReference(xi_chart, "xi_chart"); StringBuilder result = new StringBuilder(); #if PRINT_STATS ArrayList items = new ArrayList(xi_chart.Items.Values); items.Sort(new ail.net.parser.EarleyParser.ItemComparer()); foreach (ail.net.parser.EarleyParser.Item item in items) { result.Append("\t"); result.Append(DecorateItem(item)); result.Append(Environment.NewLine); } #endif return(result.ToString()); }
private ail.net.parser.EarleyParser.Chart BuildInitialSet() { // initial set S0 contains item [S' -> • S, 0] ail.net.parser.EarleyParser.Chart result = AddChart(); ArrayList core_items = (ArrayList)PredictTable[Grammar.StartSymbolId]; ail.net.framework.Assert.NonNullReference(core_items, "core_items"); foreach (ail.net.parser.EarleyParser.CoreItem core_item in core_items) { AddItem(core_item, result, result, null, ail.net.parser.EarleyParser.EFlags.eInitAction, 0, true); } return(result); }
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 bool BuildChartList() { // build initial set bool result = false; ail.net.parser.EarleyParser.Chart chart = BuildInitialSet(); if (chart != (object)null) { Closure(chart); result = true; // build list of sets (fixed point) for (;;) { ail.net.parser.EarleyParser.Chart prev_chart = chart; if (LexerMode == ail.net.parser.EarleyParser.ELexerMode.eIgnoreWhitespace) { // skip whitespace do { Lexer.NextLexeme(); }while(Lexer.Token.Type == (int)ail.net.parser.Token.EType.eWhiteSpace); } else { Lexer.NextLexeme(); } if (Lexer.Token.Type == (int)ail.net.parser.Token.EType.eEndOfStream) { if (IsChartCompleted(chart)) { Status = ail.net.parser.Parser.EStatus.eRecognized; } else { result = false; Status = ail.net.parser.Parser.EStatus.eFailed; chart = ErrorScan(prev_chart); Closure(chart); } break; } chart = Scan(chart); if (chart == null) { result = false; Status = ail.net.parser.Parser.EStatus.eFailed; chart = ErrorScan(prev_chart); if (chart == null) { break; } } Closure(chart); } } #if PRINT_STATS if (Charts.Count < 16) { Console.WriteLine(DecorateCharts()); } else { Console.WriteLine(DecorateChart((ail.net.parser.EarleyParser.Chart)Charts[Charts.Count - 1])); } #endif return(result); }