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