wikipeg 2.0.5 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/VERSION +1 -1
- package/bin/wikipeg +18 -0
- package/lib/compiler/language/javascript.js +8 -2
- package/lib/compiler/language/php.js +15 -10
- package/lib/compiler/passes/ast-to-code.js +61 -18
- package/lib/parser.js +2 -0
- package/lib/peg.js +1 -1
- package/lib/runtime/template.js +1 -3
- package/lib/runtime/template.php +61 -47
- package/package.json +47 -47
- package/src/DefaultTracer.php +61 -60
- package/src/Expectation.php +48 -46
- package/src/InternalError.php +1 -1
- package/src/Location.php +33 -32
- package/src/LocationRange.php +32 -30
- package/src/PEGParserBase.php +298 -277
- package/src/SyntaxError.php +30 -27
- package/src/Tracer.php +2 -2
- package/CHANGELOG.md +0 -433
package/src/PEGParserBase.php
CHANGED
|
@@ -1,282 +1,303 @@
|
|
|
1
1
|
<?php
|
|
2
2
|
|
|
3
|
-
namespace WikiPEG;
|
|
3
|
+
namespace Wikimedia\WikiPEG;
|
|
4
4
|
|
|
5
5
|
abstract class PEGParserBase {
|
|
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
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
6
|
+
protected static $FAILED;
|
|
7
|
+
protected static $UNDEFINED;
|
|
8
|
+
protected $currPos;
|
|
9
|
+
protected $savedPos;
|
|
10
|
+
protected $input;
|
|
11
|
+
protected $inputLength;
|
|
12
|
+
protected $options;
|
|
13
|
+
protected $cache;
|
|
14
|
+
|
|
15
|
+
/** @var array<int,array{line:int,column:int,seenCR:bool}> */
|
|
16
|
+
protected $posDetailsCache;
|
|
17
|
+
protected $maxFailPos;
|
|
18
|
+
protected $maxFailExpected;
|
|
19
|
+
|
|
20
|
+
/** @var array Associative arrays of expectation info */
|
|
21
|
+
protected $expectations;
|
|
22
|
+
|
|
23
|
+
/** @var Expectation[] */
|
|
24
|
+
private $expectationCache;
|
|
25
|
+
|
|
26
|
+
/** @var Tracer */
|
|
27
|
+
protected $tracer;
|
|
28
|
+
|
|
29
|
+
public function __construct() {
|
|
30
|
+
if ( !self::$FAILED ) {
|
|
31
|
+
self::$FAILED = new \stdClass;
|
|
32
|
+
}
|
|
33
|
+
if ( !self::$UNDEFINED ) {
|
|
34
|
+
self::$UNDEFINED = new \stdClass;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
protected function traceCall( $parseFunc, $name, $argNames, $args ) {
|
|
39
|
+
$argMap = [];
|
|
40
|
+
foreach ( $args as $i => $argValue ) {
|
|
41
|
+
$argMap[$argNames[$i]] = $argValue;
|
|
42
|
+
}
|
|
43
|
+
$startPos = $this->currPos;
|
|
44
|
+
$this->tracer->trace( [
|
|
45
|
+
'type' => 'rule.enter',
|
|
46
|
+
'rule' => $name,
|
|
47
|
+
'location' => $this->computeLocation( $startPos, $startPos ),
|
|
48
|
+
'args' => $argMap
|
|
49
|
+
] );
|
|
50
|
+
$result = call_user_func_array( $parseFunc, $args );
|
|
51
|
+
if ( $result !== self::$FAILED ) {
|
|
52
|
+
$this->tracer->trace( [
|
|
53
|
+
'type' => 'rule.match',
|
|
54
|
+
'rule' => $name,
|
|
55
|
+
'location' => $this->computeLocation( $startPos, $this->currPos ),
|
|
56
|
+
] );
|
|
57
|
+
} else {
|
|
58
|
+
$this->tracer->trace( [
|
|
59
|
+
'type' => 'rule.fail',
|
|
60
|
+
'rule' => $name,
|
|
61
|
+
'result' => $result,
|
|
62
|
+
'location' => $this->computeLocation( $startPos, $startPos )
|
|
63
|
+
] );
|
|
64
|
+
}
|
|
65
|
+
return $result;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
protected function text() {
|
|
69
|
+
return substr( $this->input, $this->savedPos, $this->currPos - $this->savedPos );
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
protected function location() {
|
|
73
|
+
return $this->computeLocation( $this->savedPos, $this->currPos );
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* @param string $description
|
|
78
|
+
* @return never
|
|
79
|
+
*/
|
|
80
|
+
protected function expected( $description ) {
|
|
81
|
+
throw $this->buildException(
|
|
82
|
+
null,
|
|
83
|
+
[ [ 'type' => "other", 'description' => $description ] ],
|
|
84
|
+
$this->text(),
|
|
85
|
+
$this->computeLocation( $this->savedPos, $this->currPos )
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* @param string $message
|
|
91
|
+
* @return never
|
|
92
|
+
*/
|
|
93
|
+
protected function error( $message ) {
|
|
94
|
+
throw $this->buildException(
|
|
95
|
+
$message,
|
|
96
|
+
null,
|
|
97
|
+
$this->text(),
|
|
98
|
+
$this->computeLocation( $this->savedPos, $this->currPos )
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
public static function charAt( $s, $byteOffset ) {
|
|
103
|
+
if ( !isset( $s[$byteOffset] ) ) {
|
|
104
|
+
return '';
|
|
105
|
+
}
|
|
106
|
+
$char = $s[$byteOffset];
|
|
107
|
+
$byte1 = ord( $char );
|
|
108
|
+
if ( ( $byte1 & 0xc0 ) === 0xc0 ) {
|
|
109
|
+
$char .= $s[$byteOffset + 1];
|
|
110
|
+
}
|
|
111
|
+
if ( ( $byte1 & 0xe0 ) === 0xe0 ) {
|
|
112
|
+
$char .= $s[$byteOffset + 2];
|
|
113
|
+
}
|
|
114
|
+
if ( ( $byte1 & 0xf0 ) === 0xf0 ) {
|
|
115
|
+
$char .= $s[$byteOffset + 3];
|
|
116
|
+
}
|
|
117
|
+
return $char;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
public static function charsAt( $s, $byteOffset, $numChars ) {
|
|
121
|
+
$ret = '';
|
|
122
|
+
for ( $i = 0; $i < $numChars; $i++ ) {
|
|
123
|
+
$ret .= self::consumeChar( $s, $byteOffset );
|
|
124
|
+
}
|
|
125
|
+
return $ret;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
public static function consumeChar( $s, &$byteOffset ) {
|
|
129
|
+
if ( !isset( $s[$byteOffset] ) ) {
|
|
130
|
+
return '';
|
|
131
|
+
}
|
|
132
|
+
$char = $s[$byteOffset++];
|
|
133
|
+
$byte1 = ord( $char );
|
|
134
|
+
if ( ( $byte1 & 0xc0 ) === 0xc0 ) {
|
|
135
|
+
$char .= $s[$byteOffset++];
|
|
136
|
+
}
|
|
137
|
+
if ( ( $byte1 & 0xe0 ) === 0xe0 ) {
|
|
138
|
+
$char .= $s[$byteOffset++];
|
|
139
|
+
}
|
|
140
|
+
if ( ( $byte1 & 0xf0 ) === 0xf0 ) {
|
|
141
|
+
$char .= $s[$byteOffset++];
|
|
142
|
+
}
|
|
143
|
+
return $char;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
public static function &newRef( $value ) {
|
|
147
|
+
return $value;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* @param int $pos
|
|
152
|
+
* @return array{line:int,column:int,seenCR:bool}
|
|
153
|
+
*/
|
|
154
|
+
protected function computePosDetails( $pos ) {
|
|
155
|
+
if ( isset( $this->posDetailsCache[$pos] ) ) {
|
|
156
|
+
return $this->posDetailsCache[$pos];
|
|
157
|
+
}
|
|
158
|
+
$p = $pos - 1;
|
|
159
|
+
while ( !isset( $this->posDetailsCache[$p] ) ) {
|
|
160
|
+
$p--;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
$details = $this->posDetailsCache[$p];
|
|
164
|
+
|
|
165
|
+
while ( $p < $pos ) {
|
|
166
|
+
$ch = self::charAt( $this->input, $p );
|
|
167
|
+
if ( $ch === "\n" ) {
|
|
168
|
+
if ( !$details['seenCR'] ) { $details['line']++;
|
|
169
|
+
}
|
|
170
|
+
$details['column'] = 1;
|
|
171
|
+
$details['seenCR'] = false;
|
|
172
|
+
} elseif ( $ch === "\r" || $ch === "\u2028" || $ch === "\u2029" ) {
|
|
173
|
+
$details['line']++;
|
|
174
|
+
$details['column'] = 1;
|
|
175
|
+
$details['seenCR'] = true;
|
|
176
|
+
} else {
|
|
177
|
+
$details['column']++;
|
|
178
|
+
$details['seenCR'] = false;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
$p++;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
$this->posDetailsCache[$pos] = $details;
|
|
185
|
+
return $details;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
protected function computeLocation( $startPos, $endPos ) {
|
|
189
|
+
if ( $endPos > $this->inputLength ) {
|
|
190
|
+
$endPos--;
|
|
191
|
+
}
|
|
192
|
+
$startPosDetails = $this->computePosDetails( $startPos );
|
|
193
|
+
$endPosDetails = $this->computePosDetails( $endPos );
|
|
194
|
+
|
|
195
|
+
return new LocationRange(
|
|
196
|
+
$startPos,
|
|
197
|
+
$startPosDetails['line'],
|
|
198
|
+
$startPosDetails['column'],
|
|
199
|
+
$endPos,
|
|
200
|
+
$endPosDetails['line'],
|
|
201
|
+
$endPosDetails['column']
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
protected function fail( $expected ) {
|
|
206
|
+
if ( $this->currPos < $this->maxFailPos ) {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if ( $this->currPos > $this->maxFailPos ) {
|
|
211
|
+
$this->maxFailPos = $this->currPos;
|
|
212
|
+
$this->maxFailExpected = [];
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
$this->maxFailExpected[] = $expected;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* @param array<int|array{type:string,value?:?string,description:string}> $expected
|
|
220
|
+
* @return Expectation[]
|
|
221
|
+
*/
|
|
222
|
+
private function expandExpectations( $expected ) {
|
|
223
|
+
$expanded = [];
|
|
224
|
+
foreach ( $expected as $index ) {
|
|
225
|
+
if ( is_int( $index ) ) {
|
|
226
|
+
if ( !isset( $this->expectationCache[$index] ) ) {
|
|
227
|
+
$this->expectationCache[$index] = new Expectation( $this->expectations[$index] );
|
|
228
|
+
}
|
|
229
|
+
$expanded[] = $this->expectationCache[$index];
|
|
230
|
+
} else {
|
|
231
|
+
$expanded[] = new Expectation( $index );
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return $expanded;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
private function buildMessage( $expected, $found ) {
|
|
238
|
+
$expectedDescs = [];
|
|
239
|
+
|
|
240
|
+
foreach ( $expected as $info ) {
|
|
241
|
+
$expectedDescs[] = $info->description;
|
|
242
|
+
}
|
|
243
|
+
$lastDesc = array_pop( $expectedDescs );
|
|
244
|
+
if ( $expectedDescs ) {
|
|
245
|
+
$expectedDesc = implode( ', ', $expectedDescs ) . ' or ' . $lastDesc;
|
|
246
|
+
} else {
|
|
247
|
+
$expectedDesc = $lastDesc;
|
|
248
|
+
}
|
|
249
|
+
$foundDesc = $found ? json_encode( $found ) : "end of input";
|
|
250
|
+
|
|
251
|
+
return "Expected " . $expectedDesc . " but " . $foundDesc . " found.";
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
protected function buildException( $message, $expected, $found, $location ) {
|
|
255
|
+
if ( $expected !== null ) {
|
|
256
|
+
sort( $expected );
|
|
257
|
+
$expected = array_unique( $expected );
|
|
258
|
+
$expandedExpected = $this->expandExpectations( $expected );
|
|
259
|
+
usort( $expandedExpected, static function ( $a, $b ) {
|
|
260
|
+
return Expectation::compare( $a, $b );
|
|
261
|
+
} );
|
|
262
|
+
} else {
|
|
263
|
+
$expandedExpected = [];
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
return new SyntaxError(
|
|
267
|
+
$message ?? $this->buildMessage( $expandedExpected, $found ),
|
|
268
|
+
$expandedExpected,
|
|
269
|
+
$found,
|
|
270
|
+
$location
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
protected function buildParseException() {
|
|
275
|
+
$char = self::charAt( $this->input, $this->maxFailPos );
|
|
276
|
+
return $this->buildException(
|
|
277
|
+
null,
|
|
278
|
+
$this->maxFailExpected,
|
|
279
|
+
$char === '' ? null : $char,
|
|
280
|
+
$this->computeLocation( $this->maxFailPos, $this->maxFailPos + 1 )
|
|
281
|
+
);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
protected function initialize() {
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
protected function initInternal( $input, $options ) {
|
|
288
|
+
$this->currPos = 0;
|
|
289
|
+
$this->savedPos = 0;
|
|
290
|
+
$this->input = $input;
|
|
291
|
+
$this->inputLength = strlen( $input );
|
|
292
|
+
$this->options = $options;
|
|
293
|
+
$this->cache = [];
|
|
294
|
+
$this->posDetailsCache = [ [ 'line' => 1, 'column' => 1, 'seenCR' => false ] ];
|
|
295
|
+
$this->maxFailPos = 0;
|
|
296
|
+
$this->maxFailExpected = [];
|
|
297
|
+
$this->tracer = $options['tracer'] ?? new DefaultTracer;
|
|
298
|
+
|
|
299
|
+
$this->initialize();
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
abstract public function parse( $input, $options = [] );
|
|
282
303
|
}
|
package/src/SyntaxError.php
CHANGED
|
@@ -1,34 +1,37 @@
|
|
|
1
1
|
<?php
|
|
2
2
|
|
|
3
|
-
namespace WikiPEG;
|
|
3
|
+
namespace Wikimedia\WikiPEG;
|
|
4
4
|
|
|
5
5
|
class SyntaxError extends \Exception implements \JsonSerializable {
|
|
6
|
-
|
|
6
|
+
public $expected;
|
|
7
|
+
public $found;
|
|
8
|
+
public $location;
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
10
|
+
/**
|
|
11
|
+
* @param string $message
|
|
12
|
+
* @param Expectation[] $expected
|
|
13
|
+
* @param string|null $found
|
|
14
|
+
* @param LocationRange $location
|
|
15
|
+
*/
|
|
16
|
+
public function __construct( string $message, array $expected, $found, LocationRange $location ) {
|
|
17
|
+
parent::__construct( $message );
|
|
18
|
+
$this->expected = $expected;
|
|
19
|
+
$this->found = $found;
|
|
20
|
+
$this->location = $location;
|
|
21
|
+
}
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
23
|
+
/**
|
|
24
|
+
* JSON serialization similar to the JavaScript SyntaxError, for testing
|
|
25
|
+
* @return array
|
|
26
|
+
*/
|
|
27
|
+
#[\ReturnTypeWillChange]
|
|
28
|
+
public function jsonSerialize(): array {
|
|
29
|
+
return [
|
|
30
|
+
'name' => 'SyntaxError',
|
|
31
|
+
'message' => $this->message,
|
|
32
|
+
'expected' => $this->expected,
|
|
33
|
+
'found' => $this->found,
|
|
34
|
+
'location' => $this->location
|
|
35
|
+
];
|
|
36
|
+
}
|
|
34
37
|
}
|