Completed
Push — master ( 82eb41...4f6b0a )
by Alexander
03:49
created

Lexer::tokenize()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 25
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 25
ccs 18
cts 18
cp 1
rs 8.8571
cc 3
eloc 16
nc 3
nop 1
crap 3
1
<?php
2
namespace Xiag\Rql\Parser;
3
4
use Xiag\Rql\Parser\Exception\SyntaxErrorException;
5
6
class Lexer
7
{
8
    /**
9
     * @var SubLexerInterface
10
     */
11
    protected $subLexer;
12
13
    /**
14
     * @param SubLexerInterface $subLexer
15
     */
16 85
    public function __construct(SubLexerInterface $subLexer = null)
17
    {
18 85
        $this->subLexer = $subLexer ?: static::createDefaultSubLexer();
19 85
    }
20
21
    /**
22
     * @param SubLexerInterface $subLexer
23
     * @return $this
24
     * @codeCoverageIgnore
25
     */
26
    public function setSubLexer(SubLexerInterface $subLexer)
27
    {
28
        $this->subLexer = $subLexer;
29
        return $this;
30
    }
31
32
    /**
33
     * @return SubLexerInterface
34
     * @codeCoverageIgnore
35
     */
36
    public function getSubLexer()
37
    {
38
        return $this->subLexer;
39
    }
40
41
    /**
42
     * @return SubLexerInterface
43
     */
44 85
    public static function createDefaultSubLexer()
45
    {
46 85
        return (new SubLexerChain())
47 85
            ->addSubLexer(new SubLexer\ConstantSubLexer())
48 85
            ->addSubLexer(new SubLexer\PunctuationSubLexer())
49 85
            ->addSubLexer(new SubLexer\FiqlOperatorSubLexer())
50 85
            ->addSubLexer(new SubLexer\RqlOperatorSubLexer())
51 85
            ->addSubLexer(new SubLexer\TypeSubLexer())
52
53 85
            ->addSubLexer(new SubLexer\GlobSubLexer())
54 85
            ->addSubLexer(new SubLexer\StringSubLexer())
55 85
            ->addSubLexer(new SubLexer\DatetimeSubLexer())
56 85
            ->addSubLexer(new SubLexer\NumberSubLexer())
57
58 85
            ->addSubLexer(new SubLexer\SortSubLexer());
59
    }
60
61
    /**
62
     * @param string $code
63
     * @return TokenStream
64
     * @throws SyntaxErrorException
65
     */
66 85
    public function tokenize($code)
67
    {
68 85
        $end    = strlen($code);
69 85
        $cursor = 0;
70 85
        $tokens = [];
71
72 85
        while ($cursor < $end) {
73 85
            $token = $this->subLexer->getTokenAt($code, $cursor);
74 85
            if ($token === null) {
75 2
                throw new SyntaxErrorException(
76 2
                    sprintf(
77 2
                        'Invalid character "%s" at position %d',
78 2
                        $code[$cursor],
79
                        $cursor
80 2
                    )
81 2
                );
82
            }
83
84 85
            $tokens[] = $token;
85 85
            $cursor = $token->getEnd();
86 85
        }
87 81
        $tokens[] = new Token(Token::T_END, '', $cursor, $cursor);
88
89 81
        return new TokenStream($tokens);
90
    }
91
}
92