lib/citrus.rb in citrus-2.3.4 vs lib/citrus.rb in citrus-2.3.5
- old
+ new
@@ -17,21 +17,19 @@
Infinity = 1.0 / 0
CLOSE = -1
- @cache = {}
-
# Returns a map of paths of files that have been loaded via #load to the
# result of #eval on the code in that file.
#
# Note: These paths are not absolute unless you pass an absolute path to
# #load. That means that if you change the working directory and try to
# #require the same file with a different relative path, it will be loaded
# twice.
def self.cache
- @cache
+ @cache ||= {}
end
# Evaluates the given Citrus parsing expression grammar +code+ and returns an
# array of any grammar modules that are created. Accepts the same +options+ as
# GrammarMethods#parse.
@@ -69,26 +67,26 @@
#
# Citrus.load('mygrammar')
# # => [MyGrammar]
#
def self.load(file, options={})
- file += '.citrus' unless file =~ /\.citrus$/
+ file += '.citrus' unless /\.citrus$/ === file
force = options.delete(:force)
- if force || !@cache[file]
+ if force || !cache[file]
raise LoadError, "Cannot find file #{file}" unless ::File.file?(file)
raise LoadError, "Cannot read file #{file}" unless ::File.readable?(file)
begin
- @cache[file] = eval(::File.read(file), options)
+ cache[file] = eval(::File.read(file), options)
rescue SyntaxError => e
e.message.replace("#{::File.expand_path(file)}: #{e.message}")
raise e
end
end
- @cache[file]
+ cache[file]
end
# Searches the <tt>$LOAD_PATH</tt> for a +file+ with the .citrus suffix and
# attempts to load it via #load. Returns the path to the file that was loaded
# on success, +nil+ on failure. Accepts the same +options+ as #load.
@@ -97,15 +95,17 @@
# # => "/path/to/mygrammar.citrus"
# Citrus.cache[path]
# # => [MyGrammar]
#
def self.require(file, options={})
- file += '.citrus' unless file =~ /\.citrus$/
+ file += '.citrus' unless /\.citrus$/ === file
found = nil
- (Pathname.new(file).absolute? ? [''] : $LOAD_PATH).each do |dir|
- found = Dir[::File.join(dir, file)].first
+ paths = ['']
+ paths += $LOAD_PATH unless Pathname.new(file).absolute?
+ paths.each do |path|
+ found = Dir[::File.join(path, file)].first
break if found
end
if found
Citrus.load(found, options)
@@ -668,10 +668,15 @@
else
to_citrus
end
end
+ # This alias allows strings to be compared to the string representation of
+ # Rule objects. It is most useful in assertions in unit tests, e.g.:
+ #
+ # assert_equal('"a" | "b"', rule)
+ #
alias_method :to_str, :to_s
# Returns the Citrus notation of this rule as a string that is suitable to
# be embedded in the string representation of another rule.
def to_embedded_s # :nodoc:
@@ -1285,24 +1290,27 @@
def to_s
@string
end
+ # This alias allows strings to be compared to the string value of Match
+ # objects. It is most useful in assertions in unit tests, e.g.:
+ #
+ # assert_equal("a string", match)
+ #
alias_method :to_str, :to_s
# The default value for a match is its string value. This method is
# overridden in most cases to be more meaningful according to the desired
# interpretation.
alias_method :value, :to_s
# Returns this match plus all sub #matches in an array.
def to_a
- [captures[0]] + matches
+ [self] + matches
end
- alias_method :to_ary, :to_a
-
# Returns the capture at the given +key+. If it is an Integer (and an
# optional length) or a Range, the result of #to_a with the same arguments
# is returned. Otherwise, the value at +key+ in #captures is returned.
def [](key, *args)
case key
@@ -1311,12 +1319,10 @@
else
captures[key]
end
end
- alias_method :fetch, :[]
-
def ==(other)
case other
when String
@string == other
when Match
@@ -1380,10 +1386,11 @@
def process_events!
@captures = captures_hash
@matches = []
capture!(@events[0], self)
+ @captures[0] = self
stack = []
offset = 0
close = false
index = 0
@@ -1402,11 +1409,14 @@
start = stack.pop
match = Match.new(@string.slice(os, event), @events[start..index])
capture!(rule, match)
- @matches << match if stack.size == 1
+ if stack.size == 1
+ @matches << match
+ @captures[@matches.size] = match
+ end
capture = true
end
last_length = event unless last_length
@@ -1434,16 +1444,9 @@
capture = false if Proxy === event
end
end
index += 1
- end
-
- # Add numeric indices to @captures.
- @captures[0] = self
-
- @matches.each_with_index do |match, index|
- @captures[index + 1] = match
end
end
def capture!(rule, match)
# We can lookup matches that were created by proxy by the name of