From 85d0e62653160808357fb7f3f9b80c45554d7545 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Mon, 4 Mar 2013 13:55:07 -0600 Subject: hide the implementation of the parser --- src/main/scala/org/perl8/test/tap/Parser.scala | 186 +++++++++++++------------ 1 file changed, 99 insertions(+), 87 deletions(-) diff --git a/src/main/scala/org/perl8/test/tap/Parser.scala b/src/main/scala/org/perl8/test/tap/Parser.scala index 1ab192f..360b3af 100644 --- a/src/main/scala/org/perl8/test/tap/Parser.scala +++ b/src/main/scala/org/perl8/test/tap/Parser.scala @@ -12,9 +12,7 @@ import org.perl8.test.tap.Consumer._ class Parser private ( cb: TAPEvent => Unit, indent: String -) extends Parsers { - type Elem = Line - +) { def this (cb: TAPEvent => Unit = e => ()) = this(cb, "") @@ -22,6 +20,8 @@ class Parser private ( this(e => (), indent) def parse (input: InputStream): TAPResult = { + import parser._ + cb(StartEvent) tap(new LineReader(input)) match { case Success(result, _) => { @@ -38,105 +38,117 @@ class Parser private ( def parse (input: OutputStream): TAPResult = parse(input.toString) - def tap: Parser[TAPResult] = - planFirst | planLast + private val parser = new TAPParser(cb, indent) - private def planFirst: Parser[TAPResult] = - plan ~ rep(result) ^^ { case plan ~ results => - new TAPResult(plan, results) - } + private class TAPParser ( + cb: TAPEvent => Unit, + indent: String + ) extends Parsers { + type Elem = Line - private def planLast: Parser[TAPResult] = - rep(result) ~ plan ^^ { case results ~ plan => - new TAPResult(plan, results) - } + def tap: Parser[TAPResult] = + planFirst | planLast - private def plan: Parser[Plan] = - planLine ^^ { p => - cb(PlanEvent(p.plan)) - p.plan - } + private def planFirst: Parser[TAPResult] = + plan ~ rep(result) ^^ { case plan ~ results => + new TAPResult(plan, results) + } - private def result: Parser[TestResult] = - simpleResult | subtestResult + private def planLast: Parser[TAPResult] = + rep(result) ~ plan ^^ { case results ~ plan => + new TAPResult(plan, results) + } - private def simpleResult: Parser[TestResult] = - resultLine ^^ { r => - cb(ResultEvent(r.result)) - r.result - } + private def plan: Parser[Plan] = + planLine ^^ { p => + cb(PlanEvent(p.plan)) + p.plan + } - private def subtestResult: Parser[TestResult] = - subtest ~ simpleResult ^^ { case subtest ~ simpleResult => - new TestResult( - simpleResult.passed, - simpleResult.number, - simpleResult.description, - simpleResult.directive, - Some(subtest) - ) - } + private def result: Parser[TestResult] = + simpleResult | subtestResult - private def subtest: Parser[TAPResult] = - LineParser("subtest") { in => - // can't just return the result directly, because it's of a different - // type (the path dependent type associated with the new Parser instance - // we create here, rather than the path dependent type associated with - // this) - val subParser = new org.perl8.test.tap.Parser(e => (), in.first.indent) - subParser.tap(in) match { - case subParser.Success(p, rest) => Success(p, rest) - case subParser.Failure(m, rest) => Failure(m, rest) - case subParser.Error(m, rest) => Error(m, rest) + private def simpleResult: Parser[TestResult] = + resultLine ^^ { r => + cb(ResultEvent(r.result)) + r.result } - } - private def planLine: Parser[PlanLine] = LineParser("plan") { in => - val line = in.first - if (line.indent == indent) { - line match { - case p: PlanLine => - Success(p, in.rest) - case _ => - Failure("Plan line expected, but '" + line + "' found", in) + private def subtestResult: Parser[TestResult] = + subtest ~ simpleResult ^^ { case subtest ~ simpleResult => + new TestResult( + simpleResult.passed, + simpleResult.number, + simpleResult.description, + simpleResult.directive, + Some(subtest) + ) } - } - else { - Failure( - "Plan line expected, but " + - "'" + line + "' has incorrect indentation", - in - ) - } - } - private def resultLine: Parser[ResultLine] = LineParser("result") { in => - val line = in.first - if (line.indent == indent) { - line match { - case p: ResultLine => - Success(p, in.rest) - case _ => - Failure("Result line expected, but '" + line + "' found", in) + private def subtest: Parser[TAPResult] = + LineParser("subtest") { in => + // can't just return the result directly, because it's of a different + // type (the path dependent type associated with the new Parser instance + // we create here, rather than the path dependent type associated with + // this) + val subParser = new TAPParser( + e => (), + in.first.indent + ) + subParser.tap(in) match { + case subParser.Success(p, rest) => Success(p, rest) + case subParser.Failure(m, rest) => Failure(m, rest) + case subParser.Error(m, rest) => Error(m, rest) + } + } + + private def planLine: Parser[PlanLine] = LineParser("plan") { in => + val line = in.first + if (line.indent == indent) { + line match { + case p: PlanLine => + Success(p, in.rest) + case _ => + Failure("Plan line expected, but '" + line + "' found", in) + } + } + else { + Failure( + "Plan line expected, but " + + "'" + line + "' has incorrect indentation", + in + ) } } - else { - Failure( - "Result line expected, but " + - "'" + line + "' has incorrect indentation", - in - ) - } - } - private def LineParser[T] (lineType: String)( - body: Input => ParseResult[T] - ): Parser[T] = Parser { in => - if (in.atEnd) { - Failure(lineType + " line expected, but end of input found", in) + private def resultLine: Parser[ResultLine] = LineParser("result") { in => + val line = in.first + if (line.indent == indent) { + line match { + case p: ResultLine => + Success(p, in.rest) + case _ => + Failure("Result line expected, but '" + line + "' found", in) + } + } + else { + Failure( + "Result line expected, but " + + "'" + line + "' has incorrect indentation", + in + ) + } } - else { - body(in) + + private def LineParser[T] (lineType: String)( + body: Input => ParseResult[T] + ): Parser[T] = Parser { in => + if (in.atEnd) { + Failure(lineType + " line expected, but end of input found", in) + } + else { + body(in) + } } } -- cgit v1.2.3