treesl 0.0.1

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.
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,5 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Jacob Rothstein
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,32 @@
1
+ h1. TreeSL
2
+
3
+ TreeSL is my effort to define a flexible domain specific language (DSL). I think it's similar to a recursive descent parser.
4
+
5
+ TreeSL will try a number of alternative matches for a given node until it finds a matching alternative. This is incredibly inefficient, but the goal is flexibility, not on-the-fly DSL speed.
6
+
7
+ h2. Example
8
+
9
+ <pre><code>
10
+ require 'treesl'
11
+
12
+ parser = TreeSL.define do
13
+ root 'person'
14
+
15
+ person 'title firstname lastname'
16
+ person 'title lastname'
17
+ person 'firstname lastname'
18
+
19
+ title /^Mr|Mrs|Ms$/
20
+ firstname 'propernoun'
21
+ lastname 'propernoun'
22
+ propernoun /^[A-Z][a-z]+/
23
+ end
24
+
25
+ p parser.match("Sam Jones") #=> {"firstname lastname"=>{"lastname"=>"Jones", "firstname"=>"Sam"}}
26
+ p parser.match("Mr Sam Jones") #=> {"title firstname lastname"=>{"title"=>"Mr", "lastname"=>"Jones", "firstname"=>"Sam"}}
27
+ p parser.match("Mr Jones") #=> {"title lastname"=>{"title"=>"Mr", "lastname"=>"Jones"}}
28
+ </code></pre>
29
+
30
+ h2. Copyright
31
+
32
+ Copyright (c) 2009 Jacob Rothstein. See LICENSE for details.
@@ -0,0 +1,57 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "treesl"
8
+ gem.summary = %Q{TreeSL is a DSL parser}
9
+ gem.description = %Q{TreeSL parses flexible DSLs}
10
+ gem.email = "github@jacobrothstein.com"
11
+ gem.homepage = "http://github.com/jbr/treesl"
12
+ gem.authors = ["Jacob Rothstein"]
13
+ # gem.add_development_dependency ""
14
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
+ end
16
+ Jeweler::GemcutterTasks.new
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
19
+ end
20
+
21
+ require 'rake/testtask'
22
+ Rake::TestTask.new(:test) do |test|
23
+ test.libs << 'lib' << 'test'
24
+ test.pattern = 'test/**/*_test.rb'
25
+ test.verbose = true
26
+ end
27
+
28
+ begin
29
+ require 'rcov/rcovtask'
30
+ Rcov::RcovTask.new do |test|
31
+ test.libs << 'test'
32
+ test.pattern = 'test/**/*_test.rb'
33
+ test.verbose = true
34
+ end
35
+ rescue LoadError
36
+ task :rcov do
37
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
38
+ end
39
+ end
40
+
41
+ task :test => :check_dependencies
42
+
43
+ task :default => :test
44
+
45
+ require 'rake/rdoctask'
46
+ Rake::RDocTask.new do |rdoc|
47
+ if File.exist?('VERSION')
48
+ version = File.read('VERSION')
49
+ else
50
+ version = ""
51
+ end
52
+
53
+ rdoc.rdoc_dir = 'rdoc'
54
+ rdoc.title = "treesl #{version}"
55
+ rdoc.rdoc_files.include('README*')
56
+ rdoc.rdoc_files.include('lib/**/*.rb')
57
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,18 @@
1
+ require 'treesl'
2
+
3
+ parser = TreeSL.define do
4
+ root 'person'
5
+
6
+ person 'title firstname lastname'
7
+ person 'title lastname'
8
+ person 'firstname lastname'
9
+
10
+ title /^Mr|Mrs|Ms$/
11
+ firstname 'propernoun'
12
+ lastname 'propernoun'
13
+ propernoun /^[A-Z][a-z]+/
14
+ end
15
+
16
+ p parser.match("Sam Jones") #=> {"firstname lastname"=>{"lastname"=>"Jones", "firstname"=>"Sam"}}
17
+ p parser.match("Mr Sam Jones") #=> {"title firstname lastname"=>{"title"=>"Mr", "lastname"=>"Jones", "firstname"=>"Sam"}}
18
+ p parser.match("Mr Jones") #=> {"title lastname"=>{"title"=>"Mr", "lastname"=>"Jones"}}
@@ -0,0 +1,74 @@
1
+ require 'rubygems'
2
+ require 'active_support'
3
+
4
+ class TreeSL
5
+ attr_accessor :matchers, :root_node, :post_procs, :namespace
6
+ def initialize
7
+ @matchers = {}
8
+ @post_procs = {}
9
+ @namespace = TreeSL
10
+ end
11
+
12
+ def self.define(namespace = nil, options = {}, &blk)
13
+ rdp = TreeSL.new
14
+ rdp.root_node = options[:root] || 'root'
15
+ rdp.namespace = namespace if namespace
16
+ rdp.instance_eval &blk
17
+ rdp
18
+ end
19
+
20
+ def match(string, matcher = nil)
21
+ matcher ||= root_node
22
+ string.strip!
23
+ # p [string,matcher]
24
+ result = if matcher.is_a? Array
25
+ matcher.each do |alternative|
26
+ dup_string = string.dup
27
+ if alternative_match = match(dup_string, alternative)
28
+ string.replace dup_string
29
+ return {alternative => alternative_match}
30
+ end
31
+ end
32
+ nil
33
+ elsif matcher.is_a? String
34
+ if matcher =~ / /
35
+ matches = matcher.split(' ').inject({}) do |hash, atom|
36
+ hash.merge atom => match(string, atom)
37
+ end
38
+ matches.values.any?{|v| v.nil?} ? nil : matches
39
+ elsif new_matcher = matchers[matcher.to_sym]
40
+ match string, new_matcher
41
+ else
42
+ match string, Regexp.new("^#{matcher}")
43
+ end
44
+ elsif matcher.is_a? Regexp
45
+ if string =~ matcher
46
+ string.gsub!(matcher, '');
47
+ $&
48
+ end
49
+ end
50
+
51
+ if result && matcher.is_a?(String) && matcher =~ /^[a-z_]+$/ && namespace.const_defined?(matcher.camelcase.to_sym)
52
+ "#{namespace}::#{matcher.to_s.camelcase}".constantize.new(result) rescue result
53
+ else
54
+ result
55
+ end
56
+ end
57
+
58
+ def rule(key, *values)
59
+ key = key.to_sym
60
+ matchers[key] = if matchers[key].nil?
61
+ if values.length == 1
62
+ values.first
63
+ else
64
+ values
65
+ end
66
+ else
67
+ [matchers[key]].flatten + values
68
+ end
69
+ end
70
+
71
+ def method_missing(method, *args)
72
+ rule method, *args
73
+ end
74
+ end
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'treesl'
8
+
9
+ class Test::Unit::TestCase
10
+ end
@@ -0,0 +1,7 @@
1
+ require 'test_helper'
2
+
3
+ class TreeslTest < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
@@ -0,0 +1,51 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{treesl}
8
+ s.version = "0.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Jacob Rothstein"]
12
+ s.date = %q{2009-10-15}
13
+ s.description = %q{TreeSL parses flexible DSLs}
14
+ s.email = %q{github@jacobrothstein.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.textile"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.textile",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "lib/example.rb",
27
+ "lib/treesl.rb",
28
+ "test/test_helper.rb",
29
+ "test/treesl_test.rb",
30
+ "treesl.gemspec"
31
+ ]
32
+ s.homepage = %q{http://github.com/jbr/treesl}
33
+ s.rdoc_options = ["--charset=UTF-8"]
34
+ s.require_paths = ["lib"]
35
+ s.rubygems_version = %q{1.3.5}
36
+ s.summary = %q{TreeSL is a DSL parser}
37
+ s.test_files = [
38
+ "test/test_helper.rb",
39
+ "test/treesl_test.rb"
40
+ ]
41
+
42
+ if s.respond_to? :specification_version then
43
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
44
+ s.specification_version = 3
45
+
46
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
47
+ else
48
+ end
49
+ else
50
+ end
51
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: treesl
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Jacob Rothstein
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-10-15 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: TreeSL parses flexible DSLs
17
+ email: github@jacobrothstein.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - LICENSE
24
+ - README.textile
25
+ files:
26
+ - .document
27
+ - .gitignore
28
+ - LICENSE
29
+ - README.textile
30
+ - Rakefile
31
+ - VERSION
32
+ - lib/example.rb
33
+ - lib/treesl.rb
34
+ - test/test_helper.rb
35
+ - test/treesl_test.rb
36
+ - treesl.gemspec
37
+ has_rdoc: true
38
+ homepage: http://github.com/jbr/treesl
39
+ licenses: []
40
+
41
+ post_install_message:
42
+ rdoc_options:
43
+ - --charset=UTF-8
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: "0"
51
+ version:
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ version:
58
+ requirements: []
59
+
60
+ rubyforge_project:
61
+ rubygems_version: 1.3.5
62
+ signing_key:
63
+ specification_version: 3
64
+ summary: TreeSL is a DSL parser
65
+ test_files:
66
+ - test/test_helper.rb
67
+ - test/treesl_test.rb