Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package main.Atoms
- import org.parboiled.scala._
- import main.StringNode
- import main.StringNode
- import org.parboiled.scala.rules.Rule0
- import scala.Predef._
- import main.StringNode
- import org.parboiled.Context
- import scala.collection.mutable
- class AString extends Parser {
- private def qString = rule { AString.q("'")() }
- private def qbString = rule { "q" ~ AString.q.values.map(_() ~ EMPTY).reduce((a, b) => a | b) }
- private def qqString = rule { AString.q("\"")() }
- private def qqbString = rule { "qq" ~ AString.qq.values.map(_() ~ EMPTY).reduce((a, b) => a | b) }
- private def String : Rule1[StringNode] = rule {
- (qString | qbString | qqString | qqbString) ~~> (StringNode(_, true))
- }
- }
- object AString {
- val qq = new mutable.HashMap[String, BracketsMatcher]()
- val q = new mutable.HashMap[String, BracketsMatcher]()
- for (pair <- List(
- ("(", ")", true),
- ("{", "}", true),
- ("@", "@", false),
- ("[", "]", true),
- ("/", "/", false),
- ("'", "'", false),
- ("\"", "\"", false)
- )
- ) {
- q(pair._1) = new BracketsMatcher(pair._1, pair._2, pair._3, false) { override val buildParseTree = true }
- qq(pair._1) = new BracketsMatcher(pair._1, pair._2, pair._3, true) { override val buildParseTree = true }
- }
- private val string = new AString { override val buildParseTree = true }
- def String = string.String
- }
- class BracketsMatcher(left : String, right : String, paired : Boolean, interpolate : Boolean) extends Parser {
- private def appendToSb(c: Char): Context[Any] => Unit = { ctx =>
- ctx.getValueStack.peek.asInstanceOf[StringBuilder].append(c)
- ()
- }
- private def appendToSb(c: String): Context[Any] => Unit = { ctx =>
- ctx.getValueStack.peek.asInstanceOf[StringBuilder].append(c)
- ()
- }
- private def rawCharacters = rule {
- push(new StringBuilder) ~ zeroOrMore(
- "\\" ~ right ~ appendToSb(right) |
- "\\" ~ appendToSb("\\") |
- normalChar
- )
- }
- private def interCalc: Rule0 =
- rule {
- "$" ~ BracketsMatcher.curly ~~% withContext((inner, ctx) => appendToSb("${" + inner.toString + "}")(ctx))
- }
- private def intepolateCharacters = rule {
- push(new StringBuilder) ~ zeroOrMore(
- "\\" ~ escapedChar |
- interCalc |
- normalChar
- )
- }
- private def escapedChar = rule {
- anyOf(s"$right\\/") ~:% withContext(appendToSb(_)(_)) |
- "b" ~ appendToSb('\b') |
- "f" ~ appendToSb('\f') |
- "n" ~ appendToSb('\n') |
- "r" ~ appendToSb('\r') |
- "t" ~ appendToSb('\t') |
- unicode ~~% withContext((code, ctx) => appendToSb(code.asInstanceOf[Char])(ctx))
- }
- private def normalChar = rule {
- !anyOf(s"$right") ~ ANY ~:% (withContext(appendToSb(_)(_)))
- }
- private def unicode = rule {
- "u" ~ group(Number.hDigit ~ Number.hDigit ~ Number.hDigit ~ Number.hDigit) ~> (java.lang.Integer.parseInt(_, 16))
- }
- def apply() =
- if ( interpolate )
- left ~ intepolateCharacters ~ right ~~> (_.toString)
- else
- left ~ rawCharacters ~ right ~~> (_.toString)
- }
- object BracketsMatcher {
- private val curlyMatcher = new BracketsMatcher("{", "}", true, false) { override val buildParseTree = true }
- def curly = curlyMatcher()
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement