Parser::callback()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 5
ccs 3
cts 3
cp 1
crap 1
rs 10
c 1
b 1
f 0
1
<?php
2
3
namespace Vanderlee\Comprehend\Parser;
4
5
use InvalidArgumentException;
6
use Vanderlee\Comprehend\Core\Context;
7
use Vanderlee\Comprehend\Match\Failure;
8
use Vanderlee\Comprehend\Match\AbstractMatch;
9
use Vanderlee\Comprehend\Match\Success;
10
use Vanderlee\Comprehend\Parser\Output\AssignTrait;
11
use Vanderlee\Comprehend\Parser\Output\ResultTrait;
12
use Vanderlee\Comprehend\Parser\Output\TokenTrait;
13
14
abstract class Parser
15
{
16
    use ResultTrait, TokenTrait, AssignTrait;
17
18
    /**
19
     * List of callbacks to call when this parser has matched a part of the full parse.
20
     *
21
     * @var callable[]
22
     */
23
    private $callbacks = [];
24
25 85
    protected static function parseCharacter($character)
26
    {
27 85
        if ($character === '' || $character === null) {
28 4
            throw new InvalidArgumentException('Empty argument');
29
        }
30
31 82
        if (is_int($character)) {
32 11
            return chr($character);
33 81
        } elseif (mb_strlen($character) > 1) {
34 4
            throw new InvalidArgumentException('Non-character argument');
35
        }
36
37 78
        return $character;
38
    }
39
40
    /**
41
     * Match the input with this parser, starting from the offset position.
42
     *
43
     * @param string $input
44
     * @param int $offset
45
     * @param Context $context
46
     *
47
     * @return AbstractMatch
48
     */
49
    abstract protected function parse(&$input, $offset, Context $context);
50
51
    /**
52
     * @param string $input
53
     * @param int $offset
54
     *
55
     * @return AbstractMatch;
56
     */
57 513
    public function match($input, $offset = 0)
58
    {
59 513
        if ($offset < 0) {
60 1
            throw new InvalidArgumentException('Negative offset');
61
        }
62
63 513
        return $this->parse($input, $offset, new Context())->resolve();
64
    }
65
66 35
    public function __invoke($input, $offset = 0)
67
    {
68 35
        return $this->match($input, $offset);
69
    }
70
71
    /**
72
     * Create a match.
73
     *
74
     * @param bool $success
75
     * @param string $input
76
     * @param int $offset
77
     * @param int $length
78
     * @param Success[]|Success $successes
79
     *
80
     * @return AbstractMatch
81
     */
82 334
    protected function makeMatch($success, &$input, $offset, $length = 0, &$successes = [])
83
    {
84 334
        return $success
85 278
            ? $this->success($input, $offset, $length, $successes)
86 334
            : $this->failure($input, $offset);
87
    }
88
89
    /**
90
     * Create a successful match.
91
     *
92
     * @param string $input
93
     * @param int $offset
94
     * @param int $length
95
     * @param Success[]|Success $successes
96
     *
97
     * @return Success
98
     */
99 401
    protected function success($input, $offset, $length = 0, &$successes = [])
100
    {
101 401
        $successes = is_array($successes)
102 401
            ? $successes
103 401
            : [$successes];
104
105 401
        $success = new Success($length, $successes);
106
107
        // ResultTrait
108 401
        $success->addResultCallback(function (&$results) use ($input, $offset, $length) {
109 145
            $text = substr($input, $offset, $length);
110
111 145
            $this->resolveResultCallbacks($results, $text);
112 401
        });
113
114
        // AssignTrait
115 401
        $callbacks = $this->callbacks;
116 401
        $success->addCustomCallback(function () use ($input, $offset, $length, $callbacks) {
117 371
            $text = substr($input, $offset, $length);
118
119 371
            $this->resolveAssignCallbacks($text);
120
121 371
            foreach ($callbacks as $callback) {
122 1
                $callback($text, $input, $offset, $length);
123
            }
124 401
        });
125
126
        // TokenTrait
127 401
        $success->setTokenCallback(function (&$children) use ($input, $offset, $length) {
128 8
            return $this->resolveToken($input, $offset, $length, $children, get_class($this));
129 401
        });
130
131 401
        return $success;
132
    }
133
134
    /**
135
     * Create a failed match.
136
     *
137
     * @param string $input
138
     * @param int $offset
139
     * @param int $length
140
     *
141
     * @return Failure
142
     */
143 279
    protected function failure(&$input, $offset, $length = 0)
0 ignored issues
show
Unused Code introduced by
The parameter $input is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

143
    protected function failure(/** @scrutinizer ignore-unused */ &$input, $offset, $length = 0)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $offset is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

143
    protected function failure(&$input, /** @scrutinizer ignore-unused */ $offset, $length = 0)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
144
    {
145 279
        return new Failure($length);
146
    }
147
148
    /**
149
     * Assign a function to be called if (and only if) this parser matched successfully as part of the whole syntax.
150
     *
151
     * @param callable $callback
152
     *
153
     * @return $this
154
     */
155 1
    public function callback(callable $callback)
156
    {
157 1
        $this->callbacks[] = $callback;
158
159 1
        return $this;
160
    }
161
162
    abstract public function __toString();
163
}
164