PrintView
(parsley-debug
)
The core parsley-debug
library contains one view, namely PrintView
. This can be
used in place of more advanced functionality present in the other "companion" libraries.
It is perhaps less featureful than the "vanilla" .debug
combinator, which supports breakpoints,
but does work cross platform and across all Scala versions. The advantage over .debug
, of course,
is that for large-scale debugging, @debuggable
is far more ergonomic to apply to a whole parser,
and gives more intermediate information. With no internal state, this view is reusable, however,
concurrent executions within a parser (if used with attachReusable
) may interleave and be confusing.
Please see the @parsley.debuggable
page first, as this is used
to provide meaningful names for this functionality.
Configuration
The PrintView
configuration is very simple. By default, the PrintView
object will print the
debug trace directly to Console.out
. It is possible to use the PrintView.apply
methods to
produce new views that print their output elsewhere: for instance to a file.
What does it look like?
As an example, here is the trace without @debuggable
:
import parsley.quick.*
import parsley.debug.combinator.*
import parsley.debug.PrintView
val hello = ( atomic(string("hello"))
| (string("hey")
| string("hi"))
)
// hello: Parsley[String] = parsley.Parsley@6dd11d0a
hello.attach(PrintView).parse("hey")
// |'s parse tree for input:
//
// hey
//
//
// [ | ]: ("{1}" [(1,1) -> (1,4)], Success - [ hey ])
// |
// +-[ atomic ]: ("" [(1,1) -> (1,1)], Failure)
// | |
// | +-[ string(hello) ]: ("he" [(1,1) -> (1,3)], Failure)
// |
// +-[ |(1) ]: ("{1}" [(1,1) -> (1,4)], Success - [ hey ])
// |
// +-[ string(hey)(1) ]: ("hey" [(1,1) -> (1,4)], Success - [ hey ])
// res0: parsley.Result[String, String] = Success(hey)
hello.attach(PrintView).parse("hi")
// |'s parse tree for input:
//
// hi
//
//
// [ | ]: ("{1}" [(1,1) -> (1,2)], Failure)
// |
// +-[ atomic ]: ("" [(1,1) -> (1,1)], Failure)
// | |
// | +-[ string(hello) ]: ("h" [(1,1) -> (1,2)], Failure)
// |
// +-[ |(1) ]: ("{1}" [(1,1) -> (1,2)], Failure)
// |
// +-[ string(hey)(1) ]: ("h" [(1,1) -> (1,2)], Failure)
// res1: parsley.Result[String, String] = Failure((line 1, column 1):
// unexpected "hi"
// expected "hello" or "hey"
// >hi
// ^^)
As you can see, without an @debuggable
annotation, this just prints the names of the combinators
used to construct the parser, which is ok here, but would be undecipherable for more complex parsers.
The rendering style is slightly different to the vanilla combinator as well, rendering in a tree
shape as opposed to using explicit entry/exit markers.