Expression::getTokens()   D
last analyzed

Complexity

Conditions 20
Paths 24

Size

Total Lines 84
Code Lines 67

Duplication

Lines 8
Ratio 9.52 %

Code Coverage

Tests 60
CRAP Score 21.8529

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 8
loc 84
ccs 60
cts 72
cp 0.8333
rs 4.8263
cc 20
eloc 67
nc 24
nop 2
crap 21.8529

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
 * For licensing information, please see the LICENSE file accompanied with this file.
4
 *
5
 * @author Gerard van Helden <[email protected]>
6
 * @copyright 2012 Gerard van Helden <http://melp.nl>
7
 */
8
9
namespace Zicht\Tool\Script\Tokenizer;
10
11
use Zicht\Tool\Script\Token;
12
use Zicht\Tool\Script\TokenizerInterface;
13
14
/**
15
 * Tokenizer for expressions
16
 */
17
class Expression implements TokenizerInterface
18
{
19
    /**
20
     * @{inheritDoc}
21
     */
22 22
    public function getTokens($string, &$needle = 0)
23
    {
24 22
        $depth = 1;
25 22
        $ret = array();
26 22
        $len = strlen($string);
27 22
        while ($needle < $len) {
28 22
            $substr = substr($string, $needle);
29 22
            $before = $needle;
30
31 22
            if (preg_match('/^(==|=~|<=?|>=?|!=?|\?|:|\|\||&&|xor\b|or\b|and\b|\.|\[|\]|\(|\)|\+|-|\/|\*)/', $substr, $m)) {
32 21
                if ($m[0] == ')') {
33 18
                    $depth--;
34 18
                    if ($depth == 0) {
35 15
                        $ret[] = new Token(Token::EXPR_END, ')');
36 15
                        $needle++;
37 15
                        break;
38
                    }
39 13
                } elseif ($m[0] === '(') {
40 6
                    $depth++;
41 6
                }
42 13
                $ret[] = new Token(Token::OPERATOR, $m[0]);
43 13
                $needle += strlen($m[0]);
44 22 View Code Duplication
            } elseif (preg_match('/^(true|false|in|as|null)\b/', $substr, $m)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
45
                $ret[] = new Token(Token::KEYWORD, $m[0]);
46
                $needle += strlen($m[0]);
47 22
            } elseif (preg_match('/^[a-z_][\w]*/i', $substr, $m)) {
48 16
                $ret[] = new Token(Token::IDENTIFIER, $m[0]);
49 16
                $needle += strlen($m[0]);
50 22 View Code Duplication
            } elseif (preg_match('/^\s+/', $substr, $m)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
51 6
                $ret[] = new Token(Token::WHITESPACE, $m[0]);
52 6
                $needle += strlen($m[0]);
53 11
            } elseif (preg_match('/^([0-9]*.)?[0-9]+/', $substr, $m)) {
54 4
                $ret[] = new Token(Token::NUMBER, $m[0]);
55 4
                $needle += strlen($m[0]);
56 9
            } elseif (preg_match('/^[\?,]/', $substr, $m)) {
57 1
                $ret[] = new Token($m[0]);
58 1
                $needle++;
59 6
            } elseif ($string{$needle} == '"') {
60 5
                $strData = '';
61
62 5
                $escape = false;
63 5
                for ($j = $needle + 1; $j < $len; $j++) {
64 5
                    $ch = $string{$j};
65
66 5
                    if ($ch == '\\') {
67 2
                        $escape = true;
68 5
                    } elseif ($ch == '"') {
69 5
                        if ($escape) {
70
                            $escape = false;
71
                        } else {
72 5
                            $j++;
73 5
                            break;
74
                        }
75
                    } else {
76 5
                        if ($escape) {
77
                            switch ($ch) {
78 2
                                case 'n':
79
                                    $strData .= "\n";
80
                                    break;
81 2
                                case '\\':
82
                                    $strData .= "\\";
83
                                    break;
84 2
                                default:
85 2
                                    $strData .= '\\' . $ch;
86 2
                                    break;
87 2
                            }
88 2
                            $escape = false;
89 2
                        } else {
90 5
                            $strData .= $ch;
91
                        }
92
                    }
93 5
                }
94 5
                $ret[] = new Token(Token::STRING, $strData);
95 5
                $needle = $j;
96 5
            }
97 22
            if ($before === $needle) {
98
                // safety net.
99
                throw new \UnexpectedValueException(
100
                    "Unexpected input near token {$string{$needle}}, unsupported character ($string)"
101
                );
102
            }
103 22
        }
104 22
        return $ret;
105
    }
106
}
107