예제 #1
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);
        }
예제 #2
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);
      }
    }
예제 #3
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);
        }
예제 #4
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;
    }
예제 #5
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();
    }
예제 #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
    /// <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;
    }
예제 #8
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();
        }