예제 #1
0
파일: Recovery.cs 프로젝트: tomByrer/Nitra
        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);
                }
            }
        }
예제 #2
0
파일: Recovery.cs 프로젝트: tomByrer/Nitra
        /// <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);
        }
예제 #3
0
파일: Recovery.cs 프로젝트: tomByrer/Nitra
        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));
            }
        }
예제 #4
0
파일: Recovery.cs 프로젝트: tomByrer/Nitra
    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);
      }
    }
예제 #5
0
파일: Recovery.cs 프로젝트: tomByrer/Nitra
        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);
        }
예제 #6
0
파일: Recovery.cs 프로젝트: hwwang/Nitra
    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);
      }
    }
예제 #7
0
파일: Recovery.cs 프로젝트: hwwang/Nitra
    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;
    }
예제 #8
0
파일: Recovery.cs 프로젝트: hwwang/Nitra
    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);
    }
예제 #9
0
파일: Recovery.cs 프로젝트: hwwang/Nitra
 private static HashSet<ParsedSequence> GetSequences(RecoveryParser rp, int maxPos)
 {
   return new SCG.HashSet<ParsedSequence>(rp.Records[maxPos].Select(r => r.Sequence));
 }
예제 #10
0
파일: Recovery.cs 프로젝트: hwwang/Nitra
    /// <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;
    }
예제 #11
0
파일: Recovery.cs 프로젝트: hwwang/Nitra
    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));
    }
예제 #12
0
파일: Recovery.cs 프로젝트: hwwang/Nitra
    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;
    }
예제 #13
0
파일: Recovery.cs 프로젝트: tomByrer/Nitra
        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);
        }
예제 #14
0
파일: Recovery.cs 프로젝트: hwwang/Nitra
    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();
    }
예제 #15
0
파일: Recovery.cs 프로젝트: tomByrer/Nitra
        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();
        }
예제 #16
0
파일: Recovery.cs 프로젝트: tomByrer/Nitra
        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);
        }
예제 #17
0
파일: Recovery.cs 프로젝트: tomByrer/Nitra
 private static HashSet <ParsedSequence> GetSequences(RecoveryParser rp, int maxPos)
 {
     return(new SCG.HashSet <ParsedSequence>(rp.Records[maxPos].Select(r => r.Sequence)));
 }
예제 #18
0
파일: Recovery.cs 프로젝트: hwwang/Nitra
    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;
    }
예제 #19
0
        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);
        }