progs/display/thompson2.scala
changeset 487 a697421eaa04
child 488 598741d39d21
equal deleted inserted replaced
486:8178fcf377dc 487:a697421eaa04
       
     1 // Thompson Construction (Part 2)
       
     2 
       
     3 // some more types abbreviations
       
     4 type NFAtrans = (TState, Char) :=> Set[TState]
       
     5 type eNFAtrans = (TState, Option[Char]) :=> Set[TState]
       
     6 
       
     7 
       
     8 // for composing an eNFA transition with a NFA transition
       
     9 implicit class RichPF(val f: eNFAtrans) extends AnyVal {
       
    10   def +++(g: NFAtrans) : eNFAtrans = 
       
    11   { case (q, None) =>  applyOrElse(f, (q, None)) 
       
    12     case (q, Some(c)) => 
       
    13       applyOrElse(f, (q, Some(c))) | applyOrElse(g, (q, c))  }
       
    14 }
       
    15 
       
    16 // sequence of two NFAs
       
    17 def NFA_SEQ(enfa1: NFAt, enfa2: NFAt) : NFAt = {
       
    18   val new_delta : eNFAtrans = 
       
    19     { case (q, None) if enfa1.fins(q) => enfa2.starts }
       
    20   
       
    21   eNFA(enfa1.starts, new_delta +++ enfa1.delta +++ enfa2.delta, 
       
    22        enfa2.fins)
       
    23 }
       
    24 
       
    25 // alternative of two NFAs
       
    26 def NFA_ALT(enfa1: NFAt, enfa2: NFAt) : NFAt = {
       
    27   val Q = TState()
       
    28   val new_delta : eNFAtrans = 
       
    29     { case (Q, None) => enfa1.starts | enfa2.starts }
       
    30   val new_fins = (q: TState) => enfa1.fins(q) || enfa2.fins(q)
       
    31 
       
    32   eNFA(Set(Q), new_delta +++ enfa1.delta +++ enfa2.delta, 
       
    33        new_fins)
       
    34 }
       
    35 
       
    36 // star of a NFA
       
    37 def NFA_STAR(enfa: NFAt) : NFAt = {
       
    38   val Q = TState()
       
    39   val new_delta : eNFAtrans = 
       
    40     { case (Q, None) => enfa.starts
       
    41       case (q, None) if enfa.fins(q) => Set(Q) }
       
    42 
       
    43   eNFA(Set(Q), new_delta +++ enfa.delta, Set(Q))
       
    44 }