parboiled2
parboiled2 copied to clipboard
Add support for "continuation parsing"
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 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?
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 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?
@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.
@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?
Sorry, Alex, I currently don't have any capacity for this review. It'll have to wait for a few days.
NP.
I implemented continuation parsing with CPS. It computes. And other rules might be implemented in a same manner.
Things to note:
- is functions manipulations effective enough?
- how to avoid explicit typing
def apply[I <: HList: c.WeakTypeTag, O <: HList: c.WeakTypeTag](tree: Tree)
- how to avoid typing of
sealed abstract class ParserInput[T]
- 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.
- how to avoid explicit typing
def apply[I <: HList: c.WeakTypeTag, O <: HList: c.WeakTypeTag](tree: Tree)
Done.
I made rest of rules to pass tests, yet without continuation support. I would clean up, and then PR.