Advertisement
Ladies_Man

scala3 +restoration

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