From 6a0844a9be28ab845272cf194773bf6a2b99c552 Mon Sep 17 00:00:00 2001 From: Johannes Rudolph Date: Tue, 8 Jul 2014 14:24:41 +0200 Subject: fix parsing to allow an arbitrary number of elements on the top-level, fixes #3 --- .../scala/spray/boilerplate/TemplateParser.scala | 22 ++++++++++++++-------- .../scala/spray/boilerplate/GeneratorSpecs.scala | 2 +- .../spray/boilerplate/TemplateParserSpecs.scala | 9 +++------ 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/main/scala/spray/boilerplate/TemplateParser.scala b/src/main/scala/spray/boilerplate/TemplateParser.scala index d42ba98..41d971b 100644 --- a/src/main/scala/spray/boilerplate/TemplateParser.scala +++ b/src/main/scala/spray/boilerplate/TemplateParser.scala @@ -11,8 +11,11 @@ import java.lang.RuntimeException sealed trait TemplateElement case class Sequence(elements: Seq[TemplateElement]) extends TemplateElement +/** A string possibly containing patterns to replace */ case class LiteralString(literal: String) extends TemplateElement +/** A fixed string that shouldn't be changed */ case class FixedString(literal: String) extends TemplateElement +/** A region in which to apply expansions */ case class Expand(inner: TemplateElement, separator: String) extends TemplateElement object TemplateParser extends RegexParsers { @@ -33,19 +36,22 @@ object TemplateParser extends RegexParsers { def literal: Parser[LiteralString] = literalChars ^^ LiteralString def fixed: Parser[FixedString] = "##" ~> """\d+""".r ^^ (new String(_)) ^^ FixedString - - def outsideTemplate: Parser[FixedString]= """(?s).*?(?=(\[#)|(\z))""".r ^^ (FixedString(_)) + + def outsideTemplate: Parser[FixedString]= """(?s).+?(?=(\[#)|(\z))""".r ^^ (FixedString(_)) def expand: Parser[Expand] = "[#" ~> elements ~ "#" ~ separatorChars <~ "]" ^^ { case els ~ x ~ sep => Expand(els, sep.getOrElse(", ")) } - def embeddedTemplate:Parser[TemplateElement] = opt(outsideTemplate)~expand~opt(outsideTemplate) ^^ { - case before~ex~after => Sequence(Seq(before,Some(ex),after).flatten) - } + def outsideElements: Parser[TemplateElement] = + rep1(expand | outsideTemplate) ^^ { + case one :: Nil => one + case several => Sequence(several) + } + def separatorChars: Parser[Option[String]] = rep("""[^\]]""".r) ^^ (_.reduceLeftOption(_ + _)) def parse(input:String): TemplateElement = - phrase(embeddedTemplate)(new scala.util.parsing.input.CharArrayReader(input.toCharArray)) match { + phrase(outsideElements)(new scala.util.parsing.input.CharArrayReader(input.toCharArray)) match { case Success(res,_) => res case x:NoSuccess => throw new RuntimeException(x.msg) } @@ -59,14 +65,14 @@ object TestParser extends App { println("-----End-----\n") } - check("""This text + check("""This text |should not be parsed |Tuple1 | [#Tuple1#] | |Product 1""".stripMargin) - + check("[#abc ##1 # ++ ]") check("[#abc Tuple##22 #]") check("[#abc Tuple1 #]") diff --git a/src/test/scala/spray/boilerplate/GeneratorSpecs.scala b/src/test/scala/spray/boilerplate/GeneratorSpecs.scala index 7651398..d88010b 100644 --- a/src/test/scala/spray/boilerplate/GeneratorSpecs.scala +++ b/src/test/scala/spray/boilerplate/GeneratorSpecs.scala @@ -5,7 +5,7 @@ import org.specs2.mutable.Specification class GeneratorSpecs extends Specification { "Generation" should { "keep outer template unchanged" in { - gen4("a1b2c3d4") === "a1b2c3d4" pendingUntilFixed + gen4("a1b2c3d4") === "a1b2c3d4" } "inflate 1 in expansion" in { gen4("[#a1#]") === "a1, a2, a3, a4" diff --git a/src/test/scala/spray/boilerplate/TemplateParserSpecs.scala b/src/test/scala/spray/boilerplate/TemplateParserSpecs.scala index 063eaa0..a0ff049 100644 --- a/src/test/scala/spray/boilerplate/TemplateParserSpecs.scala +++ b/src/test/scala/spray/boilerplate/TemplateParserSpecs.scala @@ -7,18 +7,15 @@ class TemplateParserSpecs extends Specification { "TemplateParser.parse" should { "without expansion" in { - parse("abc") === FixedString("abc") pendingUntilFixed + parse("abc") === FixedString("abc") } - "just expansion" in { - parse("[# def #]") === Expand(LiteralString(" def "), ", ") pendingUntilFixed + parse("[# def #]") === Expand(LiteralString(" def "), ", ") } - "multiple expansions" in { parse("[#a#]abc[#b#]") === - Sequence(List(Expand(LiteralString("a"), ", "), FixedString("abc"), Expand(LiteralString("b"), ", "))) pendingUntilFixed + Sequence(List(Expand(LiteralString("a"), ", "), FixedString("abc"), Expand(LiteralString("b"), ", "))) } - "one surrounded expansion" in { parse("abc[#a#]def") === Sequence(List(FixedString("abc"), Expand(LiteralString("a"), ", "), FixedString("def"))) } -- cgit v1.2.3