TokenReader   A
last analyzed

Complexity

Total Complexity 8

Size/Duplication

Total Lines 61
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 24
dl 0
loc 61
rs 10
c 0
b 0
f 0
wmc 8

4 Methods

Rating   Name   Duplication   Size   Complexity  
A read() 0 7 2
A __construct() 0 8 1
A matchEoiToken() 0 7 2
A matchSymbolToken() 0 11 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Remorhaz\UniLex\Lexer;
6
7
use Remorhaz\UniLex\IO\CharBufferInterface;
8
use Remorhaz\UniLex\Exception;
9
10
class TokenReader implements TokenReaderInterface
11
{
12
    private $buffer;
13
14
    private $matcher;
15
16
    private $isEnd = false;
17
18
    private $tokenFactory;
19
20
    public function __construct(
21
        CharBufferInterface $buffer,
22
        TokenMatcherInterface $matcher,
23
        TokenFactoryInterface $tokenFactory
24
    ) {
25
        $this->buffer = $buffer;
26
        $this->matcher = $matcher;
27
        $this->tokenFactory = $tokenFactory;
28
    }
29
30
    /**
31
     * @return Token
32
     * @throws Exception
33
     */
34
    public function read(): Token
35
    {
36
        $token = $this->buffer->isEnd()
37
            ? $this->matchEoiToken()
38
            : $this->matchSymbolToken();
39
        $this->buffer->finishToken($token);
40
        return $token;
41
    }
42
43
    /**
44
     * @return Token
45
     * @throws Exception
46
     */
47
    private function matchEoiToken(): Token
48
    {
49
        if ($this->isEnd) {
50
            throw new Exception("Buffer end reached");
51
        }
52
        $this->isEnd = true;
53
        return $this->tokenFactory->createEoiToken();
54
    }
55
56
    /**
57
     * @return Token
58
     * @throws Exception
59
     */
60
    private function matchSymbolToken(): Token
61
    {
62
        $result = $this->matcher->match($this->buffer, $this->tokenFactory);
63
        if ($result) {
64
            return $this->matcher->getToken();
65
        }
66
        $position = $this->buffer->getTokenPosition();
67
        if ($this->buffer->isEnd()) {
68
            throw new Exception("Unexpected end of input at position {$position->getFinishOffset()}");
69
        }
70
        throw new Exception("Unexpected character at position {$position->getFinishOffset()}");
71
    }
72
}
73