fancy 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (242) hide show
  1. data/AUTHORS +7 -0
  2. data/LICENSE +19 -0
  3. data/README +173 -0
  4. data/Rakefile +255 -0
  5. data/bin/fancy +40 -0
  6. data/bin/fdoc +23 -0
  7. data/bin/fyi +22 -0
  8. data/bin/ifancy +46 -0
  9. data/boot/README +12 -0
  10. data/boot/code_loader.rb +165 -0
  11. data/boot/compile.fy +3 -0
  12. data/boot/fancy_ext.rb +13 -0
  13. data/boot/fancy_ext/block_env.rb +29 -0
  14. data/boot/fancy_ext/class.rb +26 -0
  15. data/boot/fancy_ext/kernel.rb +12 -0
  16. data/boot/fancy_ext/module.rb +89 -0
  17. data/boot/fancy_ext/object.rb +34 -0
  18. data/boot/fancy_ext/string_helper.rb +10 -0
  19. data/boot/load.rb +72 -0
  20. data/boot/rbx-compiler/README +12 -0
  21. data/boot/rbx-compiler/compiler.rb +24 -0
  22. data/boot/rbx-compiler/compiler/ast.rb +23 -0
  23. data/boot/rbx-compiler/compiler/ast/README +11 -0
  24. data/boot/rbx-compiler/compiler/ast/array_literal.rb +13 -0
  25. data/boot/rbx-compiler/compiler/ast/assign.rb +57 -0
  26. data/boot/rbx-compiler/compiler/ast/block.rb +70 -0
  27. data/boot/rbx-compiler/compiler/ast/class_def.rb +35 -0
  28. data/boot/rbx-compiler/compiler/ast/expression_list.rb +57 -0
  29. data/boot/rbx-compiler/compiler/ast/hash_literal.rb +11 -0
  30. data/boot/rbx-compiler/compiler/ast/identifier.rb +120 -0
  31. data/boot/rbx-compiler/compiler/ast/match.rb +81 -0
  32. data/boot/rbx-compiler/compiler/ast/message_send.rb +71 -0
  33. data/boot/rbx-compiler/compiler/ast/method_def.rb +116 -0
  34. data/boot/rbx-compiler/compiler/ast/node.rb +6 -0
  35. data/boot/rbx-compiler/compiler/ast/range_literal.rb +22 -0
  36. data/boot/rbx-compiler/compiler/ast/require.rb +20 -0
  37. data/boot/rbx-compiler/compiler/ast/return.rb +29 -0
  38. data/boot/rbx-compiler/compiler/ast/ruby_args.rb +35 -0
  39. data/boot/rbx-compiler/compiler/ast/script.rb +56 -0
  40. data/boot/rbx-compiler/compiler/ast/singleton_method_def.rb +39 -0
  41. data/boot/rbx-compiler/compiler/ast/string_literal.rb +14 -0
  42. data/boot/rbx-compiler/compiler/ast/super.rb +25 -0
  43. data/boot/rbx-compiler/compiler/ast/try_catch_block.rb +220 -0
  44. data/boot/rbx-compiler/compiler/ast/tuple_literal.rb +33 -0
  45. data/boot/rbx-compiler/compiler/command.rb +39 -0
  46. data/boot/rbx-compiler/compiler/compiler.rb +83 -0
  47. data/boot/rbx-compiler/compiler/stages.rb +99 -0
  48. data/boot/rbx-compiler/parser.rb +2 -0
  49. data/boot/rbx-compiler/parser/README +15 -0
  50. data/boot/rbx-compiler/parser/Rakefile +54 -0
  51. data/boot/rbx-compiler/parser/extconf.rb +3 -0
  52. data/boot/rbx-compiler/parser/fancy_parser.bundle +0 -0
  53. data/boot/rbx-compiler/parser/fancy_parser.c +46 -0
  54. data/boot/rbx-compiler/parser/fancy_parser.h +8 -0
  55. data/boot/rbx-compiler/parser/lexer.lex +180 -0
  56. data/boot/rbx-compiler/parser/parser.rb +356 -0
  57. data/boot/rbx-compiler/parser/parser.y +711 -0
  58. data/boot/rsexp_pretty_printer.rb +76 -0
  59. data/doc/api/fancy.css +93 -0
  60. data/doc/api/fancy.jsonp +1 -0
  61. data/doc/api/fdoc.js +187 -0
  62. data/doc/api/index.html +57 -0
  63. data/doc/api/underscore-min.js +18 -0
  64. data/doc/features.md +228 -0
  65. data/examples/argv.fy +8 -0
  66. data/examples/arithmetic.fy +7 -0
  67. data/examples/armstrong_numbers.fy +33 -0
  68. data/examples/array.fy +52 -0
  69. data/examples/blocks.fy +15 -0
  70. data/examples/boolean.fy +24 -0
  71. data/examples/call_with_receiver.fy +9 -0
  72. data/examples/class.fy +68 -0
  73. data/examples/closures.fy +24 -0
  74. data/examples/constant_access.fy +15 -0
  75. data/examples/default_args.fy +17 -0
  76. data/examples/define_methods.fy +15 -0
  77. data/examples/documentation.fy +57 -0
  78. data/examples/documentation_formatters.fy +25 -0
  79. data/examples/echo.fy +16 -0
  80. data/examples/empty_catch.fy +4 -0
  81. data/examples/exception.fy +9 -0
  82. data/examples/factorial.fy +12 -0
  83. data/examples/fibonacci.fy +16 -0
  84. data/examples/files.fy +23 -0
  85. data/examples/finally.fy +5 -0
  86. data/examples/game_of_life.fy +148 -0
  87. data/examples/hashes.fy +7 -0
  88. data/examples/hello_world.fy +6 -0
  89. data/examples/html_generator.fy +54 -0
  90. data/examples/implicit_return.fy +3 -0
  91. data/examples/matchers.fy +6 -0
  92. data/examples/methods.fy +29 -0
  93. data/examples/nested_classes.fy +27 -0
  94. data/examples/nested_try.fy +9 -0
  95. data/examples/numbers.fy +12 -0
  96. data/examples/pattern_matching.fy +40 -0
  97. data/examples/person.fy +65 -0
  98. data/examples/project-euler/01.fy +8 -0
  99. data/examples/project-euler/02.fy +21 -0
  100. data/examples/project-euler/28.fy +33 -0
  101. data/examples/rbx/and_or.fy +7 -0
  102. data/examples/rbx/blocks.fy +22 -0
  103. data/examples/rbx/classes.fy +32 -0
  104. data/examples/rbx/hello.fy +8 -0
  105. data/examples/rbx/include.fy +12 -0
  106. data/examples/rbx/inherit.fy +11 -0
  107. data/examples/rbx/methods.fy +15 -0
  108. data/examples/rbx/nested_classes.fy +9 -0
  109. data/examples/rbx/require.fy +3 -0
  110. data/examples/rbx/strings.fy +5 -0
  111. data/examples/regex.fy +7 -0
  112. data/examples/require.fy +7 -0
  113. data/examples/retry.fy +12 -0
  114. data/examples/return.fy +13 -0
  115. data/examples/ruby_require.fy +7 -0
  116. data/examples/ruby_send.fy +3 -0
  117. data/examples/singleton_methods.fy +21 -0
  118. data/examples/stupid_quicksort.fy +12 -0
  119. data/examples/threads.fy +18 -0
  120. data/examples/tuple.fy +8 -0
  121. data/examples/webserver/webserver.fy +18 -0
  122. data/lib/argv.fy +36 -0
  123. data/lib/array.fy +207 -0
  124. data/lib/block.fy +88 -0
  125. data/lib/boot.fy +41 -0
  126. data/lib/class.fy +106 -0
  127. data/lib/compiler.fy +14 -0
  128. data/lib/compiler/ast.fy +40 -0
  129. data/lib/compiler/ast/assign.fy +96 -0
  130. data/lib/compiler/ast/block.fy +84 -0
  131. data/lib/compiler/ast/class_def.fy +33 -0
  132. data/lib/compiler/ast/expression_list.fy +47 -0
  133. data/lib/compiler/ast/identifier.fy +113 -0
  134. data/lib/compiler/ast/literals.fy +122 -0
  135. data/lib/compiler/ast/match.fy +88 -0
  136. data/lib/compiler/ast/message_send.fy +110 -0
  137. data/lib/compiler/ast/method_def.fy +90 -0
  138. data/lib/compiler/ast/node.fy +7 -0
  139. data/lib/compiler/ast/range.fy +16 -0
  140. data/lib/compiler/ast/require.fy +15 -0
  141. data/lib/compiler/ast/return.fy +23 -0
  142. data/lib/compiler/ast/script.fy +52 -0
  143. data/lib/compiler/ast/singleton_method_def.fy +35 -0
  144. data/lib/compiler/ast/super.fy +17 -0
  145. data/lib/compiler/ast/try_catch.fy +176 -0
  146. data/lib/compiler/ast/tuple_literal.fy +34 -0
  147. data/lib/compiler/command.fy +51 -0
  148. data/lib/compiler/compiler.fy +73 -0
  149. data/lib/compiler/stages.fy +81 -0
  150. data/lib/directory.fy +17 -0
  151. data/lib/documentation.fy +115 -0
  152. data/lib/enumerable.fy +269 -0
  153. data/lib/eval.fy +31 -0
  154. data/lib/fancy_spec.fy +202 -0
  155. data/lib/fdoc.fy +359 -0
  156. data/lib/fdoc_hook.fy +10 -0
  157. data/lib/file.fy +54 -0
  158. data/lib/hash.fy +56 -0
  159. data/lib/main.fy +80 -0
  160. data/lib/method.fy +22 -0
  161. data/lib/nil_class.fy +56 -0
  162. data/lib/number.fy +87 -0
  163. data/lib/object.fy +170 -0
  164. data/lib/package.fy +61 -0
  165. data/lib/package/dependency.fy +24 -0
  166. data/lib/package/installer.fy +180 -0
  167. data/lib/package/specification.fy +55 -0
  168. data/lib/package/uninstaller.fy +15 -0
  169. data/lib/parser.fy +4 -0
  170. data/lib/parser/ext/README +15 -0
  171. data/lib/parser/ext/ext.c +42 -0
  172. data/lib/parser/ext/ext.h +8 -0
  173. data/lib/parser/ext/extconf.rb +3 -0
  174. data/lib/parser/ext/lexer.lex +187 -0
  175. data/lib/parser/ext/parser.y +744 -0
  176. data/lib/parser/methods.fy +297 -0
  177. data/lib/rbx.fy +37 -0
  178. data/lib/rbx/array.fy +237 -0
  179. data/lib/rbx/bignum.fy +23 -0
  180. data/lib/rbx/block.fy +9 -0
  181. data/lib/rbx/class.fy +129 -0
  182. data/lib/rbx/code_loader.fy +192 -0
  183. data/lib/rbx/console.fy +63 -0
  184. data/lib/rbx/directory.fy +46 -0
  185. data/lib/rbx/documentation.fy +64 -0
  186. data/lib/rbx/environment_variables.fy +3 -0
  187. data/lib/rbx/exception.fy +30 -0
  188. data/lib/rbx/false_class.fy +58 -0
  189. data/lib/rbx/fiber.fy +25 -0
  190. data/lib/rbx/file.fy +191 -0
  191. data/lib/rbx/fixnum.fy +25 -0
  192. data/lib/rbx/float.fy +14 -0
  193. data/lib/rbx/hash.fy +38 -0
  194. data/lib/rbx/integer.fy +15 -0
  195. data/lib/rbx/io.fy +30 -0
  196. data/lib/rbx/match_data.fy +9 -0
  197. data/lib/rbx/method.fy +22 -0
  198. data/lib/rbx/name_error.fy +3 -0
  199. data/lib/rbx/no_method_error.fy +15 -0
  200. data/lib/rbx/object.fy +117 -0
  201. data/lib/rbx/range.fy +15 -0
  202. data/lib/rbx/regexp.fy +9 -0
  203. data/lib/rbx/string.fy +63 -0
  204. data/lib/rbx/symbol.fy +12 -0
  205. data/lib/rbx/system.fy +37 -0
  206. data/lib/rbx/tcp_server.fy +6 -0
  207. data/lib/rbx/tcp_socket.fy +7 -0
  208. data/lib/rbx/thread.fy +75 -0
  209. data/lib/rbx/tuple.fy +37 -0
  210. data/lib/set.fy +61 -0
  211. data/lib/stack.fy +51 -0
  212. data/lib/string.fy +58 -0
  213. data/lib/struct.fy +13 -0
  214. data/lib/symbol.fy +23 -0
  215. data/lib/true_class.fy +43 -0
  216. data/lib/tuple.fy +68 -0
  217. data/lib/version.fy +6 -0
  218. data/tests/argv.fy +13 -0
  219. data/tests/array.fy +343 -0
  220. data/tests/assignment.fy +53 -0
  221. data/tests/block.fy +103 -0
  222. data/tests/class.fy +409 -0
  223. data/tests/control_flow.fy +79 -0
  224. data/tests/documentation.fy +24 -0
  225. data/tests/exception.fy +115 -0
  226. data/tests/file.fy +86 -0
  227. data/tests/hash.fy +101 -0
  228. data/tests/method.fy +131 -0
  229. data/tests/nil_class.fy +55 -0
  230. data/tests/number.fy +128 -0
  231. data/tests/object.fy +125 -0
  232. data/tests/parsing/sexp.fy +50 -0
  233. data/tests/pattern_matching.fy +82 -0
  234. data/tests/range.fy +11 -0
  235. data/tests/set.fy +10 -0
  236. data/tests/stack.fy +22 -0
  237. data/tests/string.fy +102 -0
  238. data/tests/symbol.fy +17 -0
  239. data/tests/true_class.fy +63 -0
  240. data/tests/tuple.fy +21 -0
  241. data/tools/fancy-mode.el +63 -0
  242. metadata +321 -0
