def parse(string_, params_=nil)
parse_params_ = default_parse_params
parse_params_.merge!(params_) if params_
parse_state_ = {
:backtrack => nil,
:string => string_,
:values => {},
:unparse_params => {},
:field => @schema.root_field,
:recognizer_index => 0,
:previous_field_missing => false
}
while (field_ = parse_state_[:field])
handler_ = @field_handlers[field_.name]
recognizer_ = handler_.get_recognizer(parse_state_[:recognizer_index])
parse_data_ = nil
if recognizer_
parse_state_[:recognizer_index] += 1
parse_data_ = recognizer_.parse(parse_state_, parse_params_)
if parse_data_
parse_state_[:previous_field_missing] = false
if recognizer_.requires_next_field
parse_state_ = {
:backtrack => parse_state_,
:string => parse_state_[:string],
:values => parse_state_[:values].dup,
:unparse_params => parse_state_[:unparse_params].dup,
:field => parse_state_[:field],
:recognizer_index => 0,
:previous_field_missing => false,
:next_field_required => true,
}
else
parse_state_[:next_field_required] = false
end
end
elsif parse_state_[:next_field_required]
parse_state_ = parse_state_[:backtrack]
else
parse_data_ = [handler_.default_value, nil, nil, nil]
parse_state_[:previous_field_missing] = true
parse_state_[:next_field_required] = false
end
if parse_data_
parse_state_[:values][field_.name] = parse_data_[0]
parse_state_[:string] = parse_data_[2] if parse_data_[2]
parse_state_[:unparse_params].merge!(parse_data_[3]) if parse_data_[3]
parse_state_[:field] = field_.child(parse_data_[0])
parse_state_[:recognizer_index] = 0
handler_.set_style_unparse_param(parse_data_[1], parse_state_[:unparse_params])
end
end
unparse_params_ = parse_state_[:unparse_params]
if parse_state_[:string].length > 0
case parse_params_[:extra_characters]
when :ignore
when :suffix
unparse_params_[:suffix] = parse_state_[:string]
else
raise Errors::ParseError, "Extra characters: #{parse_state_[:string].inspect}"
end
end
Value.new(parse_state_[:values], self, unparse_params_)
end