Last active
May 14, 2018 12:45
-
-
Save mostafa-asg/c0cc23d50341713501bf71d745c9d5ee to your computer and use it in GitHub Desktop.
Source code for this article: https://mostafa-asg.github.io/post/writing-internal-dsl-in-scala/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Dfa { | |
var states = Seq.empty[State] | |
var finalStates = Seq.empty[State] | |
var currentState : State = null | |
var input:String="" | |
val transition = new Transition | |
val transitionMap = transition.transitionMap | |
def states( block: => Seq[State] ): Dfa = { | |
states = block | |
this | |
} | |
def finalStates( block: => Seq[State] ): Dfa = { | |
finalStates = block | |
this | |
} | |
def transitions( f: Transition => Unit ): Dfa = { | |
f(transition) | |
this | |
} | |
def startFrom(start: State):Dfa = { | |
currentState=start | |
this | |
} | |
def withInput(input:String):Dfa = { | |
this.input=input | |
this | |
} | |
def run : Boolean = { | |
input.foreach { ch => | |
transitionMap.get( (currentState,ch) ) match { | |
case Some(state) => currentState=state | |
case None => throw new Exception(s"You must provide transition function for input '$ch' when state is ${currentState.toString}") | |
} | |
} | |
finalStates contains currentState | |
} | |
} | |
class Transition { | |
val transitionMap : scala.collection.mutable.HashMap[(State,Char),State] = | |
new scala.collection.mutable.HashMap() | |
def on(ch : Char) : TransitionFrom = new TransitionFrom(this,ch) | |
} | |
class TransitionFrom(val tr: Transition , val ch : Char) { | |
def from(s: State) : TransitionTo = new TransitionTo(tr,ch,s) | |
} | |
class TransitionTo(val tr:Transition , val ch : Char,val from:State) { | |
def to(s : State) : Unit = { | |
tr.transitionMap += (from,ch)->s | |
} | |
} | |
object Dfa { | |
def newDfa( f: Dfa => Unit ) : Dfa = { | |
val dfa = new Dfa | |
f(dfa) | |
dfa | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object Main { | |
def main(args: Array[String]): Unit = { | |
import Dfa._ | |
val dfa = newDfa { dfa => | |
dfa states { | |
Seq(S0, S1, S2, S3) | |
} | |
dfa finalStates { | |
Seq(S2) | |
} | |
dfa transitions { transition => | |
transition on '0' from S0 to S1 | |
transition on '1' from S0 to S3 | |
transition on '0' from S1 to S2 | |
transition on '1' from S1 to S1 | |
transition on '0' from S2 to S2 | |
transition on '1' from S2 to S1 | |
transition on '0' from S3 to S3 | |
transition on '1' from S3 to S3 | |
} | |
} startFrom S0 withInput "010101011110110110000" | |
val hasInputAccepted = dfa.run | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
sealed trait State | |
final case object S0 extends State | |
final case object S1 extends State | |
final case object S2 extends State | |
final case object S3 extends State |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment