Фрагментированный синтаксический анализ с помощью FParsec

StackOverflow https://stackoverflow.com/questions/8891019

  •  29-10-2019
  •  | 
  •  

Вопрос

Можно ли отправлять входные данные в анализатор FParsec порциями, как из сокета?Если нет, возможно ли получить текущий результат и нераспределенную часть входного потока, чтобы я мог выполнить это?Я пытаюсь запустить фрагменты входных данных, поступающих из SocketAsyncEventArgs без буферизации целых сообщений.

Обновить

Причина, по которой следует отметить использование SocketAsyncEventArgs должен был обозначать, что отправка данных в CharStream может привести к асинхронному доступу к базовому Stream.В частности, я рассматриваю возможность использования циклического буфера для передачи данных, поступающих из сокета.Я помню, что в документации FParsec отмечалось, что лежащий в основе Stream доступ к нему не должен осуществляться асинхронно, поэтому я планировал вручную управлять фрагментированным синтаксическим анализом.

Окончательные вопросы:

  1. Могу ли я использовать кольцевой буфер под моим Stream переданный в CharStream?
  2. Разве мне не нужно беспокоиться о ручном управлении разделением на фрагменты в этом сценарии?
Это было полезно?

Решение

Обычная версия FParsec (хотя и не Версия с низким уровнем доверия) считывает входные данные по частям, или "по блокам", как я называю это в CharStream Документация.Таким образом, если вы построите CharStream из System.IO.Stream и контент достаточно велик, чтобы охватить несколько CharStream блоки, вы можете начать синтаксический анализ до того, как полностью восстановите входные данные.

Однако обратите внимание, что CharStream будет потреблять входной поток порциями фиксированного (но настраиваемого) размера, т.е.это вызовет Read способ проведения System.IO.Stream так часто, как это необходимо для заполнения всего блока.Следовательно, если вы проанализируете входные данные быстрее, чем сможете получить новые входные данные, то CharStream может блокироваться, даже если уже есть какой-то нераспределенный ввод, потому что ввода еще недостаточно для заполнения полного блока.

Обновить

Ответы на ваши основные вопросы: 42.

  • Как вы реализуете Stream из которого вы строите CharStream это полностью зависит от вас.Ограничение, которое, как вы помните, исключает параллельный доступ, применимо только к CharStream класс, который не является потокобезопасным.

  • Реализуя Stream поскольку циклический буфер, скорее всего, будет ограничьте максимальное расстояние, на которое вы можете вернуться назад.

  • Размер блока в CharStream влияет на то, как далеко вы можете вернуться назад, когда Stream не поддерживает поиск.

  • Самый простой способ асинхронного анализа входных данных - выполнить синтаксический анализ в асинхронной задаче (т. е.в фоновом потоке).В задаче вы могли бы просто синхронно прочитать сокет, или, если вы не доверяете буферизации ОС, вы могли бы использовать класс stream, такой как BlockingStream описано в статье, на которую вы ссылаетесь во втором комментарии ниже.

  • Если входные данные могут быть легко разделены на независимые блоки (например,строк для текстового формата на основе строк), возможно, было бы эффективнее разбить его на части самостоятельно, а затем анализировать входной фрагмент за фрагментом.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top