Advertisement
Guest User

Untitled

a guest
Oct 23rd, 2013
47
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scala 3.37 KB | None | 0 0
  1. package main.Atoms
  2.  
  3. import org.parboiled.scala._
  4. import main.StringNode
  5. import main.StringNode
  6. import org.parboiled.scala.rules.Rule0
  7. import scala.Predef._
  8. import main.StringNode
  9. import org.parboiled.Context
  10. import scala.collection.mutable
  11. class AString extends Parser {
  12.  
  13.   private def qString = rule { AString.q("'")() }
  14.  
  15.   private def qbString = rule { "q" ~ AString.q.values.map(_() ~ EMPTY).reduce((a, b) => a | b) }
  16.  
  17.   private def qqString = rule { AString.q("\"")() }
  18.  
  19.   private def qqbString = rule { "qq" ~ AString.qq.values.map(_() ~ EMPTY).reduce((a, b) => a | b) }
  20.  
  21.   private def String : Rule1[StringNode] = rule {
  22.     (qString | qbString | qqString | qqbString) ~~> (StringNode(_, true))
  23.   }
  24. }
  25.  
  26.  
  27. object AString {
  28.   val qq = new mutable.HashMap[String, BracketsMatcher]()
  29.   val q = new mutable.HashMap[String, BracketsMatcher]()
  30.   for (pair <- List(
  31.                      ("(", ")", true),
  32.                      ("{", "}", true),
  33.                      ("@", "@", false),
  34.                      ("[", "]", true),
  35.                      ("/", "/", false),
  36.                      ("'", "'", false),
  37.                      ("\"", "\"", false)
  38.                    )
  39.   ) {
  40.     q(pair._1) = new BracketsMatcher(pair._1, pair._2, pair._3, false) { override val buildParseTree = true }
  41.     qq(pair._1) = new BracketsMatcher(pair._1, pair._2, pair._3, true) { override val buildParseTree = true }
  42.   }
  43.  
  44.   private val string = new AString { override val buildParseTree = true }
  45.  
  46.   def String = string.String
  47. }
  48.  
  49. class BracketsMatcher(left : String, right : String, paired : Boolean, interpolate : Boolean) extends Parser {
  50.   private def appendToSb(c: Char): Context[Any] => Unit = { ctx =>
  51.     ctx.getValueStack.peek.asInstanceOf[StringBuilder].append(c)
  52.     ()
  53.   }
  54.  
  55.   private def appendToSb(c: String): Context[Any] => Unit = { ctx =>
  56.     ctx.getValueStack.peek.asInstanceOf[StringBuilder].append(c)
  57.     ()
  58.   }
  59.  
  60.   private def rawCharacters = rule {
  61.     push(new StringBuilder) ~ zeroOrMore(
  62.       "\\" ~ right ~ appendToSb(right) |
  63.       "\\" ~ appendToSb("\\") |
  64.       normalChar
  65.     )
  66.   }
  67.  
  68.   private def interCalc: Rule0 =
  69.     rule {
  70.       "$" ~ BracketsMatcher.curly ~~% withContext((inner, ctx) => appendToSb("${" + inner.toString + "}")(ctx))
  71.     }
  72.  
  73.   private def intepolateCharacters = rule {
  74.     push(new StringBuilder) ~ zeroOrMore(
  75.       "\\" ~ escapedChar |
  76.       interCalc          |
  77.       normalChar
  78.     )
  79.   }
  80.  
  81.   private def escapedChar = rule {
  82.     anyOf(s"$right\\/") ~:% withContext(appendToSb(_)(_)) |
  83.       "b" ~ appendToSb('\b') |
  84.       "f" ~ appendToSb('\f') |
  85.       "n" ~ appendToSb('\n') |
  86.       "r" ~ appendToSb('\r') |
  87.       "t" ~ appendToSb('\t') |
  88.       unicode ~~% withContext((code, ctx) => appendToSb(code.asInstanceOf[Char])(ctx))
  89.   }
  90.  
  91.   private def normalChar = rule {
  92.     !anyOf(s"$right") ~ ANY ~:% (withContext(appendToSb(_)(_)))
  93.   }
  94.  
  95.   private def unicode = rule {
  96.     "u" ~ group(Number.hDigit ~ Number.hDigit ~ Number.hDigit ~ Number.hDigit) ~> (java.lang.Integer.parseInt(_, 16))
  97.   }
  98.  
  99.  
  100.   def apply() =
  101.     if ( interpolate )
  102.       left ~ intepolateCharacters ~ right  ~~> (_.toString)
  103.     else
  104.       left ~ rawCharacters ~ right  ~~> (_.toString)
  105. }
  106.  
  107. object BracketsMatcher {
  108.   private val curlyMatcher = new BracketsMatcher("{", "}", true, false) { override val buildParseTree = true }
  109.   def curly = curlyMatcher()
  110. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement