From 3fb580276af6bc12861de42c0115c04549c98177 Mon Sep 17 00:00:00 2001 From: Johannes Rudolph Date: Wed, 10 Oct 2012 12:29:01 +0200 Subject: simplified syntax and provide a proper parser --- .../cc/spray/boilerplate/TemplateParser.scala | 50 ++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 src/main/scala/cc/spray/boilerplate/TemplateParser.scala (limited to 'src/main/scala/cc/spray/boilerplate/TemplateParser.scala') diff --git a/src/main/scala/cc/spray/boilerplate/TemplateParser.scala b/src/main/scala/cc/spray/boilerplate/TemplateParser.scala new file mode 100644 index 0000000..4e280a4 --- /dev/null +++ b/src/main/scala/cc/spray/boilerplate/TemplateParser.scala @@ -0,0 +1,50 @@ +package cc.spray.boilerplate + +import util.parsing.combinator.RegexParsers +import java.lang.RuntimeException + +sealed trait TemplateElement +case class Sequence(elements: Seq[TemplateElement]) extends TemplateElement +case class LiteralString(literal: String) extends TemplateElement +case class FixedString(literal: String) extends TemplateElement +case class Expand(inner: TemplateElement, separator: String) extends TemplateElement + +object TemplateParser extends RegexParsers { + override type Elem = Char + type Tokens = TemplateElement + override val skipWhitespace = false + + def elements: Parser[TemplateElement] = rep1(element) ^^ { + case one :: Nil => one + case several => Sequence(several) + } + + def element: Parser[TemplateElement] = literal | fixed | expand + + def literalChar: Parser[String] = """(?s:(?!\[#)(?!#[^\]]*\]).)""".r + def literalChars: Parser[String] = rep1(literalChar) ^^ { _.reduceLeft(_ + _) } + + def literal: Parser[LiteralString] = literalChars ^^ LiteralString + + def fixed: Parser[FixedString] = "##" ~> ".".r ^^ (new String(_)) ^^ FixedString + + def expand: Parser[Expand] = "[#" ~> elements ~ "#" ~ separatorChars <~ "]" ^^ { + case els ~ x ~ sep => Expand(els, sep.getOrElse(", ")) + } + + def separatorChars: Parser[Option[String]] = rep("""[^\]]""".r) ^^ (_.reduceLeftOption(_ + _)) + + def parse(input:String): TemplateElement = + phrase(elements)(new scala.util.parsing.input.CharArrayReader(input.toCharArray)) match { + case Success(res,_) => res + case x:NoSuccess => throw new RuntimeException(x.msg) + } +} + +object TestParser extends App { + def check(format: String) { + println(TemplateParser.parse(format)) + } + + check("[#abc ##1 # ++ ]") +} \ No newline at end of file -- cgit v1.2.3