antelope 0.2.0 → 0.2.2
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 +4 -4
- data/.gitignore +25 -23
- data/.rspec +3 -3
- data/.travis.yml +10 -9
- data/.yardopts +7 -7
- data/CONTRIBUTING.md +38 -38
- data/GENERATORS.md +124 -124
- data/Gemfile +7 -7
- data/LICENSE.txt +22 -22
- data/README.md +104 -104
- data/Rakefile +2 -2
- data/TODO.md +58 -58
- data/antelope.gemspec +28 -28
- data/bin/antelope +7 -7
- data/examples/deterministic.ace +35 -35
- data/examples/example.ace +51 -50
- data/examples/example.err +192 -0
- data/examples/{example.output → example.inf} +384 -385
- data/examples/liquidscript.ace +233 -162
- data/examples/simple.ace +22 -22
- data/lib/antelope/ace/compiler.rb +334 -334
- data/lib/antelope/ace/errors.rb +48 -48
- data/lib/antelope/ace/grammar/generation.rb +80 -80
- data/lib/antelope/ace/grammar/loading.rb +53 -53
- data/lib/antelope/ace/grammar/precedences.rb +68 -65
- data/lib/antelope/ace/grammar/productions.rb +156 -150
- data/lib/antelope/ace/grammar/symbols.rb +66 -66
- data/lib/antelope/ace/grammar.rb +69 -69
- data/lib/antelope/ace/precedence.rb +61 -61
- data/lib/antelope/ace/production.rb +57 -57
- data/lib/antelope/ace/scanner/argument.rb +57 -57
- data/lib/antelope/ace/scanner/first.rb +89 -89
- data/lib/antelope/ace/scanner/second.rb +177 -177
- data/lib/antelope/ace/scanner/third.rb +27 -27
- data/lib/antelope/ace/scanner.rb +134 -134
- data/lib/antelope/ace/token/epsilon.rb +24 -24
- data/lib/antelope/ace/token/error.rb +26 -26
- data/lib/antelope/ace/token/nonterminal.rb +17 -17
- data/lib/antelope/ace/token/terminal.rb +17 -17
- data/lib/antelope/ace/token.rb +238 -238
- data/lib/antelope/ace.rb +53 -53
- data/lib/antelope/cli.rb +55 -55
- data/lib/antelope/errors.rb +8 -8
- data/lib/antelope/generation/constructor/first.rb +88 -88
- data/lib/antelope/generation/constructor/follow.rb +103 -103
- data/lib/antelope/generation/constructor/nullable.rb +64 -64
- data/lib/antelope/generation/constructor.rb +126 -126
- data/lib/antelope/generation/errors.rb +17 -17
- data/lib/antelope/generation/null.rb +13 -13
- data/lib/antelope/generation/recognizer/rule.rb +216 -216
- data/lib/antelope/generation/recognizer/state.rb +130 -130
- data/lib/antelope/generation/recognizer.rb +180 -180
- data/lib/antelope/generation/tableizer.rb +175 -154
- data/lib/antelope/generation.rb +15 -15
- data/lib/antelope/generator/base.rb +264 -264
- data/lib/antelope/generator/c.rb +11 -11
- data/lib/antelope/generator/c_header.rb +105 -105
- data/lib/antelope/generator/c_source.rb +39 -39
- data/lib/antelope/generator/error.rb +34 -0
- data/lib/antelope/generator/group.rb +57 -57
- data/lib/antelope/generator/html.rb +51 -0
- data/lib/antelope/generator/info.rb +47 -0
- data/lib/antelope/generator/null.rb +18 -18
- data/lib/antelope/generator/output.rb +17 -49
- data/lib/antelope/generator/ruby.rb +79 -79
- data/lib/antelope/generator/templates/c_header.ant +36 -36
- data/lib/antelope/generator/templates/c_source.ant +202 -202
- data/lib/antelope/generator/templates/error.ant +33 -0
- data/lib/antelope/generator/templates/html/antelope.css +1 -0
- data/lib/antelope/generator/templates/html/antelope.html +1 -0
- data/lib/antelope/generator/templates/html/antelope.js +1 -0
- data/lib/antelope/generator/templates/html/css.ant +53 -0
- data/lib/antelope/generator/templates/html/html.ant +82 -0
- data/lib/antelope/generator/templates/html/js.ant +9 -0
- data/lib/antelope/generator/templates/info.ant +53 -0
- data/lib/antelope/generator/templates/ruby.ant +178 -146
- data/lib/antelope/generator.rb +66 -63
- data/lib/antelope/template/compiler.rb +78 -78
- data/lib/antelope/template/errors.rb +9 -9
- data/lib/antelope/template/scanner.rb +109 -109
- data/lib/antelope/template.rb +65 -60
- data/lib/antelope/version.rb +6 -6
- data/lib/antelope.rb +13 -13
- data/optimizations.txt +42 -0
- data/spec/antelope/ace/compiler_spec.rb +60 -60
- data/spec/antelope/ace/scanner_spec.rb +27 -27
- data/spec/antelope/constructor_spec.rb +133 -136
- data/spec/antelope/template_spec.rb +50 -49
- data/spec/fixtures/simple.ace +22 -22
- data/spec/spec_helper.rb +39 -39
- data/spec/support/benchmark_helper.rb +5 -5
- data/spec/support/grammar_helper.rb +15 -15
- data/subl/Ace (Ruby).JSON-tmLanguage +94 -94
- data/subl/Ace (Ruby).tmLanguage +153 -153
- metadata +17 -6
- data/lib/antelope/generator/templates/output.ant +0 -68
@@ -1,24 +1,24 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module Antelope
|
4
|
-
module Ace
|
5
|
-
class Token
|
6
|
-
|
7
|
-
# Defines an epsilon token. An epsilon token represents
|
8
|
-
# nothing. This is used to say that a nonterminal can
|
9
|
-
# reduce to nothing.
|
10
|
-
class Epsilon < Token
|
11
|
-
# Initialize. Technically takes no arguments. Sets
|
12
|
-
# the name of the token to be `:$empty`.
|
13
|
-
def initialize(*)
|
14
|
-
super :"$empty"
|
15
|
-
end
|
16
|
-
|
17
|
-
# (see Token#epsilon?)
|
18
|
-
def epsilon?
|
19
|
-
true
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Antelope
|
4
|
+
module Ace
|
5
|
+
class Token
|
6
|
+
|
7
|
+
# Defines an epsilon token. An epsilon token represents
|
8
|
+
# nothing. This is used to say that a nonterminal can
|
9
|
+
# reduce to nothing.
|
10
|
+
class Epsilon < Token
|
11
|
+
# Initialize. Technically takes no arguments. Sets
|
12
|
+
# the name of the token to be `:$empty`.
|
13
|
+
def initialize(*)
|
14
|
+
super :"$empty"
|
15
|
+
end
|
16
|
+
|
17
|
+
# (see Token#epsilon?)
|
18
|
+
def epsilon?
|
19
|
+
true
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -1,26 +1,26 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module Antelope
|
4
|
-
module Ace
|
5
|
-
class Token
|
6
|
-
|
7
|
-
# Defines an error token. This may be used internally by the
|
8
|
-
# parser when it enters panic mode; any tokens following this
|
9
|
-
# are the synchronisation tokens. This is considered a terminal
|
10
|
-
# for the purposes of rule definitions.
|
11
|
-
class Error < Terminal
|
12
|
-
|
13
|
-
# Initialize the error token. Technically takes no arguments.
|
14
|
-
# Sets the name to be `:$error`.
|
15
|
-
def initialize(*)
|
16
|
-
super :$error
|
17
|
-
end
|
18
|
-
|
19
|
-
# (see Token#error?)
|
20
|
-
def error?
|
21
|
-
true
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Antelope
|
4
|
+
module Ace
|
5
|
+
class Token
|
6
|
+
|
7
|
+
# Defines an error token. This may be used internally by the
|
8
|
+
# parser when it enters panic mode; any tokens following this
|
9
|
+
# are the synchronisation tokens. This is considered a terminal
|
10
|
+
# for the purposes of rule definitions.
|
11
|
+
class Error < Terminal
|
12
|
+
|
13
|
+
# Initialize the error token. Technically takes no arguments.
|
14
|
+
# Sets the name to be `:$error`.
|
15
|
+
def initialize(*)
|
16
|
+
super :$error
|
17
|
+
end
|
18
|
+
|
19
|
+
# (see Token#error?)
|
20
|
+
def error?
|
21
|
+
true
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -1,17 +1,17 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module Antelope
|
4
|
-
module Ace
|
5
|
-
class Token
|
6
|
-
|
7
|
-
# Defines a nonterminal token.
|
8
|
-
class Nonterminal < Token
|
9
|
-
|
10
|
-
# (see Token#nonterminal?)
|
11
|
-
def nonterminal?
|
12
|
-
true
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Antelope
|
4
|
+
module Ace
|
5
|
+
class Token
|
6
|
+
|
7
|
+
# Defines a nonterminal token.
|
8
|
+
class Nonterminal < Token
|
9
|
+
|
10
|
+
# (see Token#nonterminal?)
|
11
|
+
def nonterminal?
|
12
|
+
true
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -1,17 +1,17 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module Antelope
|
4
|
-
module Ace
|
5
|
-
class Token
|
6
|
-
|
7
|
-
# Defines a terminal token.
|
8
|
-
class Terminal < Token
|
9
|
-
|
10
|
-
# (see Token#terminal?)
|
11
|
-
def terminal?
|
12
|
-
true
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Antelope
|
4
|
+
module Ace
|
5
|
+
class Token
|
6
|
+
|
7
|
+
# Defines a terminal token.
|
8
|
+
class Terminal < Token
|
9
|
+
|
10
|
+
# (see Token#terminal?)
|
11
|
+
def terminal?
|
12
|
+
true
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/antelope/ace/token.rb
CHANGED
@@ -1,238 +1,238 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require "antelope/ace/token/nonterminal"
|
4
|
-
require "antelope/ace/token/terminal"
|
5
|
-
require "antelope/ace/token/epsilon"
|
6
|
-
require "antelope/ace/token/error"
|
7
|
-
|
8
|
-
|
9
|
-
module Antelope
|
10
|
-
module Ace
|
11
|
-
|
12
|
-
# Defines a token type for productions/rules.
|
13
|
-
#
|
14
|
-
# @abstract This class should be inherited to define a real token.
|
15
|
-
# A base class does not match any token; however, any token can
|
16
|
-
# match the base class.
|
17
|
-
class Token
|
18
|
-
|
19
|
-
# The name of the token.
|
20
|
-
#
|
21
|
-
# @return [Symbol]
|
22
|
-
attr_reader :name
|
23
|
-
|
24
|
-
# The from state that this token is transitioned from. This is
|
25
|
-
# the _source_. This is used in the constructor in order to
|
26
|
-
# handle lookahead sets.
|
27
|
-
#
|
28
|
-
# @return [Recognizer::State]
|
29
|
-
attr_reader :from
|
30
|
-
|
31
|
-
# The to state that this token is transitioned to. This is the
|
32
|
-
# _destination_. This is used in the constructor in order to
|
33
|
-
# handle lookahead sets.
|
34
|
-
#
|
35
|
-
# @return [Recognizer::State]
|
36
|
-
attr_reader :to
|
37
|
-
|
38
|
-
# The type of the token. This is given by a caret argument to
|
39
|
-
# the grammar. This is primarily used for generators.
|
40
|
-
#
|
41
|
-
# @return [String]
|
42
|
-
attr_reader :type
|
43
|
-
|
44
|
-
attr_accessor :id
|
45
|
-
|
46
|
-
# Initialize.
|
47
|
-
#
|
48
|
-
# @param name [Symbol] the name of the token.
|
49
|
-
# @param type [String?] the type of the token. For definitions,
|
50
|
-
# this is the given type of the token (for typed language
|
51
|
-
# output).
|
52
|
-
# @param id [String?] the id of the token in the production.
|
53
|
-
# For some languages, this allows references to the token via
|
54
|
-
# the id.
|
55
|
-
# @param value [String?] the value of the token. This is only
|
56
|
-
# used in output representation to the developer.
|
57
|
-
def initialize(name, type = nil, id = nil, value = nil)
|
58
|
-
@name = name
|
59
|
-
@value = value
|
60
|
-
@type = type
|
61
|
-
@id = id
|
62
|
-
@from = nil
|
63
|
-
@to = nil
|
64
|
-
end
|
65
|
-
|
66
|
-
include Comparable
|
67
|
-
|
68
|
-
# Whether or not the token is a terminal.
|
69
|
-
#
|
70
|
-
# @abstract
|
71
|
-
# @return [Boolean]
|
72
|
-
def terminal?
|
73
|
-
false
|
74
|
-
end
|
75
|
-
|
76
|
-
# Whether or not the token is a nonterminal.
|
77
|
-
#
|
78
|
-
# @abstract
|
79
|
-
# @return [Boolean]
|
80
|
-
def nonterminal?
|
81
|
-
false
|
82
|
-
end
|
83
|
-
|
84
|
-
# Whether or not the token is an epsilon token.
|
85
|
-
#
|
86
|
-
# @abstract
|
87
|
-
# @return [Boolean]
|
88
|
-
def epsilon?
|
89
|
-
false
|
90
|
-
end
|
91
|
-
|
92
|
-
# Whether or not the token is an error token.
|
93
|
-
#
|
94
|
-
# @abstract
|
95
|
-
# @return [Boolean]
|
96
|
-
def error?
|
97
|
-
false
|
98
|
-
end
|
99
|
-
|
100
|
-
# Sets the from state of the token and invalidates the cache.
|
101
|
-
#
|
102
|
-
# @param state [Recognizer::State]
|
103
|
-
# @return [void]
|
104
|
-
def from=(state)
|
105
|
-
invalidate_cache!
|
106
|
-
@from = state
|
107
|
-
end
|
108
|
-
|
109
|
-
# Sets the to state of the token and invalidates the cache.
|
110
|
-
#
|
111
|
-
# @param state [Recognizer::State]
|
112
|
-
# @return [void]
|
113
|
-
def to=(state)
|
114
|
-
invalidate_cache!
|
115
|
-
@to = state
|
116
|
-
end
|
117
|
-
|
118
|
-
# Sets the type of the token and invalidates the cache.
|
119
|
-
#
|
120
|
-
# @param type [String]
|
121
|
-
# @return [void]
|
122
|
-
def type=(type)
|
123
|
-
invalidate_cache!
|
124
|
-
@type = type
|
125
|
-
end
|
126
|
-
|
127
|
-
# Gives a string representation of the token. The output is
|
128
|
-
# formatted like so: `<data>["(" [<from_id>][:<to_id>] ")"]`,
|
129
|
-
# where `<data>` is either the value (if it's non-nil) or the
|
130
|
-
# name, `<from_id>` is the from state id, and `<to_id>` is the
|
131
|
-
# to state id. The last part of the format is optional; if
|
132
|
-
# neither the from state or to state is non-nil, it's non-
|
133
|
-
# existant.
|
134
|
-
#
|
135
|
-
# @return [String] the string representation.
|
136
|
-
# @see #from
|
137
|
-
# @see #to
|
138
|
-
# @see #name
|
139
|
-
def to_s
|
140
|
-
buf = if @value
|
141
|
-
@value.inspect
|
142
|
-
else
|
143
|
-
@name.to_s
|
144
|
-
end
|
145
|
-
|
146
|
-
if from or to
|
147
|
-
buf << "("
|
148
|
-
buf << "#{from.id}" if from
|
149
|
-
buf << ":#{to.id}" if to
|
150
|
-
buf << ")"
|
151
|
-
end
|
152
|
-
|
153
|
-
buf
|
154
|
-
end
|
155
|
-
|
156
|
-
# Returns a nice inspect.
|
157
|
-
#
|
158
|
-
# @return [String]
|
159
|
-
def inspect
|
160
|
-
"#<#{self.class} from=#{from.id if from} to=#{to.id if to} " \
|
161
|
-
"name=#{name.inspect} value=#{@value.inspect}>"
|
162
|
-
end
|
163
|
-
|
164
|
-
# Compares this class to any other object. If the other object
|
165
|
-
# is a token, it converts both this class and the other object
|
166
|
-
# to an array and compares the array. Otherwise, it delegates
|
167
|
-
# the comparison.
|
168
|
-
#
|
169
|
-
# @param other [Object] the other object to compare.
|
170
|
-
# @return [Numeric]
|
171
|
-
def <=>(other)
|
172
|
-
if other.is_a? Token
|
173
|
-
to_a <=> other.to_a
|
174
|
-
else
|
175
|
-
super
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
|
-
def ==(other)
|
180
|
-
hash == other.hash if other.respond_to?(:hash)
|
181
|
-
end
|
182
|
-
|
183
|
-
alias_method :eql?, :==
|
184
|
-
|
185
|
-
# Compares this class and another object, fuzzily. If the other
|
186
|
-
# object is a token, it removes the transitions (to and from)
|
187
|
-
# on both objects and compares them like that. Otherwise, it
|
188
|
-
# delegates the comparison.
|
189
|
-
#
|
190
|
-
# @param other [Object] the other object to compare.
|
191
|
-
# @return [Boolean] if they are equal.
|
192
|
-
def ===(other)
|
193
|
-
if other.is_a? Token
|
194
|
-
without_transitions == other.without_transitions
|
195
|
-
else
|
196
|
-
super
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
|
-
# Creates a new token without to or from states.
|
201
|
-
#
|
202
|
-
# @return [Token]
|
203
|
-
def without_transitions
|
204
|
-
self.class.new(name, @type, @id, @value)
|
205
|
-
end
|
206
|
-
|
207
|
-
# Invalidates the cache.
|
208
|
-
#
|
209
|
-
# @return [void]
|
210
|
-
def invalidate_cache!
|
211
|
-
@_hash = nil
|
212
|
-
@_array = nil
|
213
|
-
end
|
214
|
-
|
215
|
-
# Generates a hash for this class.
|
216
|
-
#
|
217
|
-
# @note This is not intended for use. It is only defined to be
|
218
|
-
# compatible with Hashs (and by extension, Sets).
|
219
|
-
# @private
|
220
|
-
# @return [Object]
|
221
|
-
def hash
|
222
|
-
@_hash ||= to_a.hash
|
223
|
-
end
|
224
|
-
|
225
|
-
alias_method :eql?, :==
|
226
|
-
|
227
|
-
# Creates an array representation of this class.
|
228
|
-
#
|
229
|
-
# @note This is not intended for use. It is only defined to
|
230
|
-
# make equality checking easier, and to create a hash.
|
231
|
-
# @private
|
232
|
-
# @return [Array<(Recognizer::State, Recognizer::State, Class, Symbol, String?)>]
|
233
|
-
def to_a
|
234
|
-
@_array ||= [to, from, self.class, name, @value]
|
235
|
-
end
|
236
|
-
end
|
237
|
-
end
|
238
|
-
end
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "antelope/ace/token/nonterminal"
|
4
|
+
require "antelope/ace/token/terminal"
|
5
|
+
require "antelope/ace/token/epsilon"
|
6
|
+
require "antelope/ace/token/error"
|
7
|
+
|
8
|
+
|
9
|
+
module Antelope
|
10
|
+
module Ace
|
11
|
+
|
12
|
+
# Defines a token type for productions/rules.
|
13
|
+
#
|
14
|
+
# @abstract This class should be inherited to define a real token.
|
15
|
+
# A base class does not match any token; however, any token can
|
16
|
+
# match the base class.
|
17
|
+
class Token
|
18
|
+
|
19
|
+
# The name of the token.
|
20
|
+
#
|
21
|
+
# @return [Symbol]
|
22
|
+
attr_reader :name
|
23
|
+
|
24
|
+
# The from state that this token is transitioned from. This is
|
25
|
+
# the _source_. This is used in the constructor in order to
|
26
|
+
# handle lookahead sets.
|
27
|
+
#
|
28
|
+
# @return [Recognizer::State]
|
29
|
+
attr_reader :from
|
30
|
+
|
31
|
+
# The to state that this token is transitioned to. This is the
|
32
|
+
# _destination_. This is used in the constructor in order to
|
33
|
+
# handle lookahead sets.
|
34
|
+
#
|
35
|
+
# @return [Recognizer::State]
|
36
|
+
attr_reader :to
|
37
|
+
|
38
|
+
# The type of the token. This is given by a caret argument to
|
39
|
+
# the grammar. This is primarily used for generators.
|
40
|
+
#
|
41
|
+
# @return [String]
|
42
|
+
attr_reader :type
|
43
|
+
|
44
|
+
attr_accessor :id
|
45
|
+
|
46
|
+
# Initialize.
|
47
|
+
#
|
48
|
+
# @param name [Symbol] the name of the token.
|
49
|
+
# @param type [String?] the type of the token. For definitions,
|
50
|
+
# this is the given type of the token (for typed language
|
51
|
+
# output).
|
52
|
+
# @param id [String?] the id of the token in the production.
|
53
|
+
# For some languages, this allows references to the token via
|
54
|
+
# the id.
|
55
|
+
# @param value [String?] the value of the token. This is only
|
56
|
+
# used in output representation to the developer.
|
57
|
+
def initialize(name, type = nil, id = nil, value = nil)
|
58
|
+
@name = name
|
59
|
+
@value = value
|
60
|
+
@type = type
|
61
|
+
@id = id
|
62
|
+
@from = nil
|
63
|
+
@to = nil
|
64
|
+
end
|
65
|
+
|
66
|
+
include Comparable
|
67
|
+
|
68
|
+
# Whether or not the token is a terminal.
|
69
|
+
#
|
70
|
+
# @abstract
|
71
|
+
# @return [Boolean]
|
72
|
+
def terminal?
|
73
|
+
false
|
74
|
+
end
|
75
|
+
|
76
|
+
# Whether or not the token is a nonterminal.
|
77
|
+
#
|
78
|
+
# @abstract
|
79
|
+
# @return [Boolean]
|
80
|
+
def nonterminal?
|
81
|
+
false
|
82
|
+
end
|
83
|
+
|
84
|
+
# Whether or not the token is an epsilon token.
|
85
|
+
#
|
86
|
+
# @abstract
|
87
|
+
# @return [Boolean]
|
88
|
+
def epsilon?
|
89
|
+
false
|
90
|
+
end
|
91
|
+
|
92
|
+
# Whether or not the token is an error token.
|
93
|
+
#
|
94
|
+
# @abstract
|
95
|
+
# @return [Boolean]
|
96
|
+
def error?
|
97
|
+
false
|
98
|
+
end
|
99
|
+
|
100
|
+
# Sets the from state of the token and invalidates the cache.
|
101
|
+
#
|
102
|
+
# @param state [Recognizer::State]
|
103
|
+
# @return [void]
|
104
|
+
def from=(state)
|
105
|
+
invalidate_cache!
|
106
|
+
@from = state
|
107
|
+
end
|
108
|
+
|
109
|
+
# Sets the to state of the token and invalidates the cache.
|
110
|
+
#
|
111
|
+
# @param state [Recognizer::State]
|
112
|
+
# @return [void]
|
113
|
+
def to=(state)
|
114
|
+
invalidate_cache!
|
115
|
+
@to = state
|
116
|
+
end
|
117
|
+
|
118
|
+
# Sets the type of the token and invalidates the cache.
|
119
|
+
#
|
120
|
+
# @param type [String]
|
121
|
+
# @return [void]
|
122
|
+
def type=(type)
|
123
|
+
invalidate_cache!
|
124
|
+
@type = type
|
125
|
+
end
|
126
|
+
|
127
|
+
# Gives a string representation of the token. The output is
|
128
|
+
# formatted like so: `<data>["(" [<from_id>][:<to_id>] ")"]`,
|
129
|
+
# where `<data>` is either the value (if it's non-nil) or the
|
130
|
+
# name, `<from_id>` is the from state id, and `<to_id>` is the
|
131
|
+
# to state id. The last part of the format is optional; if
|
132
|
+
# neither the from state or to state is non-nil, it's non-
|
133
|
+
# existant.
|
134
|
+
#
|
135
|
+
# @return [String] the string representation.
|
136
|
+
# @see #from
|
137
|
+
# @see #to
|
138
|
+
# @see #name
|
139
|
+
def to_s
|
140
|
+
buf = if @value
|
141
|
+
@value.inspect
|
142
|
+
else
|
143
|
+
@name.to_s
|
144
|
+
end
|
145
|
+
|
146
|
+
if from or to
|
147
|
+
buf << "("
|
148
|
+
buf << "#{from.id}" if from
|
149
|
+
buf << ":#{to.id}" if to
|
150
|
+
buf << ")"
|
151
|
+
end
|
152
|
+
|
153
|
+
buf
|
154
|
+
end
|
155
|
+
|
156
|
+
# Returns a nice inspect.
|
157
|
+
#
|
158
|
+
# @return [String]
|
159
|
+
def inspect
|
160
|
+
"#<#{self.class} from=#{from.id if from} to=#{to.id if to} " \
|
161
|
+
"name=#{name.inspect} value=#{@value.inspect}>"
|
162
|
+
end
|
163
|
+
|
164
|
+
# Compares this class to any other object. If the other object
|
165
|
+
# is a token, it converts both this class and the other object
|
166
|
+
# to an array and compares the array. Otherwise, it delegates
|
167
|
+
# the comparison.
|
168
|
+
#
|
169
|
+
# @param other [Object] the other object to compare.
|
170
|
+
# @return [Numeric]
|
171
|
+
def <=>(other)
|
172
|
+
if other.is_a? Token
|
173
|
+
to_a <=> other.to_a
|
174
|
+
else
|
175
|
+
super
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def ==(other)
|
180
|
+
hash == other.hash if other.respond_to?(:hash)
|
181
|
+
end
|
182
|
+
|
183
|
+
alias_method :eql?, :==
|
184
|
+
|
185
|
+
# Compares this class and another object, fuzzily. If the other
|
186
|
+
# object is a token, it removes the transitions (to and from)
|
187
|
+
# on both objects and compares them like that. Otherwise, it
|
188
|
+
# delegates the comparison.
|
189
|
+
#
|
190
|
+
# @param other [Object] the other object to compare.
|
191
|
+
# @return [Boolean] if they are equal.
|
192
|
+
def ===(other)
|
193
|
+
if other.is_a? Token
|
194
|
+
without_transitions == other.without_transitions
|
195
|
+
else
|
196
|
+
super
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
# Creates a new token without to or from states.
|
201
|
+
#
|
202
|
+
# @return [Token]
|
203
|
+
def without_transitions
|
204
|
+
self.class.new(name, @type, @id, @value)
|
205
|
+
end
|
206
|
+
|
207
|
+
# Invalidates the cache.
|
208
|
+
#
|
209
|
+
# @return [void]
|
210
|
+
def invalidate_cache!
|
211
|
+
@_hash = nil
|
212
|
+
@_array = nil
|
213
|
+
end
|
214
|
+
|
215
|
+
# Generates a hash for this class.
|
216
|
+
#
|
217
|
+
# @note This is not intended for use. It is only defined to be
|
218
|
+
# compatible with Hashs (and by extension, Sets).
|
219
|
+
# @private
|
220
|
+
# @return [Object]
|
221
|
+
def hash
|
222
|
+
@_hash ||= to_a.hash
|
223
|
+
end
|
224
|
+
|
225
|
+
alias_method :eql?, :==
|
226
|
+
|
227
|
+
# Creates an array representation of this class.
|
228
|
+
#
|
229
|
+
# @note This is not intended for use. It is only defined to
|
230
|
+
# make equality checking easier, and to create a hash.
|
231
|
+
# @private
|
232
|
+
# @return [Array<(Recognizer::State, Recognizer::State, Class, Symbol, String?)>]
|
233
|
+
def to_a
|
234
|
+
@_array ||= [to, from, self.class, name, @value]
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|