sexpistol 0.0.2 → 0.0.3

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/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.2
1
+ 0.0.3
@@ -3,10 +3,21 @@
3
3
  # native Ruby representation like:
4
4
  # [:def, :something [:lambda, [:a], [:do_something]]]
5
5
  class Sexpistol
6
+
6
7
  attr_accessor :ruby_keyword_literals
7
8
 
8
9
  def initialize
9
10
  @ruby_keyword_literals = false
11
+
12
+ # Setup all of our token patterns as instance variables
13
+ # so they don't have to be re-instantiated for each
14
+ # run & match
15
+ @string_literal_pattern = /"([^"\\]|\\.)*"/
16
+ @integer_literal_pattern = /[\-\+]?[0-9]+/
17
+ @float_literal_pattern = /[\-\+]?[0-9]+\.[0-9]+(e[0-9]+)?/
18
+ @symbol_pattern = /[^\"\'\,\(\)]+/
19
+
20
+ @string_replacement_token = "__++STRING_LITERAL++__"
10
21
  end
11
22
 
12
23
  # Parse a string containing an S-Expression into a
@@ -14,16 +25,7 @@ class Sexpistol
14
25
  def parse_string( string )
15
26
  string_array = split_outside_strings(string)
16
27
  tokens = process_tokens( string_array )
17
- check_tokens( tokens )
18
- structure( tokens )
19
- end
20
-
21
- # Check and array of tokens to make sure that the number
22
- # of open and closing parentheses match
23
- def check_tokens( tokens )
24
- unless( (tokens.reject {|x| x == "("}).length == (tokens.reject {|x| x == ")"}).length)
25
- raise Exception, "Invalid S-Expression. The number of opening and closing parentheses does not match."
26
- end
28
+ structure( tokens )[1]
27
29
  end
28
30
 
29
31
  # Iterate over an array of strings and turn each
@@ -32,11 +34,11 @@ class Sexpistol
32
34
  tokens = []
33
35
  token_array.each do |t|
34
36
  if(@ruby_keyword_literals)
35
- tokens << nil and next if(is_nil?(t))
36
- tokens << true and next if(is_true?(t))
37
- tokens << false and next if(is_false?(t))
37
+ tokens << nil and next if(t == "nil")
38
+ tokens << true and next if(t == "true")
39
+ tokens << false and next if(t == "false")
38
40
  end
39
- tokens << t and next if(is_paren?(t))
41
+ tokens << t and next if(t == "(" || t == ")")
40
42
  tokens << t.to_f and next if( is_float?(t))
41
43
  tokens << t.to_i and next if( is_integer?(t))
42
44
  tokens << t.to_sym and next if( is_symbol?(t))
@@ -61,30 +63,27 @@ class Sexpistol
61
63
  end
62
64
  offset += 1
63
65
  end
64
- if(internal)
65
- return [offset, program]
66
- else
67
- return program
68
- end
66
+ return [offset, program]
69
67
  end
70
68
 
71
69
  # Split up a string into an array where delimited by whitespace,
72
70
  # except inside string literals
73
71
  def split_outside_strings( string )
74
- string_literal_pattern = /"([^"\\]|\\.)*"/
75
- string_token = "__++STRING_LITERAL++__"
76
72
  # Find and extract all the string literals
77
73
  string_literals = []
78
- string.gsub(string_literal_pattern) {|x| string_literals << x}
79
- # Replace all the string literals with a special token
80
- string = string.gsub(string_literal_pattern, string_token)
74
+ string = string.gsub(@string_literal_pattern) do |x|
75
+ string_literals << x
76
+ @string_replacement_token
77
+ end
78
+ # Make sure the s-expression is valid
79
+ unless( string.count("(") == string.count(")") )
80
+ raise Exception, "Invalid S-Expression. The number of opening and closing parentheses does not match."
81
+ end
81
82
  # Split the string up on whitespace and parentheses
82
- string.gsub!("(", " ( ")
83
- string.gsub!(")", " ) ")
84
- array = string.split(" ")
83
+ array = string.gsub("(", " ( ").gsub(")", " ) ").split(" ")
85
84
  # replace the special string token with the original string literals
86
85
  array.collect! do |x|
87
- if( x == string_token)
86
+ if( x == @string_replacement_token)
88
87
  string_literals.shift
89
88
  else
90
89
  x
@@ -93,44 +92,24 @@ class Sexpistol
93
92
  return array
94
93
  end
95
94
 
96
- # Test to see whether or not a string represents the 'nil' literal
97
- def is_nil?( string )
98
- true if(string == "nil")
99
- end
100
-
101
- # Test to see whether or not a string represents the 'true' literal
102
- def is_true?( string )
103
- true if(string == "true")
104
- end
105
-
106
- # Test to see whether or not a string represents the 'false' literal
107
- def is_false?( string )
108
- true if(string == "false")
109
- end
110
-
111
- # Test to see whether a string represents a parentheses
112
- def is_paren?( string )
113
- is_match?( string, /[\(\)]+/ )
114
- end
115
-
116
95
  # Test to see whether or not a string represents an integer
117
96
  def is_integer?( string )
118
- is_match?( string, /[\-\+]?[0-9]+/ )
97
+ is_match?( string, @integer_literal_pattern )
119
98
  end
