void Generator::generateNonGreedyQuantifier(JumpList& failures, GenerateAtomFunctor& functor, unsigned min, unsigned max) { JumpList atomFailedList; JumpList alternativeFailedList; // (0) Setup: Save, then init repeatCount. push(repeatCount); move(Imm32(0), repeatCount); Jump start = jump(); // (4) Quantifier failed: No more atom reading possible. Label quantifierFailed(this); pop(repeatCount); failures.append(jump()); // (3) Alternative failed: If we can, read another atom, then fall through to (2) to try again. Label alternativeFailed(this); pop(index); if (max != Quantifier::Infinity) je32(repeatCount, Imm32(max), quantifierFailed); // (1) Read an atom. if (min) start.link(this); Label readAtom(this); functor.generateAtom(this, atomFailedList); atomFailedList.linkTo(quantifierFailed, this); add32(Imm32(1), repeatCount); // (2) Keep reading if we're under the minimum. if (min > 1) jl32(repeatCount, Imm32(min), readAtom); // (3) Test the rest of the alternative. if (!min) start.link(this); push(index); m_parser.parseAlternative(alternativeFailedList); alternativeFailedList.linkTo(alternativeFailed, this); pop(); pop(repeatCount); }
void Generator::generateGreedyQuantifier(JumpList& failures, GenerateAtomFunctor& functor, unsigned min, unsigned max) { if (!max) return; JumpList doneReadingAtomsList; JumpList alternativeFailedList; // (0) Setup: Save, then init repeatCount. push(repeatCount); move(Imm32(0), repeatCount); // (1) Greedily read as many copies of the atom as possible, then jump to (2). Label readAtom(this); functor.generateAtom(this, doneReadingAtomsList); add32(Imm32(1), repeatCount); if (max == Quantifier::Infinity) jump(readAtom); else if (max == 1) doneReadingAtomsList.append(jump()); else { jne32(repeatCount, Imm32(max), readAtom); doneReadingAtomsList.append(jump()); } // (5) Quantifier failed: No more backtracking possible. Label quantifierFailed(this); pop(repeatCount); failures.append(jump()); // (4) Alternative failed: Backtrack, then fall through to (2) to try again. Label alternativeFailed(this); pop(index); functor.backtrack(this); sub32(Imm32(1), repeatCount); // (2) Verify that we have enough atoms. doneReadingAtomsList.link(this); jl32(repeatCount, Imm32(min), quantifierFailed); // (3) Test the rest of the alternative. push(index); m_parser.parseAlternative(alternativeFailedList); alternativeFailedList.linkTo(alternativeFailed, this); pop(); pop(repeatCount); }