Advertisement
Guest User

Untitled

a guest
Mar 22nd, 2018
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.72 KB | None | 0 0
  1.  
  2. class Pos (val prog: String, val offs: Int, val line: Int, val col: Int){
  3. def this(prog: String) = this(prog, 0, 1, 1)
  4. def ch = if(offs == prog.length) -1 else prog(offs)
  5. def getCol = col
  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. override def toString = "(" + line + ", " + col + ")"
  12. }
  13.  
  14. object DomainTags extends Enumeration{
  15. type Tag = Value
  16. val WHITESPACE, IDENT, NUMBER10, NUMBER16, STR, END_OF_PROGRAM, ERROR = Value
  17. }
  18. import DomainTags ._
  19. class Scanner {
  20. def scan(start: Pos ): (Tag, Pos) =
  21. sys.error("syntax error at " + start)
  22. }
  23.  
  24. class Token(val start: Pos, scanner: Scanner){
  25. val (tag, follow) = start.ch match{
  26. case -1 => (END_OF_PROGRAM, start)
  27. case _ => scanner.scan(start)
  28. }
  29. def image = start.prog.substring(start.offs, follow.offs)
  30. def next = new Token(follow, scanner)
  31. }
  32.  
  33. trait Whitespaces extends Scanner{
  34. private def missWhitespace (pos: Pos): Pos = pos.ch match {
  35. case ' ' => missWhitespace(pos.inc)
  36. case '\t' => missWhitespace(pos.inc)
  37. case '\n' => missWhitespace(pos.inc)
  38. case _ => pos
  39. }
  40.  
  41. override def scan(start: Pos) = {
  42. val follow = missWhitespace(start)
  43. if(start != follow) (WHITESPACE, follow)
  44. else super.scan(start)
  45. }
  46. }
  47. trait Number10 extends Scanner {
  48. private def missNumber(pos: Pos): Pos = {
  49. if (pos.ch.toChar.isDigit) {missNumber(pos.inc)}
  50. else pos
  51. }
  52. override def scan(start: Pos) = {
  53. val follow = missNumber(start)
  54. if(start != follow) (NUMBER10, follow)
  55. else super.scan(start)
  56. }
  57. }
  58.  
  59. trait Number16 extends Scanner {
  60. private def missNumber(pos: Pos): Pos = {
  61. if (pos.ch.toChar.isDigit || (pos.ch.toChar == 'A') || (pos.ch.toChar == 'B') || (pos.ch.toChar == 'C') || (pos.ch.toChar == 'D') || (pos.ch.toChar == 'E') || (pos.ch.toChar == 'F')) {missNumber(pos.inc)}
  62. else pos
  63. }
  64. override def scan(start: Pos) = {
  65. val pos = start.inc;
  66. val follow = if((start.ch.toChar == '$') && (pos.ch.toChar.isDigit || (pos.ch.toChar == 'A') || (pos.ch.toChar == 'B') || (pos.ch.toChar == 'C') || (pos.ch.toChar == 'D') || (pos.ch.toChar == 'E') || (pos.ch.toChar == 'F'))) missNumber(start.inc) else start
  67. if(start != follow) (NUMBER16, follow)
  68. else super.scan(start)
  69. }
  70. }
  71. trait Ident extends Scanner {
  72. private def missI(pos: Pos): Pos = {
  73. if (pos.ch.toChar.isLetter || pos.ch.toChar.isDigit || pos.ch.toChar == '$' ) missI(pos.inc)
  74. else pos
  75. }
  76. override def scan(start: Pos) = {
  77. val follow = if(start.ch.toChar.isLetter) missI(start) else start
  78. if(start != follow) (IDENT, follow)
  79. else super.scan(start)
  80. }
  81. }
  82. trait Error extends Scanner {
  83. private def missMiss(pos: Pos): Pos = {
  84. if (!pos.ch.toChar.isLetter && !pos.ch.toChar.isDigit
  85. && !(pos.ch.toChar == ' ') && !(pos.ch.toChar == '\"') && !(pos.ch.toChar =='\t') && !(pos.ch.toChar =='\n')) missMiss(pos.inc)
  86. else pos
  87. }
  88. override def scan(start: Pos) = {
  89. val follow = missMiss(start)
  90. if(start != follow) (ERROR, follow)
  91. else super.scan(start)
  92. }
  93. }
  94. trait Str extends Scanner {
  95. private def missK(pos: Pos, temp: Pos, flag:Int, temp2: Pos): (Pos, Pos) = {
  96. if (pos.inc.getCol == 1 && pos.ch.toChar != '\\') (pos, temp.inc) else {
  97. if (pos.ch.toChar == '\"' && pos.inc.ch.toChar == '\"' && pos.offs == temp.offs) missK(pos.inc.inc, pos.inc, flag, pos.inc)
  98. else {
  99. if (pos.ch.toChar == '\"' && pos.inc.ch.toChar == '\"' && pos.offs != temp.offs) (pos.inc, pos.inc)
  100. else {
  101. if (pos.ch.toChar == '\"' && flag == 0) missK(pos.inc, temp.inc, 1, temp2)
  102. else {
  103. if (pos.ch.toChar == '\"' && flag == 1) (pos.inc, pos.inc)
  104. else {
  105. if (pos.ch == -1) (temp2.inc, temp2.inc.inc)
  106. else missK(pos.inc, temp.inc, flag, temp2)
  107. }
  108. }
  109. }
  110. }
  111. }
  112. }
  113.  
  114. override def scan(start: Pos) = {
  115. val (follow, temp) = if(start.ch.toChar == '\"') missK(start, start, 0, start) else (start, start)
  116. if (start != follow) {
  117. if (follow.offs == temp.offs) (STR, follow)
  118. else (ERROR, follow)
  119. }
  120.  
  121. else super.scan(start)
  122. }
  123. }
  124.  
  125.  
  126.  
  127. var t = new Token(
  128. new Pos("123 $123ABC 123$ \"abc\" \" \"\" \" i$1dsd ~~ lol12 \" abc \\n abc\" "), //"\" \"\"kcd124\"123 $12ABC \"\" \"\"\" 12$ABC\" "),
  129. new Scanner
  130. with Error
  131. with Ident
  132. with Str
  133. with Number16
  134. with Number10
  135. with Whitespaces
  136. )
  137.  
  138. while (t.tag != END_OF_PROGRAM) {
  139. println(t.tag.toString + " " + t.start + "-" + t.follow + ": " + t.image)
  140. t = t.next
  141. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement