Im trying to create a parser for a small language with commands including labels and goto:
...
lazy val cmds = opt("{")~>rep(cmd<~opt(";"))<~opt("}") ^^ {...}
lazy val cmd = ("if"~boolexpr~"then"~cmds~"else"~cmds
^^ { case _~b~_~c1~_~c2 => IFCMD(boolexpr,c1
| ident ~":="~numericLit ^^ {case i1~_~v => ASSIGN(i1,v) }
| "goto" ~>ident ^^ { case l => GOTO(l) }
| ident~":"~cmd ^^ { case l~_~c => <APPENDLABELTO_CORE>
...
the GOTO
, IFCMD
etc are case classes extending abstract class Core
In keeping with the functional/scala-like/immutable-objecty -way I'm thinking that defining Core
like this is wrong:
abstract class Core(var label:Option[String] = None )
but would allow me to replace the part with <APPENDLABELTO_CORE>
with:
| ident~":"~cmd ^^ { case l~_~c => c.label = Some(l); c }
Can anyone point out the "scalaish" way to do this?
( I've tried c copy (label=Some(l))
but the abstract base class hasn't got the automatic copy constructor magic )