@@ -0,0 +1,83 @@
1
+ class Fancy
2
+
3
+ class Compiler < Rubinius::Compiler
4
+
5
+ def self.fancy_compiled_name(file)
6
+ if file.suffix? ".fy"
7
+ file + "c"
8
+ else
9
+ file + ".compiled.fyc"
10
+ end
11
+ end
12
+
13
+ # Writes the compiled output file
14
+ def self.compile_fancy_file(file, output = nil, line = 1, print = false)
15
+ compiler = new :fancy_file, :compiled_file
16
+
17
+ parser = compiler.parser
18
+ parser.root Rubinius::AST::Script
19
+
20
+ parser.input file, line
21
+
22
+ if print
23
+ parser.print
24
+ printer = compiler.packager.print
25
+ printer.bytecode = true
26
+ end
27
+
28
+ writer = compiler.writer
29
+ writer.name = output ? output : fancy_compiled_name(file)
30
+
31
+ begin
32
+ compiler.run
33
+ rescue Exception => e
34
+ compiler_error "Error trying to compile fancy: #{file}", e
35
+ end
36
+ end
37
+
38
+ # Returns a compiled method to be loaded by the rbx runtime.
39
+ def self.compile_fancy_code(code, filename = "(eval)", line = 1, print = false)
40
+ compiler = new :fancy_code, :compiled_method
41
+
42
+ parser = compiler.parser
43
+ parser.root Rubinius::AST::Script
44
+ parser.input code, filename, line
45
+
46
+ if print
47
+ parser.print
48
+ printer = compiler.packager.print
49
+ printer.bytecode = true
50
+ end
51
+
52
+ begin
53
+ compiler.run
54
+ rescue Exception => e
55
+ compiler_error "Error trying to compile fancy: #{filename}", e
56
+ end
57
+ end
58
+
59
+ # Returns a compiled method to be evaled by the rbx runtime.
60
+ def self.compile_fancy_eval(code, variable_scope, filename = "(eval)", line = 1, print = false)
61
+ compiler = new :fancy_code, :compiled_method
62
+
63
+ parser = compiler.parser
64
+ parser.root Rubinius::AST::EvalExpression
65
+ parser.input code, filename, line
66
+
67
+ if print
68
+ parser.print
69
+ printer = compiler.packager.print
70
+ printer.bytecode = true
71
+ end
72
+
73
+ compiler.generator.variable_scope = variable_scope
74
+
75
+ begin
76
+ compiler.run
77
+ rescue Exception => e
78
+ compiler_error "Error trying to compile fancy: #{filename}", e
79
+ end
80
+ end
81
+ end
82
+
83
+ end
@@ -0,0 +1,99 @@
1
+ #
2
+ # Stages for compiling Fancy to Rubinius bytecode.
3
+ #
4
+
5
+ class Fancy
6
+ class Compiler
7
+
8
+ # FancyAST -> Rubinius Symbolic bytecode
9
+ class FancyGenerator < Rubinius::Compiler::Stage
10
+ stage :fancy_bytecode
11
+ next_stage Rubinius::Compiler::Encoder
12
+
13
+ attr_accessor :variable_scope
14
+
15
+ def initialize(compiler, last)
16
+ super
17
+ @variable_scope = nil
18
+ compiler.generator = self
19
+ end
20
+
21
+ def run
22
+ @output = Rubinius::Generator.new
23
+ @input.variable_scope = @variable_scope
24
+ @input.bytecode @output
25
+ @output.close
26
+ run_next
27
+ end
28
+
29
+ def input(root_ast)
30
+ @input = root_ast
31
+ end
32
+ end
33
+
34
+ # Fancy string -> AST
35
+ class FancyCodeParser < Rubinius::Compiler::Stage
36
+ stage :fancy_code
37
+ next_stage FancyGenerator
38
+
39
+ def initialize(compiler, last)
40
+ super
41
+ compiler.parser = self
42
+ end
43
+
44
+ def root(root)
45
+ @root = root
46
+ end
47
+
48
+ def print
49
+ @print = true
50
+ end
51
+
52
+ def input(code, filename="(eval)", line=1)
53
+ @input = code
54
+ @filename = filename
55
+ @line = line
56
+ end
57
+
58
+ def run
59
+ ast = Parser.parse_string(@input, @line, @filename)
60
+ @output = @root.new ast
61
+ @output.file = @filename
62
+ run_next
63
+ end
64
+ end
65
+
66
+ # Fancy file -> AST
67
+ class FancyFileParser < Rubinius::Compiler::Stage
68
+ stage :fancy_file
69
+ next_stage FancyGenerator
70
+
71
+ def initialize(compiler, last)
72
+ super
73
+ compiler.parser = self
74
+ end
75
+
76
+ def root(root)
77
+ @root = root
78
+ end
79
+
80
+ def print
81
+ @print = true
82
+ end
83
+
84
+ def input(filename, line=1)
85
+ @filename = filename
86
+ @line = line
87
+ end
88
+
89
+ def run
90
+ ast = Parser.parse_file(@filename, @line)
91
+ # p ast if @print
92
+ @output = @root.new ast
93
+ @output.file = @filename
94
+ run_next
95
+ end
96
+ end
97
+
98
+ end
99
+ end
@@ -0,0 +1,2 @@
1
+ require File.expand_path("parser/parser", File.dirname(__FILE__))
2
+ require File.expand_path("parser/fancy_parser", File.dirname(__FILE__))
@@ -0,0 +1,15 @@
1
+ This directory contains all the code that deals with parsing Fancy
2
+ source files (.fy) and creating an object-oriented representation (a
3
+ so-called AST - Abstract Syntax Tree) from it to be used in the
4
+ compiler for further processing (mostly to .fyc bytecode files).
5
+
6
+ The parser.y file contains the grammar rules in GNU Bison (YACC
7
+ compatible) syntax, which make up the parser. The parser actions are
8
+ written in C and call out to Ruby methods defined in parser.rb via
9
+ rbx's C-extension interface to build the actual AST objects.
10
+
11
+ The lexer.y contains the lexer rules in GNU Flex syntax for scanning a
12
+ source file for tokens.
13
+
14
+ The parser.rb file contains all the methods used by the parser to
15
+ create AST objects.
@@ -0,0 +1,54 @@
1
+ require 'rbconfig'
2
+ dl_ext = RbConfig::CONFIG['DLEXT']
3
+
4
+ namespace :rbx_parser do
5
+
6
+ _ = lambda { |file| File.expand_path(file, File.dirname(__FILE__)); }
7
+
8
+ lexer_c = file _["lexer.c"] => _["lexer.lex"] do |task|
9
+ Dir.chdir _["."] do
10
+ sh 'flex', '--outfile', task.to_s, '--header-file=lexer.h',
11
+ task.prerequisites.first
12
+ end
13
+ end
14
+
15
+ parser_c = file _["parser.c"] => _["parser.y"] do |task|
16
+ Dir.chdir(_["."]) { sh "bison", "--output", task.to_s, "-d", "-v", task.prerequisites.first }
17
+ end
18
+
19
+ makefile = file _["Makefile"] => [_["extconf.rb"], lexer_c, parser_c] do |task|
20
+ Dir.chdir(_["."]) { sh 'rbx', task.prerequisites.first }
21
+ end
22
+
23
+ desc "Builds the parser."
24
+ task :parser => parser_c
25
+
26
+ desc "Builds the lexer."
27
+ task :lexer => lexer_c
28
+
29
+ desc "Compiles the generated lexer and parser."
30
+ task :compile => [makefile, parser_c, lexer_c] do
31
+ sh 'make', '-C', _["."]
32
+ end
33
+
34
+ desc "Cleans up generated files."
35
+ task :clean do
36
+ rm_f lexer_c.to_s
37
+ rm_f parser_c.to_s
38
+ rm_f makefile.to_s
39
+ rm_f _["lexer.h"]
40
+ rm_f _["parser.h"]
41
+ rm_f _["parser.output"]
42
+ rm_f Dir.glob(_["*.{o,so,rbc,log}"])
43
+ sh 'make', '-C', _["."], "clean" rescue nil
44
+ end
45
+
46
+ parser_e = file _["fancy_parser.#{dl_ext}"] => :compile
47
+ task :ext => parser_e
48
+
49
+ desc "Invokes the compile task."
50
+ task :default => :compile
51
+ end
52
+
53
+
54
+ task :clean => "rbx_parser:clean"
@@ -0,0 +1,3 @@
1
+ require 'mkmf'
2
+ have_library("fl")
3
+ create_makefile('fancy_parser')
@@ -0,0 +1,46 @@
1
+ #include "fancy_parser.h"
2
+ #include "ruby.h"
3
+ #include "lexer.h"
4
+
5
+
6
+ static VALUE
7
+ parse_string(VALUE self, VALUE code) {
8
+ VALUE lineno = rb_funcall(self, rb_intern("lineno"), 0);
9
+ char *str = StringValueCStr(code);
10
+ YY_BUFFER_STATE buffstate = yy_scan_string(str);
11
+ yy_switch_to_buffer(buffstate);
12
+ yylineno = NUM2INT(lineno);
13
+ yyparse(self);
14
+ yy_delete_buffer(buffstate);
15
+ return self;
16
+ }
17
+
18
+ static VALUE
19
+ parse_file(VALUE self) {
20
+ VALUE filename = rb_funcall(self, rb_intern("filename"), 0);
21
+ VALUE lineno = rb_funcall(self, rb_intern("lineno"), 0);
22
+ char *str = StringValueCStr(filename);
23
+ FILE *f = fopen(str, "r");
24
+ if(!f) {
25
+ rb_funcall(self, rb_intern("file_error"), 2, rb_str_new2("Could not open file"), rb_str_new2(str));
26
+ return Qnil;
27
+ }
28
+ YY_BUFFER_STATE buffstate = yy_create_buffer(f, YY_BUF_SIZE);
29
+ yy_switch_to_buffer(buffstate);
30
+ yylineno = NUM2INT(lineno);
31
+ yyparse(self);
32
+ yy_delete_buffer(buffstate);
33
+ return self;
34
+ }
35
+
36
+ void
37
+ Init_fancy_parser() {
38
+ VALUE ext = rb_funcall(rb_cModule, rb_intern("new"), 0);
39
+ rb_define_method(ext, "parse_string", parse_string, 1);
40
+ rb_define_method(ext, "parse_file", parse_file, 0);
41
+ VALUE fancy = rb_const_get(rb_cObject, rb_intern("Fancy"));
42
+ VALUE parser = rb_const_get(fancy, rb_intern("Parser"));
43
+ rb_funcall(parser, rb_intern("include"), 1, ext);
44
+ }
45
+
46
+
@@ -0,0 +1,8 @@
1
+ #ifndef _FANCY_PARSER_H_
2
+ #define _FANCY_PARSER_H_
3
+
4
+ /* Size of default input buffer. */
5
+ #define YY_BUF_SIZE 16384
6
+
7
+
8
+ #endif /* _FANCY_PARSER_H_ */
@@ -0,0 +1,180 @@
1
+ %{
2
+ #include "ruby.h"
3
+ #include "parser.h"
4
+
5
+ int yyerror(char *s);
6
+ %}
7
+
8
+ %option yylineno
9
+
10
+ digit [0-9]
11
+ octdigit [0-7]
12
+ hexdigit [0-9a-fA-F]
13
+ bindigit [01]
14
+ capital [A-Z]
15
+ lower [a-z]
16
+ letter [A-Za-z]
17
+ special [-+?!=*/^><%&~]
18
+ special_under ({special}|"_")
19
+ operator ({special}+|"||"{special_under}*)
20
+ int_lit [-+]?{digit}({digit}|_{digit})*
21
+ double_lit {int_lit}\.{digit}+
22
+ hex_lit 0[xX]{hexdigit}+
23
+ bin_lit 0[bB]{bindigit}+
24
+ oct_lit 0[oO]{octdigit}+
25
+ string_lit L?\"(\\.|[^\\"])*\"
26
+ multiline_string L?\"\"\"(\\.|[^\\"])*\"\"\"
27
+ lparen \(
28
+ rparen \)
29
+ lcurly "{"
30
+ rcurly "}"
31
+ lbracket "["
32
+ rbracket "]"
33
+ lhash "<["
34
+ rhash "]>"
35
+ stab "|"
36
+ arrow "=>"
37
+ thin_arrow "->"
38
+ delimiter [ \n\r\t\(\)]
39
+ return_local "return_local"
40
+ return "return"
41
+ require "require:"
42
+ try "try"
43
+ catch "catch"
44
+ finally "finally"
45
+ retry "retry"
46
+ super "super"
47
+ private "private"
48
+ protected "protected"
49
+ self "self"
50
+ match "match"
51
+ case "case"
52
+ identifier @?@?({lower}|[_&*])({letter}|{digit}|{special_under})*
53
+ constant {capital}({letter}|{digit}|{special_under})*
54
+ nested_constant ({constant}::)+{constant}
55
+ symbol_lit \'({identifier}|{operator}|:|"[]")+
56
+ ruby_send_open {identifier}{lparen}
57
+ ruby_oper_open {operator}{lparen}
58
+ regexp_lit "/".*"/"
59
+ comma ,
60
+
61
+ semi ;
62
+ equals =
63
+ colon :
64
+ class "class"
65
+ def "def"
66
+ dot "."
67
+ dollar "$"
68
+ comment #[^\n]*
69
+ escaped_newline "\\".*\n
70
+
71
+ %%
72
+
73
+ {class} { return CLASS; }
74
+ {def} { return DEF; }
75
+ {hex_lit} {
76
+ yylval.object = rb_str_new2(yytext);
77
+ return HEX_LITERAL;
78
+ }
79
+ {oct_lit} {
80
+ yylval.object = rb_str_new2(yytext);
81
+ return OCT_LITERAL;
82
+ }
83
+ {bin_lit} {
84
+ yylval.object = rb_str_new2(yytext);
85
+ return BIN_LITERAL;
86
+ }
87
+ {int_lit} {
88
+ yylval.object = rb_str_new2(yytext);
89
+ return INTEGER_LITERAL;
90
+ }
91
+ {double_lit} {
92
+ yylval.object = rb_str_new2(yytext);
93
+ return DOUBLE_LITERAL;
94
+ }
95
+ {string_lit} {
96
+ yylval.object = rb_str_new2(yytext);
97
+ return STRING_LITERAL;
98
+ }
99
+ {multiline_string} {
100
+ yylval.object = rb_str_new2(yytext);
101
+ return MULTI_STRING_LITERAL;
102
+ }
103
+ {lparen} { return LPAREN; }
104
+ {rparen} { return RPAREN; }
105
+ {lcurly} { return LCURLY; }
106
+ {rcurly} { return RCURLY; }
107
+ {lbracket} { return LBRACKET; }
108
+ {rbracket} { return RBRACKET; }
109
+ {lhash} { return LHASH; }
110
+ {rhash} { return RHASH; }
111
+ {stab} { return STAB; }
112
+ {arrow} { return ARROW; }
113
+ {thin_arrow} { return THIN_ARROW; }
114
+ {equals} { return EQUALS; }
115
+ {operator} {
116
+ yylval.object = rb_str_new2(yytext);
117
+ return OPERATOR;
118
+ }
119
+ {return_local} { return RETURN_LOCAL; }
120
+ {return} { return RETURN; }
121
+ {require} { return REQUIRE; }
122
+ {try} { return TRY; }
123
+ {catch} { return CATCH; }
124
+ {finally} { return FINALLY; }
125
+ {retry} { return RETRY; }
126
+ {super} { return SUPER; }
127
+ {private} { return PRIVATE; }
128
+ {protected} { return PROTECTED; }
129
+ {self} {
130
+ yylval.object = rb_str_new2(yytext);
131
+ return IDENTIFIER;
132
+ }
133
+ {match} {
134
+ return MATCH;
135
+ }
136
+ {case} {
137
+ return CASE;
138
+ }
139
+ {identifier} {
140
+ yylval.object = rb_str_new2(yytext);
141
+ return IDENTIFIER;
142
+ }
143
+ {ruby_send_open} {
144
+ yylval.object = rb_str_new2(yytext);
145
+ return RUBY_SEND_OPEN;
146
+ }
147
+ {ruby_oper_open} {
148
+ yylval.object = rb_str_new2(yytext);
149
+ return RUBY_OPER_OPEN;
150
+ }
151
+ {constant} {
152
+ yylval.object = rb_str_new2(yytext);
153
+ return CONSTANT;
154
+ }
155
+ {nested_constant} {
156
+ yylval.object = rb_str_new2(yytext);
157
+ return CONSTANT;
158
+ }
159
+ {symbol_lit} {
160
+ yylval.object = rb_str_new2(yytext);
161
+ return SYMBOL_LITERAL;
162
+ }
163
+ {regexp_lit} {
164
+ yylval.object = rb_str_new2(yytext);
165
+ return REGEX_LITERAL;
166
+ }
167
+ {comma} { return COMMA; }
168
+ {semi} { return SEMI; }
169
+ {colon} { return COLON; }
170
+ {dot} { return DOT; }
171
+ {dollar} { return DOLLAR; }
172
+
173
+ {comment} {}
174
+
175
+ [ \t]* {}
176
+ {escaped_newline} {}
177
+ [\n] { return NL; }
178
+
179
+ . { fprintf(stderr, "SCANNER %d", yyerror("")); exit(1); }
180
+