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.
- data/AUTHORS +7 -0
- data/LICENSE +19 -0
- data/README +173 -0
- data/Rakefile +255 -0
- data/bin/fancy +40 -0
- data/bin/fdoc +23 -0
- data/bin/fyi +22 -0
- data/bin/ifancy +46 -0
- data/boot/README +12 -0
- data/boot/code_loader.rb +165 -0
- data/boot/compile.fy +3 -0
- data/boot/fancy_ext.rb +13 -0
- data/boot/fancy_ext/block_env.rb +29 -0
- data/boot/fancy_ext/class.rb +26 -0
- data/boot/fancy_ext/kernel.rb +12 -0
- data/boot/fancy_ext/module.rb +89 -0
- data/boot/fancy_ext/object.rb +34 -0
- data/boot/fancy_ext/string_helper.rb +10 -0
- data/boot/load.rb +72 -0
- data/boot/rbx-compiler/README +12 -0
- data/boot/rbx-compiler/compiler.rb +24 -0
- data/boot/rbx-compiler/compiler/ast.rb +23 -0
- data/boot/rbx-compiler/compiler/ast/README +11 -0
- data/boot/rbx-compiler/compiler/ast/array_literal.rb +13 -0
- data/boot/rbx-compiler/compiler/ast/assign.rb +57 -0
- data/boot/rbx-compiler/compiler/ast/block.rb +70 -0
- data/boot/rbx-compiler/compiler/ast/class_def.rb +35 -0
- data/boot/rbx-compiler/compiler/ast/expression_list.rb +57 -0
- data/boot/rbx-compiler/compiler/ast/hash_literal.rb +11 -0
- data/boot/rbx-compiler/compiler/ast/identifier.rb +120 -0
- data/boot/rbx-compiler/compiler/ast/match.rb +81 -0
- data/boot/rbx-compiler/compiler/ast/message_send.rb +71 -0
- data/boot/rbx-compiler/compiler/ast/method_def.rb +116 -0
- data/boot/rbx-compiler/compiler/ast/node.rb +6 -0
- data/boot/rbx-compiler/compiler/ast/range_literal.rb +22 -0
- data/boot/rbx-compiler/compiler/ast/require.rb +20 -0
- data/boot/rbx-compiler/compiler/ast/return.rb +29 -0
- data/boot/rbx-compiler/compiler/ast/ruby_args.rb +35 -0
- data/boot/rbx-compiler/compiler/ast/script.rb +56 -0
- data/boot/rbx-compiler/compiler/ast/singleton_method_def.rb +39 -0
- data/boot/rbx-compiler/compiler/ast/string_literal.rb +14 -0
- data/boot/rbx-compiler/compiler/ast/super.rb +25 -0
- data/boot/rbx-compiler/compiler/ast/try_catch_block.rb +220 -0
- data/boot/rbx-compiler/compiler/ast/tuple_literal.rb +33 -0
- data/boot/rbx-compiler/compiler/command.rb +39 -0
- data/boot/rbx-compiler/compiler/compiler.rb +83 -0
- data/boot/rbx-compiler/compiler/stages.rb +99 -0
- data/boot/rbx-compiler/parser.rb +2 -0
- data/boot/rbx-compiler/parser/README +15 -0
- data/boot/rbx-compiler/parser/Rakefile +54 -0
- data/boot/rbx-compiler/parser/extconf.rb +3 -0
- data/boot/rbx-compiler/parser/fancy_parser.bundle +0 -0
- data/boot/rbx-compiler/parser/fancy_parser.c +46 -0
- data/boot/rbx-compiler/parser/fancy_parser.h +8 -0
- data/boot/rbx-compiler/parser/lexer.lex +180 -0
- data/boot/rbx-compiler/parser/parser.rb +356 -0
- data/boot/rbx-compiler/parser/parser.y +711 -0
- data/boot/rsexp_pretty_printer.rb +76 -0
- data/doc/api/fancy.css +93 -0
- data/doc/api/fancy.jsonp +1 -0
- data/doc/api/fdoc.js +187 -0
- data/doc/api/index.html +57 -0
- data/doc/api/underscore-min.js +18 -0
- data/doc/features.md +228 -0
- data/examples/argv.fy +8 -0
- data/examples/arithmetic.fy +7 -0
- data/examples/armstrong_numbers.fy +33 -0
- data/examples/array.fy +52 -0
- data/examples/blocks.fy +15 -0
- data/examples/boolean.fy +24 -0
- data/examples/call_with_receiver.fy +9 -0
- data/examples/class.fy +68 -0
- data/examples/closures.fy +24 -0
- data/examples/constant_access.fy +15 -0
- data/examples/default_args.fy +17 -0
- data/examples/define_methods.fy +15 -0
- data/examples/documentation.fy +57 -0
- data/examples/documentation_formatters.fy +25 -0
- data/examples/echo.fy +16 -0
- data/examples/empty_catch.fy +4 -0
- data/examples/exception.fy +9 -0
- data/examples/factorial.fy +12 -0
- data/examples/fibonacci.fy +16 -0
- data/examples/files.fy +23 -0
- data/examples/finally.fy +5 -0
- data/examples/game_of_life.fy +148 -0
- data/examples/hashes.fy +7 -0
- data/examples/hello_world.fy +6 -0
- data/examples/html_generator.fy +54 -0
- data/examples/implicit_return.fy +3 -0
- data/examples/matchers.fy +6 -0
- data/examples/methods.fy +29 -0
- data/examples/nested_classes.fy +27 -0
- data/examples/nested_try.fy +9 -0
- data/examples/numbers.fy +12 -0
- data/examples/pattern_matching.fy +40 -0
- data/examples/person.fy +65 -0
- data/examples/project-euler/01.fy +8 -0
- data/examples/project-euler/02.fy +21 -0
- data/examples/project-euler/28.fy +33 -0
- data/examples/rbx/and_or.fy +7 -0
- data/examples/rbx/blocks.fy +22 -0
- data/examples/rbx/classes.fy +32 -0
- data/examples/rbx/hello.fy +8 -0
- data/examples/rbx/include.fy +12 -0
- data/examples/rbx/inherit.fy +11 -0
- data/examples/rbx/methods.fy +15 -0
- data/examples/rbx/nested_classes.fy +9 -0
- data/examples/rbx/require.fy +3 -0
- data/examples/rbx/strings.fy +5 -0
- data/examples/regex.fy +7 -0
- data/examples/require.fy +7 -0
- data/examples/retry.fy +12 -0
- data/examples/return.fy +13 -0
- data/examples/ruby_require.fy +7 -0
- data/examples/ruby_send.fy +3 -0
- data/examples/singleton_methods.fy +21 -0
- data/examples/stupid_quicksort.fy +12 -0
- data/examples/threads.fy +18 -0
- data/examples/tuple.fy +8 -0
- data/examples/webserver/webserver.fy +18 -0
- data/lib/argv.fy +36 -0
- data/lib/array.fy +207 -0
- data/lib/block.fy +88 -0
- data/lib/boot.fy +41 -0
- data/lib/class.fy +106 -0
- data/lib/compiler.fy +14 -0
- data/lib/compiler/ast.fy +40 -0
- data/lib/compiler/ast/assign.fy +96 -0
- data/lib/compiler/ast/block.fy +84 -0
- data/lib/compiler/ast/class_def.fy +33 -0
- data/lib/compiler/ast/expression_list.fy +47 -0
- data/lib/compiler/ast/identifier.fy +113 -0
- data/lib/compiler/ast/literals.fy +122 -0
- data/lib/compiler/ast/match.fy +88 -0
- data/lib/compiler/ast/message_send.fy +110 -0
- data/lib/compiler/ast/method_def.fy +90 -0
- data/lib/compiler/ast/node.fy +7 -0
- data/lib/compiler/ast/range.fy +16 -0
- data/lib/compiler/ast/require.fy +15 -0
- data/lib/compiler/ast/return.fy +23 -0
- data/lib/compiler/ast/script.fy +52 -0
- data/lib/compiler/ast/singleton_method_def.fy +35 -0
- data/lib/compiler/ast/super.fy +17 -0
- data/lib/compiler/ast/try_catch.fy +176 -0
- data/lib/compiler/ast/tuple_literal.fy +34 -0
- data/lib/compiler/command.fy +51 -0
- data/lib/compiler/compiler.fy +73 -0
- data/lib/compiler/stages.fy +81 -0
- data/lib/directory.fy +17 -0
- data/lib/documentation.fy +115 -0
- data/lib/enumerable.fy +269 -0
- data/lib/eval.fy +31 -0
- data/lib/fancy_spec.fy +202 -0
- data/lib/fdoc.fy +359 -0
- data/lib/fdoc_hook.fy +10 -0
- data/lib/file.fy +54 -0
- data/lib/hash.fy +56 -0
- data/lib/main.fy +80 -0
- data/lib/method.fy +22 -0
- data/lib/nil_class.fy +56 -0
- data/lib/number.fy +87 -0
- data/lib/object.fy +170 -0
- data/lib/package.fy +61 -0
- data/lib/package/dependency.fy +24 -0
- data/lib/package/installer.fy +180 -0
- data/lib/package/specification.fy +55 -0
- data/lib/package/uninstaller.fy +15 -0
- data/lib/parser.fy +4 -0
- data/lib/parser/ext/README +15 -0
- data/lib/parser/ext/ext.c +42 -0
- data/lib/parser/ext/ext.h +8 -0
- data/lib/parser/ext/extconf.rb +3 -0
- data/lib/parser/ext/lexer.lex +187 -0
- data/lib/parser/ext/parser.y +744 -0
- data/lib/parser/methods.fy +297 -0
- data/lib/rbx.fy +37 -0
- data/lib/rbx/array.fy +237 -0
- data/lib/rbx/bignum.fy +23 -0
- data/lib/rbx/block.fy +9 -0
- data/lib/rbx/class.fy +129 -0
- data/lib/rbx/code_loader.fy +192 -0
- data/lib/rbx/console.fy +63 -0
- data/lib/rbx/directory.fy +46 -0
- data/lib/rbx/documentation.fy +64 -0
- data/lib/rbx/environment_variables.fy +3 -0
- data/lib/rbx/exception.fy +30 -0
- data/lib/rbx/false_class.fy +58 -0
- data/lib/rbx/fiber.fy +25 -0
- data/lib/rbx/file.fy +191 -0
- data/lib/rbx/fixnum.fy +25 -0
- data/lib/rbx/float.fy +14 -0
- data/lib/rbx/hash.fy +38 -0
- data/lib/rbx/integer.fy +15 -0
- data/lib/rbx/io.fy +30 -0
- data/lib/rbx/match_data.fy +9 -0
- data/lib/rbx/method.fy +22 -0
- data/lib/rbx/name_error.fy +3 -0
- data/lib/rbx/no_method_error.fy +15 -0
- data/lib/rbx/object.fy +117 -0
- data/lib/rbx/range.fy +15 -0
- data/lib/rbx/regexp.fy +9 -0
- data/lib/rbx/string.fy +63 -0
- data/lib/rbx/symbol.fy +12 -0
- data/lib/rbx/system.fy +37 -0
- data/lib/rbx/tcp_server.fy +6 -0
- data/lib/rbx/tcp_socket.fy +7 -0
- data/lib/rbx/thread.fy +75 -0
- data/lib/rbx/tuple.fy +37 -0
- data/lib/set.fy +61 -0
- data/lib/stack.fy +51 -0
- data/lib/string.fy +58 -0
- data/lib/struct.fy +13 -0
- data/lib/symbol.fy +23 -0
- data/lib/true_class.fy +43 -0
- data/lib/tuple.fy +68 -0
- data/lib/version.fy +6 -0
- data/tests/argv.fy +13 -0
- data/tests/array.fy +343 -0
- data/tests/assignment.fy +53 -0
- data/tests/block.fy +103 -0
- data/tests/class.fy +409 -0
- data/tests/control_flow.fy +79 -0
- data/tests/documentation.fy +24 -0
- data/tests/exception.fy +115 -0
- data/tests/file.fy +86 -0
- data/tests/hash.fy +101 -0
- data/tests/method.fy +131 -0
- data/tests/nil_class.fy +55 -0
- data/tests/number.fy +128 -0
- data/tests/object.fy +125 -0
- data/tests/parsing/sexp.fy +50 -0
- data/tests/pattern_matching.fy +82 -0
- data/tests/range.fy +11 -0
- data/tests/set.fy +10 -0
- data/tests/stack.fy +22 -0
- data/tests/string.fy +102 -0
- data/tests/symbol.fy +17 -0
- data/tests/true_class.fy +63 -0
- data/tests/tuple.fy +21 -0
- data/tools/fancy-mode.el +63 -0
- 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,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"
|
Binary file
|
@@ -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,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
|
+
|