TokenStream::expect()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2.0932

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 10
ccs 5
cts 7
cp 0.7143
rs 9.4285
cc 2
eloc 7
nc 2
nop 2
crap 2.0932
1
<?php
2
/**
3
 * @author Gerard van Helden <[email protected]>
4
 * @copyright Zicht Online <http://zicht.nl>
5
 */
6
7
namespace Zicht\Tool\Script;
8
9
/**
10
 * Wraps a list of tokens into an convenience class for matching and iterating the tokens
11
 */
12
class TokenStream
13
{
14
    protected $ptr = 0;
15
16
    /**
17
     * Create the tokenstream with the specified list of tokens.
18
     *
19
     * @param Token[] $tokenList
20
     * @param bool $skipWhitespace
21
     */
22 13
    public function __construct($tokenList, $skipWhitespace = true)
23
    {
24 13
        if ($skipWhitespace) {
25 13
            $callback = function (Token $token) {
26 12
                return !$token->match(Token::WHITESPACE);
27 13
            };
28 13
            $this->tokenList = array_values(array_filter($tokenList, $callback));
0 ignored issues
show
Bug introduced by
The property tokenList does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
29 13
        } else {
30
            $this->tokenList = $tokenList;
31
        }
32 13
    }
33
34
35
    /**
36
     * Advances the internal pointer
37
     *
38
     * @return void
39
     */
40 12
    public function next()
41
    {
42 12
        $this->ptr++;
43 12
    }
44
45
    /**
46
     * Checks if there is a next token
47
     *
48
     * @return bool
49
     */
50
    public function hasNext()
51
    {
52
        return $this->ptr < count($this->tokenList) - 1;
53
    }
54
55
56
    /**
57
     * Checks if there is a current token
58
     *
59
     * @return bool
60
     */
61 13
    public function valid()
62
    {
63 13
        return $this->ptr < count($this->tokenList);
64
    }
65
66
67
    /**
68
     * Returns the current token
69
     *
70
     * @return Token
71
     * @throws \UnexpectedValueException
72
     */
73 12
    public function current()
74
    {
75 12
        if (!isset($this->tokenList[$this->ptr])) {
76
            throw new \UnexpectedValueException("Unexpected input at offset {$this->ptr}, unexpected end of stream");
77
        }
78 12
        return $this->tokenList[$this->ptr];
79
    }
80
81
82
    /**
83
     * Returns the pointer in the stream
84
     *
85
     * @return int
86
     */
87
    public function key()
88
    {
89
        return $this->ptr;
90
    }
91
92
93
    /**
94
     * Checks if the current token matches the specified type and/or value
95
     *
96
     * @param string $type
97
     * @param string $value
98
     * @return boolean
99
     */
100 12
    public function match($type, $value = null)
101
    {
102 12
        return $this->current()->match($type, $value);
103
    }
104
105
106
    /**
107
     * Asserts the current token matches the specified value and/or type. Throws an exception if it doesn't
108
     *
109
     * @param string $type
110
     * @param string $value
111
     * @return Token
112
     *
113
     * @throws \UnexpectedValueException
114
     */
115 11
    public function expect($type, $value = null)
116
    {
117 11
        if (!$this->match($type, $value)) {
118
            $msg = "Unexpected token {$this->current()->type} '{$this->current()->value}', expected {$type}";
119
            throw new \UnexpectedValueException($msg);
120
        }
121 11
        $current = $this->current();
122 11
        $this->next();
123 11
        return $current;
124
    }
125
}