module FixtureFox class Token attr_reader :file attr_reader :lineno attr_reader :initial_indent attr_reader :pos attr_reader :litt attr_reader :value def initialize(file, lineno, initial_indent, pos, litt) @file, @lineno, @initial_indent, @pos, @litt = file, lineno, initial_indent, pos, litt @value = @litt end def ==(s) @litt == s end def to_s() @litt end def error(msg) raise ParseError.new(file, lineno, initial_indent + pos, msg) end end class AnchorToken < Token def initialize(file, lineno, initial_indent, pos, litt) super @value = litt[1..-1].to_sym end # Convert an Ident token to a AnchorToken token def self.of_ident(ident) AnchorToken.new(ident.file, ident.lineno, ident.initial_indent, ident.pos, "&#{ident.litt}") end end class Empty < Token end class Directive < Token def initialize(file, lineno, initial_indent, pos, litt) super @value = litt[1..-1] end end class Ident < Token end class Reference < Token # attr_reader :reference def initialize(file, lineno, initial_indent, pos, litt) super @value = litt[1..-1] end end class Value < Token attr_reader :klass # NilClass, TrueClass, Integer, Float, String, Array def initialize(file, lineno, initial_indent, pos, litt) super i = 1 case litt when /^(nil)/, /^(null)/ i += $1.size @klass = NilClass @value = nil when /^(true)/, /^(false)/ i += $1.size @klass = TrueClass @value = ($1 == "true") when /^([-+]?\d+\.\d+)/ i += $1.size @klass = Float @value = $1.to_f when /^([-+]?\d+)/ i += $1.size @klass = Integer @value = $1.to_i when /^"/ @value = "" @klass = String loop do i < litt.size or self.error("Unterminated string") if litt[i] == "\\" if litt[i+1] == "\\" @value += "\\" i += 2 elsif litt[i+1] == '"' @value += '"' i += 2 elsif litt[i+1] == 'n' @value += "\n" i += 2 elsif litt[i+1] == 't' @value += "\t" i += 2 else @value += "\\" i += 1 end elsif litt[i] == '"' i += 1 break else @value += litt[i] i += 1 end end when /^'/ @value = "" @klass = String loop do i < litt.size or self.error("Unterminated string") if litt[i] == "'" if litt[i+1] == "'" @value += "'" i += 2 else i += 1 break end else @value += litt[i] i += 1 end end # Inline arrays are split on ',' and on blanks. '\' is the escape # character # # FIXME: Quotes doesn't override separator. Eg. this throws an # exception: ['hello world'] when /^(\[\s*)(.*)\]$/ i += $1.size elements = $2 matches = elements.split(/(\s*(?