yard 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of yard might be problematic. Click here for more details.

Files changed (264) hide show
  1. data/{LICENSE.txt → LICENSE} +1 -1
  2. data/README +211 -0
  3. data/Rakefile +31 -0
  4. data/benchmarks/builtins_vs_eval.rb +23 -0
  5. data/benchmarks/erb_vs_erubis.rb +53 -0
  6. data/benchmarks/generation.rb +37 -0
  7. data/benchmarks/parsing.rb +33 -0
  8. data/bin/view_generator +17 -0
  9. data/bin/yard-graph +4 -0
  10. data/bin/yardoc +1 -93
  11. data/bin/yri +12 -3
  12. data/lib/yard.rb +10 -5
  13. data/lib/yard/autoload.rb +116 -0
  14. data/lib/yard/cli/yard_graph.rb +86 -0
  15. data/lib/yard/cli/yardoc.rb +131 -0
  16. data/lib/yard/code_objects/base.rb +321 -0
  17. data/lib/yard/code_objects/class_object.rb +89 -0
  18. data/lib/yard/code_objects/class_variable_object.rb +4 -0
  19. data/lib/yard/code_objects/constant_object.rb +4 -0
  20. data/lib/yard/code_objects/method_object.rb +51 -0
  21. data/lib/yard/code_objects/module_object.rb +4 -0
  22. data/lib/yard/code_objects/namespace_object.rb +88 -0
  23. data/lib/yard/code_objects/proxy.rb +183 -0
  24. data/lib/yard/code_objects/root_object.rb +8 -0
  25. data/lib/yard/core_ext/file.rb +26 -0
  26. data/lib/yard/core_ext/logger.rb +5 -0
  27. data/lib/yard/core_ext/module.rb +9 -0
  28. data/lib/yard/core_ext/string.rb +13 -0
  29. data/lib/yard/core_ext/symbol_hash.rb +24 -0
  30. data/lib/yard/generators/attributes_generator.rb +22 -0
  31. data/lib/yard/generators/base.rb +285 -0
  32. data/lib/yard/generators/class_generator.rb +25 -0
  33. data/lib/yard/generators/constants_generator.rb +73 -0
  34. data/lib/yard/generators/constructor_generator.rb +25 -0
  35. data/lib/yard/generators/deprecated_generator.rb +15 -0
  36. data/lib/yard/generators/docstring_generator.rb +15 -0
  37. data/lib/yard/generators/full_doc_generator.rb +59 -0
  38. data/lib/yard/generators/helpers/base_helper.rb +52 -0
  39. data/lib/yard/generators/helpers/filter_helper.rb +21 -0
  40. data/lib/yard/generators/helpers/html_helper.rb +137 -0
  41. data/lib/yard/generators/helpers/method_helper.rb +27 -0
  42. data/lib/yard/generators/helpers/uml_helper.rb +16 -0
  43. data/lib/yard/generators/inheritance_generator.rb +16 -0
  44. data/lib/yard/generators/method_details_generator.rb +18 -0
  45. data/lib/yard/generators/method_generator.rb +31 -0
  46. data/lib/yard/generators/method_listing_generator.rb +105 -0
  47. data/lib/yard/generators/method_missing_generator.rb +25 -0
  48. data/lib/yard/generators/method_signature_generator.rb +19 -0
  49. data/lib/yard/generators/method_summary_generator.rb +21 -0
  50. data/lib/yard/generators/mixins_generator.rb +15 -0
  51. data/lib/yard/generators/module_generator.rb +22 -0
  52. data/lib/yard/generators/quick_doc_generator.rb +31 -0
  53. data/lib/yard/generators/source_generator.rb +26 -0
  54. data/lib/yard/generators/tags_generator.rb +50 -0
  55. data/lib/yard/generators/uml_generator.rb +92 -0
  56. data/lib/yard/generators/visibility_group_generator.rb +26 -0
  57. data/lib/yard/handlers/alias_handler.rb +32 -0
  58. data/lib/yard/handlers/attribute_handler.rb +54 -0
  59. data/lib/yard/handlers/base.rb +509 -0
  60. data/lib/yard/handlers/class_handler.rb +44 -0
  61. data/lib/yard/handlers/class_variable_handler.rb +13 -0
  62. data/lib/yard/handlers/constant_handler.rb +13 -0
  63. data/lib/yard/handlers/exception_handler.rb +12 -0
  64. data/lib/yard/handlers/method_handler.rb +27 -0
  65. data/lib/yard/handlers/mixin_handler.rb +16 -0
  66. data/lib/yard/handlers/module_handler.rb +9 -0
  67. data/lib/yard/handlers/visibility_handler.rb +14 -0
  68. data/lib/yard/handlers/yield_handler.rb +26 -0
  69. data/lib/yard/logging.rb +27 -0
  70. data/lib/yard/parser/ruby_lex.rb +1344 -0
  71. data/lib/yard/parser/source_parser.rb +109 -0
  72. data/lib/yard/parser/statement.rb +36 -0
  73. data/lib/yard/parser/statement_list.rb +167 -0
  74. data/lib/yard/parser/token_list.rb +58 -0
  75. data/lib/yard/rake/yardoc_task.rb +30 -0
  76. data/lib/yard/registry.rb +136 -0
  77. data/lib/yard/serializers/base.rb +16 -0
  78. data/lib/yard/serializers/file_system_serializer.rb +48 -0
  79. data/lib/yard/serializers/process_serializer.rb +14 -0
  80. data/lib/yard/serializers/stdout_serializer.rb +21 -0
  81. data/lib/yard/tags/default_factory.rb +98 -0
  82. data/lib/yard/tags/library.rb +109 -0
  83. data/lib/yard/tags/merbdoc_factory.rb +47 -0
  84. data/lib/yard/tags/tag.rb +35 -0
  85. data/spec/code_objects/base_spec.rb +219 -0
  86. data/spec/code_objects/class_object_spec.rb +176 -0
  87. data/spec/code_objects/code_object_list_spec.rb +33 -0
  88. data/spec/code_objects/constants_spec.rb +79 -0
  89. data/spec/code_objects/method_object_spec.rb +30 -0
  90. data/spec/code_objects/module_object_spec.rb +73 -0
  91. data/spec/code_objects/namespace_object_spec.rb +129 -0
  92. data/spec/code_objects/proxy_spec.rb +80 -0
  93. data/spec/code_objects/spec_helper.rb +3 -0
  94. data/spec/core_ext/file_spec.rb +20 -0
  95. data/spec/core_ext/string_spec.rb +4 -0
  96. data/spec/core_ext/symbol_hash_spec.rb +80 -0
  97. data/spec/generators/base_spec.rb +64 -0
  98. data/spec/generators/helpers/base_helper_spec.rb +15 -0
  99. data/spec/generators/helpers/html_helper_spec.rb +56 -0
  100. data/spec/generators/quick_doc_generator_spec.rb +13 -0
  101. data/spec/handlers/alias_handler_spec.rb +50 -0
  102. data/spec/handlers/attribute_handler_spec.rb +78 -0
  103. data/spec/handlers/base_spec.rb +165 -0
  104. data/spec/handlers/class_handler_spec.rb +68 -0
  105. data/spec/handlers/class_variable_handler_spec.rb +9 -0
  106. data/spec/handlers/constant_handler_spec.rb +13 -0
  107. data/spec/handlers/examples/alias_handler_001.rb.txt +24 -0
  108. data/spec/handlers/examples/attribute_handler_001.rb.txt +19 -0
  109. data/spec/handlers/examples/class_handler_001.rb.txt +39 -0
  110. data/spec/handlers/examples/class_variable_handler_001.rb.txt +9 -0
  111. data/spec/handlers/examples/constant_handler_001.rb.txt +10 -0
  112. data/spec/handlers/examples/exception_handler_001.rb.txt +42 -0
  113. data/spec/handlers/examples/method_handler_001.rb.txt +35 -0
  114. data/spec/handlers/examples/mixin_handler_001.rb.txt +12 -0
  115. data/spec/handlers/examples/module_handler_001.rb.txt +16 -0
  116. data/spec/handlers/examples/visibility_handler_001.rb.txt +20 -0
  117. data/spec/handlers/examples/yield_handler_001.rb.txt +55 -0
  118. data/spec/handlers/exception_handler_spec.rb +35 -0
  119. data/spec/handlers/method_handler_spec.rb +35 -0
  120. data/spec/handlers/mixin_handler_spec.rb +30 -0
  121. data/spec/handlers/module_handler_spec.rb +25 -0
  122. data/spec/handlers/spec_helper.rb +21 -0
  123. data/spec/handlers/visibility_handler_spec.rb +24 -0
  124. data/spec/handlers/yield_handler_spec.rb +51 -0
  125. data/spec/parser/examples/example1.rb.txt +8 -0
  126. data/spec/parser/examples/tag_handler_001.rb.txt +8 -0
  127. data/spec/parser/source_parser_spec.rb +43 -0
  128. data/spec/parser/tag_parsing_spec.rb +18 -0
  129. data/spec/parser/token_list_spec.rb +35 -0
  130. data/spec/registry_spec.rb +70 -0
  131. data/spec/serializers/file_system_serializer_spec.rb +91 -0
  132. data/spec/serializers/spec_helper.rb +2 -0
  133. data/spec/spec_helper.rb +77 -0
  134. data/templates/default/attributes/html/header.erb +35 -0
  135. data/templates/default/attributes/text/header.erb +10 -0
  136. data/templates/default/class/html/header.erb +4 -0
  137. data/templates/default/constants/html/constants.erb +9 -0
  138. data/templates/default/constants/html/header.erb +3 -0
  139. data/templates/default/constants/html/included.erb +9 -0
  140. data/templates/default/constants/html/inherited.erb +9 -0
  141. data/templates/default/constructor/html/header.erb +10 -0
  142. data/templates/default/deprecated/html/main.erb +4 -0
  143. data/templates/default/deprecated/text/main.erb +3 -0
  144. data/templates/default/docstring/html/main.erb +3 -0
  145. data/templates/default/docstring/text/main.erb +3 -0
  146. data/templates/default/fulldoc/html/all_methods.erb +25 -0
  147. data/templates/default/fulldoc/html/all_namespaces.erb +19 -0
  148. data/templates/default/fulldoc/html/app.js +18 -0
  149. data/templates/default/fulldoc/html/header.erb +15 -0
  150. data/templates/default/fulldoc/html/html_head.erb +3 -0
  151. data/templates/default/fulldoc/html/index.erb +18 -0
  152. data/templates/default/fulldoc/html/jquery.js +11 -0
  153. data/templates/default/fulldoc/html/readme.erb +15 -0
  154. data/templates/default/fulldoc/html/style.css +65 -0
  155. data/templates/default/fulldoc/html/syntax_highlight.css +21 -0
  156. data/templates/default/inheritance/html/header.erb +8 -0
  157. data/templates/default/inheritance/text/header.erb +3 -0
  158. data/templates/default/method/html/aliases.erb +6 -0
  159. data/templates/default/method/html/header.erb +3 -0
  160. data/templates/default/method/html/title.erb +3 -0
  161. data/templates/default/methoddetails/html/header.erb +8 -0
  162. data/templates/default/methoddetails/html/method_header.erb +3 -0
  163. data/templates/default/methodmissing/html/header.erb +12 -0
  164. data/templates/default/methodsignature/html/main.erb +8 -0
  165. data/templates/default/methodsignature/text/main.erb +5 -0
  166. data/templates/default/methodsummary/html/header.erb +5 -0
  167. data/templates/default/methodsummary/html/included.erb +9 -0
  168. data/templates/default/methodsummary/html/inherited.erb +9 -0
  169. data/templates/default/methodsummary/html/summary.erb +25 -0
  170. data/templates/default/methodsummary/text/header.erb +5 -0
  171. data/templates/default/methodsummary/text/included.erb +0 -0
  172. data/templates/default/methodsummary/text/inherited.erb +0 -0
  173. data/templates/default/methodsummary/text/summary.erb +3 -0
  174. data/templates/default/mixins/html/header.erb +4 -0
  175. data/templates/default/module/html/header.erb +4 -0
  176. data/templates/default/quickdoc/html/header.erb +15 -0
  177. data/templates/default/quickdoc/text/header.erb +12 -0
  178. data/templates/default/source/html/main.erb +15 -0
  179. data/templates/default/source/text/main.erb +4 -0
  180. data/templates/default/tags/html/header.erb +4 -0
  181. data/templates/default/tags/html/see.erb +13 -0
  182. data/templates/default/tags/html/tags.erb +20 -0
  183. data/templates/default/tags/text/header.erb +3 -0
  184. data/templates/default/tags/text/see.erb +5 -0
  185. data/templates/default/tags/text/tags.erb +7 -0
  186. data/templates/default/uml/dot/child.erb +1 -0
  187. data/templates/default/uml/dot/dependencies.erb +10 -0
  188. data/templates/default/uml/dot/header.erb +6 -0
  189. data/templates/default/uml/dot/info.erb +14 -0
  190. data/templates/default/uml/dot/subgraph.erb +6 -0
  191. data/templates/default/uml/dot/superclasses.erb +9 -0
  192. data/templates/default/uml/dot/unknown.erb +3 -0
  193. data/templates/default/uml/dot/unknown_child.erb +1 -0
  194. data/templates/default/visibilitygroup/html/header.erb +6 -0
  195. data/templates/javadoc/attributes/html/header.erb +16 -0
  196. data/templates/javadoc/class/html/header.erb +4 -0
  197. data/templates/javadoc/constants/html/constants.erb +9 -0
  198. data/templates/javadoc/constants/html/header.erb +3 -0
  199. data/templates/javadoc/constants/html/included.erb +12 -0
  200. data/templates/javadoc/constants/html/inherited.erb +12 -0
  201. data/templates/javadoc/constructor/html/header.erb +10 -0
  202. data/templates/javadoc/deprecated/html/main.erb +0 -0
  203. data/templates/javadoc/docstring/html/main.erb +6 -0
  204. data/templates/javadoc/fulldoc/html/all_methods.erb +25 -0
  205. data/templates/javadoc/fulldoc/html/all_namespaces.erb +19 -0
  206. data/templates/javadoc/fulldoc/html/app.js +18 -0
  207. data/templates/javadoc/fulldoc/html/header.erb +15 -0
  208. data/templates/javadoc/fulldoc/html/html_head.erb +3 -0
  209. data/templates/javadoc/fulldoc/html/index.erb +18 -0
  210. data/templates/javadoc/fulldoc/html/jquery.js +11 -0
  211. data/templates/javadoc/fulldoc/html/readme.erb +15 -0
  212. data/templates/javadoc/fulldoc/html/style.css +22 -0
  213. data/templates/javadoc/fulldoc/html/syntax_highlight.css +21 -0
  214. data/templates/javadoc/inheritance/html/header.erb +6 -0
  215. data/templates/javadoc/method/html/aliases.erb +6 -0
  216. data/templates/javadoc/method/html/header.erb +4 -0
  217. data/templates/javadoc/method/html/title.erb +4 -0
  218. data/templates/javadoc/methoddetails/html/header.erb +8 -0
  219. data/templates/javadoc/methoddetails/html/method_header.erb +0 -0
  220. data/templates/javadoc/methodmissing/html/header.erb +12 -0
  221. data/templates/javadoc/methodsignature/html/main.erb +8 -0
  222. data/templates/javadoc/methodsummary/html/header.erb +5 -0
  223. data/templates/javadoc/methodsummary/html/included.erb +12 -0
  224. data/templates/javadoc/methodsummary/html/inherited.erb +12 -0
  225. data/templates/javadoc/methodsummary/html/summary.erb +25 -0
  226. data/templates/javadoc/mixins/html/header.erb +5 -0
  227. data/templates/javadoc/module/html/header.erb +4 -0
  228. data/templates/javadoc/source/html/main.erb +15 -0
  229. data/templates/javadoc/tags/html/header.erb +5 -0
  230. data/templates/javadoc/tags/html/see.erb +8 -0
  231. data/templates/javadoc/tags/html/tags.erb +19 -0
  232. data/templates/javadoc/visibilitygroup/html/header.erb +5 -0
  233. metadata +352 -50
  234. data/README.pdf +0 -0
  235. data/lib/code_object.rb +0 -337
  236. data/lib/extra.rb +0 -8
  237. data/lib/formatter.rb +0 -90
  238. data/lib/handlers/all_handlers.rb +0 -2
  239. data/lib/handlers/attribute_handler.rb +0 -51
  240. data/lib/handlers/class_handler.rb +0 -30
  241. data/lib/handlers/class_variable_handler.rb +0 -9
  242. data/lib/handlers/code_object_handler.rb +0 -104
  243. data/lib/handlers/constant_handler.rb +0 -11
  244. data/lib/handlers/exception_handler.rb +0 -20
  245. data/lib/handlers/method_handler.rb +0 -28
  246. data/lib/handlers/mixin_handler.rb +0 -15
  247. data/lib/handlers/module_handler.rb +0 -9
  248. data/lib/handlers/visibility_handler.rb +0 -7
  249. data/lib/handlers/yield_handler.rb +0 -33
  250. data/lib/logger.rb +0 -19
  251. data/lib/namespace.rb +0 -98
  252. data/lib/quick_doc.rb +0 -104
  253. data/lib/ruby_lex.rb +0 -1321
  254. data/lib/source_parser.rb +0 -253
  255. data/lib/tag_library.rb +0 -175
  256. data/lib/tag_type.rb +0 -155
  257. data/templates/default/html/_fulldoc.erb +0 -64
  258. data/templates/default/html/class.erb +0 -226
  259. data/templates/default/html/method.erb +0 -20
  260. data/templates/default/html/module.erb +0 -126
  261. data/test/fixtures/docstring.txt +0 -23
  262. data/test/fixtures/docstring2.txt +0 -4
  263. data/test/test_code_object.rb +0 -66
  264. data/test/test_namespace.rb +0 -10
