Parslet: как буферизовать / разбирать данные постепенно - PullRequest
0 голосов
/ 06 ноября 2018

Я пишу синтаксический анализатор HTTP / 1 ответов с помощью parslet. Это работает, но только когда я отправляю всю полезную нагрузку.

У меня что-то вроде этого:

rule(:response) {
   response_line >> crlf >>
   header.repeat.as(:headers) >> crlf >>
   data.as(:data)
}
root :response

Но если я пропущу неполную полезную нагрузку, я получу:

parser.parse("HTTP/1.1 200 OK\r\n")
#=> Parslet::ParseFailed: Failed to match sequence (RESPONSE_LINE CRLF headers:(HEADER{0, }) CRLF data:DATA) at line 1 char 16.

Я бы хотел иметь возможность передавать байты парсеру без сбоев, по крайней мере, если они не нарушают ожидания. Есть ли способ как-то «буферизовать», пока какое-то правило не будет нарушено или все ожидания будут оправданы?

1 Ответ

0 голосов
/ 05 декабря 2018

Петрушка сопоставляет грамматику с целым документом.

Если вы хотите разрешить ему анализировать частичный документ, вам нужно определить свою грамматику так, чтобы отсутствующие части были необязательными.

Одним из подходов может быть определение грамматики, которая будет соответствовать любым элементам из заголовка, и определение группы захвата 'the_rest', которая соответствует 'any.repeat'

Тогда вы можете рекурсивно вызывать синтаксический анализатор каждый раз, когда вы получаете больше документов ... с "остальными" плюс все, что вы прочитали.

Каждый раз, когда вы звоните, вы возвращаете одну часть заголовка.

...