ruby_token_parser 0.0.6
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.
- checksums.yaml +7 -0
- data/LICENSE.txt +27 -0
- data/README.md +107 -0
- data/lib/ruby_token_parser.rb +1 -0
- data/lib/ruby_token_parser/parse.rb +74 -0
- data/lib/ruby_token_parser/requires.rb +5 -0
- data/lib/ruby_token_parser/ruby_token_constants.rb +188 -0
- data/lib/ruby_token_parser/ruby_token_parser.rb +438 -0
- data/ruby_token_parser.gemspec +49 -0
- data/test/testing_ruby_token_parser.rb +73 -0
- metadata +61 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 2c60c4b936d34a0388136c3585afa1726b580b256b7bb277f1323706a5bbe4e0
|
4
|
+
data.tar.gz: 1de41610a7b060f7ded20bd3e1d953fb6e86b21de47e01747364a7a2ce8e9364
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 72ce6264df8b2154cfbe423a03d30b2972b57f05f096ec438c45a0de41057bf58a6efc0f23a4db74f09d6cd7013376104c5b4fb59c99ab759751f88277abda7e
|
7
|
+
data.tar.gz: 763aed054956357e20b6b983fff7e8e00ce22d466e41e421da63d7b2e1dea80d8925dc8363ed028da9d3ea6fe9097de0efce9c8190b8a7ee6a696d182965efb0
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
Original Copyright (c) 2012-2014, Stefan Rusterholz <stefan.rusterholz@gmail.com>
|
2
|
+
|
3
|
+
Derived work Copyright (c) 2015, "shevy" Robert A. Heiler <shevegen@gmail.com>
|
4
|
+
|
5
|
+
All rights reserved.
|
6
|
+
|
7
|
+
Redistribution and use in source and binary forms, with or without modification,
|
8
|
+
are permitted provided that the following conditions are met:
|
9
|
+
|
10
|
+
Redistributions of source code must retain the above copyright notice,
|
11
|
+
this list of conditions and the following disclaimer.
|
12
|
+
|
13
|
+
Redistributions in binary form must reproduce the above copyright notice,
|
14
|
+
this list of conditions and the following disclaimer in the documentation
|
15
|
+
and/or other materials provided with the distribution.
|
16
|
+
|
17
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
18
|
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
19
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
20
|
+
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
21
|
+
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
22
|
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
23
|
+
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
24
|
+
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
25
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
26
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
27
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
README
|
2
|
+
======
|
3
|
+
|
4
|
+
|
5
|
+
Summary
|
6
|
+
-------
|
7
|
+
|
8
|
+
This project, called ruby_token_parser, will parse strings containing
|
9
|
+
ruby literals and return a proper ruby object.
|
10
|
+
|
11
|
+
This can be used to deconstruct a String into its constituent members
|
12
|
+
as valid ruby objects, similar as to what IRB is doing when you let
|
13
|
+
it evaluate the user input you supply it with.
|
14
|
+
|
15
|
+
|
16
|
+
Features
|
17
|
+
--------
|
18
|
+
|
19
|
+
* Recognizes about all Ruby literals:
|
20
|
+
|
21
|
+
nil, true, false, Symbols, Integers, Floats, Hashes, Arrays and
|
22
|
+
also Ranges.
|
23
|
+
|
24
|
+
* Additionally parses Constants, Dates and Times.
|
25
|
+
|
26
|
+
* Simple to use through [] or .parse such as:
|
27
|
+
|
28
|
+
RubyTokenParser[]
|
29
|
+
|
30
|
+
Installation
|
31
|
+
------------
|
32
|
+
|
33
|
+
`gem install ruby_token_parser`
|
34
|
+
|
35
|
+
|
36
|
+
Usage
|
37
|
+
-----
|
38
|
+
|
39
|
+
Several examples follow next:
|
40
|
+
|
41
|
+
RubyTokenParser.parse("nil") # => nil
|
42
|
+
RubyTokenParser.parse(":foo") # => :foo
|
43
|
+
RubyTokenParser.parse("123") # => 123
|
44
|
+
RubyTokenParser.parse("1.5") # => 1.5
|
45
|
+
RubyTokenParser.parse("1.5", use_big_decimal: true) # => #<BigDecimal:…,'0.15E1',18(18)>
|
46
|
+
RubyTokenParser.parse("[1, 2, 3]") # => [1, 2, 3]
|
47
|
+
RubyTokenParser.parse("{:a => 1, :b => 2}") # => {:a => 1, :b => 2}
|
48
|
+
RubyTokenParser.parse("(1..15)")
|
49
|
+
RubyTokenParser["(1..15)"]
|
50
|
+
|
51
|
+
|
52
|
+
License
|
53
|
+
-------
|
54
|
+
|
55
|
+
You can use this code under the {file:LICENSE.txt BSD-2-Clause License},
|
56
|
+
free of charge.
|
57
|
+
|
58
|
+
A link to the content of this license is provided here:
|
59
|
+
|
60
|
+
https://opensource.org/licenses/BSD-2-Clause
|
61
|
+
|
62
|
+
Note that the original version of this gem, called "literal_parser",
|
63
|
+
was written by apeiros (Stefan Rusterholz) - you may be able to find
|
64
|
+
his work here at:
|
65
|
+
|
66
|
+
https://github.com/apeiros
|
67
|
+
https://github.com/apeiros/literal_parser
|
68
|
+
|
69
|
+
If you need a different license in regards to the original literal_parser,
|
70
|
+
please ask apeiros, not me, since it was his original code and work.
|
71
|
+
|
72
|
+
My (shevy) modifications were small, mostly just cosmetic, some renaming,
|
73
|
+
the addition of Range-objects (since I needed that in one other project
|
74
|
+
specifically), a bit more documentation, a general restructure of the
|
75
|
+
code to make it easier for me to read and the addition of [] as a class
|
76
|
+
method.
|
77
|
+
|
78
|
+
The BSD-2 license mandates that one has to retain the original copyright.
|
79
|
+
|
80
|
+
I assume that the original copyright is the following one here:
|
81
|
+
|
82
|
+
Copyright (c) 2012-2014, apeiros (Stefan Rusterholz)
|
83
|
+
|
84
|
+
The link to that license can be found at:
|
85
|
+
|
86
|
+
https://github.com/apeiros/literal_parser/blob/master/LICENSE.txt
|
87
|
+
|
88
|
+
Or respectively as part of apeiros' literal_parser project.
|
89
|
+
|
90
|
+
This LICENSE.txt is also part of the gem here and was included in
|
91
|
+
the literal_parser project.
|
92
|
+
|
93
|
+
I will add the disclaimer as part of the license link to the readme
|
94
|
+
here, as the original link at opensource.org also states something
|
95
|
+
somewhat similar:
|
96
|
+
|
97
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
98
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
99
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
100
|
+
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
101
|
+
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
102
|
+
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
103
|
+
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
104
|
+
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
105
|
+
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
106
|
+
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
107
|
+
THE POSSIBILITY OF SUCH DAMAGE.
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'ruby_token_parser/ruby_token_parser.rb'
|
@@ -0,0 +1,74 @@
|
|
1
|
+
class RubyTokenParser
|
2
|
+
|
3
|
+
# ========================================================================= #
|
4
|
+
# === RubyTokenParser.parse
|
5
|
+
#
|
6
|
+
# The RubyTokenParser.parse() method will parse a String, and return
|
7
|
+
# the (ruby) object which it contains.
|
8
|
+
#
|
9
|
+
# @usage example:
|
10
|
+
#
|
11
|
+
# RubyTokenParser.parse(":foo") # => :foo
|
12
|
+
#
|
13
|
+
# @param [String] string
|
14
|
+
#
|
15
|
+
# The (input) String which should be parsed.
|
16
|
+
#
|
17
|
+
# @param [nil, Hash] options
|
18
|
+
#
|
19
|
+
# An options-hash
|
20
|
+
#
|
21
|
+
# @param [Boolean] do_raise_an_exception
|
22
|
+
#
|
23
|
+
# This boolean will determine whether we will raise an exception
|
24
|
+
# or whether we will not.
|
25
|
+
#
|
26
|
+
# @option options [Boolean] :use_big_decimal
|
27
|
+
#
|
28
|
+
# Whether to use BigDecimal instead of Float for objects like "1.23".
|
29
|
+
# Defaults to false.
|
30
|
+
#
|
31
|
+
# @option options [Boolean] :constant_base
|
32
|
+
#
|
33
|
+
# Determines from what constant other constants are searched.
|
34
|
+
# Defaults to Object (nil is treated as Object too, Object
|
35
|
+
# is the toplevel-namespace).
|
36
|
+
#
|
37
|
+
# @return [Object] The object in the string.
|
38
|
+
#
|
39
|
+
# @raise [RubyTokenParser::SyntaxError]
|
40
|
+
#
|
41
|
+
# If the String does not contain exactly one valid literal,
|
42
|
+
# a SyntaxError is raised.
|
43
|
+
#
|
44
|
+
# Usage example:
|
45
|
+
# x = RubyTokenParser.parse("[1,2,3]")
|
46
|
+
# ========================================================================= #
|
47
|
+
def self.parse(
|
48
|
+
string,
|
49
|
+
options = nil,
|
50
|
+
do_raise_an_exception = RubyTokenParser.raise_exception?
|
51
|
+
)
|
52
|
+
# ======================================================================= #
|
53
|
+
# === Instantiate a new parser
|
54
|
+
# ======================================================================= #
|
55
|
+
parser = new(string, options)
|
56
|
+
begin
|
57
|
+
value = parser.scan_value
|
58
|
+
rescue RubyTokenParser::SyntaxError # Must rescue things such as: @foo = foo
|
59
|
+
value = RubyTokenParser::SyntaxError
|
60
|
+
end
|
61
|
+
if do_raise_an_exception
|
62
|
+
unless parser.end_of_string? or
|
63
|
+
value.nil?
|
64
|
+
# =================================================================== #
|
65
|
+
# Raise the Syntax Error.
|
66
|
+
# =================================================================== #
|
67
|
+
raise SyntaxError,
|
68
|
+
"Unexpected superfluous data: #{parser.rest.inspect}"
|
69
|
+
end unless value.is_a? Range # Make an exception for Range objects.
|
70
|
+
end
|
71
|
+
value
|
72
|
+
end; self.instance_eval { alias [] parse } # === RubyTokenParser[]
|
73
|
+
# ^^^ Add an alias to it, aka [].
|
74
|
+
end
|
@@ -0,0 +1,188 @@
|
|
1
|
+
class RubyTokenParser
|
2
|
+
|
3
|
+
# ========================================================================= #
|
4
|
+
# === RubyTokenParser::Expressions
|
5
|
+
#
|
6
|
+
# @private
|
7
|
+
#
|
8
|
+
# All the expressions used to parse the literals will be bundled here.
|
9
|
+
# ========================================================================= #
|
10
|
+
module Expressions # === RubyTokenParser::Expressions
|
11
|
+
|
12
|
+
# ======================================================================= #
|
13
|
+
# === Match to the start of an Array
|
14
|
+
# ======================================================================= #
|
15
|
+
RArrayBegin = /\[/
|
16
|
+
|
17
|
+
# ======================================================================= #
|
18
|
+
# === Match whitespace between elements in an Array
|
19
|
+
# ======================================================================= #
|
20
|
+
RArrayVoid = /\s*/
|
21
|
+
|
22
|
+
# ======================================================================= #
|
23
|
+
# === Match the separator of Array elements
|
24
|
+
#
|
25
|
+
# This depends on RArrayVoid having been defined before.
|
26
|
+
#
|
27
|
+
# A separator in an Array is something such as:
|
28
|
+
# [1,2,3]
|
29
|
+
# ======================================================================= #
|
30
|
+
RArraySeparator = /#{RArrayVoid},#{RArrayVoid}/
|
31
|
+
|
32
|
+
# ======================================================================= #
|
33
|
+
# === Match to the end of an Array
|
34
|
+
# ======================================================================= #
|
35
|
+
RArrayEnd = /\]/
|
36
|
+
|
37
|
+
# ======================================================================= #
|
38
|
+
# === Match to the start of a Hash
|
39
|
+
# ======================================================================= #
|
40
|
+
RHashBegin = /\{/
|
41
|
+
|
42
|
+
# ======================================================================= #
|
43
|
+
# === Match whitespace between elements in a Hash
|
44
|
+
# ======================================================================= #
|
45
|
+
RHashVoid = /\s*/
|
46
|
+
|
47
|
+
# ======================================================================= #
|
48
|
+
# === Match the separator of hash key/value pairs
|
49
|
+
# ======================================================================= #
|
50
|
+
RHashSeparator = /#{RHashVoid},#{RHashVoid}/
|
51
|
+
|
52
|
+
# ======================================================================= #
|
53
|
+
# === Match the separator between a key and a value in a hash
|
54
|
+
# ======================================================================= #
|
55
|
+
RHashArrow = /#{RHashVoid}=>#{RHashVoid}/
|
56
|
+
|
57
|
+
# ======================================================================= #
|
58
|
+
# === Match end of a Hash
|
59
|
+
# ======================================================================= #
|
60
|
+
RHashEnd = /\}/
|
61
|
+
|
62
|
+
# ======================================================================= #
|
63
|
+
# === Match constant names (with nesting)
|
64
|
+
# ======================================================================= #
|
65
|
+
RConstant = /[A-Z]\w*(?:::[A-Z]\w*)*/
|
66
|
+
|
67
|
+
# ======================================================================= #
|
68
|
+
# === Match to nil
|
69
|
+
# ======================================================================= #
|
70
|
+
RNil = /nil/
|
71
|
+
|
72
|
+
# ======================================================================= #
|
73
|
+
# === Match false
|
74
|
+
# ======================================================================= #
|
75
|
+
RFalse = /false/
|
76
|
+
|
77
|
+
# ======================================================================= #
|
78
|
+
# === Match true
|
79
|
+
# ======================================================================= #
|
80
|
+
RTrue = /true/
|
81
|
+
|
82
|
+
# ======================================================================= #
|
83
|
+
# === Match an Integer in decimal notation
|
84
|
+
# ======================================================================= #
|
85
|
+
RInteger = /[+-]?\d[\d_]*/
|
86
|
+
|
87
|
+
# ======================================================================= #
|
88
|
+
# === Match an Integer in binary notation
|
89
|
+
# ======================================================================= #
|
90
|
+
RBinaryInteger = /[+-]?0b[01][01_]*/
|
91
|
+
|
92
|
+
# ======================================================================= #
|
93
|
+
# === Match an Integer in hexadecimal notation
|
94
|
+
# ======================================================================= #
|
95
|
+
RHexInteger = /[+-]?0x[A-Fa-f\d][A-Fa-f\d_]*/
|
96
|
+
|
97
|
+
# ======================================================================= #
|
98
|
+
# === Match a decimal number (Float or BigDecimal)
|
99
|
+
# ======================================================================= #
|
100
|
+
RBigDecimal = /#{RInteger}\.\d+/
|
101
|
+
|
102
|
+
# ======================================================================= #
|
103
|
+
# === Match a decimal number in scientific notation
|
104
|
+
# ======================================================================= #
|
105
|
+
RFloat = /#{RBigDecimal}(?:f|e#{RInteger})/
|
106
|
+
|
107
|
+
# ======================================================================= #
|
108
|
+
# === Match a date
|
109
|
+
# ======================================================================= #
|
110
|
+
RDate = /(\d{4})-(\d{2})-(\d{2})/
|
111
|
+
|
112
|
+
# ======================================================================= #
|
113
|
+
# === Match a time (without date)
|
114
|
+
# ======================================================================= #
|
115
|
+
RTime = /(\d{2}):(\d{2}):(\d{2})(?:RTimeZone)?/
|
116
|
+
|
117
|
+
# ======================================================================= #
|
118
|
+
# === Match a datetime (must come after RTime was defined)
|
119
|
+
# ======================================================================= #
|
120
|
+
RDateTime = /#{RDate}T#{RTime}/
|
121
|
+
|
122
|
+
# ======================================================================= #
|
123
|
+
# === Match a regular expression
|
124
|
+
# ======================================================================= #
|
125
|
+
RRegexp = %r{/((?:[^\\/]+|\\.)*)/([imxnNeEsSuU]*)}
|
126
|
+
|
127
|
+
# ======================================================================= #
|
128
|
+
# === Match a double quoted string.
|
129
|
+
# ======================================================================= #
|
130
|
+
RDString = /"(?:[^\\"]+|\\.)*"/
|
131
|
+
|
132
|
+
# ======================================================================= #
|
133
|
+
# === Match a single quoted string.
|
134
|
+
# ======================================================================= #
|
135
|
+
RSString = /'(?:[^\\']+|\\.)*'/
|
136
|
+
|
137
|
+
# ======================================================================= #
|
138
|
+
# === Match a symbol (symbol tag)
|
139
|
+
#
|
140
|
+
# Note that this depends on RSString and RDString, so these
|
141
|
+
# must come before that.
|
142
|
+
# ======================================================================= #
|
143
|
+
RSymbol = /:[A-Za-z_]\w*|:#{RSString}|:#{RDString}/
|
144
|
+
|
145
|
+
# ======================================================================= #
|
146
|
+
# === Match a symbol used as key in a Hash
|
147
|
+
# ======================================================================= #
|
148
|
+
RHashKeySymbol = /([A-Za-z_]\w*):/
|
149
|
+
|
150
|
+
# ======================================================================= #
|
151
|
+
# === Match a timezone
|
152
|
+
# ======================================================================= #
|
153
|
+
RTimeZone = /(Z|[A-Z]{3,4}|[+-]\d{4})/
|
154
|
+
|
155
|
+
# ======================================================================= #
|
156
|
+
# === Match a Regex such as (1..5)
|
157
|
+
# ======================================================================= #
|
158
|
+
RRange = /\(\d*..\d*\)/
|
159
|
+
|
160
|
+
# ======================================================================= #
|
161
|
+
# === Match an Integer in octal notation
|
162
|
+
# ======================================================================= #
|
163
|
+
ROctalInteger = /[+-]?0[0-7][0-7'_,]*/
|
164
|
+
|
165
|
+
# ======================================================================= #
|
166
|
+
# === DoubleQuotedStringEscapes
|
167
|
+
#
|
168
|
+
# Map escape sequences in double quoted strings.
|
169
|
+
#
|
170
|
+
# This will be a really huge Hash.
|
171
|
+
# ======================================================================= #
|
172
|
+
DoubleQuotedStringEscapes = {
|
173
|
+
'\\\\' => "\\",
|
174
|
+
"\\'" => "'",
|
175
|
+
'\\"' => '"',
|
176
|
+
'\t' => "\t",
|
177
|
+
'\f' => "\f",
|
178
|
+
'\r' => "\r",
|
179
|
+
'\n' => "\n",
|
180
|
+
}
|
181
|
+
256.times { |i|
|
182
|
+
DoubleQuotedStringEscapes["\\%o" % i] = i.chr
|
183
|
+
DoubleQuotedStringEscapes["\\%03o" % i] = i.chr
|
184
|
+
DoubleQuotedStringEscapes["\\x%02x" % i] = i.chr
|
185
|
+
DoubleQuotedStringEscapes["\\x%02X" % i] = i.chr
|
186
|
+
}
|
187
|
+
|
188
|
+
end; end
|
@@ -0,0 +1,438 @@
|
|
1
|
+
#!/System/Index/bin/ruby -w
|
2
|
+
# Encoding: ISO-8859-1
|
3
|
+
# =========================================================================== #
|
4
|
+
# === RubyTokenParser
|
5
|
+
#
|
6
|
+
# require 'ruby_token_parser'; x = RubyTokenParser.parse("(1..3)")
|
7
|
+
# require 'ruby_token_parser'; x = RubyTokenParser.parse("[1,2,3]")
|
8
|
+
# require 'ruby_token_parser'; RubyTokenParser["(1..3)"]
|
9
|
+
# =========================================================================== #
|
10
|
+
require 'ruby_token_parser/requires.rb'
|
11
|
+
|
12
|
+
# =========================================================================== #
|
13
|
+
# === RubyTokenParser
|
14
|
+
#
|
15
|
+
# Parse Strings containing ruby literals.
|
16
|
+
#
|
17
|
+
# @examples
|
18
|
+
#
|
19
|
+
# RubyTokenParser.parse("nil") # => nil
|
20
|
+
# RubyTokenParser.parse(":foo") # => :foo
|
21
|
+
# RubyTokenParser.parse("123") # => 123
|
22
|
+
# RubyTokenParser.parse("1.5") # => 1.5
|
23
|
+
# RubyTokenParser.parse("1.5", use_big_decimal: true) # => #<BigDecimal:…,'0.15E1',18(18)>
|
24
|
+
# RubyTokenParser.parse("[1, 2, 3]") # => [1, 2, 3]
|
25
|
+
# RubyTokenParser.parse("{:a => 1, :b => 2}") # => {:a => 1, :b => 2}
|
26
|
+
# RubyTokenParser.parse("(1..3)")
|
27
|
+
#
|
28
|
+
# RubyTokenParser recognizes constants and the following literals:
|
29
|
+
#
|
30
|
+
# nil # nil
|
31
|
+
# true # true
|
32
|
+
# false # false
|
33
|
+
# -123 # Fixnum/Bignum (decimal)
|
34
|
+
# 0b1011 # Fixnum/Bignum (binary)
|
35
|
+
# 0755 # Fixnum/Bignum (octal)
|
36
|
+
# 0xff # Fixnum/Bignum (hexadecimal)
|
37
|
+
# 120.30 # Float (optional: BigDecimal)
|
38
|
+
# 1e0 # Float
|
39
|
+
# "foo" # String, no interpolation, but \t etc. work
|
40
|
+
# 'foo' # String, only \\ and \' are escaped
|
41
|
+
# /foo/ # Regexp
|
42
|
+
# :foo # Symbol
|
43
|
+
# :"foo" # Symbol
|
44
|
+
# 2012-05-20 # Date
|
45
|
+
# 2012-05-20T18:29:52 # DateTime
|
46
|
+
# [Any, Literals, Here] # Array
|
47
|
+
# {Any => Literals} # Hash
|
48
|
+
# (1..20) # Range
|
49
|
+
#
|
50
|
+
# @note Limitations
|
51
|
+
#
|
52
|
+
# * RubyTokenParser does not support ruby 1.9's `{key: value}` syntax.
|
53
|
+
# * RubyTokenParser does not currently support all of rubys escape
|
54
|
+
# sequences in strings and symbols.
|
55
|
+
# * Trailing commas in Array and Hash are not supported.
|
56
|
+
#
|
57
|
+
# @note BigDecimals
|
58
|
+
#
|
59
|
+
# You can instruct RubyTokenParser to parse "12.5" as a bigdecimal
|
60
|
+
# and use "12.5e" to have it parsed as float (short for "12.5e0",
|
61
|
+
# equivalent to "1.25e1")
|
62
|
+
#
|
63
|
+
# @note Date & Time
|
64
|
+
#
|
65
|
+
# RubyTokenParser supports a subset of ISO-8601 for Date and Time which
|
66
|
+
# are not actual valid ruby literals. The form YYYY-MM-DD (e.g. 2012-05-20)
|
67
|
+
# is translated to a Date object, and YYYY-MM-DD"T"HH:MM:SS (e.g.
|
68
|
+
# 2012-05-20T18:29:52) is translated to a Time object.
|
69
|
+
# =========================================================================== #
|
70
|
+
class RubyTokenParser
|
71
|
+
|
72
|
+
include RubyTokenParser::Expressions
|
73
|
+
|
74
|
+
# ========================================================================= #
|
75
|
+
# === @do_raise_exception
|
76
|
+
# ========================================================================= #
|
77
|
+
@do_raise_exception = true
|
78
|
+
|
79
|
+
# ========================================================================= #
|
80
|
+
# === RubyTokenParser.set_do_raise_exception
|
81
|
+
# ========================================================================= #
|
82
|
+
def self.set_do_raise_exception(i = true)
|
83
|
+
@do_raise_exception = i
|
84
|
+
end
|
85
|
+
|
86
|
+
# ========================================================================= #
|
87
|
+
# === RubyTokenParser.raise_exception?
|
88
|
+
# ========================================================================= #
|
89
|
+
def self.raise_exception?
|
90
|
+
@do_raise_exception
|
91
|
+
end
|
92
|
+
|
93
|
+
# ========================================================================= #
|
94
|
+
# === RubyTokenParser::SyntaxError
|
95
|
+
#
|
96
|
+
# This error is raised when a String could not be parsed.
|
97
|
+
# ========================================================================= #
|
98
|
+
class SyntaxError < StandardError; end
|
99
|
+
|
100
|
+
# ========================================================================= #
|
101
|
+
# === initialize
|
102
|
+
#
|
103
|
+
# Parse a String, returning the object which it contains.
|
104
|
+
#
|
105
|
+
# @param [String] string
|
106
|
+
# The string which should be parsed
|
107
|
+
#
|
108
|
+
# @param [nil, Hash] options
|
109
|
+
# An options-hash
|
110
|
+
#
|
111
|
+
# @option options [Boolean] :use_big_decimal
|
112
|
+
# Whether to use BigDecimal instead of Float for objects like "1.23".
|
113
|
+
# Defaults to false.
|
114
|
+
#
|
115
|
+
# @option options [Boolean] :constant_base
|
116
|
+
#
|
117
|
+
# Determines from what constant other constants are searched.
|
118
|
+
#
|
119
|
+
# Defaults to Object (nil is treated as Object too, Object
|
120
|
+
# is the toplevel-namespace).
|
121
|
+
# ========================================================================= #
|
122
|
+
def initialize(string, options = nil)
|
123
|
+
@string = string
|
124
|
+
options = options ? options.dup : {}
|
125
|
+
@constant_base = options[:constant_base] # nil means toplevel
|
126
|
+
@use_big_decimal = options.delete(:use_big_decimal) { false }
|
127
|
+
@scanner = StringScanner.new(string)
|
128
|
+
end
|
129
|
+
|
130
|
+
# ========================================================================= #
|
131
|
+
# === position?
|
132
|
+
#
|
133
|
+
# @return [Integer]
|
134
|
+
#
|
135
|
+
# The position of the scanner in the string.
|
136
|
+
# ========================================================================= #
|
137
|
+
def position?
|
138
|
+
@scanner.pos
|
139
|
+
end; alias position position? # === position
|
140
|
+
|
141
|
+
# ========================================================================= #
|
142
|
+
# === position=
|
143
|
+
#
|
144
|
+
# Moves the scanners position to the given character-index.
|
145
|
+
#
|
146
|
+
# @param [Integer] value
|
147
|
+
#
|
148
|
+
# The new position of the scanner
|
149
|
+
# ========================================================================= #
|
150
|
+
def position=(i)
|
151
|
+
@scanner.pos = i
|
152
|
+
end
|
153
|
+
|
154
|
+
# ========================================================================= #
|
155
|
+
# === end_of_string?
|
156
|
+
#
|
157
|
+
# @return [Boolean]
|
158
|
+
#
|
159
|
+
# Whether the scanner reached the end of the string.
|
160
|
+
# ========================================================================= #
|
161
|
+
def end_of_string?
|
162
|
+
@scanner.eos?
|
163
|
+
end
|
164
|
+
|
165
|
+
# ========================================================================= #
|
166
|
+
# === rest
|
167
|
+
#
|
168
|
+
# @return [String] The currently unprocessed rest of the string.
|
169
|
+
# ========================================================================= #
|
170
|
+
def rest
|
171
|
+
@scanner.rest
|
172
|
+
end
|
173
|
+
|
174
|
+
# ========================================================================= #
|
175
|
+
# === content?
|
176
|
+
#
|
177
|
+
# Reader method over the current value of the scanner.
|
178
|
+
# ========================================================================= #
|
179
|
+
def content?
|
180
|
+
@scanner.string
|
181
|
+
end
|
182
|
+
|
183
|
+
# ========================================================================= #
|
184
|
+
# === use_big_decimal?
|
185
|
+
#
|
186
|
+
# @return [Boolean]
|
187
|
+
#
|
188
|
+
# True if "1.25" should be parsed into a big-decimal,
|
189
|
+
# false if it should be parsed as Float.
|
190
|
+
# ========================================================================= #
|
191
|
+
def use_big_decimal?
|
192
|
+
@use_big_decimal
|
193
|
+
end; alias use_big_decimal use_big_decimal? # === use_big_decimal
|
194
|
+
|
195
|
+
# ========================================================================= #
|
196
|
+
# === inspect?
|
197
|
+
# ========================================================================= #
|
198
|
+
def inspect?
|
199
|
+
@scanner.rest.inspect
|
200
|
+
end
|
201
|
+
|
202
|
+
# ========================================================================= #
|
203
|
+
# === constant_base?
|
204
|
+
#
|
205
|
+
# @return [Module, nil]
|
206
|
+
#
|
207
|
+
# Where to lookup constants. Nil is toplevel (equivalent to Object).
|
208
|
+
# ========================================================================= #
|
209
|
+
def constant_base?
|
210
|
+
@constant_base
|
211
|
+
end; alias constant_base constant_base? # === constant_base
|
212
|
+
|
213
|
+
# ========================================================================= #
|
214
|
+
# === scan_value
|
215
|
+
#
|
216
|
+
# Scans the string for a single value and advances the parsers position.
|
217
|
+
#
|
218
|
+
# @return [Object] the scanned value
|
219
|
+
#
|
220
|
+
# @raise [RubyTokenParser::SyntaxError]
|
221
|
+
#
|
222
|
+
# When no valid ruby object could be scanned at the given position,
|
223
|
+
# a RubyTokenParser::SyntaxError is raised. Alternative you can
|
224
|
+
# disable raising an error by calling:
|
225
|
+
#
|
226
|
+
# RubyTokenParser.set_do_raise_exception(false)
|
227
|
+
#
|
228
|
+
# ========================================================================= #
|
229
|
+
def scan_value
|
230
|
+
case
|
231
|
+
# ======================================================================= #
|
232
|
+
# === Handle Ranges (range tag, ranges tag)
|
233
|
+
# ======================================================================= #
|
234
|
+
when (!content?.scan(RRange).empty?)
|
235
|
+
_ = content?.delete('(').delete(')').squeeze('.').split('.').map(&:to_i)
|
236
|
+
min = _.first
|
237
|
+
max = _.last
|
238
|
+
Range.new(min, max)
|
239
|
+
# ======================================================================= #
|
240
|
+
# === Handle Arrays (arrays tag, array tag)
|
241
|
+
# ======================================================================= #
|
242
|
+
when @scanner.scan(RArrayBegin)
|
243
|
+
value = []
|
244
|
+
@scanner.scan(RArrayVoid)
|
245
|
+
if @scanner.scan(RArrayEnd)
|
246
|
+
value
|
247
|
+
else
|
248
|
+
value << scan_value
|
249
|
+
while @scanner.scan(RArraySeparator)
|
250
|
+
value << scan_value
|
251
|
+
end
|
252
|
+
unless @scanner.scan(RArrayVoid) && @scanner.scan(RArrayEnd)
|
253
|
+
raise SyntaxError, 'Expected ]'
|
254
|
+
end
|
255
|
+
value
|
256
|
+
end
|
257
|
+
# ======================================================================= #
|
258
|
+
# === Handle Hashes
|
259
|
+
#
|
260
|
+
# This is quite complicated. We have to scan whether we may find
|
261
|
+
# the {} syntax or the end of a hash.
|
262
|
+
# ======================================================================= #
|
263
|
+
when @scanner.scan(RHashBegin)
|
264
|
+
value = {}
|
265
|
+
@scanner.scan(RHashVoid)
|
266
|
+
if @scanner.scan(RHashEnd)
|
267
|
+
value
|
268
|
+
else
|
269
|
+
if @scanner.scan(RHashKeySymbol)
|
270
|
+
key = @scanner[1].to_sym
|
271
|
+
@scanner.scan(RHashVoid)
|
272
|
+
else
|
273
|
+
key = scan_value
|
274
|
+
unless @scanner.scan(RHashArrow)
|
275
|
+
raise SyntaxError, 'Expected =>'
|
276
|
+
end
|
277
|
+
end
|
278
|
+
val = scan_value
|
279
|
+
value[key] = val
|
280
|
+
while @scanner.scan(RHashSeparator)
|
281
|
+
if @scanner.scan(RHashKeySymbol)
|
282
|
+
key = @scanner[1].to_sym
|
283
|
+
@scanner.scan(RHashVoid)
|
284
|
+
else
|
285
|
+
key = scan_value
|
286
|
+
raise SyntaxError, 'Expected =>' unless @scanner.scan(RHashArrow)
|
287
|
+
end
|
288
|
+
val = scan_value
|
289
|
+
value[key] = val
|
290
|
+
end
|
291
|
+
unless @scanner.scan(RHashVoid) && @scanner.scan(RHashEnd)
|
292
|
+
raise SyntaxError, 'Expected }'
|
293
|
+
end
|
294
|
+
value
|
295
|
+
end
|
296
|
+
# ======================================================================= #
|
297
|
+
# === Handle Constants
|
298
|
+
#
|
299
|
+
# eval() is evil but it may be sane due to the regex, also
|
300
|
+
# it's less annoying than deep_const_get.
|
301
|
+
#
|
302
|
+
# @constant_base can be set via the Hash options[:constant_base].
|
303
|
+
# ======================================================================= #
|
304
|
+
when @scanner.scan(RConstant)
|
305
|
+
eval("#{@constant_base}::#{@scanner.first}")
|
306
|
+
# ======================================================================= #
|
307
|
+
# === Handle Nil values
|
308
|
+
# ======================================================================= #
|
309
|
+
when @scanner.scan(RNil)
|
310
|
+
nil
|
311
|
+
# ======================================================================= #
|
312
|
+
# === Handle True values
|
313
|
+
# ======================================================================= #
|
314
|
+
when @scanner.scan(RTrue) # true tag
|
315
|
+
true
|
316
|
+
# ======================================================================= #
|
317
|
+
# === Handle False values
|
318
|
+
# ======================================================================= #
|
319
|
+
when @scanner.scan(RFalse) # false tag
|
320
|
+
false
|
321
|
+
# ======================================================================= #
|
322
|
+
# === Handle DateTime values
|
323
|
+
# ======================================================================= #
|
324
|
+
when @scanner.scan(RDateTime)
|
325
|
+
Time.mktime( # Tap into the regex pattern next.
|
326
|
+
@scanner[1], @scanner[2],
|
327
|
+
@scanner[3], @scanner[4],
|
328
|
+
@scanner[5], @scanner[6]
|
329
|
+
)
|
330
|
+
# ======================================================================= #
|
331
|
+
# === Handle Date values
|
332
|
+
# ======================================================================= #
|
333
|
+
when @scanner.scan(RDate)
|
334
|
+
date = @scanner[1].to_i, @scanner[2].to_i, @scanner[3].to_i
|
335
|
+
Date.civil(*date)
|
336
|
+
# ======================================================================= #
|
337
|
+
# === Handle RTime values
|
338
|
+
# ======================================================================= #
|
339
|
+
when @scanner.scan(RTime)
|
340
|
+
now = Time.now
|
341
|
+
Time.mktime(
|
342
|
+
now.year, now.month, now.day,
|
343
|
+
@scanner[1].to_i, @scanner[2].to_i, @scanner[3].to_i
|
344
|
+
)
|
345
|
+
# ======================================================================= #
|
346
|
+
# === Handle Float values
|
347
|
+
# ======================================================================= #
|
348
|
+
when @scanner.scan(RFloat)
|
349
|
+
Float(@scanner.matched.delete('^0-9.e-'))
|
350
|
+
# ======================================================================= #
|
351
|
+
# === Handle BigDecimal values
|
352
|
+
# ======================================================================= #
|
353
|
+
when @scanner.scan(RBigDecimal)
|
354
|
+
data = @scanner.matched.delete('^0-9.-')
|
355
|
+
@use_big_decimal ? BigDecimal(data) : Float(data)
|
356
|
+
# ======================================================================= #
|
357
|
+
# === Handle OctalInteger values
|
358
|
+
# ======================================================================= #
|
359
|
+
when @scanner.scan(ROctalInteger)
|
360
|
+
# ===================================================================== #
|
361
|
+
# We can make use of Integer to turn them into valid ruby objects.
|
362
|
+
# ===================================================================== #
|
363
|
+
Integer(@scanner.matched.delete('^0-9-'))
|
364
|
+
# ======================================================================= #
|
365
|
+
# === Handle HexInteger values
|
366
|
+
# ======================================================================= #
|
367
|
+
when @scanner.scan(RHexInteger)
|
368
|
+
Integer(@scanner.matched.delete('^xX0-9A-Fa-f-'))
|
369
|
+
# ======================================================================= #
|
370
|
+
# === Handle BinaryInteger values
|
371
|
+
# ======================================================================= #
|
372
|
+
when @scanner.scan(RBinaryInteger)
|
373
|
+
Integer(@scanner.matched.delete('^bB01-'))
|
374
|
+
# ======================================================================= #
|
375
|
+
# === Handle Integer values
|
376
|
+
# ======================================================================= #
|
377
|
+
when @scanner.scan(RInteger)
|
378
|
+
@scanner.matched.delete('^0-9-').to_i
|
379
|
+
# ======================================================================= #
|
380
|
+
# === Handle Regexp values
|
381
|
+
# ======================================================================= #
|
382
|
+
when @scanner.scan(RRegexp)
|
383
|
+
source = @scanner[1]
|
384
|
+
flags = 0
|
385
|
+
lang = nil
|
386
|
+
if @scanner[2]
|
387
|
+
flags |= Regexp::IGNORECASE if @scanner[2].include?('i') # Value of 1
|
388
|
+
flags |= Regexp::EXTENDED if @scanner[2].include?('m') # Value of 2
|
389
|
+
flags |= Regexp::MULTILINE if @scanner[2].include?('x') # Value of true
|
390
|
+
lang = @scanner[2].delete('^nNeEsSuU')[-1,1]
|
391
|
+
end
|
392
|
+
Regexp.new(source, flags, lang)
|
393
|
+
# ======================================================================= #
|
394
|
+
# === Handle double-quoted string values
|
395
|
+
# ======================================================================= #
|
396
|
+
when @scanner.scan(RDString)
|
397
|
+
@scanner.matched[1..-2].gsub(/\\(?:[0-3]?\d\d?|x[A-Fa-f\d]{2}|.)/) { |m|
|
398
|
+
DStringEscapes[m]
|
399
|
+
}
|
400
|
+
# ======================================================================= #
|
401
|
+
# === Handle Symbol values (symbol tag, symbols tag)
|
402
|
+
# ======================================================================= #
|
403
|
+
when @scanner.scan(RSymbol)
|
404
|
+
# ===================================================================== #
|
405
|
+
# Next, check the first character matched.
|
406
|
+
# ===================================================================== #
|
407
|
+
case @scanner.matched[1,1] # Might be "f".
|
408
|
+
# ===================================================================== #
|
409
|
+
# If it is a '"' quote, enter here.
|
410
|
+
# ===================================================================== #
|
411
|
+
when '"'
|
412
|
+
@scanner.matched[2..-2].gsub(/\\(?:[0-3]?\d\d?|x[A-Fa-f\d]{2}|.)/) { |m|
|
413
|
+
DStringEscapes[m]
|
414
|
+
}.to_sym
|
415
|
+
# ===================================================================== #
|
416
|
+
# If it is a "'" quote, enter here.
|
417
|
+
# ===================================================================== #
|
418
|
+
when "'"
|
419
|
+
@scanner.matched[2..-2].gsub(/\\'/, "'").gsub(/\\\\/, "\\").to_sym
|
420
|
+
else # Default here. Match all but the leading ':'
|
421
|
+
@scanner.matched[1..-1].to_sym
|
422
|
+
end
|
423
|
+
# ======================================================================= #
|
424
|
+
# === Handle single-quoted string values
|
425
|
+
# ======================================================================= #
|
426
|
+
when @scanner.scan(RSString)
|
427
|
+
@scanner.matched[1..-2].gsub(/\\'/, "'").gsub(/\\\\/, "\\")
|
428
|
+
# ======================================================================= #
|
429
|
+
# === Handle everything else
|
430
|
+
#
|
431
|
+
# This can lead to a runtime error, so we must raise a SyntaxError.
|
432
|
+
# ======================================================================= #
|
433
|
+
else # else tag
|
434
|
+
raise SyntaxError, "Unrecognized pattern: #{inspect?}"
|
435
|
+
end
|
436
|
+
end
|
437
|
+
|
438
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# =========================================================================== #
|
2
|
+
# Gemspec for Project RubyTokenParser.
|
3
|
+
# =========================================================================== #
|
4
|
+
Gem::Specification.new { |s|
|
5
|
+
|
6
|
+
s.name = 'ruby_token_parser'
|
7
|
+
s.version = '0.0.6'
|
8
|
+
s.date = Time.now.strftime('%Y-%m-%d')
|
9
|
+
|
10
|
+
DESCRIPTION = <<-EOF
|
11
|
+
|
12
|
+
This project is called ruby_token_parser.
|
13
|
+
|
14
|
+
It allows one to parse for ruby literals, which can
|
15
|
+
be used to return a proper ruby object.
|
16
|
+
|
17
|
+
This project is based on apeiros' prior work, his gem
|
18
|
+
is called literal_parser - check it out.
|
19
|
+
|
20
|
+
If you have specific suggestions to make this gem more
|
21
|
+
useful for others, please drop me an email at:
|
22
|
+
|
23
|
+
shevegen@gmail.com
|
24
|
+
|
25
|
+
Thank you.
|
26
|
+
EOF
|
27
|
+
|
28
|
+
s.summary = DESCRIPTION
|
29
|
+
s.description = DESCRIPTION
|
30
|
+
|
31
|
+
s.extra_rdoc_files = %w()
|
32
|
+
|
33
|
+
s.authors = ['Robert A. Heiler']
|
34
|
+
s.email = 'shevegen@gmail.com'
|
35
|
+
s.files = Dir['**/*']
|
36
|
+
s.files << 'README.md'
|
37
|
+
s.license = 'BSD-2-Clause'
|
38
|
+
s.homepage = 'https://github.com/shevegen/ruby_token_parser'
|
39
|
+
|
40
|
+
s.required_ruby_version = '>= '+RUBY_VERSION
|
41
|
+
s.required_rubygems_version = '>= '+Gem::VERSION
|
42
|
+
s.rubygems_version = '>= '+Gem::VERSION
|
43
|
+
|
44
|
+
# ========================================================================= #
|
45
|
+
# External dependencies for the project:
|
46
|
+
# ========================================================================= #
|
47
|
+
# s.add_dependency 'foo'
|
48
|
+
|
49
|
+
}
|
@@ -0,0 +1,73 @@
|
|
1
|
+
#!/System/Index/bin/ruby -w
|
2
|
+
# Encoding: ISO-8859-1
|
3
|
+
# =========================================================================== #
|
4
|
+
require 'pp'
|
5
|
+
require 'cliner'
|
6
|
+
require 'colour_e/autoinclude'
|
7
|
+
require 'ruby_token_parser'
|
8
|
+
|
9
|
+
cliner {
|
10
|
+
e 'We will next test the '+simp('RubyTokenParser')
|
11
|
+
}
|
12
|
+
# =========================================================================== #
|
13
|
+
# === test_this_string
|
14
|
+
# =========================================================================== #
|
15
|
+
def test_this_string(i, optional_argument = nil)
|
16
|
+
e 'We will test this input next: '+simp(i)
|
17
|
+
x = RubyTokenParser.parse(i, optional_argument)
|
18
|
+
pp x
|
19
|
+
end
|
20
|
+
|
21
|
+
_ = '(1..3)'
|
22
|
+
test_this_string(_)
|
23
|
+
cliner
|
24
|
+
|
25
|
+
_ = "[1,2,3]"
|
26
|
+
test_this_string(_)
|
27
|
+
cliner
|
28
|
+
|
29
|
+
_ = '(1..5)'
|
30
|
+
test_this_string(_) # => (1..5)
|
31
|
+
cliner
|
32
|
+
|
33
|
+
_ = 'nil'
|
34
|
+
test_this_string(_) # => nil
|
35
|
+
cliner
|
36
|
+
|
37
|
+
# =========================================================================== #
|
38
|
+
# === Handle Symbols
|
39
|
+
# =========================================================================== #
|
40
|
+
_ = ':foo'
|
41
|
+
test_this_string(_) # => :foo
|
42
|
+
cliner
|
43
|
+
|
44
|
+
# =========================================================================== #
|
45
|
+
# === Handle Integers
|
46
|
+
# =========================================================================== #
|
47
|
+
_ = '123'
|
48
|
+
test_this_string(_) # => 123
|
49
|
+
cliner
|
50
|
+
|
51
|
+
_ = '1.5'
|
52
|
+
test_this_string(_) # => 1.5
|
53
|
+
cliner
|
54
|
+
|
55
|
+
_ = '1.5'
|
56
|
+
test_this_string(_, use_big_decimal: true) # <BigDecimal:…,'0.15E1',18(18)>
|
57
|
+
cliner
|
58
|
+
|
59
|
+
_ = '[1, 2, 3]'
|
60
|
+
test_this_string(_) # => [1, 2, 3]
|
61
|
+
cliner
|
62
|
+
|
63
|
+
_ = '{:a => 1, :b => 2}'
|
64
|
+
test_this_string(_) # => {:a => 1, :b => 2}
|
65
|
+
cliner
|
66
|
+
|
67
|
+
_ = '(1..3)'
|
68
|
+
test_this_string(_) # => (1..3)
|
69
|
+
cliner
|
70
|
+
|
71
|
+
_ = '"xyz"'
|
72
|
+
test_this_string(_) # =>
|
73
|
+
cliner
|
metadata
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ruby_token_parser
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.6
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Robert A. Heiler
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-10-28 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: "\n This project is called ruby_token_parser.\n \n It allows
|
14
|
+
one to parse for ruby literals, which can\n be used to return a proper ruby object.\n
|
15
|
+
\ \n This project is based on apeiros' prior work, his gem\n is called literal_parser
|
16
|
+
- check it out.\n\n If you have specific suggestions to make this gem more\n
|
17
|
+
\ useful for others, please drop me an email at:\n\n shevegen@gmail.com\n\n
|
18
|
+
\ Thank you.\n"
|
19
|
+
email: shevegen@gmail.com
|
20
|
+
executables: []
|
21
|
+
extensions: []
|
22
|
+
extra_rdoc_files: []
|
23
|
+
files:
|
24
|
+
- LICENSE.txt
|
25
|
+
- README.md
|
26
|
+
- lib/ruby_token_parser.rb
|
27
|
+
- lib/ruby_token_parser/parse.rb
|
28
|
+
- lib/ruby_token_parser/requires.rb
|
29
|
+
- lib/ruby_token_parser/ruby_token_constants.rb
|
30
|
+
- lib/ruby_token_parser/ruby_token_parser.rb
|
31
|
+
- ruby_token_parser.gemspec
|
32
|
+
- test/testing_ruby_token_parser.rb
|
33
|
+
homepage: https://github.com/shevegen/ruby_token_parser
|
34
|
+
licenses:
|
35
|
+
- BSD-2-Clause
|
36
|
+
metadata: {}
|
37
|
+
post_install_message:
|
38
|
+
rdoc_options: []
|
39
|
+
require_paths:
|
40
|
+
- lib
|
41
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 2.5.3
|
46
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: 2.7.7
|
51
|
+
requirements: []
|
52
|
+
rubyforge_project:
|
53
|
+
rubygems_version: 2.7.7
|
54
|
+
signing_key:
|
55
|
+
specification_version: 4
|
56
|
+
summary: 'This project is called ruby_token_parser. It allows one to parse for ruby
|
57
|
+
literals, which can be used to return a proper ruby object. This project is based
|
58
|
+
on apeiros'' prior work, his gem is called literal_parser - check it out. If you
|
59
|
+
have specific suggestions to make this gem more useful for others, please drop me
|
60
|
+
an email at: shevegen@gmail.com Thank you.'
|
61
|
+
test_files: []
|