Ladies_Man

#Scala Lab3 Traits COMPLETE

May 11th, 2016
149
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scala 3.76 KB | None | 0 0
  1.  
  2. class Pos private(val prog: String, val offs: Int, val line: Int, val col: Int) {
  3.     def this(prog: String) = this(prog, 0, 1, 1)
  4.  
  5.     def ch = if (offs == prog.length) -1 else prog.codePointAt(offs)
  6.  
  7.     def inc = ch match {
  8.         case '\n' => new Pos(prog, offs+1, line+1, 1)
  9.         case -1   => this
  10.         case _    => new Pos(prog, offs+1, line, col+1)
  11.     }
  12.  
  13.     override def toString = "(" + line + ", " + col + ")"
  14.  
  15.     def isLetter = if (ch >= 'a' && ch <= 'z') true else false
  16.  
  17.     def isDigit = if (ch >= '0' && ch <= '9') true else false
  18. }
  19.  
  20. object DomainTags extends Enumeration {
  21.     type Tag = Value
  22.     val WHITESPACE, IDENT, NUMBER, OPERATION, ERROR, END_OF_PROGRAM = Value
  23. }
  24.  
  25. import DomainTags._
  26.  
  27. class Scanner {
  28.     def scan(start: Pos): (Tag, Pos) = {
  29.         //sys.error("Syntax error at " + start)
  30.          (ERROR, start.inc)
  31.     }
  32. }
  33.  
  34. class Token(val start: Pos, scanner: Scanner) {
  35.     val (tag, follow) = start.ch match {
  36.       case -1 => (END_OF_PROGRAM, start)
  37.       case _  => scanner.scan(start)
  38.     }
  39.  
  40.     def image = start.prog.substring(start.offs, follow.offs)
  41.  
  42.     def next = new Token(follow, scanner)
  43. }
  44.  
  45.  
  46.  
  47. trait Whitespaces extends Scanner {
  48.     private def missWhitespace(pos: Pos): Pos = pos.ch match {
  49.         case ' '  => missWhitespace(pos.inc)
  50.         case '\t' => missWhitespace(pos.inc)
  51.         case '\n' => missWhitespace(pos.inc)
  52.         case _    => pos
  53.     }
  54.  
  55.     override def scan(start: Pos) = {
  56.         val follow = missWhitespace(start)
  57.         if (start != follow) (WHITESPACE, follow)
  58.         else super.scan(start)
  59.   }
  60. }
  61.  
  62.  
  63. // Вар 7
  64. // Идентификаторы: последовательности латинских букв и десятичных цифр, оканчивающиеся на цифру.
  65. // Числовые литералы: последовательности десятичных цифр, органиченные знаками «<» и «>».
  66. // Операции: «<=», «=», «==».
  67.  
  68.  
  69. trait Idents extends Scanner {
  70.  
  71.     private def recognizeIdent(pos: Pos): (Pos, Boolean) = pos.ch match {
  72.         case _ if pos.isDigit &&
  73.          (!pos.inc.isLetter && !pos.inc.isDigit)    => (pos.inc, false)
  74.         case _ if pos.isDigit                       => recognizeIdent(pos.inc)
  75.         case _ if pos.isLetter                      => recognizeIdent(pos.inc)
  76.         case _                                      => (pos, true)
  77.     }
  78.  
  79.     override def scan(start: Pos) = {
  80.         val (follow, err) =
  81.             if (start.isDigit || start.isLetter) recognizeIdent(start)
  82.             else (start, false)
  83.  
  84.         if (start != follow) {
  85.             if (err) (ERROR, follow)
  86.             else (IDENT, follow)
  87.         }
  88.         else super.scan(start)
  89.     }
  90. }
  91.  
  92.  
  93.  
  94. trait Numbers extends Scanner {
  95.  
  96.     private def recognizeNumber(pos: Pos): (Pos, Boolean) = pos.ch match {
  97.         case '<'                    => recognizeNumber(pos.inc)
  98.         case '>'                    => (pos.inc, false)
  99.         case _ if pos.isDigit       => recognizeNumber(pos.inc)
  100.         case _                      => (pos, true)
  101.     }
  102.  
  103.     override def scan(start: Pos) = {
  104.         val (follow, err) =
  105.             if ('<' == start.ch && start.inc.isDigit) recognizeNumber(start)
  106.             else (start, false)
  107.  
  108.         if (start != follow) {
  109.             if (err) (ERROR, follow)
  110.             else (NUMBER, follow)
  111.         }
  112.         else super.scan(start)
  113.     }
  114. }
  115.  
  116.  
  117.  
  118. trait Operations extends Scanner {
  119.  
  120.     override def scan(start: Pos) = {
  121.         val follow =
  122.             if ('<' == start.ch && '=' == start.inc.ch) start.inc.inc
  123.             else if ('=' == start.ch&& '=' == start.inc.ch) start.inc.inc
  124.                 else if ('=' == start.ch) start.inc
  125.                     else start
  126.  
  127.         if (start != follow) (OPERATION,  follow)
  128.         else super.scan(start)
  129.   }
  130. }
  131.  
  132. //X extends A with B, C, D.
  133. //Linearization(X) = X, D, C, B, A
  134. var t = new Token(
  135.     new Pos(" <   <456 <== <1337> == 4w3s0m3 1den7> 3rr0r "),
  136.     new Scanner
  137.       with Numbers
  138.       with Operations
  139.       with Idents
  140.       with Whitespaces
  141. )
  142.  
  143. while (t.tag != END_OF_PROGRAM) {
  144.     println(t.tag.toString + " " + t.start + "-" + t.follow + ": \t\t" + t.image)
  145.     t = t.next
  146. }
Advertisement
Add Comment
Please, Sign In to add comment