Guest User

Untitled

a guest
Feb 19th, 2018
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.21 KB | None | 0 0
  1. module CodeRay module Scanners
  2.  
  3. #A simple scanner for a simple language: Io
  4.  
  5. class Io < Scanner
  6.  
  7. register_for :io
  8.  
  9. RESERVED_WORDS = [ 'clone','init', 'method', 'list', 'vector', 'block', 'if','ifTrue','ifFalse','ifTrueIfFalse','then', 'for','loop',
  10. 'reverseForeach','foreach','map','continue','break','while','do','return',
  11. 'self','sender','target','proto','parent','protos']
  12.  
  13. PREDEFINED_TYPES = []
  14.  
  15. PREDEFINED_CONSTANTS = ['Object', 'Lobby',
  16. 'TRUE','true','FALSE','false','NULL','null','Null','Nil','nil','YES','NO']
  17.  
  18. IDENT_KIND = WordList.new(:ident).
  19. add(RESERVED_WORDS, :reserved).
  20. add(PREDEFINED_TYPES, :pre_type).
  21. add(PREDEFINED_CONSTANTS, :pre_constant)
  22.  
  23. ESCAPE = / [rbfnrtv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x
  24. UNICODE_ESCAPE = / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} /x
  25.  
  26. def scan_tokens tokens, options
  27.  
  28. state = :initial
  29.  
  30. until eos?
  31.  
  32. kind = :error
  33. match = nil
  34.  
  35. if state == :initial
  36.  
  37. if scan(/ \s+ | \\\n /x)
  38. kind = :space
  39.  
  40. elsif scan(%r! // [^\n\\]* (?: \\. [^\n\\]* )* | /\* (?: .*? \*/ | .* ) !mx)
  41. kind = :comment
  42.  
  43.  
  44. elsif scan(/ [-+*\/\$\@=<>?:;,!&^|()\[\]{}~%]+ | \.(?!\d) /x)
  45. kind = :operator
  46.  
  47. elsif match = scan(/ [A-Za-z_][A-Za-z_0-9]* /x)
  48. kind = IDENT_KIND[match]
  49. if kind == :ident and check(/:(?!:)/)
  50. match << scan(/:/)
  51. kind = :label
  52. end
  53.  
  54. elsif match = scan(/L?"/)
  55. tokens << [:open, :string]
  56. if match[0] == ?L
  57. tokens << ['L', :modifier]
  58. match = '"'
  59. end
  60. state = :string
  61. kind = :delimiter
  62.  
  63. elsif scan(/#\s*(\w*)/)
  64. kind = :preprocessor # FIXME multiline preprocs
  65. state = :include_expected if self[1] == 'include'
  66.  
  67. elsif scan(/ L?' (?: [^\'\n\\] | \\ #{ESCAPE} )? '? /ox)
  68. kind = :char
  69.  
  70. elsif scan(/0[xX][0-9A-Fa-f]+/)
  71. kind = :hex
  72.  
  73. elsif scan(/(?:0[0-7]+)(?![89.eEfF])/)
  74. kind = :oct
  75.  
  76. elsif scan(/(?:\d+)(?![.eEfF])/)
  77. kind = :integer
  78.  
  79. elsif scan(/\d[fF]?|\d*\.\d+(?:[eE][+-]?\d+)?[fF]?|\d+[eE][+-]?\d+[fF]?/)
  80. kind = :float
  81.  
  82. else
  83. getch
  84. end
  85.  
  86. elsif state == :string
  87. if scan(/[^\\"]+/)
  88. kind = :content
  89. elsif scan(/"/)
  90. tokens << ['"', :delimiter]
  91. tokens << [:close, :string]
  92. state = :initial
  93. next
  94. elsif scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox)
  95. kind = :char
  96. elsif scan(/ \\ | $ /x)
  97. kind = :error
  98. state = :initial
  99. else
  100. raise "else case \" reached; %p not handled." % peek(1), tokens
  101. end
  102.  
  103. elsif state == :include_expected
  104. if scan(/<[^>\n]+>?|"[^"\n\\]*(?:\\.[^"\n\\]*)*"?/)
  105. kind = :include
  106. state = :initial
  107.  
  108. elsif match = scan(/\s+/)
  109. kind = :space
  110. state = :initial if match.index ?\n
  111.  
  112. else
  113. getch
  114.  
  115. end
  116.  
  117. else
  118. raise 'else-case reached', tokens
  119.  
  120. end
  121.  
  122. match ||= matched
  123. raise [match, kind], tokens if kind == :error
  124.  
  125. tokens << [match, kind]
  126.  
  127. end
  128.  
  129. tokens
  130. end
  131.  
  132. end
  133.  
  134. end end
Add Comment
Please, Sign In to add comment