Tokenizer
MMO\core\helpers · 1 symbol · generated 30 Sep 2026
Tokenizer
Tokenizer.php:19A generic, hand-rollable lexer: split text into a stream of Token instances, driven by a stack of
- Namespace
MMO\core\helpers- Implements
- Iterator, iSerializable
- See
TokenDomain"grammars" (e.g. one for the top level, another opened while inside a quoted string or bracketed group). Implements \Iterator, soforeach ($tokenizer as $token)walks the whole token stream. Used byJsonParser/XmlParser.
Index
| CHUNK_SIZE | ||
| USER_TOKEN_ID | ||
| col | {int} general column offset | |
| domains | {array<TokenDomain>} stack of domains in use | |
| filters | {array<fn(string $text): string>} list of filters to apply to incoming text | |
| line | {int} general line offset | |
| offset | {int} general offset | |
| stream | ||
| text | {string} current text being treated. | |
| token | {?Token} current token | |
| tokens | {array<Token>} tokens found | |
| addFilter($fn, $priority) | Register a text filter (applied by addText to every chunk of incoming text, e.g. | |
| addText($text, $first) | Append more text to the not-yet-tokenized buffer (running it through every registered addFilter first). | |
| clear() | Reset all state (text, tokens read so far, open domains) but keep the root domain, so this instance is ready to tokenize a new text via setText. | |
| closeDomain() | Pop the current domain, returning to its parent. | |
| current() | \Iterator::current -- the current Token | |
| currentDomain() | ||
| getCol() | ||
| getDomains() | ||
| getLastTokenIndex($token, $offset) | Same as getTokenIndex, but searches backward from $offset. | |
| getLine() | ||
| getOffset() | ||
| getStream() | ||
| getText($length, $offset) | Peek at the not-yet-tokenized text buffer, without consuming it. | |
| getToken($index) | ||
| getTokenIndex($token, $offset) | ||
| getTokens() | ||
| goto($search) | Advance tokenizer to the searched token. | |
| ignore($search) | Advance tokenizer until it does not find the searched token. | |
| isEscaped($char, $offsetFromEnd) | Tells if current token is escaped (by backslash). | |
| isInsideDomain($domain) | ||
| key() | \Iterator::key -- the number of tokens already consumed before this one | |
| next() | \Iterator::next -- read and consume the next token from the buffer (pulling more from getStream if needed), delegating to the current domain's own token list, and to TokenDomain::open / :… | |
| nextToken($count) | Advance $count tokens forward. | |
| openDomain($domain) | Push a domain onto the stack (e.g. | |
| parentDomain() | ||
| rewind() | WARNING: this function won't rewind stream. | |
| rootDomain() | ||
| serialize($path, $serializer) | \MMO\core\interfaces\iSerializable::serialize -- only the root domain is persisted (grammar, not read progress) | |
| setRootDomain($domain) | ||
| setText($stream) | Set what to tokenize: a plain string (read whole, immediately), a stream resource (read in | |
| setToken($token) | Consume $token: record it as current, advance offset/line/col past it, and remove its text from the not-yet-tokenized buffer. | |
| unserialize($data, $path, $instances) | \MMO\core\interfaces\iSerializable::unserialize -- rebuilds a fresh instance with the stored root domain | |
| valid() | \Iterator::valid -- false once tokenizing has reached the end of the text | |
| __construct($domain) |
Constants2
CHUNK_SIZE
USER_TOKEN_ID
Properties9
col
{int} general column offset
- Type
- int
domains
{array<TokenDomain>} stack of domains in use
- Type
- array
filters
{array<fn(string $text): string>} list of filters to apply to incoming text
- Type
- array
line
{int} general line offset
- Type
- int
offset
{int} general offset
- Type
- int
stream
text
{string} current text being treated. it is shrunk every time a token is created
- Type
- string
token
{?Token} current token
tokens
{array<Token>} tokens found
- Type
- array
Methods34
addFilter($fn, $priority)
Tokenizer.php:210Register a text filter (applied by addText to every chunk of incoming text, e.g. before tokenizing).
| $fn | callable | function(string $text): string |
| $priority = 0 | int | |
| returns | void | NOTE: the original insertion logic was genuinely broken -- it only ever compared the new filter against the single element it happened to stop scanning at, not the array as a whole, so filters routinely ended up in neither ascending nor descending order (verified: adding priorities 1, 2, 3 in that order produced [2, 3, 1] instead of the correct [3, 2, 1]). No code in the framework currently calls this, so this replaces the insertion with a correct, verified stable descending-priority insert instead of patching the old one. |
addText($text, $first)
Tokenizer.php:68Append more text to the not-yet-tokenized buffer (running it through every registered addFilter first). Used internally to read more from setText's stream as tokenizing progresses, but can also be called directly to feed text incrementally.
clear()
Tokenizer.php:52Reset all state (text, tokens read so far, open domains) but keep the root domain, so this instance is ready to tokenize a new text via setText.
| returns | void |
closeDomain()
Tokenizer.php:277Pop the current domain, returning to its parent.
| returns | null | TokenDomain | the closed domain, or null if already at the root (the root is never popped) |
current()
Tokenizer.php:368\Iterator::current -- the current Token
| returns | mixed |
currentDomain()
Tokenizer.php:282| returns | TokenDomain | the innermost (currently active) domain |
getCol()
Tokenizer.php:117| returns | int | the current column |
getDomains()
Tokenizer.php:287| returns | array | the whole domain stack, root first |
getLastTokenIndex($token, $offset)
Tokenizer.php:162Same as getTokenIndex, but searches backward from $offset.
getLine()
Tokenizer.php:112| returns | int | the 1-based line of the token currently being read (updated as tokens containing '\n' are consumed) |
getOffset()
Tokenizer.php:122| returns | int | how many characters have been consumed (tokenized) so far |
getStream()
Tokenizer.php:96| returns | the stream passed to setText, if any |
getText($length, $offset)
Tokenizer.php:107Peek at the not-yet-tokenized text buffer, without consuming it.
getToken($index)
Tokenizer.php:130getTokenIndex($token, $offset)
Tokenizer.php:145getTokens()
Tokenizer.php:136| returns | array | every token consumed so far |
goto($search)
Tokenizer.php:320Advance tokenizer to the searched token.
| ...$search | the token's id or text to look for | |
| returns | array |
ignore($search)
Tokenizer.php:336Advance tokenizer until it does not find the searched token.
isEscaped($char, $offsetFromEnd)
Tokenizer.php:228Tells if current token is escaped (by backslash).
isInsideDomain($domain)
Tokenizer.php:298| $domain | TokenDomain | |
| returns | bool | true if $domain is anywhere in the current domain stack |
key()
Tokenizer.php:373\Iterator::key -- the number of tokens already consumed before this one
| returns | mixed |
next()
Tokenizer.php:382\Iterator::next -- read and consume the next token from the buffer (pulling more from getStream if needed), delegating to the current domain's own token list, and to TokenDomain::open / ::close for nested domains.
| returns | void |
nextToken($count)
Tokenizer.php:309Advance $count tokens forward.
openDomain($domain)
Tokenizer.php:269Push a domain onto the stack (e.g. entering a quoted string or bracketed group) -- it becomes
- See
currentDomainuntilcloseDomainpops it.
| $domain | TokenDomain | |
| returns | void |
parentDomain()
Tokenizer.php:292| returns | null | TokenDomain | the domain enclosing currentDomain, or null if currently at the root |
rewind()
Tokenizer.php:349WARNING: this function won't rewind stream. You need to do it manually
| returns | void |
rootDomain()
Tokenizer.php:259| returns | TokenDomain | the bottom of the domain stack |
serialize($path, $serializer)
Tokenizer.php:436\MMO\core\interfaces\iSerializable::serialize -- only the root domain is persisted (grammar, not read progress)
setRootDomain($domain)
Tokenizer.php:254| $domain | TokenDomain | replaces the whole domain stack with just this one |
| returns | void |
setText($stream)
Tokenizer.php:85Set what to tokenize: a plain string (read whole, immediately), a stream resource (read in
- See
CHUNK_SIZEchunks as tokenizing progresses), or null (nothing -- e.g. to tokenize only via manual,addTextcalls).
| $stream | ||
| returns | ||
| throws | for any other type |
setToken($token)
Tokenizer.php:179Consume $token: record it as current, advance offset/line/col past it, and remove its text from the not-yet-tokenized buffer.
| $token | Token | |
| returns |
unserialize($data, $path, $instances)
Tokenizer.php:441\MMO\core\interfaces\iSerializable::unserialize -- rebuilds a fresh instance with the stored root domain
valid()
Tokenizer.php:363\Iterator::valid -- false once tokenizing has reached the end of the text
| returns | bool |
__construct($domain)
Tokenizer.php:43| $domain | TokenDomain | the top-level grammar (setRootDomain) |