120
99
 
121
100
  # Test to see whether or not a string represents a float
122
101
  def is_float?( string )
123
- is_match?( string, /[\-\+]?[0-9]+\.[0-9]+(e[0-9]+)?/ )
102
+ is_match?( string, @float_literal_pattern )
124
103
  end
125
104
 
126
105
  # Test to see whether or not a string represents a symbol
127
106
  def is_symbol?( string )
128
- is_match?( string, /[^\"\'\,\(\)]+/ )
107
+ is_match?( string, @symbol_pattern )
129
108
  end
130
109
 
131
110
  # Test to see whether or not a string represents a string literal
132
111
  def is_string_literal?( string )
133
- is_match?( string, /"([^"\\]|\\.)*"/)
112
+ is_match?( string, @string_literal_pattern )
134
113
  end
135
114
 
136
115
  # Convert a set of nested arrays back into an S-Expression
data/sexpistol.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{sexpistol}
8
- s.version = "0.0.2"
8
+ s.version = "0.0.3"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Aaron Gough"]
12
- s.date = %q{2010-10-03}
12
+ s.date = %q{2010-10-06}
13
13
  s.description = %q{Sexpistol is an easy-to-use S-Expression parser for Ruby. It is fast and has no dependencies.}
14
14
  s.email = %q{aaron@aarongough.com}
15
15
  s.extra_rdoc_files = [
@@ -25,6 +25,7 @@ Gem::Specification.new do |s|
25
25
  "lib/sexpistol.rb",
26
26
  "lib/sexpistol/sexpistol.rb",
27
27
  "sexpistol.gemspec",
28
+ "test/performance/benchmark_test.rb",
28
29
  "test/setup/test_unit_extensions.rb",
29
30
  "test/test_helper.rb",
30
31
  "test/unit/float_literal_test.rb",
@@ -41,7 +42,8 @@ Gem::Specification.new do |s|
41
42
  s.rubygems_version = %q{1.3.7}
42
43
  s.summary = %q{An S-Expression Parser Library for Ruby}
43
44
  s.test_files = [
44
- "test/setup/test_unit_extensions.rb",
45
+ "test/performance/benchmark_test.rb",
46
+ "test/setup/test_unit_extensions.rb",
45
47
  "test/test_helper.rb",
46
48
  "test/unit/float_literal_test.rb",
47
49
  "test/unit/integer_literal_test.rb",
@@ -0,0 +1,34 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'test_helper.rb'))
2
+
3
+ class BenchmarkTest < Test::Unit::TestCase
4
+
5
+ require 'benchmark'
6
+
7
+ test "benchmark sexpistol" do
8
+ puts "\nRunning performance test...\n"
9
+ parser = Sexpistol.new
10
+ parser.ruby_keyword_literals = true
11
+ Benchmark.bmbm do |b|
12
+ b.report do
13
+ 5000.times do
14
+ parser.parse_string <<-EOD
15
+
16
+ (display "This is a test string!")
17
+
18
+ (define test (lambda () (begin
19
+ (display (== 1 1))
20
+ (display (== true true))
21
+ (display (== false false))
22
+ (display (== nil nil))
23
+ (display (== 2.09 1.08))
24
+ (display (== 2e6 2e12))
25
+ )))
26
+
27
+ EOD
28
+ end
29
+ end
30
+ end
31
+ puts
32
+ end
33
+
34
+ end
@@ -5,10 +5,10 @@ class RubyKeywordLiteralsTest < Test::Unit::TestCase
5
5
  def setup
6
6
  @parser = Sexpistol.new
7
7
  end
8
-
8
+
9
9
  test "should create nested set of arrays from s-expression" do
10
- ast = @parser.parse_string('(this (is (an (s_expression))))')
11
- assert_equal [[:this, [:is, [:an, [:s_expression]]]]], ast
10
+ ast = @parser.parse_string('(this (is (an (s_expression) (also) blah) foo) (test))')
11
+ assert_equal [[:this, [:is, [:an, [:s_expression], [:also], :blah], :foo], [:test]]], ast
12
12
  end
13
13
 
14
14
  test "should create nested set of arrays from s-expression with string literals" do
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 2
9
- version: 0.0.2
8
+ - 3
9
+ version: 0.0.3
10
10
  platform: ruby
11
11
  authors:
12
12
  - Aaron Gough
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-10-03 00:00:00 -04:00
17
+ date: 2010-10-06 00:00:00 -04:00
18
18
  default_executable:
19
19
  dependencies: []
20
20
 
@@ -36,6 +36,7 @@ files:
36
36
  - lib/sexpistol.rb
37
37
  - lib/sexpistol/sexpistol.rb
38
38
  - sexpistol.gemspec
39
+ - test/performance/benchmark_test.rb
39
40
  - test/setup/test_unit_extensions.rb
40
41
  - test/test_helper.rb
41
42
  - test/unit/float_literal_test.rb
@@ -80,6 +81,7 @@ signing_key:
80
81
  specification_version: 3
81
82
  summary: An S-Expression Parser Library for Ruby
82
83
  test_files:
84
+ - test/performance/benchmark_test.rb
83
85
  - test/setup/test_unit_extensions.rb
84
86
  - test/test_helper.rb
85
87
  - test/unit/float_literal_test.rb