$ rake
$ ruby -I. test.rb
-
Need to add support for regexps.
-
The current implementation translates the AST directly to ragel, should we generate a GTG first so the table is more compact?
*.c | |
*.rl |
$ rake
$ ruby -I. test.rb
Need to add support for regexps.
The current implementation translates the AST directly to ragel, should we generate a GTG first so the table is more compact?
require 'mkmf' | |
# :stopdoc: | |
create_makefile 'router' | |
# :startdoc: |
task :clean do | |
rm_f 'router.c' | |
rm_f 'router.rl' | |
rm_f 'router.o' | |
rm_f 'Makefile' | |
rm_f 'router.bundle' | |
rm_f 'router.so' | |
end | |
task :default do | |
ruby 'route_compiler.rb > router.rl' | |
sh 'ragel router.rl' | |
ruby 'extconf.rb' | |
sh 'make' | |
end |
require 'journey' | |
def asts paths | |
parser = Journey::Parser.new | |
Journey::Nodes::Or.new paths.map { |x| parser.parse x } | |
end | |
class Ragel < Journey::Visitors::Visitor | |
def terminal(n) | |
n.left.inspect | |
end | |
def visit_OR(n) | |
"(#{n.children.map { |x| visit x }.join ' | '})" | |
end | |
def visit_GROUP(n) | |
"(#{visit n})" | |
end | |
def visit_CAT(n) | |
"#{visit n.left} . #{visit n.right}" | |
end | |
end | |
## These come from your routes.rb | |
ast = asts %w{ | |
/articles | |
/articles/new | |
} | |
ragel = Ragel.new.accept ast | |
data = <<-eoc | |
#include <ruby.h> | |
%%{ | |
machine router; | |
action match { ret = Qtrue; } | |
main := #{ragel} %match; | |
}%% | |
%% write data; | |
static VALUE match(VALUE self, VALUE string) | |
{ | |
int cs = 0; | |
char *p = RSTRING_PTR(string); | |
char *pe = p + RSTRING_LEN(string); | |
char *eof = pe; | |
VALUE ret = Qfalse; | |
%% write init; | |
%% write exec; | |
return ret; | |
} | |
void Init_router() | |
{ | |
VALUE mRouter = rb_define_class("Router", rb_cObject); | |
rb_define_method(mRouter, "match", match, 1); | |
} | |
eoc | |
puts data |
# ruby -I. test.rb | |
require 'router' | |
require 'minitest/autorun' | |
class RouterTest < MiniTest::Unit::TestCase | |
def setup | |
@router = Router.new | |
end | |
def test_omg | |
assert @router.match '/articles/new' | |
refute @router.match '/articles/nw' | |
assert @router.match '/articles' | |
end | |
end |