sexpistol 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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