private void RecoverAllWays(RecoveryParser rp) { // ReSharper disable once RedundantAssignment int maxPos = rp.MaxPos; var failPositions = new HashSet<int>(); var deleted = new List<Tuple<int, ParsedSequence>>(); do { var tmpDeleted = FindMaxFailPos(rp); if (rp.MaxPos != rp.ParseResult.Text.Length) UpdateParseErrorCount(); if (!CheckUnclosedToken(rp)) deleted.AddRange(tmpDeleted); else { } maxPos = rp.MaxPos; failPositions.Add(maxPos); var records = new SCG.Queue<ParseRecord>(rp.Records[maxPos]); var prevRecords = new SCG.HashSet<ParseRecord>(rp.Records[maxPos]); do { if (_parseResult.TerminateParsing) throw new OperationCanceledException(); while (records.Count > 0) { var record = records.Dequeue(); if (record.IsComplete) { rp.StartParseSubrule(maxPos, record); continue; } if (record.Sequence.IsToken) continue; foreach (var state in record.ParsingState.Next) { var newRecord = new ParseRecord(record.Sequence, state, maxPos); if (!rp.Records[maxPos].Contains(newRecord)) { records.Enqueue(newRecord); prevRecords.Add(newRecord); } } rp.SubruleParsed(maxPos, maxPos, record); rp.PredictionOrScanning(maxPos, record, false); } rp.Parse(); foreach (var record in rp.Records[maxPos]) if (!prevRecords.Contains(record)) records.Enqueue(record); prevRecords.UnionWith(rp.Records[maxPos]); } while (records.Count > 0); } while (rp.MaxPos > maxPos); foreach (var del in deleted) DeleteTokens(rp, del.Item1, del.Item2, NumberOfTokensForSpeculativeDeleting); rp.Parse(); }
private void RecoverAllWays(RecoveryParser rp) { // ReSharper disable once RedundantAssignment int maxPos = rp.MaxPos; var failPositions = new HashSet <int>(); var deleted = new List <Tuple <int, ParsedSequence> >(); do { var tmpDeleted = FindMaxFailPos(rp); if (rp.MaxPos != rp.ParseResult.Text.Length) { UpdateParseErrorCount(); } if (!CheckUnclosedToken(rp)) { deleted.AddRange(tmpDeleted); } else { } maxPos = rp.MaxPos; failPositions.Add(maxPos); var records = new SCG.Queue <ParseRecord>(rp.Records[maxPos]); var prevRecords = new SCG.HashSet <ParseRecord>(rp.Records[maxPos]); do { if (_parseResult.TerminateParsing) { throw new OperationCanceledException(); } while (records.Count > 0) { var record = records.Dequeue(); if (record.IsComplete) { rp.StartParseSubrule(maxPos, record); continue; } if (record.Sequence.IsToken) { continue; } foreach (var state in record.ParsingState.Next) { var newRecord = new ParseRecord(record.Sequence, state, maxPos); if (!rp.Records[maxPos].Contains(newRecord)) { records.Enqueue(newRecord); prevRecords.Add(newRecord); } } rp.SubruleParsed(maxPos, maxPos, record); rp.PredictionOrScanning(maxPos, record, false); } rp.Parse(); foreach (var record in rp.Records[maxPos]) { if (!prevRecords.Contains(record)) { records.Enqueue(record); } } prevRecords.UnionWith(rp.Records[maxPos]); }while (records.Count > 0); }while (rp.MaxPos > maxPos); foreach (var del in deleted) { DeleteTokens(rp, del.Item1, del.Item2, NumberOfTokensForSpeculativeDeleting); } rp.Parse(); }
private List<Tuple<int, ParsedSequence>> FindMaxFailPos(RecoveryParser rp) { // В следстии особенностей работы основного парсере некоторые правила могут с var result = new List<Tuple<int, ParsedSequence>>(3); int maxPos; do { maxPos = rp.MaxPos; int count; do { var records = rp.Records[maxPos].ToArray(); // to materialize collection // Среди текущих состояний могут быть эски. Находим их и засовываем их кишки в Эрли. foreach (var record in records) if (record.State >= 0) { var state = record.ParsingState; if (state.IsToken) { var simple = state as ParsingState.Simple; if (simple == null || simple.RuleParser.Descriptor.Name != "S" && simple.RuleParser.Descriptor.Name != "s") continue; rp.PredictionOrScanning(maxPos, record, false); } } count = records.Length; var sequences = GetSequences(rp, maxPos).ToArray(); foreach (var sequence in sequences) { if (sequence.IsToken) { // если последовательность - это эска, пробуем удалить за ней грязь или добавить ее в result для дальнешей попытки удаления токенов. if (sequence.ParsingSequence.RuleName == "s") { if (TryDeleteGarbage(rp, maxPos, sequence)) continue; result.Add(Tuple.Create(maxPos, sequence)); continue; } if (sequence.ParsingSequence.RuleName != "S") continue; } // Если в последовательнсости есть пропарсивания оканчивающиеся на место падения, добавляем кишки этого состояния в Эрли. // Это позволит, на следующем шаге, поискать в них эски. foreach (var subrule in sequence.ParsedSubrules) if (subrule.State >= 0 && subrule.End == maxPos && sequence.ParsingSequence.SequenceInfo != null) { var state = sequence.ParsingSequence.States[subrule.State]; if (state.IsToken) { var simple = state as ParsingState.Simple; if (simple == null || simple.RuleParser.Descriptor.Name != "S" && simple.RuleParser.Descriptor.Name != "s") continue; } rp.PredictionOrScanning(subrule.Begin, new ParseRecord(sequence, subrule.State, subrule.Begin), false); } } rp.Parse(); } while (count < rp.Records[maxPos].Count); } while (maxPos < rp.MaxPos); return result; }
private List <Tuple <int, ParsedSequence> > FindMaxFailPos(RecoveryParser rp) { // В следстии особенностей работы основного парсере некоторые правила могут с var result = new List <Tuple <int, ParsedSequence> >(3); int maxPos; do { maxPos = rp.MaxPos; int count; do { var records = rp.Records[maxPos].ToArray(); // to materialize collection // Среди текущих состояний могут быть эски. Находим их и засовываем их кишки в Эрли. foreach (var record in records) { if (record.State >= 0) { var state = record.ParsingState; if (state.IsToken) { var simple = state as ParsingState.Simple; if (simple == null || simple.RuleParser.Descriptor.Name != "S" && simple.RuleParser.Descriptor.Name != "s") { continue; } rp.PredictionOrScanning(maxPos, record, false); } } } count = records.Length; var sequences = GetSequences(rp, maxPos).ToArray(); foreach (var sequence in sequences) { if (sequence.IsToken) { // если последовательность - это эска, пробуем удалить за ней грязь или добавить ее в result для дальнешей попытки удаления токенов. if (sequence.ParsingSequence.RuleName == "s") { if (TryDeleteGarbage(rp, maxPos, sequence)) { continue; } result.Add(Tuple.Create(maxPos, sequence)); continue; } if (sequence.ParsingSequence.RuleName != "S") { continue; } } // Если в последовательнсости есть пропарсивания оканчивающиеся на место падения, добавляем кишки этого состояния в Эрли. // Это позволит, на следующем шаге, поискать в них эски. foreach (var subrule in sequence.ParsedSubrules) { if (subrule.State >= 0 && subrule.End == maxPos && sequence.ParsingSequence.SequenceInfo != null) { var state = sequence.ParsingSequence.States[subrule.State]; if (state.IsToken) { var simple = state as ParsingState.Simple; if (simple == null || simple.RuleParser.Descriptor.Name != "S" && simple.RuleParser.Descriptor.Name != "s") { continue; } } rp.PredictionOrScanning(subrule.Begin, new ParseRecord(sequence, subrule.State, subrule.Begin), false); } } } rp.Parse(); }while (count < rp.Records[maxPos].Count); }while (maxPos < rp.MaxPos); return(result); }