def quantifier(token)
offset = -1
target_node = node.expressions[offset]
while target_node.is_a?(FreeSpace)
target_node = node.expressions[offset -= 1]
end
target_node || raise(ArgumentError, 'No valid target found for '\
"'#{token.text}' ")
# in case of chained quantifiers, wrap target in an implicit passive group
# description of the problem: https://github.com/ammar/regexp_parser/issues/3
# rationale for this solution: https://github.com/ammar/regexp_parser/pull/69
if target_node.quantified?
new_token = Regexp::Token.new(
:group,
:passive,
'', # text
target_node.ts,
nil, # te (unused)
target_node.level,
target_node.set_level,
target_node.conditional_level
)
new_group = Group::Passive.new(new_token, active_opts)
new_group.implicit = true
new_group << target_node
increase_level(target_node)
node.expressions[offset] = new_group
target_node = new_group
end
case token.token
when :zero_or_one
target_node.quantify(:zero_or_one, token.text, 0, 1, :greedy)
when :zero_or_one_reluctant
target_node.quantify(:zero_or_one, token.text, 0, 1, :reluctant)
when :zero_or_one_possessive
target_node.quantify(:zero_or_one, token.text, 0, 1, :possessive)
when :zero_or_more
target_node.quantify(:zero_or_more, token.text, 0, -1, :greedy)
when :zero_or_more_reluctant
target_node.quantify(:zero_or_more, token.text, 0, -1, :reluctant)
when :zero_or_more_possessive
target_node.quantify(:zero_or_more, token.text, 0, -1, :possessive)
when :one_or_more
target_node.quantify(:one_or_more, token.text, 1, -1, :greedy)
when :one_or_more_reluctant
target_node.quantify(:one_or_more, token.text, 1, -1, :reluctant)
when :one_or_more_possessive
target_node.quantify(:one_or_more, token.text, 1, -1, :possessive)
when :interval
interval(target_node, token)
else
raise UnknownTokenError.new('Quantifier', token)
end
end