From 1c25c679b2aba0d94abf1791d32b3450de8737c3 Mon Sep 17 00:00:00 2001 From: Nathan Bishop Date: Wed, 29 May 2019 13:38:00 +1000 Subject: [PATCH] Add locational information about a lexeme's position with a formatted json stream/file --- src/Lexer.php | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/src/Lexer.php b/src/Lexer.php index dd3f981..c2df3bf 100644 --- a/src/Lexer.php +++ b/src/Lexer.php @@ -8,6 +8,8 @@ class Lexer implements \IteratorAggregate private $bytesIterator; private $position = 0; + private $line = 1; + private $column = 0; /** * @param \Traversable $bytesIterator @@ -16,7 +18,7 @@ class Lexer implements \IteratorAggregate { $this->bytesIterator = $bytesIterator; } - + /** * @return \Generator */ @@ -25,6 +27,7 @@ class Lexer implements \IteratorAggregate $inString = false; $tokenBuffer = ''; $isEscaping = false; + $width = 0; ${' '} = 0; ${"\n"} = 0; @@ -42,29 +45,37 @@ class Lexer implements \IteratorAggregate for ($i = 0; $i < $bytesLength; ++$i) { $byte = $bytes[$i]; ++$this->position; - if ($inString) { if ($byte === '"' && !$isEscaping) { $inString = false; } $isEscaping = ($byte =='\\' && !$isEscaping); $tokenBuffer .= $byte; + $width++; continue; } if (isset($$byte)) { + $this->column++; if ($tokenBuffer !== '') { yield $tokenBuffer; + $this->column += $width; $tokenBuffer = ''; + $width = 0; } if ($$byte) { // is not whitespace yield $byte; + // track line number and reset column for each newline + } elseif ($byte === "\r" || $byte === "\n") { + $this->line++; + $this->column = 0; } } else { if ($byte === '"') { $inString = true; } $tokenBuffer .= $byte; + $width++; } } } @@ -80,4 +91,20 @@ class Lexer implements \IteratorAggregate { return $this->position; } + + /** + * @return integer The line number of the lexeme currently being processed (index starts at one). + */ + public function getLine() + { + return $this->line; + } + + /** + * @return integer The, currently being processed, lexeme's position within the line (index starts at one). + */ + public function getColumn() + { + return $this->column; + } }