while.scala
changeset 68 a09ecb1e7384
parent 66 9215b9fb8852
child 69 cc3f7908b942
equal deleted inserted replaced
67:1419b60f6b0e 68:a09ecb1e7384
       
     1 
       
     2 //:load matcher.scala
       
     3 
       
     4 // some regular expressions
       
     5 val SYM = RANGE("""ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz_""")
       
     6 val DIGIT = RANGE("0123456789")
       
     7 val ID = SEQ(PLUS(SYM)) ~ STAR(ALT(SYM, DIGIT)) 
       
     8 
       
     9 val BTAG = SEQS("<", WORD, ">") 
       
    10 val ETAG = SEQS("</", WORD, ">")
       
    11 
       
    12 val WHITESPACE = PLUS(RANGE(" \n"))
       
    13 
       
    14 // for classifying the strings that have been recognised
       
    15 abstract class Token
       
    16 case object T_WHITESPACE extends Token
       
    17 case class T_WORD(s: String) extends Token
       
    18 case class T_ETAG(s: String) extends Token
       
    19 case class T_BTAG(s: String) extends Token
       
    20 case class T_NT(s: String, rhs: List[Token]) extends Token
       
    21 
       
    22 val lexing_rules: List[Rule[Token]] = 
       
    23   List((BTAG, (s) => T_BTAG(s.mkString)),
       
    24        (ETAG, (s) => T_ETAG(s.mkString)),
       
    25        (WORD, (s) => T_WORD(s.mkString)),
       
    26        (WHITESPACE, (s) => T_WHITESPACE))
       
    27 
       
    28 // the tokenizer
       
    29 val T = Tokenizer(lexing_rules)
       
    30 
       
    31 // width for printing
       
    32 val WIDTH = 60
       
    33 
       
    34 
       
    35 def interpret(ts: List[Token], c: Int, ctr: List[String]) : Unit= ts match {
       
    36   case Nil => println(Console.RESET)
       
    37   case T_WHITESPACE::rest => print(Console.RESET + " "); interpret(rest, c + 1, ctr)
       
    38   case T_WORD(s)::rest => {
       
    39     val newstr = Console.RESET + ctr.reverse.mkString + s
       
    40     if (c + s.length < WIDTH) {
       
    41       print(newstr);
       
    42       interpret(rest, c + s.length, ctr)
       
    43     }
       
    44     else {
       
    45       print("\n" + newstr)
       
    46       interpret(rest, s.length, ctr)
       
    47     } 
       
    48   }
       
    49   case T_BTAG("<p>")::rest => print("\n"); interpret(rest, 0, ctr)
       
    50   case T_ETAG("</p>")::rest => print("\n"); interpret(rest, 0, ctr)
       
    51   case T_BTAG("<b>")::rest => interpret(rest, c, Console.BOLD :: ctr)
       
    52   case T_BTAG("<a>")::rest => interpret(rest, c, Console.UNDERLINED :: ctr)
       
    53   case T_BTAG("<cyan>")::rest => interpret(rest, c, Console.CYAN :: ctr)
       
    54   case T_BTAG("<red>")::rest => interpret(rest, c, Console.RED :: ctr)
       
    55   case T_BTAG("<blink>")::rest => interpret(rest, c, Console.BLINK :: ctr)
       
    56   case T_ETAG(_)::rest => interpret(rest, c, ctr.tail)
       
    57   case _::rest => interpret(rest, c, ctr)
       
    58 }
       
    59  
       
    60 interpret(T.fromFile("test.html"), 0, Nil)