2012-01-17 5 views
5

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

Обновление

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

Конечные вопросы:

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

FParsec работает на CharStream, поэтому ответ, вероятно, да. Тем не менее, я буду откладывать более качественные ответы (надеюсь). –

ответ

8

Нормальная версия FParsec (хотя и не Low-Trust version) считывает входной фрагмент-накрест, или «поблочно», как я называю его в CharStream documentation. Таким образом, если вы построите CharStream с System.IO.Stream, и содержимое достаточно велико, чтобы охватить несколько блоков CharStream, вы можете начать синтаксический анализ, прежде чем полностью восстановить вход.

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

Update

Ответ (ов) к вашим последним вопросам: 42.

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

  • Реализация Stream в виде кольцевого буфера, скорее всего, restrict the maximum distance over which you can backtrack.

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

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

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

+0

Спасибо, Стефан. Я пересмотрел свой вопрос, чтобы лучше отразить то, что я пытаюсь лучше понять. Сначала я был в восторге от подхода «CharStream», но заметка, которую я нашел ранее о асинхронном доступе к основному «потоку», заставила меня остановиться. –

+0

Будет что-то вроде этой работы? http://msdn.microsoft.com/en-us/magazine/cc163290.aspx –

+0

Я обновил свой ответ. Отвечает ли это на ваши вопросы? Я не уверен, какая заметка касается асинхронного доступа к основному «потоку», на который вы ссылаетесь. Не могли бы вы написать, где именно вы нашли эту заметку? –