-
Notifications
You must be signed in to change notification settings - Fork 31
Expand file tree
/
Copy pathAbstractParser.php
More file actions
113 lines (95 loc) · 3.24 KB
/
AbstractParser.php
File metadata and controls
113 lines (95 loc) · 3.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
<?php
declare(strict_types=1);
namespace PHPCR\Util\CND\Parser;
use PHPCR\Util\CND\Exception\ParserException;
use PHPCR\Util\CND\Scanner\GenericToken;
use PHPCR\Util\CND\Scanner\GenericToken as Token;
use PHPCR\Util\CND\Scanner\TokenQueue;
/**
* Abstract base class for parsers.
*
* It implements helper functions for parsers:
*
* - checkToken - check if the next token matches
* - expectToken - expect the next token to match
* - checkAndExpectToken - check and then expect the next token to match
*
* @license http://www.apache.org/licenses Apache License Version 2.0, January 2004
* @license http://opensource.org/licenses/MIT MIT License
* @author Daniel Barsotti <daniel.barsotti@liip.ch>
*/
abstract class AbstractParser
{
protected TokenQueue $tokenQueue;
/**
* Check the next token without consuming it and return true if it matches the given type and data.
* If the data is not provided (equal to null) then only the token type is checked.
* Return false otherwise.
*/
protected function checkToken(int $type, ?string $data = null, bool $ignoreCase = false): bool
{
if ($this->tokenQueue->isEof()) {
return false;
}
$token = $this->tokenQueue->peek();
if ($token->getType() !== $type) {
return false;
}
if ($data && $token->getData() !== $data) {
if ($ignoreCase) {
return 0 !== strcasecmp($data, $token->getData());
}
return false;
}
return true;
}
/**
* Check if the token data is one of the elements of the data array.
*
* @param string[] $data
*/
protected function checkTokenIn(int $type, array $data, bool $ignoreCase = false): bool
{
foreach ($data as $d) {
if ($this->checkToken($type, $d, $ignoreCase)) {
return true;
}
}
return false;
}
/**
* Check if the next token matches the expected type and data. If it does, then consume and return it,
* otherwise throw an exception.
*
* @param int $type The expected token type
* @param string|null $data The expected token data or null
*
* @throws ParserException
*/
protected function expectToken(int $type, ?string $data = null): Token
{
$token = $this->tokenQueue->peek();
if (!$this->checkToken($type, $data)) {
throw new ParserException($this->tokenQueue, sprintf("Expected token [%s, '%s']", Token::getTypeName($type), $data));
}
\assert($token instanceof GenericToken);
$this->tokenQueue->next();
return $token;
}
/**
* Check if the next token matches the expected type and data. If it does, then consume it, otherwise
* return false.
*
* @param int $type The expected token type
* @param string|null $data The expected token data or null
*/
protected function checkAndExpectToken(int $type, ?string $data = null): false|Token
{
if ($this->checkToken($type, $data)) {
$token = $this->tokenQueue->peek();
$this->tokenQueue->next();
return $token;
}
return false;
}
}