How to force rematch?

Viewed 104

I would like to force rematch in the following scenario - I'm trying to inverse match a qualifier after each element in a list. In other words I have:

"int a, b, c" =~ m{
(?(DEFINE)
    (?<qualifs>\s*(?<qualif>\bint\b|\bfloat\b)\s*+(?{print $+{qualif}  . "\n"}))
    (?<decl>\s*(?!(?&qualif))(?<ident>[_a-zA-Z][_a-zA-Z0-9]*+)\s*(?{print $+{ident} . "\n"}))

    (?<qualifsfacet>\s*\bint\b\s*+)
    (?<declfacet>[_a-zA-Z][_a-zA-Z0-9]*+)
)


^((?&qualifsfacet)*+(?!(?&decl))
                |(?&qualifs)*+(?&declfacet)
                |((?&qualifsfacet)
                (?&declfacet)(?<negdecl>\g{lastnegdecl}(,(?&decl)))
                |(?&qualifs)*+(?&declfacet)(?<lastnegdecl>\g{negdecl})
                (?# Here how to force it to retry last with new lastnegdecl)))$
                }xxs;

And would like to have:

a
int
b
int
c
int

As output. Currently it's only this:

a
int
int

I think this might work if there is a way to tell the regex machine to retrigger a match for the new lastnegdecl that is being captured.

1 Answers

Well after some trying I finally figured it out (besides the obvious whitespace issues I had in my original post):

"int a, b, c" =~ m{
(?(DEFINE)
    (?<qualifs>\s*+(?<qualif>\bint\b|\bfloat\b)\s*+(?{print $+{qualif}  . "\n"}))
    (?<decl>\s*+(?!(?&qualif))(?<ident>[_a-zA-Z][_a-zA-Z0-9]*+)\s*(?{print $+{ident} . "\n"}))

    (?<qualifsfacet>\s*+(\bint\b|\bfloat\b)\s*+)
    (?<declfacet>\s*+[_a-zA-Z][_a-zA-Z0-9]*+\s*+)
)


^((?&qualifsfacet)(?!(?&decl))
                |(?&qualifs)*+(?&declfacet)
                |(?<restoutter>(?=(?&qualifsfacet)(?&declfacet)
                (?<rest>(?(<rest>)\g{rest}),(?&decl)))
                ((?&qualifs)(?&declfacet)\g{rest}|(?&restoutter)))
                |(?&qualifsfacet)(?&declfacet)(,(?&declfacet))*+)$
                }xxs;

Basically I'm doing a positive lookahead where decl are called with code but qualifs are not while also concatenating decl inside rest then doing a partial match with the qualifs and the rest and if it doesn't match it goes to do the same thing again. Maybe someone can explain it better but it works. The output of the program above is:

a
int
b
int
c
int

And there is a full match.

Related