import scala.util.parsing.combinator._
def ident : Parser = letter &&& rep(letter ||| digit)
def number : Parser = digit &&& rep(digit)
def list : Parser = chr('(') &&& opt(listElems) &&& chr(')')
def listElems : Parser = expr &&& (chr(',') &&& listElems ||| empty)
def expr : Parser = ident ||| number ||| list
class HResult {
private var name: String = ""
def named(n: String): this.type = {name=n; this}
}
def ~> (p: => HResult):HResult = (for(b <- p) yield b).named("~>")
*/
trait BaseElem
case class ExprElem(value: String) extends BaseElem { override def toString = value }
case class ListElems() extends BaseElem {
var list:List[BaseElem] = List()
def add(expr:BaseElem) = {
list = expr :: list
this
}
def head:BaseElem = list.head
}
case class ListElem extends BaseElem {
var list:List[ListElems] = List()
def add(elems:ListElems) = {
list = elems :: list
println("list::" + list)
this
}
def head:ListElems = list.head
}
class MyParsers extends Parsers {
type Elem = char
def mkString(cs:List[Any]) = cs.mkString("")
def letter = elem("LETTER", Character.isLetter _)
def digit = elem("DIGIT", Character.isDigit _)
def ident: Parser[String] = {
println("ident");
letter ~ (letter | digit).* ^^ { cs => cs match {
case ~(n, nList) => "" + n + nList.mkString } }
}
def number: Parser[String] = {
println("number");
digit ~ digit.* ^^ { cs => cs match {
case ~(n, nList) => ("" + n + nList.mkString)
}
}
}
val tree:ListElem = ListElem()
def list: Parser[ListElem] = '(' ~> listElems.? <~ ')' ^^ {cs => println("list:" + cs); tree}
def listElems: Parser[ListElems] = expr ~ (',' ~ listElems).* ^^ {cs =>
println("listElems:" + cs)
cs match {
case ~(l:ListElem, List()) => tree.add(ListElems()).head.add(l)
case ~(l:ListElem, _) => tree.head.add(l)
case ~(e:ExprElem, List()) => tree.add(ListElems()).head.add(e)
case ~(e:ExprElem, _) => tree.head.add(e)
}
}
def expr: Parser[ExprElem] = (ident | number | list).* ^^ {cs => println("expr:" + cs); ExprElem(cs.mkString) }
}
import scala.util.parsing.input.CharArrayReader
val p = new MyParsers
val input = new CharArrayReader("(aa,123,bb,(dd,ee))".toArray)
val ret = p.list(input)
ret.map(list =>
list.list foreach(elems =>
elems.list.foreach( x => println(x) )
))
0