Lexer::tokenize()   C
last analyzed

Complexity

Conditions 15
Paths 23

Size

Total Lines 73

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 41
CRAP Score 15.2889

Importance

Changes 0
Metric Value
dl 0
loc 73
ccs 41
cts 46
cp 0.8913
rs 5.3224
c 0
b 0
f 0
cc 15
nc 23
nop 1
crap 15.2889

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace uuf6429\ExpressionLanguage;
4
5
use Symfony\Component\ExpressionLanguage\Token;
6
use Symfony\Component\ExpressionLanguage\SyntaxError;
7
8
class Lexer extends \Symfony\Component\ExpressionLanguage\Lexer
9
{
10
    /**
11
     * {@inheritdoc}
12
     */
13 38
    public function tokenize($expression)
14
    {
15 38
        $expression = str_replace(array("\r", "\n", "\t", "\v", "\f"), ' ', $expression);
16 38
        $cursor = 0;
17 38
        $tokens = array();
18 38
        $brackets = array();
19 38
        $end = strlen($expression);
20
21 38
        while ($cursor < $end) {
22 38
            if (' ' === $expression[$cursor]) {
23 11
                ++$cursor;
24
25 11
                continue;
26
            }
27
28 38
            if (preg_match('/\d+(?:\.\d+)?/A', $expression, $match, null, $cursor)) {
29
                // numbers
30 11
                $number = (float) $match[0]; // floats
31 11
                if ($number <= PHP_INT_MAX && ctype_digit($match[0])) {
32 11
                    $number = (int) $match[0]; // integers lower than the maximum
33
                }
34 11
                $tokens[] = new Token(Token::NUMBER_TYPE, $number, $cursor + 1);
35 11
                $cursor += strlen($match[0]);
36 36
            } elseif (false !== strpos('([{', $expression[$cursor])) {
37
                // opening bracket
38 11
                $brackets[] = array($expression[$cursor], $cursor);
39
40 11
                $tokens[] = new Token(Token::PUNCTUATION_TYPE, $expression[$cursor], $cursor + 1);
41 11
                ++$cursor;
42 36
            } elseif (false !== strpos(')]}', $expression[$cursor])) {
43
                // closing bracket
44 11
                if (empty($brackets)) {
45
                    throw new SyntaxError(sprintf('Unexpected "%s"', $expression[$cursor]), $cursor);
46
                }
47
48 11
                [$expect, $cur] = array_pop($brackets);
0 ignored issues
show
Bug introduced by
The variable $expect does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $cur does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
49 11
                if ($expression[$cursor] !== strtr($expect, '([{', ')]}')) {
50
                    throw new SyntaxError(sprintf('Unclosed "%s"', $expect), $cur);
51
                }
52
53 11
                $tokens[] = new Token(Token::PUNCTUATION_TYPE, $expression[$cursor], $cursor + 1);
54 11
                ++$cursor;
55 36
            } elseif (preg_match('/"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\'/A', $expression, $match, null, $cursor)) {
56
                // strings
57 9
                $tokens[] = new Token(Token::STRING_TYPE, stripcslashes(substr($match[0], 1, -1)), $cursor + 1);
58 9
                $cursor += strlen($match[0]);
59 32
            } elseif (preg_match('/\->|not in(?=[\s(])|\!\=\=|not(?=[\s(])|and(?=[\s(])|\=\=\=|\>\=|or(?=[\s(])|\<\=|\*\*|\.\.|in(?=[\s(])|&&|\|\||matches|\=\=|\!\=|\*|~|%|\/|\>|\||\!|\^|&|\+|\<|\-/A', $expression, $match, null, $cursor)) {
60
                // operators
61 13
                $tokens[] = new Token(Token::OPERATOR_TYPE, $match[0], $cursor + 1);
62 13
                $cursor += strlen($match[0]);
63 26
            } elseif (false !== strpos('.,?:', $expression[$cursor])) {
64
                // punctuation
65 16
                $tokens[] = new Token(Token::PUNCTUATION_TYPE, $expression[$cursor], $cursor + 1);
66 16
                ++$cursor;
67 25
            } elseif (preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/A', $expression, $match, null, $cursor)) {
68
                // names
69 25
                $tokens[] = new Token(Token::NAME_TYPE, $match[0], $cursor + 1);
70 25
                $cursor += strlen($match[0]);
71
            } else {
72
                // unlexable
73
                throw new SyntaxError(sprintf('Unexpected character "%s"', $expression[$cursor]), $cursor);
74
            }
75
        }
76
77 38
        $tokens[] = new Token(Token::EOF_TYPE, null, $cursor + 1);
78
79 38
        if (!empty($brackets)) {
80
            [$expect, $cur] = array_pop($brackets);
81
            throw new SyntaxError(sprintf('Unclosed "%s"', $expect), $cur);
82
        }
83
84 38
        return new TokenStream($tokens);
85
    }
86
}
87