Consider reading multi-part MIME data, especially as HTTP traffic or an e-mail with file attachments: it alternates back and forth between highly-structured header-data (amenable to scan/parse techniques) and then looking for some delimiter you don't get until run-time.
Let the stream and the scanner be separate objects. Let the interface between them be such that user code can intervene both to peek at the stream and move its "cursor", so that any scanner applied to said stream agrees to play along.
Incidentally, this begins to hint at the dark path of PEGs, but it remains just a hint.
Consider reading multi-part MIME data, especially as HTTP traffic or an e-mail with file attachments: it alternates back and forth between highly-structured header-data (amenable to scan/parse techniques) and then looking for some delimiter you don't get until run-time.
Let the stream and the scanner be separate objects. Let the interface between them be such that user code can intervene both to peek at the stream and move its "cursor", so that any scanner applied to said stream agrees to play along.
Incidentally, this begins to hint at the dark path of PEGs, but it remains just a hint.