Lexer   A
last analyzed

Complexity

Total Complexity 7

Size/Duplication

Total Lines 53
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 2

Importance

Changes 0
Metric Value
dl 0
loc 53
c 0
b 0
f 0
wmc 7
lcom 0
cbo 2
rs 10

2 Methods

Rating   Name   Duplication   Size   Complexity  
A lex() 0 18 4
A matchToken() 0 14 3
1
<?php
2
3
namespace Netdudes\DataSourceryBundle\UQL;
4
5
use Netdudes\DataSourceryBundle\UQL\Exception\UqlLexerException;
6
7
/**
8
 * Class Lexer
9
 *
10
 * The Lexer component has the task of translating the user-typed syntax into
11
 * concrete Tokens with definite meanings in the language's syntax.
12
 *
13
 * @package Netdudes\NetdudesDataSourceryBundle\UQL
14
 */
15
class Lexer
16
{
17
    /**
18
     * Lex the input string by moving through it trying to match any of
19
     * the defined language tokens.
20
     *
21
     * @param $string
22
     *
23
     * @return array
24
     * @throws \Exception
25
     */
26
    public static function lex($string)
27
    {
28
        $tokens = [];
29
        $cursor = 0;
30
31
        while ($cursor < strlen($string)) {
32
            $result = static::matchToken($string, $cursor);
33
            if ($result === false) {
34
                throw new UqlLexerException('Can\'t parse at character ' . $cursor . ': "' . substr($string, $cursor, 50) . '[...]"');
35
            } elseif ($result['token'] != "T_WHITESPACE") {
36
                // We found a non-whitespace token. Store it.
37
                $tokens[] = $result;
38
            }
39
            $cursor += strlen($result['match']);
40
        }
41
42
        return $tokens;
43
    }
44
45
    /**
46
     * Tries to match any of the tokens to the current cursor position.
47
     *
48
     * @param $string
49
     * @param $cursor
50
     *
51
     * @return array|bool
52
     */
53
    public static function matchToken($string, $cursor)
54
    {
55
        $string = substr($string, $cursor);
56
        foreach (Tokens::$terminalTokens as $regex => $token) {
57
            if (preg_match($regex, $string, $matches)) {
58
                return [
59
                    'match' => $matches[1],
60
                    'token' => $token,
61
                ];
62
            }
63
        }
64
65
        return false;
66
    }
67
}
68