Item::offsetGet()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
/**
3
 * This file is part of PHP-Yacc package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
declare(strict_types=1);
9
10
namespace PhpYacc\Lalr;
11
12
use PhpYacc\Exception\LogicException;
13
use PhpYacc\Yacc\Production;
14
15
class Item implements \ArrayAccess, \IteratorAggregate
16
{
17
    /**
18
     * @var Production
19
     */
20
    protected $production;
21
22
    /**
23
     * @var int
24
     */
25
    protected $pos = 0;
26
27
    /**
28
     * Item constructor.
29
     *
30
     * @param Production $production
31
     * @param int        $offset
32
     */
33
    public function __construct(Production $production, int $offset)
34
    {
35
        \assert($offset >= 1);
36
        \assert($offset <= \count($production->body));
37
        $this->production = $production;
38
        $this->pos = $offset;
39
    }
40
41
    /**
42
     * @return \Generator
43
     */
44
    public function getIterator(): \Generator
45
    {
46
        for ($i = $this->pos, $l = \count($this->production->body); $i < $l; $i++) {
47
            yield $this->production->body[$i];
48
        }
49
    }
50
51
    /**
52
     * @param int $n
53
     *
54
     * @return Item
55
     */
56
    public function slice(int $n): self
57
    {
58
        return new self($this->production, $this->pos + $n);
59
    }
60
61
    /**
62
     * @param mixed $index
63
     *
64
     * @return bool
65
     */
66
    public function offsetExists($index)
67
    {
68
        return isset($this->production->body[$index + $this->pos]);
69
    }
70
71
    /**
72
     * @param mixed $index
73
     *
74
     * @throws LogicException
75
     *
76
     * @return \PhpYacc\Grammar\Symbol
77
     */
78
    public function offsetGet($index)
79
    {
80
        if (!$this->offsetExists($index)) {
81
            throw new LogicException("Offset $index does not exist");
82
        }
83
84
        return $this->production->body[$index + $this->pos];
85
    }
86
87
    /**
88
     * @param mixed $index
89
     * @param mixed $value
90
     *
91
     * @throws LogicException
92
     */
93
    public function offsetSet($index, $value)
94
    {
95
        throw new LogicException('Not supported');
96
    }
97
98
    /**
99
     * @param mixed $index
100
     *
101
     * @throws LogicException
102
     *
103
     * @return void
104
     */
105
    public function offsetUnset($index)
106
    {
107
        throw new LogicException('Not supported');
108
    }
109
110
    /**
111
     * @return bool
112
     */
113
    public function isHeadItem(): bool
114
    {
115
        return $this->pos === 1;
116
    }
117
118
    /**
119
     * @return bool
120
     */
121
    public function isTailItem(): bool
122
    {
123
        return $this->pos === \count($this->production->body);
124
    }
125
126
    /**
127
     * @return Production
128
     */
129
    public function getProduction(): Production
130
    {
131
        return $this->production;
132
    }
133
134
    /**
135
     * @return int
136
     */
137
    public function getPos(): int
138
    {
139
        return $this->pos;
140
    }
141
142
    /**
143
     * @return string
144
     */
145
    public function __toString()
146
    {
147
        $result = '('.$this->production->num.')';
148
        for ($i = 0, $l = \count($this->production->body); $i < $l; $i++) {
149
            if ($i === 1) {
150
                $result .= ' :';
151
            }
152
153
            if ($i === $this->pos) {
154
                $result .= ' .';
155
            }
156
157
            $result .= ' '.$this->production->body[$i]->name;
158
        }
159
160
        if ($i === 1) {
161
            $result .= ' :';
162
        }
163
164
        if ($i === $this->pos) {
165
            $result .= ' .';
166
        }
167
168
        return $result;
169
    }
170
}
171