@@ -1,1321 +0,0 @@
1
- require "e2mmap"
2
- require "irb/slex"
3
-
4
- module YARD
5
- module RubyToken
6
- EXPR_BEG = :EXPR_BEG
7
- EXPR_MID = :EXPR_MID
8
- EXPR_END = :EXPR_END
9
- EXPR_ARG = :EXPR_ARG
10
- EXPR_FNAME = :EXPR_FNAME
11
- EXPR_DOT = :EXPR_DOT
12
- EXPR_CLASS = :EXPR_CLASS
13
-
14
- class Token
15
- NO_TEXT = "??".freeze
16
- attr :text
17
-
18
- def initialize(line_no, char_no)
19
- @line_no = line_no
20
- @char_no = char_no
21
- @text = NO_TEXT
22
- end
23
-
24
- # Because we're used in contexts that expect to return a token,
25
- # we set the text string and then return ourselves
26
- def set_text(text)
27
- @text = text
28
- self
29
- end
30
-
31
- attr_reader :line_no, :char_no, :text
32
- attr_accessor :lex_state
33
- end
34
-
35
- class TkNode < Token
36
- attr :node
37
- end
38
-
39
- class TkId < Token
40
- def initialize(line_no, char_no, name)
41
- super(line_no, char_no)
42
- @name = name
43
- end
44
- attr :name
45
- end
46
-
47
- class TkKW < TkId
48
- end
49
-
50
- class TkVal < Token
51
- def initialize(line_no, char_no, value = nil)
52
- super(line_no, char_no)
53
- set_text(value)
54
- end
55
- end
56
-
57
- class TkOp < Token
58
- def name
59
- self.class.op_name
60
- end
61
- end
62
-
63
- class TkOPASGN < TkOp
64
- def initialize(line_no, char_no, op)
65
- super(line_no, char_no)
66
- op = TkReading2Token[op] unless op.kind_of?(Symbol)
67
- @op = op
68
- end
69
- attr :op
70
- end
71
-
72
- class TkUnknownChar < Token
73
- def initialize(line_no, char_no, id)
74
- super(line_no, char_no)
75
- @name = char_no.chr
76
- end
77
- attr :name
78
- end
79
-
80
- class TkError < Token
81
- end
82
-
83
- def set_token_position(line, char)
84
- @prev_line_no = line
85
- @prev_char_no = char
86
- end
87
-
88
- def Token(token, value = nil)
89
- tk = nil
90
- case token
91
- when String, Symbol
92
- source = token.kind_of?(String) ? TkReading2Token : TkSymbol2Token
93
- if (tk = source[token]).nil?
94
- IRB.fail TkReading2TokenNoKey, token
95
- end
96
- tk = Token(tk[0], value)
97
- else
98
- tk = if (token.ancestors & [TkId, TkVal, TkOPASGN, TkUnknownChar]).empty?
99
- token.new(@prev_line_no, @prev_char_no)
100
- else
101
- token.new(@prev_line_no, @prev_char_no, value)
102
- end
103
- end
104
- tk
105
- end
106
-
107
- TokenDefinitions = [
108
- [:TkCLASS, TkKW, "class", EXPR_CLASS],
109
- [:TkMODULE, TkKW, "module", EXPR_BEG],
110
- [:TkDEF, TkKW, "def", EXPR_FNAME],
111
- [:TkUNDEF, TkKW, "undef", EXPR_FNAME],
112
- [:TkBEGIN, TkKW, "begin", EXPR_BEG],
113
- [:TkRESCUE, TkKW, "rescue", EXPR_MID],
114
- [:TkENSURE, TkKW, "ensure", EXPR_BEG],
115
- [:TkEND, TkKW, "end", EXPR_END],
116
- [:TkIF, TkKW, "if", EXPR_BEG, :TkIF_MOD],
117
- [:TkUNLESS, TkKW, "unless", EXPR_BEG, :TkUNLESS_MOD],
118
- [:TkTHEN, TkKW, "then", EXPR_BEG],
119
- [:TkELSIF, TkKW, "elsif", EXPR_BEG],
120
- [:TkELSE, TkKW, "else", EXPR_BEG],
121
- [:TkCASE, TkKW, "case", EXPR_BEG],
122
- [:TkWHEN, TkKW, "when", EXPR_BEG],
123
- [:TkWHILE, TkKW, "while", EXPR_BEG, :TkWHILE_MOD],
124
- [:TkUNTIL, TkKW, "until", EXPR_BEG, :TkUNTIL_MOD],
125
- [:TkFOR, TkKW, "for", EXPR_BEG],
126
- [:TkBREAK, TkKW, "break", EXPR_END],
127
- [:TkNEXT, TkKW, "next", EXPR_END],
128
- [:TkREDO, TkKW, "redo", EXPR_END],
129
- [:TkRETRY, TkKW, "retry", EXPR_END],
130
- [:TkIN, TkKW, "in", EXPR_BEG],
131
- [:TkDO, TkKW, "do", EXPR_BEG],
132
- [:TkRETURN, TkKW, "return", EXPR_MID],
133
- [:TkYIELD, TkKW, "yield", EXPR_END],
134
- [:TkSUPER, TkKW, "super", EXPR_END],
135
- [:TkSELF, TkKW, "self", EXPR_END],
136
- [:TkNIL, TkKW, "nil", EXPR_END],
137
- [:TkTRUE, TkKW, "true", EXPR_END],
138
- [:TkFALSE, TkKW, "false", EXPR_END],
139
- [:TkAND, TkKW, "and", EXPR_BEG],
140
- [:TkOR, TkKW, "or", EXPR_BEG],
141
- [:TkNOT, TkKW, "not", EXPR_BEG],
142
- [:TkIF_MOD, TkKW],
143
- [:TkUNLESS_MOD, TkKW],
144
- [:TkWHILE_MOD, TkKW],
145
- [:TkUNTIL_MOD, TkKW],
146
- [:TkALIAS, TkKW, "alias", EXPR_FNAME],
147
- [:TkDEFINED, TkKW, "defined?", EXPR_END],
148
- [:TklBEGIN, TkKW, "BEGIN", EXPR_END],
149
- [:TklEND, TkKW, "END", EXPR_END],
150
- [:Tk__LINE__, TkKW, "__LINE__", EXPR_END],
151
- [:Tk__FILE__, TkKW, "__FILE__", EXPR_END],
152
-
153
- [:TkIDENTIFIER, TkId],
154
- [:TkFID, TkId],
155
- [:TkGVAR, TkId],
156
- [:TkIVAR, TkId],
157
- [:TkCONSTANT, TkId],
158
-
159
- [:TkINTEGER, TkVal],
160
- [:TkFLOAT, TkVal],
161
- [:TkSTRING, TkVal],
162
- [:TkXSTRING, TkVal],
163
- [:TkREGEXP, TkVal],
164
- [:TkCOMMENT, TkVal],
165
-
166
- [:TkDSTRING, TkNode],
167
- [:TkDXSTRING, TkNode],
168
- [:TkDREGEXP, TkNode],
169
- [:TkNTH_REF, TkId],
170
- [:TkBACK_REF, TkId],
171
-
172
- [:TkUPLUS, TkOp, "+@"],
173
- [:TkUMINUS, TkOp, "-@"],
174
- [:TkPOW, TkOp, "**"],
175
- [:TkCMP, TkOp, "<=>"],
176
- [:TkEQ, TkOp, "=="],
177
- [:TkEQQ, TkOp, "==="],
178
- [:TkNEQ, TkOp, "!="],
179
- [:TkGEQ, TkOp, ">="],
180
- [:TkLEQ, TkOp, "<="],
181
- [:TkANDOP, TkOp, "&&"],
182
- [:TkOROP, TkOp, "||"],
183
- [:TkMATCH, TkOp, "=~"],
184
- [:TkNMATCH, TkOp, "!~"],
185
- [:TkDOT2, TkOp, ".."],
186
- [:TkDOT3, TkOp, "..."],
187
- [:TkAREF, TkOp, "[]"],
188
- [:TkASET, TkOp, "[]="],
189
- [:TkLSHFT, TkOp, "<<"],
190
- [:TkRSHFT, TkOp, ">>"],
191
- [:TkCOLON2, TkOp],
192
- [:TkCOLON3, TkOp],
193
- [:OPASGN, TkOp], # +=, -= etc. #
194
- [:TkASSOC, TkOp, "=>"],
195
- [:TkQUESTION, TkOp, "?"], #?
196
- [:TkCOLON, TkOp, ":"], #:
197
-
198
- [:TkfLPAREN], # func( #
199
- [:TkfLBRACK], # func[ #
200
- [:TkfLBRACE], # func{ #
201
- [:TkSTAR], # *arg
202
- [:TkAMPER], # &arg #
203
- [:TkSYMBOL, TkId], # :SYMBOL
204
- [:TkSYMBEG, TkId],
205
- [:TkGT, TkOp, ">"],
206
- [:TkLT, TkOp, "<"],
207
- [:TkPLUS, TkOp, "+"],
208
- [:TkMINUS, TkOp, "-"],
209
- [:TkMULT, TkOp, "*"],
210
- [:TkDIV, TkOp, "/"],
211
- [:TkMOD, TkOp, "%"],
212
- [:TkBITOR, TkOp, "|"],
213
- [:TkBITXOR, TkOp, "^"],
214
- [:TkBITAND, TkOp, "&"],
215
- [:TkBITNOT, TkOp, "~"],
216
- [:TkNOTOP, TkOp, "!"],
217
-
218
- [:TkBACKQUOTE, TkOp, "`"],
219
-
220
- [:TkASSIGN, Token, "="],
221
- [:TkDOT, Token, "."],
222
- [:TkLPAREN, Token, "("], #(exp)
223
- [:TkLBRACK, Token, "["], #[arry]
224
- [:TkLBRACE, Token, "{"], #{hash}
225
- [:TkRPAREN, Token, ")"],
226
- [:TkRBRACK, Token, "]"],
227
- [:TkRBRACE, Token, "}"],
228
- [:TkCOMMA, Token, ","],
229
- [:TkSEMICOLON, Token, ";"],
230
-
231
- [:TkRD_COMMENT],
232
- [:TkSPACE],
233
- [:TkNL],
234
- [:TkEND_OF_SCRIPT],
235
-
236
- [:TkBACKSLASH, TkUnknownChar, "\\"],
237
- [:TkAT, TkUnknownChar, "@"],
238
- [:TkDOLLAR, TkUnknownChar, "\$"], #"
239
- ]
240
-
241
- # {reading => token_class}
242
- # {reading => [token_class, *opt]}
243
- TkReading2Token = {}
244
- TkSymbol2Token = {}
245
-
246
- def RubyToken.def_token(token_n, super_token = Token, reading = nil, *opts)
247
- token_n = token_n.id2name unless token_n.kind_of?(String)
248
- if RubyToken.const_defined?(token_n)
249
- #IRB.fail AlreadyDefinedToken, token_n
250
- end
251
-
252
- token_c = Class.new super_token
253
- RubyToken.const_set token_n, token_c
254
- # token_c.inspect
255
-
256
- if reading
257
- if TkReading2Token[reading]
258
- IRB.fail TkReading2TokenDuplicateError, token_n, reading
259
- end
260
- if opts.empty?
261
- TkReading2Token[reading] = [token_c]
262
- else
263
- TkReading2Token[reading] = [token_c].concat(opts)
264
- end
265
- end
266
- TkSymbol2Token[token_n.intern] = token_c
267
-
268
- if token_c <= TkOp
269
- token_c.class_eval %{
270
- def self.op_name; "#{reading}"; end
271
- }
272
- end
273
- end
274
-
275
- for defs in TokenDefinitions
276
- def_token(*defs)
277
- end
278
-
279
- NEWLINE_TOKEN = TkNL.new(0,0)
280
- NEWLINE_TOKEN.set_text("\n")
281
-
282
- end
283
-
284
-
285
-
286
- # Lexical analyzer for Ruby source
287
-
288
- class RubyLex
289
-
290
- ######################################################################
291
- #
292
- # Read an input stream character by character. We allow for unlimited
293
- # ungetting of characters just read.
294
- #
295
- # We simplify the implementation greatly by reading the entire input
296
- # into a buffer initially, and then simply traversing it using
297
- # pointers.
298
- #
299
- # We also have to allow for the <i>here document diversion</i>. This
300
- # little gem comes about when the lexer encounters a here
301
- # document. At this point we effectively need to split the input
302
- # stream into two parts: one to read the body of the here document,
303
- # the other to read the rest of the input line where the here
304
- # document was initially encountered. For example, we might have
305
- #
306
- # do_something(<<-A, <<-B)
307
- # stuff
308
- # for
309
- # A
310
- # stuff
311
- # for
312
- # B
313
- #
314
- # When the lexer encounters the <<A, it reads until the end of the
315
- # line, and keeps it around for later. It then reads the body of the
316
- # here document. Once complete, it needs to read the rest of the
317
- # original line, but then skip the here document body.
318
- #
319
-
320
- class BufferedReader
321
-
322
- attr_reader :line_num
323
-
324
- def initialize(content)
325
- if /\t/ =~ content
326
- tab_width = 2
327
- content = content.split(/\n/).map do |line|
328
- 1 while line.gsub!(/\t+/) { ' ' * (tab_width*$&.length - $`.length % tab_width)} && $~ #`
329
- line
330
- end .join("\n")
331
- end
332
- @content = content
333
- @content << "\n" unless @content[-1,1] == "\n"
334
- @size = @content.size
335
- @offset = 0
336
- @hwm = 0
337
- @line_num = 1
338
- @read_back_offset = 0
339
- @last_newline = 0
340
- @newline_pending = false
341
- end
342
-
343
- def column
344
- @offset - @last_newline
345
- end
346
-
347
- def getc
348
- return nil if @offset >= @size
349
- ch = @content[@offset, 1]
350
-
351
- @offset += 1
352
- @hwm = @offset if @hwm < @offset
353
-
354
- if @newline_pending
355
- @line_num += 1
356
- @last_newline = @offset - 1
357
- @newline_pending = false
358
- end
359
-
360
- if ch == "\n"
361
- @newline_pending = true
362
- end
363
- ch
364
- end
365
-
366
- def getc_already_read
367
- getc
368
- end
369
-
370
- def ungetc(ch)
371
- raise "unget past beginning of file" if @offset <= 0
372
- @offset -= 1
373
- if @content[@offset] == ?\n
374
- @newline_pending = false
375
- end
376
- end
377
-
378
- def get_read
379
- res = @content[@read_back_offset...@offset]
380
- @read_back_offset = @offset
381
- res
382
- end
383
-
384
- def peek(at)
385
- pos = @offset + at
386
- if pos >= @size
387
- nil
388
- else
389
- @content[pos, 1]
390
- end
391
- end
392
-
393
- def peek_equal(str)
394
- @content[@offset, str.length] == str
395
- end
396
-
397
- def divert_read_from(reserve)
398
- @content[@offset, 0] = reserve
399
- @size = @content.size
400
- end
401
- end
402
-
403
- # end of nested class BufferedReader
404
-
405
- extend Exception2MessageMapper
406
- def_exception(:AlreadyDefinedToken, "Already defined token(%s)")
407
- def_exception(:TkReading2TokenNoKey, "key nothing(key='%s')")
408
- def_exception(:TkSymbol2TokenNoKey, "key nothing(key='%s')")
409
- def_exception(:TkReading2TokenDuplicateError,
410
- "key duplicate(token_n='%s', key='%s')")
411
- def_exception(:SyntaxError, "%s")
412
-
413
- include RubyToken
414
- include IRB
415
-
416
- attr_reader :continue
417
- attr_reader :lex_state
418
-
419
- def RubyLex.debug?
420
- false
421
- end
422
-
423
- def initialize(content)
424
- lex_init
425
-
426
- @reader = BufferedReader.new(content)
427
-
428
- @exp_line_no = @line_no = 1
429
- @base_char_no = 0
430
- @indent = 0
431
-
432
- @ltype = nil
433
- @quoted = nil
434
- @lex_state = EXPR_BEG
435
- @space_seen = false
436
-
437
- @continue = false
438
- @line = ""
439
-
440
- @skip_space = false
441
- @read_auto_clean_up = false
442
- @exception_on_syntax_error = true
443
- end
444
-
445
- attr :skip_space, true
446
- attr :read_auto_clean_up, true
447
- attr :exception_on_syntax_error, true
448
-
449
- attr :indent
450
-
451
- # io functions
452
- def line_no
453
- @reader.line_num
454
- end
455
-
456
- def char_no
457
- @reader.column
458
- end
459
-
460
- def get_read
461
- @reader.get_read
462
- end
463
-
464
- def getc
465
- @reader.getc
466
- end
467
-
468
- def getc_of_rests
469
- @reader.getc_already_read
470
- end
471
-
472
- def gets
473
- c = getc or return
474
- l = ""
475
- begin
476
- l.concat c unless c == "\r"
477
- break if c == "\n"
478
- end while c = getc
479
- l
480
- end
481
-
482
-
483
- def ungetc(c = nil)
484
- @reader.ungetc(c)
485
- end
486
-
487
- def peek_equal?(str)
488
- @reader.peek_equal(str)
489
- end
490
-
491
- def peek(i = 0)
492
- @reader.peek(i)
493
- end
494
-
495
- def lex
496
- until (((tk = token).kind_of?(TkNL) || tk.kind_of?(TkEND_OF_SCRIPT)) &&
497
- !@continue or
498
- tk.nil?)
499
- end
500
- line = get_read
501
-
502
- if line == "" and tk.kind_of?(TkEND_OF_SCRIPT) || tk.nil?
503
- nil
504
- else
505
- line
506
- end
507
- end
508
-
509
- def token
510
- set_token_position(line_no, char_no)
511
- begin
512
- begin
513
- tk = @OP.match(self)
514
- @space_seen = tk.kind_of?(TkSPACE)
515
- rescue SyntaxError
516
- abort if @exception_on_syntax_error
517
- tk = TkError.new(line_no, char_no)
518
- end
519
- end while @skip_space and tk.kind_of?(TkSPACE)
520
- if @read_auto_clean_up
521
- get_read
522
- end
523
- # throw :eof unless tk
524
- p tk if $DEBUG
525
- tk.lex_state = lex_state if tk
526
- tk
527
- end
528
-
529
- ENINDENT_CLAUSE = [
530
- "case", "class", "def", "do", "for", "if",
531
- "module", "unless", "until", "while", "begin" #, "when"
532
- ]
533
- DEINDENT_CLAUSE = ["end" #, "when"
534
- ]
535
-
536
- PERCENT_LTYPE = {
537
- "q" => "\'",
538
- "Q" => "\"",
539
- "x" => "\`",
540
- "r" => "/",
541
- "w" => "]",
542
- "W" => "]"
543
- }
544
-
545
- PERCENT_PAREN = {
546
- "{" => "}",
547
- "[" => "]",
548
- "<" => ">",
549
- "(" => ")"
550
- }
551
-
552
- Ltype2Token = {
553
- "\'" => TkSTRING,
554
- "\"" => TkSTRING,
555
- "\`" => TkXSTRING,
556
- "/" => TkREGEXP,
557
- "]" => TkDSTRING
558
- }
559
- Ltype2Token.default = TkSTRING
560
-
561
- DLtype2Token = {
562
- "\"" => TkDSTRING,
563
- "\`" => TkDXSTRING,
564
- "/" => TkDREGEXP,
565
- }
566
-
567
- def lex_init()
568
- @OP = SLex.new
569
- @OP.def_rules("\0", "\004", "\032") do |chars, io|
570
- Token(TkEND_OF_SCRIPT).set_text(chars)
571
- end
572
-
573
- @OP.def_rules(" ", "\t", "\f", "\r", "\13") do |chars, io|
574
- @space_seen = TRUE
575
- while (ch = getc) =~ /[ \t\f\r\13]/
576
- chars << ch
577
- end
578
- ungetc
579
- Token(TkSPACE).set_text(chars)
580
- end
581
-
582
- @OP.def_rule("#") do
583
- |op, io|
584
- identify_comment
585
- end
586
-
587
- @OP.def_rule("=begin", proc{@prev_char_no == 0 && peek(0) =~ /\s/}) do
588
- |op, io|
589
- str = op
590
- @ltype = "="
591
-
592
-
593
- begin
594
- line = ""
595
- begin
596
- ch = getc
597
- line << ch
598
- end until ch == "\n"
599
- str << line
600
- end until line =~ /^=end/
601
-
602
- ungetc
603
-
604
- @ltype = nil
605
-
606
- if str =~ /\A=begin\s+rdoc/i
607
- str.sub!(/\A=begin.*\n/, '')
608
- str.sub!(/^=end.*/m, '')
609
- Token(TkCOMMENT).set_text(str)
610
- else
611
- Token(TkRD_COMMENT)#.set_text(str)
612
- end
613
- end
614
-
615
- @OP.def_rule("\n") do
616
- print "\\n\n" if RubyLex.debug?
617
- case @lex_state
618
- when EXPR_BEG, EXPR_FNAME, EXPR_DOT
619
- @continue = TRUE
620
- else
621
- @continue = FALSE
622
- @lex_state = EXPR_BEG
623
- end
624
- Token(TkNL).set_text("\n")
625
- end
626
-
627
- @OP.def_rules("*", "**",
628
- "!", "!=", "!~",
629
- "=", "==", "===",
630
- "=~", "<=>",
631
- "<", "<=",
632
- ">", ">=", ">>") do |op, io|
633
- @lex_state = EXPR_BEG
634
- Token(op).set_text(op)
635
- end
636
-
637
- @OP.def_rules("<<") do |op, io|
638
- tk = nil
639
- if @lex_state != EXPR_END && @lex_state != EXPR_CLASS &&
640
- (@lex_state != EXPR_ARG || @space_seen)
641
- c = peek(0)
642
- tk = identify_here_document if /[-\w_\"\'\`]/ =~ c
643
- end
644
- if !tk
645
- @lex_state = EXPR_BEG
646
- tk = Token(op).set_text(op)
647
- end
648
- tk
649
- end
650
-
651
- @OP.def_rules("'", '"') do |op, io|
652
- identify_string(op)
653
- end
654
-
655
- @OP.def_rules("`") do |op, io|
656
- if @lex_state == EXPR_FNAME
657
- Token(op).set_text(op)
658
- else
659
- identify_string(op)
660
- end
661
- end
662
-
663
- @OP.def_rules('?') do |op, io|
664
- if @lex_state == EXPR_END
665
- @lex_state = EXPR_BEG
666
- Token(TkQUESTION).set_text(op)
667
- else
668
- ch = getc
669
- if @lex_state == EXPR_ARG && ch !~ /\s/
670
- ungetc
671
- @lex_state = EXPR_BEG
672
- Token(TkQUESTION).set_text(op)
673
- else
674
- str = op
675
- str << ch
676
- if (ch == '\\') #'
677
- str << read_escape
678
- end
679
- @lex_state = EXPR_END
680
- Token(TkINTEGER).set_text(str)
681
- end
682
- end
683
- end
684
-
685
- @OP.def_rules("&", "&&", "|", "||") do |op, io|
686
- @lex_state = EXPR_BEG
687
- Token(op).set_text(op)
688
- end
689
-
690
- @OP.def_rules("+=", "-=", "*=", "**=",
691
- "&=", "|=", "^=", "<<=", ">>=", "||=", "&&=") do |op, io|
692
- @lex_state = EXPR_BEG
693
- op =~ /^(.*)=$/
694
- Token(TkOPASGN, $1).set_text(op)
695
- end
696
-
697
- @OP.def_rule("+@", proc{@lex_state == EXPR_FNAME}) do |op, io|
698
- Token(TkUPLUS).set_text(op)
699
- end
700
-
701
- @OP.def_rule("-@", proc{@lex_state == EXPR_FNAME}) do |op, io|
702
- Token(TkUMINUS).set_text(op)
703
- end
704
-
705
- @OP.def_rules("+", "-") do |op, io|
706
- catch(:RET) do
707
- if @lex_state == EXPR_ARG
708
- if @space_seen and peek(0) =~ /[0-9]/
709
- throw :RET, identify_number(op)
710
- else
711
- @lex_state = EXPR_BEG
712
- end
713
- elsif @lex_state != EXPR_END and peek(0) =~ /[0-9]/
714
- throw :RET, identify_number(op)
715
- else
716
- @lex_state = EXPR_BEG
717
- end
718
- Token(op).set_text(op)
719
- end
720
- end
721
-
722
- @OP.def_rule(".") do
723
- @lex_state = EXPR_BEG
724
- if peek(0) =~ /[0-9]/
725
- ungetc
726
- identify_number("")
727
- else
728
- # for obj.if
729
- @lex_state = EXPR_DOT
730
- Token(TkDOT).set_text(".")
731
- end
732
- end
733
-
734
- @OP.def_rules("..", "...") do |op, io|
735
- @lex_state = EXPR_BEG
736
- Token(op).set_text(op)
737
- end
738
-
739
- lex_int2
740
- end
741
-
742
- def lex_int2
743
- @OP.def_rules("]", "}", ")") do
744
- |op, io|
745
- @lex_state = EXPR_END
746
- @indent -= 1
747
- Token(op).set_text(op)
748
- end
749
-
750
- @OP.def_rule(":") do
751
- if @lex_state == EXPR_END || peek(0) =~ /\s/
752
- @lex_state = EXPR_BEG
753
- tk = Token(TkCOLON)
754
- else
755
- @lex_state = EXPR_FNAME
756
- tk = Token(TkSYMBEG)
757
- end
758
- tk.set_text(":")
759
- end
760
-
761
- @OP.def_rule("::") do
762
- # p @lex_state.id2name, @space_seen
763
- if @lex_state == EXPR_BEG or @lex_state == EXPR_ARG && @space_seen
764
- @lex_state = EXPR_BEG
765
- tk = Token(TkCOLON3)
766
- else
767
- @lex_state = EXPR_DOT
768
- tk = Token(TkCOLON2)
769
- end
770
- tk.set_text("::")
771
- end
772
-
773
- @OP.def_rule("/") do |op, io|
774
- if @lex_state == EXPR_BEG || @lex_state == EXPR_MID
775
- identify_string(op)
776
- elsif peek(0) == '='
777
- getc
778
- @lex_state = EXPR_BEG
779
- Token(TkOPASGN, :/).set_text("/=") #")
780
- elsif @lex_state == EXPR_ARG and @space_seen and peek(0) !~ /\s/
781
- identify_string(op)
782
- else
783
- @lex_state = EXPR_BEG
784
- Token("/").set_text(op)
785
- end
786
- end
787
-
788
- @OP.def_rules("^") do
789
- @lex_state = EXPR_BEG
790
- Token("^").set_text("^")
791
- end
792
-
793
- # @OP.def_rules("^=") do
794
- # @lex_state = EXPR_BEG
795
- # Token(TkOPASGN, :^)
796
- # end
797
-
798
- @OP.def_rules(",", ";") do |op, io|
799
- @lex_state = EXPR_BEG
800
- Token(op).set_text(op)
801
- end
802
-
803
- @OP.def_rule("~") do
804
- @lex_state = EXPR_BEG
805
- Token("~").set_text("~")
806
- end
807
-
808
- @OP.def_rule("~@", proc{@lex_state = EXPR_FNAME}) do
809
- @lex_state = EXPR_BEG
810
- Token("~").set_text("~@")
811
- end
812
-
813
- @OP.def_rule("(") do
814
- @indent += 1
815
- if @lex_state == EXPR_BEG || @lex_state == EXPR_MID
816
- @lex_state = EXPR_BEG
817
- tk = Token(TkfLPAREN)
818
- else
819
- @lex_state = EXPR_BEG
820
- tk = Token(TkLPAREN)
821
- end
822
- tk.set_text("(")
823
- end
824
-
825
- @OP.def_rule("[]", proc{@lex_state == EXPR_FNAME}) do
826
- Token("[]").set_text("[]")
827
- end
828
-
829
- @OP.def_rule("[]=", proc{@lex_state == EXPR_FNAME}) do
830
- Token("[]=").set_text("[]=")
831
- end
832
-
833
- @OP.def_rule("[") do
834
- @indent += 1
835
- if @lex_state == EXPR_FNAME
836
- t = Token(TkfLBRACK)
837
- else
838
- if @lex_state == EXPR_BEG || @lex_state == EXPR_MID
839
- t = Token(TkLBRACK)
840
- elsif @lex_state == EXPR_ARG && @space_seen
841
- t = Token(TkLBRACK)
842
- else
843
- t = Token(TkfLBRACK)
844
- end
845
- @lex_state = EXPR_BEG
846
- end
847
- t.set_text("[")
848
- end
849
-
850
- @OP.def_rule("{") do
851
- @indent += 1
852
- if @lex_state != EXPR_END && @lex_state != EXPR_ARG
853
- t = Token(TkLBRACE)
854
- else
855
- t = Token(TkfLBRACE)
856
- end
857
- @lex_state = EXPR_BEG
858
- t.set_text("{")
859
- end
860
-
861
- @OP.def_rule('\\') do #'
862
- if getc == "\n"
863
- @space_seen = true
864
- @continue = true
865
- Token(TkSPACE).set_text("\\\n")
866
- else
867
- ungetc
868
- Token("\\").set_text("\\") #"
869
- end
870
- end
871
-
872
- @OP.def_rule('%') do
873
- |op, io|
874
- if @lex_state == EXPR_BEG || @lex_state == EXPR_MID
875
- identify_quotation('%')
876
- elsif peek(0) == '='
877
- getc
878
- Token(TkOPASGN, "%").set_text("%=")
879
- elsif @lex_state == EXPR_ARG and @space_seen and peek(0) !~ /\s/
880
- identify_quotation('%')
881
- else
882
- @lex_state = EXPR_BEG
883
- Token("%").set_text("%")
884
- end
885
- end
886
-
887
- @OP.def_rule('$') do #'
888
- identify_gvar
889
- end
890
-
891
- @OP.def_rule('@') do
892
- if peek(0) =~ /[@\w_]/
893
- ungetc
894
- identify_identifier
895
- else
896
- Token("@").set_text("@")
897
- end
898
- end
899
-
900
- # @OP.def_rule("def", proc{|op, io| /\s/ =~ io.peek(0)}) do
901
- # |op, io|
902
- # @indent += 1
903
- # @lex_state = EXPR_FNAME
904
- # # @lex_state = EXPR_END
905
- # # until @rests[0] == "\n" or @rests[0] == ";"
906
- # # rests.shift
907
- # # end
908
- # end
909
-
910
- @OP.def_rule("__END__", proc{@prev_char_no == 0 && peek(0) =~ /[\r\n]/}) do
911
- throw :eof
912
- end
913
-
914
- @OP.def_rule("") do
915
- |op, io|
916
- printf "MATCH: start %s: %s\n", op, io.inspect if RubyLex.debug?
917
- if peek(0) =~ /[0-9]/
918
- t = identify_number("")
919
- elsif peek(0) =~ /[\w_]/
920
- t = identify_identifier
921
- end
922
- printf "MATCH: end %s: %s\n", op, io.inspect if RubyLex.debug?
923
- t
924
- end
925
-
926
- p @OP if RubyLex.debug?
927
- end
928
-
929
- def identify_gvar
930
- @lex_state = EXPR_END
931
- str = "$"
932
-
933
- tk = case ch = getc
934
- when /[~_*$?!@\/\\;,=:<>".]/ #"
935
- str << ch
936
- Token(TkGVAR, str)
937
-
938
- when "-"
939
- str << "-" << getc
940
- Token(TkGVAR, str)
941
-
942
- when "&", "`", "'", "+"
943
- str << ch
944
- Token(TkBACK_REF, str)
945
-
946
- when /[1-9]/
947
- str << ch
948
- while (ch = getc) =~ /[0-9]/
949
- str << ch
950
- end
951
- ungetc
952
- Token(TkNTH_REF)
953
- when /\w/
954
- ungetc
955
- ungetc
956
- return identify_identifier
957
- else
958
- ungetc
959
- Token("$")
960
- end
961
- tk.set_text(str)
962
- end
963
-
964
- def identify_identifier
965
- token = ""
966
- token.concat getc if peek(0) =~ /[$@]/
967
- token.concat getc if peek(0) == "@"
968
-
969
- while (ch = getc) =~ /\w|_/
970
- print ":", ch, ":" if RubyLex.debug?
971
- token.concat ch
972
- end
973
- ungetc
974
-
975
- if ch == "!" or ch == "?"
976
- token.concat getc
977
- end
978
- # fix token
979
-
980
- # $stderr.puts "identifier - #{token}, state = #@lex_state"
981
-
982
- case token
983
- when /^\$/
984
- return Token(TkGVAR, token).set_text(token)
985
- when /^\@/
986
- @lex_state = EXPR_END
987
- return Token(TkIVAR, token).set_text(token)
988
- end
989
-
990
- if @lex_state != EXPR_DOT
991
- print token, "\n" if RubyLex.debug?
992
-
993
- token_c, *trans = TkReading2Token[token]
994
- if token_c
995
- # reserved word?
996
-
997
- if (@lex_state != EXPR_BEG &&
998
- @lex_state != EXPR_FNAME &&
999
- trans[1])
1000
- # modifiers
1001
- token_c = TkSymbol2Token[trans[1]]
1002
- @lex_state = trans[0]
1003
- else
1004
- if @lex_state != EXPR_FNAME
1005
- if ENINDENT_CLAUSE.include?(token)
1006
- @indent += 1
1007
- elsif DEINDENT_CLAUSE.include?(token)
1008
- @indent -= 1
1009
- end
1010
- @lex_state = trans[0]
1011
- else
1012
- @lex_state = EXPR_END
1013
- end
1014
- end
1015
- return Token(token_c, token).set_text(token)
1016
- end
1017
- end
1018
-
1019
- if @lex_state == EXPR_FNAME
1020
- @lex_state = EXPR_END
1021
- if peek(0) == '='
1022
- token.concat getc
1023
- end
1024
- elsif @lex_state == EXPR_BEG || @lex_state == EXPR_DOT
1025
- @lex_state = EXPR_ARG
1026
- else
1027
- @lex_state = EXPR_END
1028
- end
1029
-
1030
- if token[0, 1] =~ /[A-Z]/
1031
- return Token(TkCONSTANT, token).set_text(token)
1032
- elsif token[token.size - 1, 1] =~ /[!?]/
1033
- return Token(TkFID, token).set_text(token)
1034
- else
1035
- return Token(TkIDENTIFIER, token).set_text(token)
1036
- end
1037
- end
1038
-
1039
- def identify_here_document
1040
- ch = getc
1041
- if ch == "-"
1042
- ch = getc
1043
- indent = true
1044
- end
1045
- if /['"`]/ =~ ch # '
1046
- lt = ch
1047
- quoted = ""
1048
- while (c = getc) && c != lt
1049
- quoted.concat c
1050
- end
1051
- else
1052
- lt = '"'
1053
- quoted = ch.dup
1054
- while (c = getc) && c =~ /\w/
1055
- quoted.concat c
1056
- end
1057
- ungetc
1058
- end
1059
-
1060
- ltback, @ltype = @ltype, lt
1061
- reserve = ""
1062
-
1063
- while ch = getc
1064
- reserve << ch
1065
- if ch == "\\" #"
1066
- ch = getc
1067
- reserve << ch
1068
- elsif ch == "\n"
1069
- break
1070
- end
1071
- end
1072
-
1073
- str = ""
1074
- while (l = gets)
1075
- l.chomp!
1076
- l.strip! if indent
1077
- break if l == quoted
1078
- str << l.chomp << "\n"
1079
- end
1080
-
1081
- @reader.divert_read_from(reserve)
1082
-
1083
- @ltype = ltback
1084
- @lex_state = EXPR_END
1085
- Token(Ltype2Token[lt], str).set_text(str.dump)
1086
- end
1087
-
1088
- def identify_quotation(initial_char)
1089
- ch = getc
1090
- if lt = PERCENT_LTYPE[ch]
1091
- initial_char += ch
1092
- ch = getc
1093
- elsif ch =~ /\W/
1094
- lt = "\""
1095
- else
1096
- RubyLex.fail SyntaxError, "unknown type of %string ('#{ch}')"
1097
- end
1098
- # if ch !~ /\W/
1099
- # ungetc
1100
- # next
1101
- # end
1102
- #@ltype = lt
1103
- @quoted = ch unless @quoted = PERCENT_PAREN[ch]
1104
- identify_string(lt, @quoted, ch, initial_char)
1105
- end
1106
-
1107
- def identify_number(start)
1108
- str = start.dup
1109
-
1110
- if start == "+" or start == "-" or start == ""
1111
- start = getc
1112
- str << start
1113
- end
1114
-
1115
- @lex_state = EXPR_END
1116
-
1117
- if start == "0"
1118
- if peek(0) == "x"
1119
- ch = getc
1120
- str << ch
1121
- match = /[0-9a-f_]/
1122
- else
1123
- match = /[0-7_]/
1124
- end
1125
- while ch = getc
1126
- if ch !~ match
1127
- ungetc
1128
- break
1129
- else
1130
- str << ch
1131
- end
1132
- end
1133
- return Token(TkINTEGER).set_text(str)
1134
- end
1135
-
1136
- type = TkINTEGER
1137
- allow_point = TRUE
1138
- allow_e = TRUE
1139
- while ch = getc
1140
- case ch
1141
- when /[0-9_]/
1142
- str << ch
1143
-
1144
- when allow_point && "."
1145
- type = TkFLOAT
1146
- if peek(0) !~ /[0-9]/
1147
- ungetc
1148
- break
1149
- end
1150
- str << ch
1151
- allow_point = false
1152
-
1153
- when allow_e && "e", allow_e && "E"
1154
- str << ch
1155
- type = TkFLOAT
1156
- if peek(0) =~ /[+-]/
1157
- str << getc
1158
- end
1159
- allow_e = false
1160
- allow_point = false
1161
- else
1162
- ungetc
1163
- break
1164
- end
1165
- end
1166
- Token(type).set_text(str)
1167
- end
1168
-
1169
- def identify_string(ltype, quoted = ltype, opener=nil, initial_char = nil)
1170
- @ltype = ltype
1171
- @quoted = quoted
1172
- subtype = nil
1173
-
1174
- str = ""
1175
- str << initial_char if initial_char
1176
- str << (opener||quoted)
1177
-
1178
- nest = 0
1179
- begin
1180
- while ch = getc
1181
- str << ch
1182
- if @quoted == ch
1183
- if nest == 0
1184
- break
1185
- else
1186
- nest -= 1
1187
- end
1188
- elsif opener == ch
1189
- nest += 1
1190
- elsif @ltype != "'" && @ltype != "]" and ch == "#"
1191
- ch = getc
1192
- if ch == "{"
1193
- subtype = true
1194
- str << ch << skip_inner_expression
1195
- else
1196
- ungetc(ch)
1197
- end
1198
- elsif ch == '\\' #'
1199
- str << read_escape
1200
- end
1201
- end
1202
- if @ltype == "/"
1203
- if peek(0) =~ /i|o|n|e|s/
1204
- str << getc
1205
- end
1206
- end
1207
- if subtype
1208
- Token(DLtype2Token[ltype], str)
1209
- else
1210
- Token(Ltype2Token[ltype], str)
1211
- end.set_text(str)
1212
- ensure
1213
- @ltype = nil
1214
- @quoted = nil
1215
- @lex_state = EXPR_END
1216
- end
1217
- end
1218
-
1219
- def skip_inner_expression
1220
- res = ""
1221
- nest = 0
1222
- while (ch = getc)
1223
- res << ch
1224
- if ch == '}'
1225
- break if nest.zero?
1226
- nest -= 1
1227
- elsif ch == '{'
1228
- nest += 1
1229
- end
1230
- end
1231
- res
1232
- end
1233
-
1234
- def identify_comment
1235
- @ltype = "#"
1236
- comment = "#"
1237
- while ch = getc
1238
- if ch == "\\"
1239
- ch = getc
1240
- if ch == "\n"
1241
- ch = " "
1242
- else
1243
- comment << "\\"
1244
- end
1245
- else
1246
- if ch == "\n"
1247
- @ltype = nil
1248
- ungetc
1249
- break
1250
- end
1251
- end
1252
- comment << ch
1253
- end
1254
- return Token(TkCOMMENT).set_text(comment)
1255
- end
1256
-
1257
- def read_escape
1258
- res = ""
1259
- case ch = getc
1260
- when /[0-7]/
1261
- ungetc ch
1262
- 3.times do
1263
- case ch = getc
1264
- when /[0-7]/
1265
- when nil
1266
- break
1267
- else
1268
- ungetc
1269
- break
1270
- end
1271
- res << ch
1272
- end
1273
-
1274
- when "x"
1275
- res << ch
1276
- 2.times do
1277
- case ch = getc
1278
- when /[0-9a-fA-F]/
1279
- when nil
1280
- break
1281
- else
1282
- ungetc
1283
- break
1284
- end
1285
- res << ch
1286
- end
1287
-
1288
- when "M"
1289
- res << ch
1290
- if (ch = getc) != '-'
1291
- ungetc
1292
- else
1293
- res << ch
1294
- if (ch = getc) == "\\" #"
1295
- res << ch
1296
- res << read_escape
1297
- else
1298
- res << ch
1299
- end
1300
- end
1301
-
1302
- when "C", "c" #, "^"
1303
- res << ch
1304
- if ch == "C" and (ch = getc) != "-"
1305
- ungetc
1306
- else
1307
- res << ch
1308
- if (ch = getc) == "\\" #"
1309
- res << ch
1310
- res << read_escape
1311
- else
1312
- res << ch
1313
- end
1314
- end
1315
- else
1316
- res << ch
1317
- end
1318
- res
1319
- end
1320
- end
1321
- end