Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ResetPosition doesn't work by token position #53

Open
jaapio opened this issue Jul 31, 2021 · 2 comments
Open

ResetPosition doesn't work by token position #53

jaapio opened this issue Jul 31, 2021 · 2 comments

Comments

@jaapio
Copy link

jaapio commented Jul 31, 2021

When you have a lexer with formats containing multiple characters the reset position doesn't work as expected. Position is an internal pointer to the position of the lexer in the tokens array and not to the position as exposed in the token itself.

private function parseNamedReference(): string
{
$startPosition = $this->lexer->token['position'];
while ($this->lexer->moveNext()) {
}
�
$this->lexer->resetPosition($startPosition);
$this->lexer->moveNext();
$this->lexer->moveNext();
} 

In the example above I would expect that a resetPosition would throw me back to the position on method entry. But since my tokens do have multiple characters, this doesn't work.
A fix would be to set the index of each token. Like this:

$this->tokens[$match[1]] = [
'value' => $match[0],
'type' => $type,
'position' => $match[1],
];

However, this would break the step process using $this->position++

another solution could be to have a map between the token position and location in the tokens array. This would have an impact on the memory usage since it would require an extra array of integers.

I would be happy to provide a patch to fix this issue, but I would like to have some guidance on what is expected in this library. Any change in resetPosition would be a breaking change as it would change the behavior of this lib.

@jaapio
Copy link
Author

jaapio commented Aug 1, 2021

My workaround for now:

    public function resetPosition($position = 0)
    {
        parent::resetPosition($this->tokenPositions[$position]);
    }

    protected function scan($input)
    {
        parent::scan($input); // TODO: Change the autogenerated stub

        $class = new \ReflectionClass(AbstractLexer::class);
        $property = $class->getProperty('tokens');
        $property->setAccessible(true);
        $tokens = $property->getValue($this);

        $this->tokenPositions = array_flip(array_column($tokens, 'position'));
    }

@instabledesign
Copy link
Contributor

Hi 👋
is this PR #12 should solve your problem ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants