private void DeleteTokens(RecoveryParser rp, int pos, ParsedSequence sequence, int tokensToDelete) { if (tokensToDelete <= 0) { return; } var text = rp.ParseResult.Text; var parseResult = rp.ParseResult; var grammar = parseResult.RuleParser.Grammar; var res = grammar.ParseAllNonVoidGrammarTokens(pos, parseResult); RemoveEmpty(res, pos); if (res.Count == 0) { return; } foreach (var nextPos in res) { if (CanDelete(text, pos, nextPos)) { ContinueDeleteTokens(rp, sequence, pos, nextPos, tokensToDelete); } } }
/// <summary> /// В позиции облома может находиться "грязь", т.е. набор символов которые не удается разобрать ни одним правилом токена /// доступным в CompositeGrammar в данном месте. Ни одно правило не сможет спарсить этот код, так что просто ищем /// следующий корректный токе и пропускаем все что идет до него (грязь). /// </summary> /// <returns>true - если грязь была удалена</returns> private bool TryDeleteGarbage(RecoveryParser rp, int maxPos, ParsedSequence sequence) { var text = rp.ParseResult.Text; if (maxPos >= text.Length) { return(false); } var parseResult = rp.ParseResult; var grammar = parseResult.RuleParser.Grammar; var res = grammar.ParseAllGrammarTokens(maxPos, parseResult); RemoveEmpty(res, maxPos); if (res.Count == 0) { var i = maxPos + 1; for (; i < text.Length; i++) // крутимся пока не будет распознан токен или достигнут конец строки { var res2 = grammar.ParseAllGrammarTokens(i, parseResult); RemoveEmpty(res2, i); if (res2.Count > 0) { break; } } _deletedToken[new ParsedSequenceAndSubrule(sequence, new ParsedSubrule(maxPos, i, s_loopState))] = true; rp.SubruleParsed(maxPos, i, new ParseRecord(sequence, 0, maxPos)); return(true); } return(false); }
private void CollectError(RecoveryParser rp, FlattenSequences results) { //var text = rp.ParseResult.Text; var expected = new Dictionary <NSpan, HashSet <ParsedSequenceAndSubrule> >(); var failSeq = default(ParsedSequence); var failSubrule = default(ParsedSubrule); var skipRecovery = false; foreach (var result in results) { var reverse = result.ToArray().Reverse(); foreach (var x in reverse) { var ins = x.TokenChanges; var seq = x.Seq; var subrule = x.Subrule; if (skipRecovery) { if (!ins.HasChanges && seq.ParsingSequence.RuleName != "s") { skipRecovery = false; //Debug.WriteLine(x); HashSet <ParsedSequenceAndSubrule> parsedNodes; var span = new NSpan(failSubrule.Begin, subrule.Begin); if (!expected.TryGetValue(span, out parsedNodes)) { parsedNodes = new HashSet <ParsedSequenceAndSubrule>(); expected[span] = parsedNodes; } if (failSubrule.IsEmpty) { parsedNodes.Add(new ParsedSequenceAndSubrule(failSeq, failSubrule)); } else { parsedNodes.Add(new ParsedSequenceAndSubrule(seq, subrule)); } } } else { if (ins.HasChanges) { failSeq = seq; failSubrule = subrule; skipRecovery = true; } } } } var parseResult = rp.ParseResult; foreach (var e in expected) { parseResult.ReportError(new ExpectedSubrulesError(new Location(parseResult.OriginalSource, e.Key.StartPos, e.Key.EndPos), e.Value)); } }
private void ContinueDeleteTokens(RecoveryParser rp, ParsedSequence sequence, int pos, int nextPos, int tokensToDelete) { _deletedToken[new ParsedSequenceAndSubrule(sequence, new ParsedSubrule(pos, nextPos, s_loopState))] = false; rp.SubruleParsed(pos, nextPos, new ParseRecord(sequence, 0, pos)); var parseResult = rp.ParseResult; var grammar = parseResult.RuleParser.Grammar; var res2 = grammar.ParseAllVoidGrammarTokens(nextPos, parseResult); RemoveEmpty(res2, nextPos); if (res2.Count == 0) DeleteTokens(rp, nextPos, sequence, tokensToDelete - 1); foreach (var nextPos2 in res2) { //_deletedToken[new ParsedSequenceAndSubrule(sequence, new ParsedSubrule(pos, nextPos2, s_loopState))] = false; rp.SubruleParsed(nextPos, nextPos2, new ParseRecord(sequence, s_loopState, pos)); DeleteTokens(rp, nextPos2, sequence, tokensToDelete - 1); } }
private bool CheckUnclosedToken(RecoveryParser rp) { var maxPos = rp.MaxPos; var grammar = rp.ParseResult.RuleParser.Grammar; var records = rp.Records[maxPos].ToArray(); var result = new SCG.Dictionary <ParseRecord, bool>(); var unclosedTokenFound = false; foreach (var record in records) { if (record.IsComplete) { continue; } if (record.Sequence.StartPos >= maxPos) { continue; } if (record.Sequence.ParsingSequence.IsNullable) { continue; } var res = IsInsideToken(result, grammar, record); if (!res) { continue; } unclosedTokenFound = true; rp.SubruleParsed(maxPos, maxPos, record); } return(unclosedTokenFound); }
public virtual int Strategy(ParseResult parseResult) { #if DebugThreading if (ThreadId != System.Threading.Thread.CurrentThread.ManagedThreadId) Debug.Assert(false); Debug.WriteLine(">>>> Strategy " + _id + " ThreadId=" + System.Threading.Thread.CurrentThread.ManagedThreadId); #endif //Debug.Assert(parseResult.RecoveryStacks.Count > 0); _parseResult = parseResult; #if DebugOutput Debug.IndentSize = 1; var timer = Stopwatch.StartNew(); Debug.WriteLine(RecoveryDebug.CurrentTestName + " -----------------------------------------------------------"); #endif _deletedToken.Clear(); var textLen = parseResult.Text.Length; var rp = new RecoveryParser(parseResult); rp.StartParse(parseResult.RuleParser);//, parseResult.MaxFailPos); var startSeq = rp.Sequences.First().Value; UpdateEarleyParseTime(); #if DebugOutput timer.Stop(); Debug.WriteLine("Earley parse took: " + timer.Elapsed); timer.Restart(); #endif RecoverAllWays(rp); UpdateRecoverAllWaysTime(); #if DebugOutput timer.Stop(); Debug.WriteLine("RecoverAllWays took: " + timer.Elapsed); timer.Restart(); #endif if (parseResult.TerminateParsing) throw new OperationCanceledException(); var memiozation = new Dictionary<ParsedSequenceKey, SequenceTokenChanges>(); FindBestPath(startSeq, textLen, memiozation); UpdateFindBestPathTime(); #if DebugOutput timer.Stop(); Debug.WriteLine("FindBestPath took: " + timer.Elapsed); timer.Restart(); #endif if (parseResult.TerminateParsing) throw new OperationCanceledException(); var results = FlattenSequence(new FlattenSequences() { Nemerle.Collections.NList.ToList(new SubruleTokenChanges[0]) }, parseResult, startSeq, textLen, memiozation[new ParsedSequenceKey(startSeq, textLen)].TotalTokenChanges, memiozation); //ParsePathsVisializer.PrintPaths(parseResult, _deletedToken, results); if (parseResult.TerminateParsing) throw new OperationCanceledException(); UpdateFlattenSequenceTime(); #if DebugOutput timer.Stop(); Debug.WriteLine("FlattenSequence took: " + timer.Elapsed); #endif CollectError(rp, results); #if DebugThreading Debug.WriteLine("<<<< Strategy " + _id + " ThreadId=" + System.Threading.Thread.CurrentThread.ManagedThreadId); #endif if (parseResult.TerminateParsing) throw new OperationCanceledException(); AstPatcher.Patch(startSeq, rp, memiozation); _parseResult = null; return parseResult.Text.Length; }
private void DeleteTokens(RecoveryParser rp, int pos, ParsedSequence sequence, int tokensToDelete) { if (tokensToDelete <= 0) return; var text = rp.ParseResult.Text; var parseResult = rp.ParseResult; var grammar = parseResult.RuleParser.Grammar; var res = grammar.ParseAllNonVoidGrammarTokens(pos, parseResult); RemoveEmpty(res, pos); if (res.Count == 0) return; foreach (var nextPos in res) if (CanDelete(text, pos, nextPos)) ContinueDeleteTokens(rp, sequence, pos, nextPos, tokensToDelete); }
private static HashSet<ParsedSequence> GetSequences(RecoveryParser rp, int maxPos) { return new SCG.HashSet<ParsedSequence>(rp.Records[maxPos].Select(r => r.Sequence)); }
/// <summary> /// В позиции облома может находиться "грязь", т.е. набор символов которые не удается разобрать ни одним правилом токена /// доступным в CompositeGrammar в данном месте. Ни одно правило не сможет спарсить этот код, так что просто ищем /// следующий корректный токе и пропускаем все что идет до него (грязь). /// </summary> /// <returns>true - если грязь была удалена</returns> private bool TryDeleteGarbage(RecoveryParser rp, int maxPos, ParsedSequence sequence) { var text = rp.ParseResult.Text; if (maxPos >= text.Length) return false; var parseResult = rp.ParseResult; var grammar = parseResult.RuleParser.Grammar; var res = grammar.ParseAllGrammarTokens(maxPos, parseResult); RemoveEmpty(res, maxPos); if (res.Count == 0) { var i = maxPos + 1; for (; i < text.Length; i++) // крутимся пока не будет распознан токен или достигнут конец строки { var res2 = grammar.ParseAllGrammarTokens(i, parseResult); RemoveEmpty(res2, i); if (res2.Count > 0) break; } _deletedToken[new ParsedSequenceAndSubrule(sequence, new ParsedSubrule(maxPos, i, s_loopState))] = true; rp.SubruleParsed(maxPos, i, new ParseRecord(sequence, 0, maxPos)); return true; } return false; }
private void CollectError(RecoveryParser rp, FlattenSequences results) { //var text = rp.ParseResult.Text; var expected = new Dictionary<NSpan, HashSet<ParsedSequenceAndSubrule>>(); var failSeq = default(ParsedSequence); var failSubrule = default(ParsedSubrule); var skipRecovery = false; foreach (var result in results) { var reverse = result.ToArray().Reverse(); foreach (var x in reverse) { var ins = x.TokenChanges; var seq = x.Seq; var subrule = x.Subrule; if (skipRecovery) { if (!ins.HasChanges && seq.ParsingSequence.RuleName != "s") { skipRecovery = false; //Debug.WriteLine(x); HashSet<ParsedSequenceAndSubrule> parsedNodes; var span = new NSpan(failSubrule.Begin, subrule.Begin); if (!expected.TryGetValue(span, out parsedNodes)) { parsedNodes = new HashSet<ParsedSequenceAndSubrule>(); expected[span] = parsedNodes; } if (failSubrule.IsEmpty) parsedNodes.Add(new ParsedSequenceAndSubrule(failSeq, failSubrule)); else parsedNodes.Add(new ParsedSequenceAndSubrule(seq, subrule)); } } else { if (ins.HasChanges) { failSeq = seq; failSubrule = subrule; skipRecovery = true; } } } } var parseResult = rp.ParseResult; foreach (var e in expected) parseResult.ReportError(new ExpectedSubrulesError(new Location(parseResult.OriginalSource, e.Key.StartPos, e.Key.EndPos), e.Value)); }
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); }
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(); }
public virtual int Strategy(ParseResult parseResult) { #if DebugThreading if (ThreadId != System.Threading.Thread.CurrentThread.ManagedThreadId) { Debug.Assert(false); } Debug.WriteLine(">>>> Strategy " + _id + " ThreadId=" + System.Threading.Thread.CurrentThread.ManagedThreadId); #endif //Debug.Assert(parseResult.RecoveryStacks.Count > 0); _parseResult = parseResult; #if DebugOutput Debug.IndentSize = 1; var timer = Stopwatch.StartNew(); Debug.WriteLine(RecoveryDebug.CurrentTestName + " -----------------------------------------------------------"); #endif _deletedToken.Clear(); var textLen = parseResult.Text.Length; var rp = new RecoveryParser(parseResult); rp.StartParse(parseResult.RuleParser);//, parseResult.MaxFailPos); var startSeq = rp.Sequences.First().Value; UpdateEarleyParseTime(); #if DebugOutput timer.Stop(); Debug.WriteLine("Earley parse took: " + timer.Elapsed); timer.Restart(); #endif RecoverAllWays(rp); UpdateRecoverAllWaysTime(); #if DebugOutput timer.Stop(); Debug.WriteLine("RecoverAllWays took: " + timer.Elapsed); timer.Restart(); #endif if (parseResult.TerminateParsing) { throw new OperationCanceledException(); } var memiozation = new Dictionary <ParsedSequenceKey, SequenceTokenChanges>(); FindBestPath(startSeq, textLen, memiozation); UpdateFindBestPathTime(); #if DebugOutput timer.Stop(); Debug.WriteLine("FindBestPath took: " + timer.Elapsed); timer.Restart(); #endif if (parseResult.TerminateParsing) { throw new OperationCanceledException(); } var results = FlattenSequence(new FlattenSequences() { Nemerle.Collections.NList.ToList(new SubruleTokenChanges[0]) }, parseResult, startSeq, textLen, memiozation[new ParsedSequenceKey(startSeq, textLen)].TotalTokenChanges, memiozation); //ParsePathsVisializer.PrintPaths(parseResult, _deletedToken, results); if (parseResult.TerminateParsing) { throw new OperationCanceledException(); } UpdateFlattenSequenceTime(); #if DebugOutput timer.Stop(); Debug.WriteLine("FlattenSequence took: " + timer.Elapsed); #endif CollectError(rp, results); #if DebugThreading Debug.WriteLine("<<<< Strategy " + _id + " ThreadId=" + System.Threading.Thread.CurrentThread.ManagedThreadId); #endif if (parseResult.TerminateParsing) { throw new OperationCanceledException(); } AstPatcher.Patch(startSeq, rp, memiozation); _parseResult = null; return(parseResult.Text.Length); }
private static HashSet <ParsedSequence> GetSequences(RecoveryParser rp, int maxPos) { return(new SCG.HashSet <ParsedSequence>(rp.Records[maxPos].Select(r => r.Sequence))); }
private bool CheckUnclosedToken(RecoveryParser rp) { var maxPos = rp.MaxPos; var grammar = rp.ParseResult.RuleParser.Grammar; var records = rp.Records[maxPos].ToArray(); var result = new SCG.Dictionary<ParseRecord, bool>(); var unclosedTokenFound = false; foreach (var record in records) { if (record.IsComplete) continue; if (record.Sequence.StartPos >= maxPos) continue; if (record.Sequence.ParsingSequence.IsNullable) continue; var res = IsInsideToken(result, grammar, record); if (!res) continue; unclosedTokenFound = true; rp.SubruleParsed(maxPos, maxPos, record); } return unclosedTokenFound; }
public virtual int Strategy(ParseResult parseResult) { #if DebugThreading if (ThreadId != System.Threading.Thread.CurrentThread.ManagedThreadId) { Debug.Assert(false); } Debug.WriteLine(">>>> Strategy " + _id + " ThreadId=" + System.Threading.Thread.CurrentThread.ManagedThreadId); #endif //Debug.Assert(parseResult.RecoveryStacks.Count > 0); _parseResult = parseResult; #if DebugOutput Debug.IndentSize = 1; var timer = Stopwatch.StartNew(); Debug.WriteLine(RecoveryDebug.CurrentTestName + " -----------------------------------------------------------"); #endif _deletedToken.Clear(); var rp = new RecoveryParser(parseResult); _recoveryParser = rp; rp.RecoveryFromAllErrors(); var errorCollector = new ErrorCollectorWalker(); errorCollector.Walk(parseResult); UpdateEarleyParseTime(); return(parseResult.Text.Length); throw new NotImplementedException(); #if DebugOutput timer.Stop(); Debug.WriteLine("Earley parse took: " + timer.Elapsed); timer.Restart(); #endif UpdateRecoverAllWaysTime(); #if DebugOutput timer.Stop(); Debug.WriteLine("RecoverAllWays took: " + timer.Elapsed); timer.Restart(); #endif if (parseResult.TerminateParsing) { throw new OperationCanceledException(); } UpdateFindBestPathTime(); #if DebugOutput timer.Stop(); Debug.WriteLine("FindBestPath took: " + timer.Elapsed); timer.Restart(); #endif if (parseResult.TerminateParsing) { throw new OperationCanceledException(); } if (parseResult.TerminateParsing) { throw new OperationCanceledException(); } UpdateFlattenSequenceTime(); #if DebugOutput timer.Stop(); Debug.WriteLine("FlattenSequence took: " + timer.Elapsed); #endif #if DebugThreading Debug.WriteLine("<<<< Strategy " + _id + " ThreadId=" + System.Threading.Thread.CurrentThread.ManagedThreadId); #endif if (parseResult.TerminateParsing) { throw new OperationCanceledException(); } _parseResult = null; return(parseResult.Text.Length); }