Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import scala.collection.mutable.ListBuffer
- val openMobile = '['
- val closeMobile = ']'
- val sideDelimiter = '|'
- val elementDelimiter = ','
- trait Node
- case class Mobile(children: List[Node]) extends Node
- case class Leaf(weight: Double) extends Node
- def parse(mobile: String): Mobile = {
- var i = 0
- def parseMobile(subj: String): Mobile = {
- var started = false
- var right = false
- val nodes = ListBuffer.empty[Node]
- while (i < subj.length) {
- val c = subj.charAt(i)
- c match {
- case `openMobile` =>
- if (!started)
- started = true
- else
- nodes += parseMobile(subj)
- case `closeMobile` =>
- if (!started)
- throw new Exception("Closing mobile without opening it")
- else {
- i += 1
- return Mobile(nodes.toList)
- }
- case `sideDelimiter` =>
- if (!right)
- right = true
- else
- throw new Exception("More than one side delimiter")
- case `elementDelimiter` =>
- if (i + 1 < subj.length) {
- if (subj.charAt(i + 1) == sideDelimiter || subj.charAt(i + 1) == closeMobile)
- throw new Exception("Comma at invalid position")
- }
- else
- throw new Exception("Comma at invalid position")
- case _ =>
- val number = parseNumber(subj)
- nodes += Leaf(if(right) number else -number)
- }
- i += 1
- }
- Mobile(nodes.toList)
- }
- def parseNumber(subj: String): Double = {
- val buffer = StringBuilder.newBuilder
- var reachedDot = false
- while (i < subj.length) {
- subj.charAt(i) match {
- case '.' =>
- if (!reachedDot)
- reachedDot = true
- else
- throw new Exception("More dots than allowed")
- case `elementDelimiter` | `openMobile` | `closeMobile` | `sideDelimiter` if buffer.length > 0 =>
- i -= 1
- return buffer.toDouble
- case c =>
- if (c.isDigit)
- buffer.append(c)
- else
- throw new Exception(s"Invalid character '$c'")
- }
- i += 1
- }
- buffer.toDouble
- }
- if (mobile.charAt(0) == openMobile)
- parseMobile(mobile.replaceAll("\\s", ""))
- else
- throw new Exception("blargh")
- }
- parse("[1,2|4,[1,2|4,5]]");
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement