mirror of
https://github.com/halaxa/json-machine.git
synced 2025-01-17 04:58:16 +01:00
Stateful Lexer
This commit is contained in:
parent
f5492d7223
commit
955a90f637
@ -9,6 +9,10 @@ class Lexer implements \IteratorAggregate, PositionAware
|
||||
/** @var iterable */
|
||||
private $jsonChunks;
|
||||
|
||||
private $inString = false;
|
||||
private $tokenBuffer = '';
|
||||
private $escaping = false;
|
||||
|
||||
/**
|
||||
* @param iterable<string> $jsonChunks
|
||||
*/
|
||||
@ -31,9 +35,9 @@ class Lexer implements \IteratorAggregate, PositionAware
|
||||
$tokenBoundaries = $this->tokenBoundaries();
|
||||
$colonCommaBracket = $this->colonCommaBracketTokenBoundaries();
|
||||
|
||||
$inString = false;
|
||||
$tokenBuffer = '';
|
||||
$escaping = false;
|
||||
$inString = $this->inString;
|
||||
$tokenBuffer = $this->tokenBuffer;
|
||||
$escaping = $this->escaping;
|
||||
|
||||
foreach ($this->jsonChunks as $jsonChunk) {
|
||||
$bytesLength = strlen($jsonChunk);
|
||||
@ -75,9 +79,10 @@ class Lexer implements \IteratorAggregate, PositionAware
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($tokenBuffer != '') {
|
||||
yield $tokenBuffer;
|
||||
}
|
||||
|
||||
$this->inString = $inString;
|
||||
$this->tokenBuffer = $tokenBuffer;
|
||||
$this->escaping = $escaping;
|
||||
}
|
||||
|
||||
private function tokenBoundaries()
|
||||
|
23
src/QueueChunks.php
Normal file
23
src/QueueChunks.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
|
||||
namespace JsonMachine;
|
||||
|
||||
use Exception;
|
||||
use Traversable;
|
||||
|
||||
class QueueChunks implements \IteratorAggregate
|
||||
{
|
||||
private $queue = [];
|
||||
|
||||
public function push(string $jsonChunk)
|
||||
{
|
||||
$this->queue[] = $jsonChunk;
|
||||
}
|
||||
|
||||
public function getIterator()
|
||||
{
|
||||
yield from $this->queue;
|
||||
$this->queue = [];
|
||||
}
|
||||
}
|
15
test/JsonMachineTest/FollowUpParserTest.php
Normal file
15
test/JsonMachineTest/FollowUpParserTest.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace JsonMachineTest;
|
||||
|
||||
use JsonMachine\Lexer;
|
||||
use JsonMachine\QueueChunks;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class FollowUpParserTest extends TestCase
|
||||
{
|
||||
public function testParses()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ namespace JsonMachineTest;
|
||||
use JsonMachine\DebugLexer;
|
||||
use JsonMachine\Lexer;
|
||||
use JsonMachine\Exception;
|
||||
use JsonMachine\QueueChunks;
|
||||
use JsonMachine\StreamChunks;
|
||||
use JsonMachine\StringChunks;
|
||||
|
||||
@ -23,8 +24,8 @@ class LexerTest extends \PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testCorrectlyYieldsZeroToken($lexerClass)
|
||||
{
|
||||
$data = ['0'];
|
||||
$expected = ['0'];
|
||||
$data = ['[0]'];
|
||||
$expected = ['[', '0', ']'];
|
||||
$this->assertEquals($expected, iterator_to_array(new $lexerClass(new \ArrayIterator($data))));
|
||||
|
||||
$stream = fopen('data://text/plain,{"value":0}', 'r');
|
||||
@ -37,8 +38,8 @@ class LexerTest extends \PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testGeneratesTokens($lexerClass)
|
||||
{
|
||||
$data = ['{}[],:null,"string" false:', 'true,1,100000,1.555{-56]"","\\""'];
|
||||
$expected = ['{','}','[',']',',',':','null',',','"string"','false',':','true',',','1',',','100000',',','1.555','{','-56',']','""',',','"\\""'];
|
||||
$data = ['{}[],:null,"string" false:', 'true,1,100000,1.555{-56]"","\\""]'];
|
||||
$expected = ['{','}','[',']',',',':','null',',','"string"','false',':','true',',','1',',','100000',',','1.555','{','-56',']','""',',','"\\""',']'];
|
||||
$this->assertEquals($expected, iterator_to_array(new $lexerClass(new \ArrayIterator($data))));
|
||||
}
|
||||
|
||||
@ -144,6 +145,21 @@ class LexerTest extends \PHPUnit_Framework_TestCase
|
||||
}
|
||||
}
|
||||
|
||||
public function testRepeatedlyParsesModifiedQueue()
|
||||
{
|
||||
$queue = new QueueChunks();
|
||||
$lexer = new Lexer($queue);
|
||||
|
||||
$queue->push('[1,2,4');
|
||||
$this->assertEquals(['[', '1', ',', '2', ','], iterator_to_array($lexer));
|
||||
|
||||
$queue->push('2,"some ');
|
||||
$this->assertEquals(['42', ','], iterator_to_array($lexer));
|
||||
|
||||
$queue->push('string"]');
|
||||
$this->assertEquals(['"some string"', ']'], iterator_to_array($lexer));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $formattedJsonFilePath
|
||||
* @dataProvider dataProvidesLocationalData
|
||||
|
Loading…
x
Reference in New Issue
Block a user