parboiled2 icon indicating copy to clipboard operation
parboiled2 copied to clipboard

Add support for "continuation parsing"

Open sirthias opened this issue 11 years ago • 10 comments

Currently parsing simply fails if the grammar expects more content after the current EOI (end of input) has been reached.

In an alternative mode the parser could return a continuation function that you can use to continue parsing once more input is available (e.g. because another network packet has arrived).

sirthias avatar Sep 16 '13 11:09 sirthias

@sirthias This is a next inspiring feature to implement, right?

How do you imagine an interface with that feature? I guess first bits should be as follows:

val cont1: Context = aParser.partialParse(input=string1)
val cont2: Context = aParser.partialParse(input=string2, context=cont1)
val result: Result = aParser.finalParse(input=string3, context=cont2)

WDYT?

alexander-myltsev avatar Oct 10 '13 12:10 alexander-myltsev

I guess I'd prefer changing the run method of the Parser class to this:

def run[L <: HList](rule: this.type ⇒ RuleN[L]): Either[Parser.Error, L] = ...

and introduce a Result type in the Parser companion object like this:

sealed trait Result[+L <: HList]
case class Value[L <: HList](value: L) extends Result[L]
case class Continuation[L <: HList](continuation: ParserInput => Result[L]) extends Result[L]
case class Error(position: Position, errorRules: Seq[RuleStack]) extends Result[Nothing]
case class Position(index: Int, line: Int, column: Int)
case class RuleStack(frames: Seq[RuleFrame])

Then we can add a startParsing method to the Parser class:

def startParsing[L <: HList](rule: this.type ⇒ RuleN[L]): Result[L]

sirthias avatar Oct 10 '13 12:10 sirthias

@sirthias I implemented first bits in my master branch. How to determine in code you provided if a string is last chunk of data or not?

alexander-myltsev avatar Oct 16 '13 13:10 alexander-myltsev

@sirthias Solved it by adding a flag:

case class Continuation[L <: HList](continuation: (ParserInput, Boolean) => Result[L]) extends Result[L]

Works with a string now. I will expand it to the rest of rules. And then PR.

alexander-myltsev avatar Oct 17 '13 08:10 alexander-myltsev

@sirthias please take a look at recent changes to master branch. It does some computations nevertheless there are yet problems with typing and error reporting to be fixed. I wonder if you find approach good enough from performance perspective?

alexander-myltsev avatar Oct 18 '13 07:10 alexander-myltsev

Sorry, Alex, I currently don't have any capacity for this review. It'll have to wait for a few days.

sirthias avatar Oct 18 '13 07:10 sirthias

NP.

alexander-myltsev avatar Oct 18 '13 08:10 alexander-myltsev

I implemented continuation parsing with CPS. It computes. And other rules might be implemented in a same manner.

Things to note:

  1. is functions manipulations effective enough?
  2. how to avoid explicit typing def apply[I <: HList: c.WeakTypeTag, O <: HList: c.WeakTypeTag](tree: Tree)
  3. how to avoid typing of sealed abstract class ParserInput[T]
  4. also I have an implementation with delimited-continuations. Code seems to be easier but I have typing issues.

Any suggestions on how to improve it are welcome.

alexander-myltsev avatar Nov 25 '13 14:11 alexander-myltsev

  1. how to avoid explicit typing def apply[I <: HList: c.WeakTypeTag, O <: HList: c.WeakTypeTag](tree: Tree)

Done.

alexander-myltsev avatar Nov 25 '13 23:11 alexander-myltsev

I made rest of rules to pass tests, yet without continuation support. I would clean up, and then PR.

alexander-myltsev avatar Nov 28 '13 21:11 alexander-myltsev