1 %name PHP_Parser
2 %declare_class {class PHP_Parser}
3
4 %syntax_error {
5 /* ?><?php */
6 echo "Syntax Error on line " . $this->lex->line . ": token '" .
7 $this->lex->value . "' while parsing rule:";
8 foreach ($this->yystack as $entry) {
9 echo $this->tokenName($entry->major) . ' ';
10 }
11 foreach ($this->yy_get_expected_tokens($yymajor) as $token) {
12 $expect[] = self::$yyTokenName[$token];
13 }
14 throw new Exception('Unexpected ' . $this->tokenName($yymajor) . '(' . $TOKEN
15 . '), expected one of: ' . implode(',', $expect));
16 }
17 %include_class {
18 static public $transTable = array();
19
__construct()20 function __construct()
21 {
22 if (!count(self::$transTable)) {
23 $start = 240; // start nice and low to be sure
24 while (token_name($start) == 'UNKNOWN') {
25 $start++;
26 }
27 $hash = array_flip(self::$yyTokenName);
28 $map =
29 array(
30 ord(',') => self::COMMA,
31 ord('=') => self::EQUALS,
32 ord('?') => self::QUESTION,
33 ord(':') => self::COLON,
34 ord('|') => self::BAR,
35 ord('^') => self::CARAT,
36 ord('&') => self::AMPERSAND,
37 ord('<') => self::LESSTHAN,
38 ord('>') => self::GREATERTHAN,
39 ord('+') => self::PLUS,
40 ord('-') => self::MINUS,
41 ord('.') => self::DOT,
42 ord('*') => self::TIMES,
43 ord('/') => self::DIVIDE,
44 ord('%') => self::PERCENT,
45 ord('!') => self::EXCLAM,
46 ord('~') => self::TILDE,
47 ord('@') => self::AT,
48 ord('[') => self::LBRACKET,
49 ord('(') => self::LPAREN,
50 ord(')') => self::RPAREN,
51 ord(';') => self::SEMI,
52 ord('{') => self::LCURLY,
53 ord('}') => self::RCURLY,
54 ord('`') => self::BACKQUOTE,
55 ord('$') => self::DOLLAR,
56 ord(']') => self::RBRACKET,
57 ord('"') => self::DOUBLEQUOTE,
58 ord("'") => self::SINGLEQUOTE,
59 );
60 for ($i = $start; $i < self::YYERRORSYMBOL + $start; $i++) {
61 $lt = token_name($i);
62 $lt = ($lt == 'T_DOUBLE_COLON') ? 'T_PAAMAYIM_NEKUDOTAYIM' : $lt;
63 // echo "$lt has hash? ".$hash[$lt]."\n";
64 if (!isset($hash[$lt])) {
65 continue;
66 }
67
68 //echo "compare $lt with {$tokens[$i]}\n";
69 $map[$i] = $hash[$lt];
70 }
71 //print_r($map);
72 // set the map to false if nothing in there.
73 self::$transTable = $map;
74 }
75 }
76
77 public $data;
78 }
79
80 %left T_INCLUDE T_INCLUDE_ONCE T_EVAL T_REQUIRE T_REQUIRE_ONCE.
81 %left COMMA.
82 %left T_LOGICAL_OR.
83 %left T_LOGICAL_XOR.
84 %left T_LOGICAL_AND.
85 %right T_PRINT.
86 %left EQUALS T_PLUS_EQUAL T_MINUS_EQUAL T_MUL_EQUAL T_DIV_EQUAL T_CONCAT_EQUAL T_MOD_EQUAL T_AND_EQUAL T_OR_EQUAL T_XOR_EQUAL T_SL_EQUAL T_SR_EQUAL.
87 %left QUESTION COLON.
88 %left T_BOOLEAN_OR.
89 %left T_BOOLEAN_AND.
90 %left BAR.
91 %left CARAT.
92 %left AMPERSAND.
93 %nonassoc T_IS_EQUAL T_IS_NOT_EQUAL T_IS_IDENTICAL T_IS_NOT_IDENTICAL.
94 %nonassoc LESSTHAN T_IS_SMALLER_OR_EQUAL GREATERTHAN T_IS_GREATER_OR_EQUAL.
95 %left T_SL T_SR.
96 %left PLUS MINUS DOT.
97 %left TIMES DIVIDE PERCENT.
98 %right EXCLAM.
99 %nonassoc T_INSTANCEOF.
100 %right TILDE T_INC T_DEC T_INT_CAST T_DOUBLE_CAST T_STRING_CAST T_ARRAY_CAST T_OBJECT_CAST T_BOOL_CAST T_UNSET_CAST AT.
101 %right LBRACKET.
102 %nonassoc T_NEW T_CLONE.
103 %left T_ELSEIF.
104 %left T_ELSE.
105 %left T_ENDIF.
106 %right T_STATIC T_ABSTRACT T_FINAL T_PRIVATE T_PROTECTED T_PUBLIC.
107
108 %extra_argument {$lex}
109
110 %parse_accept {
111 var_dump($this->data);
112 }
113
top_statement_list(B)114 start ::= top_statement_list(B). {$this->data = B->metadata;}
115
top_statement_list(A)116 top_statement_list(A) ::= top_statement_list(B) top_statement(C). {
117 A = B;
118 A[] = C;
119 }
top_statement_list(A)120 top_statement_list(A) ::= . {A = new PHP_ParseryyToken('');}
121
top_statement(A)122 top_statement(A) ::= statement(B). {A = B;}
top_statement(A)123 top_statement(A) ::= function_declaration_statement(B). {A = B;}
top_statement(A)124 top_statement(A) ::= class_declaration_statement(B). {A = B;}
125 top_statement ::= T_HALT_COMPILER LPAREN RPAREN SEMI. { $this->lex->haltParsing(); }
126
statement(A)127 statement(A) ::= unticked_statement(B). {A = B;}
128
unticked_statement(A)129 unticked_statement(A) ::= LCURLY inner_statement_list(B) RCURLY. {A = B;}
unticked_statement(A)130 unticked_statement(A) ::= T_IF LPAREN expr(E) RPAREN statement(I) elseif_list(EL) else_single(ELL). {
131 A = new PHP_ParseryyToken('');
132 A[] = E;
133 A[] = I;
134 A[] = EL;
135 A[] = ELL;
136 }
unticked_statement(A)137 unticked_statement(A) ::= T_IF LPAREN expr(E) RPAREN COLON inner_statement_list(I) new_elseif_list(EL) new_else_single(ELL) T_ENDIF SEMI. {
138 A = new PHP_ParseryyToken('if (' . E->string . '):' . I->string . EL->string . ELL->string . 'endif;');
139 A[] = E;
140 A[] = I;
141 A[] = EL;
142 A[] = ELL;
143 }
unticked_statement(A)144 unticked_statement(A) ::= T_WHILE LPAREN expr(B) RPAREN while_statement(C). {
145 A = new PHP_ParseryyToken('');
146 A[] = B;
147 A[] = C;
148 }
unticked_statement(A)149 unticked_statement(A) ::= T_DO statement(B) T_WHILE LPAREN expr(C) RPAREN SEMI. {
150 A = new PHP_ParseryyToken('');
151 A[] = B;
152 A[] = C;
153 }
unticked_statement(A)154 unticked_statement(A) ::= T_FOR
155 LPAREN
156 for_expr(B)
157 COLON
158 for_expr(C)
159 SEMI
160 for_expr(D)
161 RPAREN
162 for_statement(E). {
163 A = new PHP_ParseryyToken('');
164 A[] = B;
165 A[] = C;
166 A[] = D;
167 A[] = E;
168 }
unticked_statement(A)169 unticked_statement(A) ::= T_SWITCH LPAREN expr(B) RPAREN switch_case_list(C). {
170 A = new PHP_ParseryyToken('');
171 A[] = B;
172 A[] = C;
173 }
174 unticked_statement ::= T_BREAK SEMI.
unticked_statement(A)175 unticked_statement(A) ::= T_BREAK expr(B) SEMI. {
176 A = new PHP_ParseryyToken('');
177 A[] = B;
178 }
179 unticked_statement ::= T_CONTINUE SEMI.
unticked_statement(A)180 unticked_statement(A) ::= T_CONTINUE expr(B) SEMI. {
181 A = new PHP_ParseryyToken('', B);
182 }
183 unticked_statement ::= T_RETURN SEMI.
unticked_statement(A)184 unticked_statement(A) ::= T_RETURN expr_without_variable(B) SEMI. {
185 A = new PHP_ParseryyToken('return ' . B->string . ';', B);
186 }
unticked_statement(A)187 unticked_statement(A) ::= T_RETURN variable(B) SEMI. {
188 A = new PHP_ParseryyToken('return ' . B->string . ';', B);
189 }
unticked_statement(A)190 unticked_statement(A) ::= T_GLOBAL global_var_list(B) SEMI. {A = B;}
unticked_statement(A)191 unticked_statement(A) ::= T_STATIC static_var_list(B) SEMI. {A = B;}
unticked_statement(A)192 unticked_statement(A) ::= T_ECHO echo_expr_list(B) SEMI. {
193 A = new PHP_ParseryyToken('', B);
194 }
195 unticked_statement ::= T_INLINE_HTML.
unticked_statement(A)196 unticked_statement(A) ::= expr(B) SEMI. {A = B;}
unticked_statement(A)197 unticked_statement(A) ::= T_USE use_filename(B) SEMI. {
198 A = new PHP_ParseryyToken('', array('uses' => B));
199 // not that "uses" would actually work in real life
200 }
unticked_statement(A)201 unticked_statement(A) ::= T_UNSET LPAREN unset_variables(B) LPAREN SEMI. {
202 A = new PHP_ParseryyToken('', B);
203 }
unticked_statement(A)204 unticked_statement(A) ::= T_FOREACH LPAREN variable(B) T_AS
205 foreach_variable foreach_optional_arg RPAREN
206 foreach_statement(C). {
207 A = new PHP_ParseryyToken('', B);
208 A[] = C;
209 }
unticked_statement(A)210 unticked_statement(A) ::= T_FOREACH LPAREN expr_without_variable(B) T_AS
211 w_variable foreach_optional_arg RPAREN
212 foreach_statement(C). {
213 A = new PHP_ParseryyToken('', B);
214 A[] = C;
215 }
unticked_statement(A)216 unticked_statement(A) ::= T_DECLARE LPAREN declare_list(B) RPAREN declare_statement(C). {
217 A = new PHP_ParseryyToken('', B);
218 A[] = C;
219 }
220 unticked_statement ::= SEMI.
unticked_statement(A)221 unticked_statement(A) ::= T_TRY LCURLY inner_statement_list(B) RCURLY
222 T_CATCH LPAREN
223 fully_qualified_class_name(C)
224 T_VARIABLE RPAREN
225 LCURLY inner_statement_list(D) RCURLY
226 additional_catches(E). {
227 A = new PHP_ParseryyToken('',
228 array(
229 'catches' => C,
230 ));
231 A[] = B;
232 A[] = D;
233 A[] = E;
234 }
unticked_statement(A)235 unticked_statement(A) ::= T_THROW expr(B) SEMI. {
236 if (B->metadata && isset(B->metadata[0]) && isset(B->metadata[0]['uses']) &&
237 B->metadata[0]['uses'] === 'class') {
238 A = new PHP_ParseryyToken('throw ' . B->string, array('throws' => B->metadata[0]['name']));
239 } else {
240 A = new PHP_ParseryyToken('throw ' . B->string);
241 A[] = B;
242 }
243 }
244
additional_catches(A)245 additional_catches(A) ::= non_empty_additional_catches(B). {A = B;}
246 additional_catches ::= .
247
non_empty_additional_catches(A)248 non_empty_additional_catches(A) ::= additional_catch(B). {A = B;}
non_empty_additional_catches(A)249 non_empty_additional_catches(A) ::= non_empty_additional_catches(B) additional_catch(C). {
250 A = B;
251 A[] = C;
252 }
253
additional_catch(A)254 additional_catch(A) ::= T_CATCH LPAREN fully_qualified_class_name(B) T_VARIABLE RPAREN LCURLY inner_statement_list(C) RCURLY. {
255 A = new PHP_ParseryyToken('', C);
256 A[] = array('catches' => B);
257 }
258
inner_statement_list(A)259 inner_statement_list(A) ::= inner_statement_list(B) inner_statement(C). {
260 A = B;
261 A[] = C;
262 }
inner_statement_list(A)263 inner_statement_list(A) ::= . {A = new PHP_ParseryyToken('');}
264
inner_statement(A)265 inner_statement(A) ::= statement(B). {
266 A = new PHP_ParseryyToken(B);
267 }
inner_statement(A)268 inner_statement(A) ::= function_declaration_statement(B). {
269 A = new PHP_ParseryyToken(B);
270 }
inner_statement(A)271 inner_statement(A) ::= class_declaration_statement(B). {
272 A = new PHP_ParseryyToken(B);
273 }
274 inner_statement ::= T_HALT_COMPILER LPAREN RPAREN SEMI. { $this->lex->haltParsing(); }
275
function_declaration_statement(A)276 function_declaration_statement(A) ::= unticked_function_declaration_statement(B). {
277 A = new PHP_ParseryyToken(B);
278 }
279
class_declaration_statement(A)280 class_declaration_statement(A) ::= unticked_class_declaration_statement(B). {
281 A = new PHP_ParseryyToken(B);
282 }
283
unticked_function_declaration_statement(A)284 unticked_function_declaration_statement(A) ::=
285 T_FUNCTION is_reference(ref) T_STRING(funcname) LPAREN parameter_list(params) RPAREN
286 LCURLY inner_statement_list(funcinfo) RCURLY. {
287 A = new PHP_ParseryyToken('function ' . (ref ? '&' : '') .
288 funcname . '(' . params->string . ')');
289 A[] = array(
290 'type' => 'function',
291 'returnsref' => ref,
292 'name' => funcname,
293 'parameters' => params->metadata,
294 'info' => funcinfo->metadata,
295 );
296 }
297
unticked_class_declaration_statement(A)298 unticked_class_declaration_statement(A) ::=
299 class_entry_type(classtype) T_STRING(C) extends_from(ext)
300 implements_list(impl)
301 LCURLY
302 class_statement_list(cinfo)
303 RCURLY. {
304 A = new PHP_ParseryyToken('', array(
305 'type' => classtype['type'],
306 'modifiers' => classtype['modifiers'],
307 'name' => C,
308 'extends' => ext,
309 'implements' => impl,
310 'info' => cinfo->metadata,
311 ));
312 }
313 unticked_class_declaration_statement ::=
314 interface_entry T_STRING
315 interface_extends_list
316 LCURLY
317 class_statement_list
318 RCURLY.
319
class_entry_type(A)320 class_entry_type(A) ::= T_CLASS. { A = new PHP_ParseryyToken('', array('type' => 'class', 'modifiers' => array())); }
class_entry_type(A)321 class_entry_type(A) ::= T_ABSTRACT T_CLASS. {
322 A = new PHP_ParseryyToken('', array('type' => 'class', 'modifiers' => array('abstract')));
323 }
class_entry_type(A)324 class_entry_type(A) ::= T_FINAL T_CLASS. {
325 A = new PHP_ParseryyToken('', array('type' => 'class', 'modifiers' => array('final')));
326 }
327
extends_from(A)328 extends_from(A) ::= T_EXTENDS fully_qualified_class_name(B). {A = new PHP_ParseryyToken(B, array(B));}
extends_from(A)329 extends_from(A) ::= . {A = new PHP_ParseryyToken('');}
330
331 interface_entry ::= T_INTERFACE.
332
333 interface_extends_list ::= T_EXTENDS interface_list.
334 interface_extends_list ::= .
335
implements_list(A)336 implements_list(A) ::= . {A = new PHP_ParseryyToken('');}
implements_list(A)337 implements_list(A) ::= T_IMPLEMENTS interface_list(B). {A = B;}
338
interface_list(A)339 interface_list(A) ::= fully_qualified_class_name(B). {A = new PHP_ParseryyToken('', array(B));}
interface_list(A)340 interface_list(A) ::= interface_list(list) COMMA fully_qualified_class_name(B). {
341 A = list;
342 A[] = B;
343 }
344
expr(A)345 expr(A) ::= r_variable(B). {A = B;}
expr(A)346 expr(A) ::= expr_without_variable(B). {A = B;}
347
expr_without_variable(A)348 expr_without_variable(A) ::= T_LIST LPAREN assignment_list(B) RPAREN EQUALS expr(C). {
349 A = new PHP_ParseryyToken('list(' . B->string . ') = ' . C->string, B);
350 A[] = C;
351 }
expr_without_variable(A)352 expr_without_variable(A) ::= variable(VAR) EQUALS expr(E). {
353 if ($this->lex->globalSearch(VAR->string)) {
354 A = new PHP_ParseryyToken(VAR->string . ' = ' . E->string,
355 array(
356 'type' => 'global',
357 'name' => VAR->string,
358 'default' => E->string,
359 ));
360 A[] = VAR;
361 A[] = E;
362 } else {
363 A = new PHP_ParseryyToken(VAR->string . ' = ' . E->string, VAR);
364 A[] = E;
365 }
366 }
expr_without_variable(A)367 expr_without_variable(A) ::= variable(VAR) EQUALS AMPERSAND variable(E).{
368 if ($this->lex->globalSearch(VAR->string)) {
369 A = new PHP_ParseryyToken(VAR->string . ' = ' . E->string,
370 array(
371 'type' => 'global',
372 'name' => VAR->string,
373 'default' => '&' . E->string,
374 ));
375 A[] = VAR;
376 A[] = E;
377 } else {
378 A = new PHP_ParseryyToken(VAR->string . ' = &' . E->string, VAR);
379 A[] = E;
380 }
381 }
382
expr_without_variable(A)383 expr_without_variable(A) ::= variable(VAR) EQUALS AMPERSAND T_NEW class_name_reference(CL) ctor_arguments(ARGS). {
384 $c = is_string(CL) ? CL : CL->string;
385 if ($this->lex->globalSearch(VAR->string)) {
386 A = new PHP_ParseryyToken(VAR->string . ' = &new ' . $c . ARGS->string,
387 array(
388 'type' => 'global',
389 'name' => VAR->string,
390 'default' => '&new ' . CL->string . ARGS->string,
391 ));
392 A[] = VAR;
393 } else {
394 A = new PHP_ParseryyToken(VAR->string . ' = &new ' . $c . ARGS->string, VAR);
395 }
396 if (is_string(CL)) {
397 A[] = array('usedclass' => CL);
398 }
399 A[] = ARGS;
400 }
expr_without_variable(A)401 expr_without_variable(A) ::= T_NEW class_name_reference(B) ctor_arguments(C). {
402 $b = is_string(B) ? B : B->string;
403 A = new PHP_ParseryyToken('new ' . $b . C->string, B);
404 A[] = C;
405 if (is_string(B)) {
406 A[] = array('uses' => 'class', 'name' => B);
407 }
408 }
expr_without_variable(A)409 expr_without_variable(A) ::= T_CLONE expr(B). {
410 A = new PHP_ParseryyToken('clone ' . B->string, B);
411 }
expr_without_variable(A)412 expr_without_variable(A) ::= variable(B) T_PLUS_EQUAL expr(C). {
413 A = new PHP_ParseryyToken(B->string . ' += ' . C->string, B);
414 A[] = C;
415 }
expr_without_variable(A)416 expr_without_variable(A) ::= variable(B) T_MINUS_EQUAL expr(C). {
417 A = new PHP_ParseryyToken(B->string . ' -= ' . C->string, B);
418 A[] = C;
419 }
420
expr_without_variable(A)421 expr_without_variable(A) ::= variable(B) T_MUL_EQUAL expr(C). {
422 A = new PHP_ParseryyToken(B->string . ' *= ' . C->string, B);
423 A[] = C;
424 }
425
expr_without_variable(A)426 expr_without_variable(A) ::= variable(B) T_DIV_EQUAL expr(C). {
427 A = new PHP_ParseryyToken(B->string . ' /= ' . C->string, B);
428 A[] = C;
429 }
430
expr_without_variable(A)431 expr_without_variable(A) ::= variable(B) T_CONCAT_EQUAL expr(C). {
432 A = new PHP_ParseryyToken(B->string . ' .= ' . C->string, B);
433 A[] = C;
434 }
435
expr_without_variable(A)436 expr_without_variable(A) ::= variable(B) T_MOD_EQUAL expr(C). {
437 A = new PHP_ParseryyToken(B->string . ' %= ' . C->string, B);
438 A[] = C;
439 }
440
expr_without_variable(A)441 expr_without_variable(A) ::= variable(B) T_AND_EQUAL expr(C). {
442 A = new PHP_ParseryyToken(B->string . ' &= ' . C->string, B);
443 A[] = C;
444 }
445
expr_without_variable(A)446 expr_without_variable(A) ::= variable(B) T_OR_EQUAL expr(C). {
447 A = new PHP_ParseryyToken(B->string . ' |= ' . C->string, B);
448 A[] = C;
449 }
450
expr_without_variable(A)451 expr_without_variable(A) ::= variable(B) T_XOR_EQUAL expr(C). {
452 A = new PHP_ParseryyToken(B->string . ' ^= ' . C->string, B);
453 A[] = C;
454 }
455
expr_without_variable(A)456 expr_without_variable(A) ::= variable(B) T_SL_EQUAL expr(C). {
457 A = new PHP_ParseryyToken(B->string . ' <<= ' . C->string, B);
458 A[] = C;
459 }
460
expr_without_variable(A)461 expr_without_variable(A) ::= variable(B) T_SR_EQUAL expr(C). {
462 A = new PHP_ParseryyToken(B->string . ' >>= ' . C->string, B);
463 A[] = C;
464 }
465
expr_without_variable(A)466 expr_without_variable(A) ::= rw_variable(B) T_INC. {
467 A = new PHP_ParseryyToken(B->string . '++', B);
468 }
expr_without_variable(A)469 expr_without_variable(A) ::= T_INC rw_variable(B). {
470 A = new PHP_ParseryyToken('++' . B->string, B);
471 }
expr_without_variable(A)472 expr_without_variable(A) ::= rw_variable(B) T_DEC. {
473 A = new PHP_ParseryyToken(B->string . '--', B);
474 }
expr_without_variable(A)475 expr_without_variable(A) ::= T_DEC rw_variable(B). {
476 A = new PHP_ParseryyToken('--' . B->string, B);
477 }
expr_without_variable(A)478 expr_without_variable(A) ::= expr(B) T_BOOLEAN_OR expr(C). {
479 A = new PHP_ParseryyToken(B->string . ' || ' . C->string, B);
480 A[] = C;
481 }
expr_without_variable(A)482 expr_without_variable(A) ::= expr(B) T_BOOLEAN_AND expr(C). {
483 A = new PHP_ParseryyToken(B->string . ' && ' . C->string, B);
484 A[] = C;
485 }
expr_without_variable(A)486 expr_without_variable(A) ::= expr(B) T_LOGICAL_OR expr(C). {
487 A = new PHP_ParseryyToken(B->string . ' OR ' . C->string, B);
488 A[] = C;
489 }
expr_without_variable(A)490 expr_without_variable(A) ::= expr(B) T_LOGICAL_AND expr(C). {
491 A = new PHP_ParseryyToken(B->string . ' AND ' . C->string, B);
492 A[] = C;
493 }
expr_without_variable(A)494 expr_without_variable(A) ::= expr(B) T_LOGICAL_XOR expr(C). {
495 A = new PHP_ParseryyToken(B->string . ' XOR ' . C->string, B);
496 A[] = C;
497 }
expr_without_variable(A)498 expr_without_variable(A) ::= expr(B) BAR expr(C). {
499 A = new PHP_ParseryyToken(B->string . ' | ' . C->string, B);
500 A[] = C;
501 }
expr_without_variable(A)502 expr_without_variable(A) ::= expr(B) AMPERSAND expr(C). {
503 A = new PHP_ParseryyToken(B->string . ' & ' . C->string, B);
504 A[] = C;
505 }
expr_without_variable(A)506 expr_without_variable(A) ::= expr(B) CARAT expr(C). {
507 A = new PHP_ParseryyToken(B->string . ' ^ ' . C->string, B);
508 A[] = C;
509 }
expr_without_variable(A)510 expr_without_variable(A) ::= expr(B) DOT expr(C). {
511 A = new PHP_ParseryyToken(B->string . ' . ' . C->string, B);
512 A[] = C;
513 }
expr_without_variable(A)514 expr_without_variable(A) ::= expr(B) PLUS expr(C). {
515 A = new PHP_ParseryyToken(B->string . ' + ' . C->string, B);
516 A[] = C;
517 }
expr_without_variable(A)518 expr_without_variable(A) ::= expr(B) MINUS expr(C). {
519 A = new PHP_ParseryyToken(B->string . ' - ' . C->string, B);
520 A[] = C;
521 }
expr_without_variable(A)522 expr_without_variable(A) ::= expr(B) TIMES expr(C). {
523 A = new PHP_ParseryyToken(B->string . ' * ' . C->string, B);
524 A[] = C;
525 }
expr_without_variable(A)526 expr_without_variable(A) ::= expr(B) DIVIDE expr(C). {
527 A = new PHP_ParseryyToken(B->string . ' / ' . C->string, B);
528 A[] = C;
529 }
expr_without_variable(A)530 expr_without_variable(A) ::= expr(B) PERCENT expr(C). {
531 A = new PHP_ParseryyToken(B->string . ' % ' . C->string, B);
532 A[] = C;
533 }
expr_without_variable(A)534 expr_without_variable(A) ::= expr(B) T_SL expr(C). {
535 A = new PHP_ParseryyToken(B->string . ' << ' . C->string, B);
536 A[] = C;
537 }
expr_without_variable(A)538 expr_without_variable(A) ::= expr(B) T_SR expr(C). {
539 A = new PHP_ParseryyToken(B->string . ' >> ' . C->string, B);
540 A[] = C;
541 }
expr_without_variable(A)542 expr_without_variable(A) ::= PLUS expr(B). {
543 A = new PHP_ParseryyToken('+' . B->string, B);
544 }
expr_without_variable(A)545 expr_without_variable(A) ::= MINUS expr(B). {
546 A = new PHP_ParseryyToken('-' . B->string, B);
547 }
expr_without_variable(A)548 expr_without_variable(A) ::= EXCLAM expr(B). {
549 A = new PHP_ParseryyToken('!' . B->string, B);
550 }
expr_without_variable(A)551 expr_without_variable(A) ::= TILDE expr(B). {
552 A = new PHP_ParseryyToken('~' . B->string, B);
553 }
expr_without_variable(A)554 expr_without_variable(A) ::= expr(B) T_IS_IDENTICAL expr(C). {
555 A = new PHP_ParseryyToken(B->string . ' === ' . C->string, B);
556 A[] = C;
557 }
expr_without_variable(A)558 expr_without_variable(A) ::= expr(B) T_IS_NOT_IDENTICAL expr(C). {
559 A = new PHP_ParseryyToken(B->string . ' !== ' . C->string, B);
560 A[] = C;
561 }
expr_without_variable(A)562 expr_without_variable(A) ::= expr(B) T_IS_EQUAL expr(C). {
563 A = new PHP_ParseryyToken(B->string . ' == ' . C->string, B);
564 A[] = C;
565 }
expr_without_variable(A)566 expr_without_variable(A) ::= expr(B) T_IS_NOT_EQUAL expr(C). {
567 A = new PHP_ParseryyToken(B->string . ' != ' . C->string, B);
568 A[] = C;
569 }
expr_without_variable(A)570 expr_without_variable(A) ::= expr(B) LESSTHAN expr(C). {
571 A = new PHP_ParseryyToken(B->string . ' < ' . C->string, B);
572 A[] = C;
573 }
expr_without_variable(A)574 expr_without_variable(A) ::= expr(B) T_IS_SMALLER_OR_EQUAL expr(C). {
575 A = new PHP_ParseryyToken(B->string . ' <= ' . C->string, B);
576 A[] = C;
577 }
expr_without_variable(A)578 expr_without_variable(A) ::= expr(B) GREATERTHAN expr(C). {
579 A = new PHP_ParseryyToken(B->string . ' > ' . C->string, B);
580 A[] = C;
581 }
expr_without_variable(A)582 expr_without_variable(A) ::= expr(B) T_IS_GREATER_OR_EQUAL expr(C). {
583 A = new PHP_ParseryyToken(B->string . ' >= ' . C->string, B);
584 A[] = C;
585 }
expr_without_variable(A)586 expr_without_variable(A) ::= expr(B) T_INSTANCEOF class_name_reference(CL). {
587 $c = is_string(CL) ? CL : CL->string;
588 A = new PHP_ParseryyToken(B->string . ' instanceof ' . $c, B);
589 if (!is_string(CL)) {
590 A[] = CL;
591 }
592 }
expr_without_variable(A)593 expr_without_variable(A) ::= LPAREN expr(B) RPAREN. {
594 A = new PHP_ParseryyToken('(' . B->string . ')', B);
595 }
expr_without_variable(A)596 expr_without_variable(A) ::= expr(B) QUESTION
597 expr(C) COLON
598 expr(D). {
599 A = new PHP_ParseryyToken(B->string . ' ? ' . C->string . ' : ' . D->string, B);
600 A[] = C;
601 A[] = D;
602 }
expr_without_variable(A)603 expr_without_variable(A) ::= internal_functions_in_yacc(B). {A = B;}
expr_without_variable(A)604 expr_without_variable(A) ::= T_INT_CAST expr(B). {
605 A = new PHP_ParseryyToken('(int) ' . B->string, B);
606 }
expr_without_variable(A)607 expr_without_variable(A) ::= T_DOUBLE_CAST expr(B). {
608 A = new PHP_ParseryyToken('(double) ' . B->string, B);
609 }
expr_without_variable(A)610 expr_without_variable(A) ::= T_STRING_CAST expr(B). {
611 A = new PHP_ParseryyToken('(string) ' . B->string, B);
612 }
expr_without_variable(A)613 expr_without_variable(A) ::= T_ARRAY_CAST expr(B). {
614 A = new PHP_ParseryyToken('(array) ' . B->string, B);
615 }
expr_without_variable(A)616 expr_without_variable(A) ::= T_OBJECT_CAST expr(B). {
617 A = new PHP_ParseryyToken('(object) ' . B->string, B);
618 }
expr_without_variable(A)619 expr_without_variable(A) ::= T_BOOL_CAST expr(B). {
620 A = new PHP_ParseryyToken('(bool) ' . B->string, B);
621 }
expr_without_variable(A)622 expr_without_variable(A) ::= T_UNSET_CAST expr(B). {
623 A = new PHP_ParseryyToken('(unset) ' . B->string, B);
624 }
expr_without_variable(A)625 expr_without_variable(A) ::= T_EXIT exit_expr(B). {
626 A = new PHP_ParseryyToken('exit ' . B->string, B);
627 }
expr_without_variable(A)628 expr_without_variable(A) ::= AT expr(B). {
629 A = new PHP_ParseryyToken('@' . B->string, B);
630 }
expr_without_variable(A)631 expr_without_variable(A) ::= scalar(B). {
632 A = new PHP_ParseryyToken(B->string, B);
633 }
expr_without_variable(A)634 expr_without_variable(A) ::= expr_without_variable_t_array LPAREN array_pair_list(B) RPAREN. {
635 A = new PHP_ParseryyToken('array(' . B->string . ')', B);
636 }
expr_without_variable(A)637 expr_without_variable(A) ::= BACKQUOTE encaps_list(B) BACKQUOTE. {
638 A = new PHP_ParseryyToken('`' . B->string . '`');
639 }
expr_without_variable(A)640 expr_without_variable(A) ::= T_PRINT expr(B). {
641 A = new PHP_ParseryyToken('print ' . B->string, B);
642 }
643
644 expr_without_variable_t_array ::= T_ARRAY. {$this->lex->trackWhitespace();}
645
exit_expr(A)646 exit_expr(A) ::= LPAREN RPAREN. {A = new PHP_ParseryyToken('()');}
exit_expr(A)647 exit_expr(A) ::= LPAREN expr(B) RPAREN. {A = new PHP_ParseryyToken('(' . B->string . ')', B);}
exit_expr(A)648 exit_expr(A) ::= . {A = new PHP_ParseryyToken('');}
649
650 common_scalar(A) ::=
651 T_LNUMBER
652 |T_DNUMBER
653 |T_CONSTANT_ENCAPSED_STRING
654 |T_LINE
655 |T_FILE
656 |T_CLASS_C
657 |T_METHOD_C
658 |T_FUNC_C(B). {A = B;}
659
660 /* compile-time evaluated scalars */
static_scalar(A)661 static_scalar(A) ::= common_scalar(B). {A = B;}
static_scalar(A)662 static_scalar(A) ::= T_STRING(B). {A = B;}
static_scalar(A)663 static_scalar(A) ::= static_scalar_t_array(B) LPAREN(C) static_array_pair_list(D) RPAREN(E). {
664 A = B . C . D . E;
665 // have to do all because of nested arrays
666 $this->lex->stopTrackingWhitespace(); // we only need whitespace for
667 // array default values
668 }
static_scalar(A)669 static_scalar(A) ::= static_class_constant(B). {A = B;}
670
static_scalar_t_array(A)671 static_scalar_t_array(A) ::= T_ARRAY(B). {
672 $this->lex->trackWhitespace();
673 A = B;
674 }
675
static_array_pair_list(A)676 static_array_pair_list(A) ::= non_empty_static_array_pair_list(B). {A = B;}
static_array_pair_list(A)677 static_array_pair_list(A) ::= non_empty_static_array_pair_list(B) COMMA(C). {
678 A = B . C;
679 }
static_array_pair_list(A)680 static_array_pair_list(A) ::= . {A = '';}
681
non_empty_static_array_pair_list(A)682 non_empty_static_array_pair_list(A) ::= non_empty_static_array_pair_list(B) COMMA(C) static_scalar(D) T_DOUBLE_ARROW(E) static_scalar(F). {
683 A = B . C . D . E . F;
684 }
non_empty_static_array_pair_list(A)685 non_empty_static_array_pair_list(A) ::= non_empty_static_array_pair_list(B) COMMA(C) static_scalar(D). {
686 A = B . C . D;
687 }
non_empty_static_array_pair_list(A)688 non_empty_static_array_pair_list(A) ::= static_scalar(B) T_DOUBLE_ARROW(C) static_scalar(D). {
689 A = B . C . D;
690 }
non_empty_static_array_pair_list(A)691 non_empty_static_array_pair_list(A) ::= static_scalar(B). {A = B;}
692
static_class_constant(A)693 static_class_constant(A) ::= T_STRING(B) T_PAAMAYIM_NEKUDOTAYIM T_STRING(C). {
694 A = B . '::' . C;
695 }
696
697 foreach_optional_arg ::= T_DOUBLE_ARROW foreach_variable.
698 foreach_optional_arg ::= .
699
700 foreach_variable ::= w_variable.
701 foreach_variable ::= AMPERSAND w_variable.
702
for_statement(A)703 for_statement(A) ::= statement(B). {A = B;}
for_statement(A)704 for_statement(A) ::= COLON inner_statement_list(B) T_ENDFOR SEMI. {A = B;}
705
foreach_statement(A)706 foreach_statement(A) ::= statement(B). {A = B;}
foreach_statement(A)707 foreach_statement(A) ::= COLON inner_statement_list(B) T_ENDFOREACH SEMI. {A = B;}
708
709
declare_statement(A)710 declare_statement(A) ::= statement(B). {A = B;}
declare_statement(A)711 declare_statement(A) ::= COLON inner_statement_list(B) T_ENDDECLARE SEMI. {A = B;}
712
declare_list(A)713 declare_list(A) ::= T_STRING(B) EQUALS static_scalar(C). {
714 A = new PHP_ParseryyToken(B . ' = ' . C, array('declare' => B, 'default' => C));
715 }
declare_list(A)716 declare_list(A) ::= declare_list(DEC) COMMA T_STRING(B) EQUALS static_scalar(C). {
717 A = new PHP_ParseryyToken(DEC->string . ', ' . B . ' = ' . C, DEC);
718 A[] = array('declare' => B, 'default' => C);
719 }
720
switch_case_list(A)721 switch_case_list(A) ::= LCURLY case_list(B) RCURLY. {A = B;}
switch_case_list(A)722 switch_case_list(A) ::= LCURLY SEMI case_list(B) RCURLY. {A = B;}
switch_case_list(A)723 switch_case_list(A) ::= COLON case_list(B) T_ENDSWITCH SEMI. {A = B;}
switch_case_list(A)724 switch_case_list(A) ::= COLON SEMI case_list(B) T_ENDSWITCH SEMI. {A = B;}
725
case_list(A)726 case_list(A) ::= case_list(LIST) T_CASE expr(B) case_separator. {
727 A = LIST;
728 A[] = B;
729 }
case_list(A)730 case_list(A) ::= case_list(LIST) T_DEFAULT case_separator inner_statement_list(B). {
731 A = LIST;
732 A[] = B;
733 }
case_list(A)734 case_list(A) ::= . {A = new PHP_ParseryyToken('');}
735
736 case_separator ::= COLON|SEMI.
737
738 while_statement(A) ::= statement(B). {A = B;}
while_statement(A)739 while_statement(A) ::= COLON inner_statement_list(B) T_ENDWHILE SEMI. {A = B;}
740
elseif_list(A)741 elseif_list(A) ::= elseif_list(B) T_ELSEIF LPAREN expr(C) RPAREN statement(D). {
742 A = B;
743 A[] = C;
744 A[] = D;
745 }
elseif_list(A)746 elseif_list(A) ::= . {A = new PHP_ParseryyToken('');}
747
new_elseif_list(A)748 new_elseif_list(A) ::= new_elseif_list(B) T_ELSEIF LPAREN expr(C) RPAREN COLON inner_statement_list(D) . {
749 A = B;
750 A[] = C;
751 A[] = D;
752 }
new_elseif_list(A)753 new_elseif_list(A) ::= . {A = new PHP_ParseryyToken('');}
754
else_single(A)755 else_single(A) ::= T_ELSE statement(B). {A = B;}
else_single(A)756 else_single(A) ::= . {A = new PHP_ParseryyToken('');}
757
new_else_single(A)758 new_else_single(A) ::= T_ELSE COLON inner_statement_list(B). {A = B;}
new_else_single(A)759 new_else_single(A) ::= . {A = new PHP_ParseryyToken('');}
760
parameter_list(A)761 parameter_list(A) ::= non_empty_parameter_list(B). {A = B;}
parameter_list(A)762 parameter_list(A) ::= . {A = new PHP_ParseryyToken('');}
763
non_empty_parameter_list(A)764 non_empty_parameter_list(A) ::= optional_class_type(T) T_VARIABLE(V). {
765 A = new PHP_ParseryyToken(T . V, array(
766 array(
767 'typehint' => T,
768 'param' => V,
769 'isreference' => false,
770 'default' => null,
771 )
772 ));
773 }
non_empty_parameter_list(A)774 non_empty_parameter_list(A) ::= optional_class_type(T) AMPERSAND T_VARIABLE(V). {
775 A = new PHP_ParseryyToken(T . '&' . V, array(
776 array(
777 'typehint' => T,
778 'param' => V,
779 'isreference' => true,
780 'default' => null,
781 )
782 ));
783 }
non_empty_parameter_list(A)784 non_empty_parameter_list(A) ::= optional_class_type(T) AMPERSAND T_VARIABLE(V) EQUALS static_scalar(D). {
785 A = new PHP_ParseryyToken(T . '&' . V . ' = ' . D, array(
786 array(
787 'typehint' => T,
788 'param' => V,
789 'isreference' => true,
790 'default' => D,
791 )
792 ));
793 }
non_empty_parameter_list(A)794 non_empty_parameter_list(A) ::= optional_class_type(T) T_VARIABLE(V) EQUALS static_scalar(D). {
795 A = new PHP_ParseryyToken(T . V . ' = ' . D, array(
796 array(
797 'typehint' => T,
798 'param' => V,
799 'isreference' => false,
800 'default' => D,
801 )
802 ));
803 }
non_empty_parameter_list(A)804 non_empty_parameter_list(A) ::= non_empty_parameter_list(list) COMMA optional_class_type(T) T_VARIABLE(V). {
805 A = new PHP_ParseryyToken(list->string . ', ' . T . V, list);
806 A[] =
807 array(
808 'typehint' => T,
809 'param' => V,
810 'isreference' => false,
811 'default' => null,
812 );
813 }
non_empty_parameter_list(A)814 non_empty_parameter_list(A) ::= non_empty_parameter_list(list) COMMA optional_class_type(T) AMPERSAND T_VARIABLE(V). {
815 A = new PHP_ParseryyToken(list->string . ', ' . T . '&' . V, list);
816 A[] =
817 array(
818 'typehint' => T,
819 'param' => V,
820 'isreference' => true,
821 'default' => null,
822 );
823 }
non_empty_parameter_list(A)824 non_empty_parameter_list(A) ::= non_empty_parameter_list(list) COMMA optional_class_type(T) AMPERSAND T_VARIABLE(V) EQUALS static_scalar(D). {
825 A = new PHP_ParseryyToken(list->string . ', ' . T . V . ' = ' . D, list);
826 A[] =
827 array(
828 'typehint' => T,
829 'param' => V,
830 'isreference' => true,
831 'default' => D,
832 );
833 }
non_empty_parameter_list(A)834 non_empty_parameter_list(A) ::= non_empty_parameter_list(list) COMMA optional_class_type(T) T_VARIABLE(V) EQUALS static_scalar(D). {
835 A = new PHP_ParseryyToken(list->string . ', ' . T . V . ' = ' . D, list);
836 A[] =
837 array(
838 'typehint' => T,
839 'param' => V,
840 'isreference' => false,
841 'default' => D,
842 );
843 }
844
845
846 optional_class_type(A) ::= T_STRING|T_ARRAY(B). {A = B;}
optional_class_type(A)847 optional_class_type(A) ::= . {A = '';}
848
function_call_parameter_list(A)849 function_call_parameter_list(A) ::= non_empty_function_call_parameter_list(B). {A = B;}
function_call_parameter_list(A)850 function_call_parameter_list(A) ::= . {A = new PHP_ParseryyToken('');}
851
non_empty_function_call_parameter_list(A)852 non_empty_function_call_parameter_list(A) ::= expr_without_variable(B). {A = new PHP_ParseryyToken(B);}
non_empty_function_call_parameter_list(A)853 non_empty_function_call_parameter_list(A) ::= variable(B). {A = PHP_ParseryyToken(B);}
non_empty_function_call_parameter_list(A)854 non_empty_function_call_parameter_list(A) ::= AMPERSAND w_variable(B). {
855 if (B instanceof PHP_ParseryyToken) {
856 $b = B->string;
857 } else {
858 $b = (string) B;
859 }
860 A = new PHP_ParseryyToken('&' . $b, B);}
non_empty_function_call_parameter_list(A)861 non_empty_function_call_parameter_list(A) ::= non_empty_function_call_parameter_list(LIST) COMMA expr_without_variable(B). {
862 if (B instanceof PHP_ParseryyToken) {
863 $b = B->string;
864 } else {
865 $b = (string) B;
866 }
867 A = new PHP_ParseryyToken(LIST->string . ', ' . $b, LIST);
868 A[] = B;
869 }
non_empty_function_call_parameter_list(A)870 non_empty_function_call_parameter_list(A) ::= non_empty_function_call_parameter_list(LIST) COMMA variable(B). {
871 if (B instanceof PHP_ParseryyToken) {
872 $b = B->string;
873 } else {
874 $b = (string) B;
875 }
876 A = new PHP_ParseryyToken(LIST->string . ', ' . $b, LIST);
877 A[] = B;
878 }
non_empty_function_call_parameter_list(A)879 non_empty_function_call_parameter_list(A) ::= non_empty_function_call_parameter_list(LIST) COMMA AMPERSAND w_variable(B). {
880 if (B instanceof PHP_ParseryyToken) {
881 $b = B->string;
882 } else {
883 $b = (string) B;
884 }
885 A = new PHP_ParseryyToken(LIST->string . ', &' . $b, LIST);
886 A[] = B;
887 }
888
global_var_list(A)889 global_var_list(A) ::= global_var_list(B) COMMA global_var(C). {
890 A = B;
891 A[] = C;
892 }
global_var_list(A)893 global_var_list(A) ::= global_var(B). {A = B;}
894
global_var(A)895 global_var(A) ::= T_VARIABLE(B). {A = new PHP_ParseryyToken(B, array('global' => B));}
global_var(A)896 global_var(A) ::= DOLLAR r_variable(B). {A = new PHP_ParseryyToken('$' . B);}
global_var(A)897 global_var(A) ::= DOLLAR LCURLY expr(B) RCURLY.{
898 A = new PHP_ParseryyToken('${' . B->string . '}', B);
899 }
900
901
static_var_list(A)902 static_var_list(A) ::= static_var_list(B) COMMA T_VARIABLE(C). {
903 A = B;
904 A[] = array('static' => C, 'default' => null);
905 }
static_var_list(A)906 static_var_list(A) ::= static_var_list(B) COMMA T_VARIABLE(C) EQUALS static_scalar(D). {
907 A = B;
908 A[] = array('static' => C, 'default' => D);
909 }
static_var_list(A)910 static_var_list(A) ::= T_VARIABLE(B). {
911 A = new PHP_ParseryyToken('', array('static' => B, 'default' => null));
912 }
static_var_list(A)913 static_var_list(A) ::= T_VARIABLE(B) EQUALS static_scalar(C). {
914 A = new PHP_ParseryyToken('', array('static' => B, 'default' => C));
915 }
916
class_statement_list(A)917 class_statement_list(A) ::= class_statement_list(list) class_statement(B). {
918 A = list;
919 A[] = B;
920 }
class_statement_list(A)921 class_statement_list(A) ::= . {A = array();}
922
class_statement(A)923 class_statement(A) ::= variable_modifiers(mod) class_variable_declaration(B) SEMI. {
924 $a = array();
925 foreach (B as $item) {
926 $a[] = array(
927 'type' => 'var',
928 'name' => $item['name'],
929 'default' => $item['default'],
930 'modifiers' => mod,
931 );
932 }
933 A = new PHP_ParseryyToken('', $a);
934 }
class_statement(A)935 class_statement(A) ::= class_constant_declaration(B) SEMI. {
936 $a = array();
937 foreach (B as $item) {
938 $a[] = array(
939 'type' => 'const',
940 'name' => $item['name'],
941 'value' => $item['value'],
942 );
943 }
944 A = new PHP_ParseryyToken('', $a);
945 }
class_statement(A)946 class_statement(A) ::= method_modifiers(mod) T_FUNCTION is_reference T_STRING(B) LPAREN parameter_list(params) RPAREN method_body. {
947 A = new PHP_ParseryyToken('', array(
948 array(
949 'type' => 'method',
950 'name' => B,
951 'parameters' => params->metadata,
952 'modifiers' => mod,
953 )
954 ));
955 }
956
957
method_body(A)958 method_body(A) ::= SEMI. /* abstract method */ {A = new PHP_ParseryyToken('');}
method_body(A)959 method_body(A) ::= LCURLY inner_statement_list(B) RCURLY. {
960 A = B;
961 }
962
variable_modifiers(A)963 variable_modifiers(A) ::= non_empty_member_modifiers(B). {A = B;}
variable_modifiers(A)964 variable_modifiers(A) ::= T_VAR. {A = array('public');}
965
method_modifiers(A)966 method_modifiers(A) ::= non_empty_member_modifiers(B). {A = B;}
method_modifiers(A)967 method_modifiers(A) ::= . {A = array('public');}
968
non_empty_member_modifiers(A)969 non_empty_member_modifiers(A) ::= member_modifier(B). {A = array(B);}
non_empty_member_modifiers(A)970 non_empty_member_modifiers(A) ::= non_empty_member_modifiers(mod) member_modifier(B). {
971 A = mod;
972 A[] = B;
973 }
974
975 member_modifier(A) ::= T_PUBLIC|T_PROTECTED|T_PRIVATE|T_STATIC|T_ABSTRACT|T_FINAL(B). {A = strtolower(B);}
976
class_variable_declaration(A)977 class_variable_declaration(A) ::= class_variable_declaration(list) COMMA T_VARIABLE(var). {
978 A = list;
979 A[] = array(
980 'name' => var,
981 'default' => null,
982 );
983 }
class_variable_declaration(A)984 class_variable_declaration(A) ::= class_variable_declaration(list) COMMA T_VARIABLE(var) EQUALS static_scalar(val). {
985 A = list;
986 A[] = array(
987 'name' => var,
988 'default' => val,
989 );
990 }
class_variable_declaration(A)991 class_variable_declaration(A) ::= T_VARIABLE(B). {
992 A = array(
993 array(
994 'name' => B,
995 'default' => null,
996 )
997 );
998 }
class_variable_declaration(A)999 class_variable_declaration(A) ::= T_VARIABLE(var) EQUALS static_scalar(val). {
1000 A = array(
1001 array(
1002 'name' => var,
1003 'default' => val,
1004 )
1005 );
1006 }
1007
class_constant_declaration(A)1008 class_constant_declaration(A) ::= class_constant_declaration(list) COMMA T_STRING(n) EQUALS static_scalar(v). {
1009 A = list;
1010 A[] = array('name' => n, 'value' => v);
1011 }
class_constant_declaration(A)1012 class_constant_declaration(A) ::= T_CONST T_STRING(n) EQUALS static_scalar(v). {
1013 A = array(
1014 array('name' => n, 'value' => v)
1015 );
1016 }
1017
echo_expr_list(A)1018 echo_expr_list(A) ::= echo_expr_list(B) COMMA expr(C). {A = B;A[] = C;}
echo_expr_list(A)1019 echo_expr_list(A) ::= expr(B). {A = B;}
1020
unset_variables(A)1021 unset_variables(A) ::= unset_variable(B). {A = B;}
unset_variables(A)1022 unset_variables(A) ::= unset_variables(B) COMMA unset_variable(C). {
1023 A = B;
1024 A[] = C;
1025 }
1026
unset_variable(A)1027 unset_variable(A) ::= variable(B). {A = B;}
1028
use_filename(A)1029 use_filename(A) ::= T_CONSTANT_ENCAPSED_STRING(B). {A = B;}
use_filename(A)1030 use_filename(A) ::= LCURLY T_CONSTANT_ENCAPSED_STRING(B) RCURLY. {
1031 A = '{' . B . '}';
1032 }
1033
r_variable(A)1034 r_variable(A) ::= variable(B). {A = B;}
1035
w_variable(A)1036 w_variable(A) ::= variable(B). {A = B;}
1037
rw_variable(A)1038 rw_variable(A) ::= variable(B). {A = B;}
1039
variable(A)1040 variable(A) ::= base_variable_with_function_calls(BASE) T_OBJECT_OPERATOR object_property(PROP) method_or_not(IS_METHOD) variable_properties(VARP). {
1041 A = new PHP_ParseryyToken((string) BASE . '->' . (string) PROP .
1042 (string) IS_METHOD . (string) VARP, array());
1043 A[] = BASE;
1044 if (is_array(PROP)) {
1045 A[] = PROP;
1046 } else {
1047 if (IS_METHOD->string) {
1048 A[] = array(
1049 'uses' => 'method',
1050 'name' => PROP,
1051 );
1052 } else {
1053 A[] = array(
1054 'uses' => 'var',
1055 'name' => PROP,
1056 );
1057 }
1058 }
1059 A[] = VARP;
1060 }
variable(A)1061 variable(A) ::= base_variable_with_function_calls(B). {A = B;}
1062
variable_properties(A)1063 variable_properties(A) ::= variable_properties(B) variable_property(C).
1064 variable_properties(A) ::= . {A = new PHP_ParseryyToken('');}
1065
variable_property(A)1066 variable_property(A) ::= T_OBJECT_OPERATOR object_property(B) method_or_not(C). {
1067 A = new PHP_ParseryyToken('->' . B->string . C->string, B);
1068 A[] = C;
1069 }
1070
method_or_not(A)1071 method_or_not(A) ::= LPAREN function_call_parameter_list(B) RPAREN. {
1072 A = new PHP_ParseryyToken('(' . B . ')', B);
1073 }
method_or_not(A)1074 method_or_not(A) ::= . {A = new PHP_ParseryyToken('');}
1075
variable_without_objects(A)1076 variable_without_objects(A) ::= reference_variable(B). {A = B;}
variable_without_objects(A)1077 variable_without_objects(A) ::= simple_indirect_reference(I) reference_variable(B). {
1078 A = new PHP_ParseryyToken(I . B->string, B);
1079 }
1080
static_member(A)1081 static_member(A) ::= fully_qualified_class_name(CLASS) T_PAAMAYIM_NEKUDOTAYIM variable_without_objects(VAR). {
1082 A = new PHP_ParseryyToken(CLASS . '::' . (string) VAR, array(
1083 array(
1084 'usedclass' => CLASS,
1085 )
1086 ));
1087 A[] = VAR;
1088 }
1089
base_variable_with_function_calls(A)1090 base_variable_with_function_calls(A) ::= base_variable(B). {A = new PHP_ParseryyToken(B);}
base_variable_with_function_calls(A)1091 base_variable_with_function_calls(A) ::= function_call(B). {A = B;}
1092
base_variable(A)1093 base_variable(A) ::= reference_variable(B). {A = B;}
base_variable(A)1094 base_variable(A) ::= simple_indirect_reference(I) reference_variable(B). {
1095 A = new PHP_ParseryyToken(I . B->string, B);
1096 }
base_variable(A)1097 base_variable(A) ::= static_member(B). {A = B;}
1098
reference_variable(A)1099 reference_variable(A) ::= reference_variable(REF) LBRACKET dim_offset(DIM) RBRACKET. {
1100 A = new PHP_ParseryyToken((string) REF . '[' . (string) DIM . ']', array());
1101 A[] = REF;
1102 A[] = DIM;
1103 }
reference_variable(A)1104 reference_variable(A) ::= reference_variable(REF) LCURLY expr(DIM) RCURLY. {
1105 A = new PHP_ParseryyToken((string) REF . '{' . (string) DIM . '}', array());
1106 A[] = REF;
1107 A[] = DIM;
1108 }
reference_variable(A)1109 reference_variable(A) ::= compound_variable(B). {A = new PHP_ParseryyToken(B);}
1110
compound_variable(A)1111 compound_variable(A) ::= T_VARIABLE(B). {A = B;}
compound_variable(A)1112 compound_variable(A) ::= DOLLAR LCURLY expr(B) RCURLY. {A = new PHP_ParseryyToken('${' . (string) B . '}', B);}
1113
dim_offset(A)1114 dim_offset(A) ::= expr(B). {A = new PHP_ParseryyToken(B);}
dim_offset(A)1115 dim_offset(A) ::= . {A = new PHP_ParseryyToken('');}
1116
object_property(A)1117 object_property(A) ::= object_dim_list(B). {A = B;}
object_property(A)1118 object_property(A) ::= variable_without_objects(B). {A = B;}
1119
object_dim_list(A)1120 object_dim_list(A) ::= object_dim_list(LIST) LBRACKET dim_offset(B) RBRACKET. {
1121 A = new PHP_ParseryyToken(LIST->string . '[' . B->string . ']', LIST);
1122 A[] = B;
1123 }
object_dim_list(A)1124 object_dim_list(A) ::= object_dim_list(LIST) LCURLY expr(B) RCURLY. {
1125 A = new PHP_ParseryyToken(LIST->string . '{' . B->string . '}', LIST);
1126 A[] = B;
1127 }
object_dim_list(A)1128 object_dim_list(A) ::= variable_name(B). {A = new PHP_ParseryyToken(B);}
1129
variable_name(A)1130 variable_name(A) ::= T_STRING(B). {A = B;}
variable_name(A)1131 variable_name(A) ::= LCURLY expr(B) RCURLY. {A = new PHP_ParseryyToken('{' . B->string . '}', B);}
1132
simple_indirect_reference(A)1133 simple_indirect_reference(A) ::= DOLLAR. {A = '$';}
simple_indirect_reference(A)1134 simple_indirect_reference(A) ::= simple_indirect_reference(B) DOLLAR. {A = B . '$';}
1135
assignment_list(A)1136 assignment_list(A) ::= assignment_list(B) COMMA assignment_list_element(C). {
1137 A = new PHP_ParseryyToken(B->string . ', ' . C->string, B);
1138 A[] = C;
1139 }
assignment_list(A)1140 assignment_list(A) ::= assignment_list_element(B). {A = B;}
1141
assignment_list_element(A)1142 assignment_list_element(A) ::= variable(B). {A = B;}
assignment_list_element(A)1143 assignment_list_element(A) ::= T_LIST LPAREN assignment_list(B) RPAREN. {
1144 A = new PHP_ParseryyToken('list(' . B->string . ')', B);
1145 }
assignment_list_element(A)1146 assignment_list_element(A) ::= . {A = new PHP_ParseryyToken('');}
1147
array_pair_list(A)1148 array_pair_list(A) ::= non_empty_array_pair_list(B) possible_comma(C). {
1149 A = new PHP_ParseryyToken(B->string . C, B);
1150 }
array_pair_list(A)1151 array_pair_list(A) ::= . {A = new PHP_ParseryyToken('');}
1152
non_empty_array_pair_list(A)1153 non_empty_array_pair_list(A) ::= expr(B) T_DOUBLE_ARROW AMPERSAND w_variable(C). {
1154 A = new PHP_ParseryyToken(B->string . ' => &' . C->string, B);
1155 A[] = C;
1156 }
non_empty_array_pair_list(A)1157 non_empty_array_pair_list(A) ::= expr(B). {A = B;}
non_empty_array_pair_list(A)1158 non_empty_array_pair_list(A) ::= AMPERSAND w_variable(B). {
1159 A = new PHP_ParseryyToken('&' . B->string, B);
1160 }
non_empty_array_pair_list(A)1161 non_empty_array_pair_list(A) ::= non_empty_array_pair_list(B) COMMA expr(C) T_DOUBLE_ARROW expr(D). {
1162 A = new PHP_ParseryyToken(B->string . ', ' . C->string . ' => ' . D->string, B);
1163 A[] = C;
1164 A[] = D;
1165 }
non_empty_array_pair_list(A)1166 non_empty_array_pair_list(A) ::= non_empty_array_pair_list(B) COMMA expr(C). {
1167 A = new PHP_ParseryyToken(B->string . ', ' . C->string, B);
1168 A[] = C;
1169 }
non_empty_array_pair_list(A)1170 non_empty_array_pair_list(A) ::= expr(B) T_DOUBLE_ARROW expr(C). {
1171 A = new PHP_ParseryyToken(B->string . ' => ' . C->string, B);
1172 A[] = C;
1173 }
non_empty_array_pair_list(A)1174 non_empty_array_pair_list(A) ::= non_empty_array_pair_list(B) COMMA expr(C) T_DOUBLE_ARROW AMPERSAND w_variable(D). {
1175 A = new PHP_ParseryyToken(B->string . ', ' . C->string . ' => &' . D->string, B);
1176 A[] = C;
1177 A[] = D;
1178 }
non_empty_array_pair_list(A)1179 non_empty_array_pair_list(A) ::= non_empty_array_pair_list(B) COMMA AMPERSAND w_variable(C). {
1180 A = new PHP_ParseryyToken(B->string . ', &' . C->string, B);
1181 A[] = C;
1182 }
1183
1184
encaps_list(A)1185 encaps_list(A) ::= encaps_list(B) encaps_var(C). {
1186 A = new PHP_ParseryyToken(B->string . C, B);
1187 A[] = C;
1188 }
encaps_list(A)1189 encaps_list(A) ::= encaps_list(B) T_STRING(C). {
1190 A = new PHP_ParseryyToken(B->string . C, B);
1191 }
encaps_list(A)1192 encaps_list(A) ::= encaps_list(B) T_NUM_STRING(C). {
1193 A = new PHP_ParseryyToken(B->string . C, B);
1194 }
encaps_list(A)1195 encaps_list(A) ::= encaps_list(B) T_ENCAPSED_AND_WHITESPACE(C). {
1196 A = new PHP_ParseryyToken(B->string . C, B);
1197 }
encaps_list(A)1198 encaps_list(A) ::= encaps_list(B) T_CHARACTER(C). {
1199 A = new PHP_ParseryyToken(B->string . C, B);
1200 }
encaps_list(A)1201 encaps_list(A) ::= encaps_list(B) T_BAD_CHARACTER(C). {
1202 A = new PHP_ParseryyToken(B->string . C, B);
1203 }
encaps_list(A)1204 encaps_list(A) ::= encaps_list(B) LBRACKET. {
1205 A = new PHP_ParseryyToken(B->string . '[', B);
1206 }
encaps_list(A)1207 encaps_list(A) ::= encaps_list(B) RBRACKET. {
1208 A = new PHP_ParseryyToken(B->string . ']', B);
1209 }
encaps_list(A)1210 encaps_list(A) ::= encaps_list(B) LCURLY. {
1211 A = new PHP_ParseryyToken(B->string . '{', B);
1212 }
encaps_list(A)1213 encaps_list(A) ::= encaps_list(B) RCURLY. {
1214 A = new PHP_ParseryyToken(B->string . '}', B);
1215 }
encaps_list(A)1216 encaps_list(A) ::= encaps_list(B) T_OBJECT_OPERATOR. {
1217 A = new PHP_ParseryyToken(B->string . '->', B);
1218 }
encaps_list(A)1219 encaps_list(A) ::= . {A = new PHP_ParseryyToken('');}
1220
encaps_var(A)1221 encaps_var(A) ::= T_VARIABLE(B). {A = new PHP_ParseryyToken(B);}
1222 encaps_var(A) ::= T_VARIABLE(B) LBRACKET T_STRING|T_NUM_STRING|T_VARIABLE(C) RBRACKET. {
1223 A = new PHP_ParseryyToken(B . '[' . C . ']');
1224 }
encaps_var(A)1225 encaps_var(A) ::= T_VARIABLE(B) T_OBJECT_OPERATOR T_STRING(C). {
1226 A = new PHP_ParseryyToken(B . '->' . C);
1227 }
encaps_var(A)1228 encaps_var(A) ::= T_DOLLAR_OPEN_CURLY_BRACES expr(B) RCURLY. {
1229 A = new PHP_ParseryyToken('${' . B->string . '}', B);
1230 }
encaps_var(A)1231 encaps_var(A) ::= T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME(B) LBRACKET expr(C) RBRACKET RCURLY. {
1232 A = new PHP_ParseryyToken('${' . B . '[' . C->string . ']}', C);
1233 }
encaps_var(A)1234 encaps_var(A) ::= T_CURLY_OPEN variable(B) RCURLY. {
1235 A = new PHP_ParseryyToken('{' . B->string, '}', B);
1236 }
1237
internal_functions_in_yacc(A)1238 internal_functions_in_yacc(A) ::= T_ISSET LPAREN isset_variables(B) RPAREN. {
1239 A = new PHP_ParseryyToken('isset(' . B->string . ')', B);
1240 }
internal_functions_in_yacc(A)1241 internal_functions_in_yacc(A) ::= T_EMPTY LPAREN variable(B) RPAREN. {
1242 A = new PHP_ParseryyToken('empty(' . B->string . ')', B);
1243 }
internal_functions_in_yacc(A)1244 internal_functions_in_yacc(A) ::= T_INCLUDE expr(B). {
1245 A = new PHP_ParseryyToken('include ' . B->string, B);
1246 A[] = array(
1247 'type' => 'include',
1248 'file' => B->string,
1249 );
1250 }
internal_functions_in_yacc(A)1251 internal_functions_in_yacc(A) ::= T_INCLUDE_ONCE expr(B). {
1252 A = new PHP_ParseryyToken('include_once ' . B->string, B);
1253 A[] = array(
1254 'type' => 'include_once',
1255 'file' => B->string,
1256 );
1257 }
internal_functions_in_yacc(A)1258 internal_functions_in_yacc(A) ::= T_EVAL LPAREN expr(B) RPAREN. {
1259 A = new PHP_ParseryyToken('eval ' . B->string, B);
1260 }
internal_functions_in_yacc(A)1261 internal_functions_in_yacc(A) ::= T_REQUIRE expr(B). {
1262 A = new PHP_ParseryyToken('require ' . B->string, B);
1263 A[] = array(
1264 'type' => 'require',
1265 'file' => B->string,
1266 );
1267 }
internal_functions_in_yacc(A)1268 internal_functions_in_yacc(A) ::= T_REQUIRE_ONCE expr(B). {
1269 A = new PHP_ParseryyToken('require_once ' . B->string, B);
1270 A[] = array(
1271 'type' => 'require_once',
1272 'file' => B->string,
1273 );
1274 }
1275
isset_variables(A)1276 isset_variables(A) ::= variable(B). {A = B;}
isset_variables(A)1277 isset_variables(A) ::= isset_variables(B) COMMA variable(C). {
1278 A = new PHP_ParseryyToken(B->string . ', ' . C->string, B);
1279 A[] = C;
1280 }
1281
class_constant(A)1282 class_constant(A) ::= fully_qualified_class_name(B) T_PAAMAYIM_NEKUDOTAYIM T_STRING(C). {
1283 A = new PHP_ParseryyToken(B . '::' . C, array('usedclass' => B));
1284 A[] = array('usedclassconstant' => B . '::' . C);
1285 }
1286
fully_qualified_class_name(A)1287 fully_qualified_class_name(A) ::= T_STRING(B). {A = B;}
1288
function_call(A)1289 function_call(A) ::= T_STRING(B) LPAREN function_call_parameter_list(C) RPAREN. {A = new PHP_ParseryyToken(B . '(' . (string) C . ')', C);}
function_call(A)1290 function_call(A) ::= fully_qualified_class_name(CLAS) T_PAAMAYIM_NEKUDOTAYIM T_STRING(FUNC) LPAREN function_call_parameter_list(PL) RPAREN. {
1291 A = new PHP_ParseryyToken(CLAS . '::' . FUNC . '(' . PL->string . ')',
1292 PL);
1293 A[] = array(
1294 'uses' => 'class',
1295 'name' => CLAS,
1296 );
1297 A[] = array(
1298 'uses' => 'method',
1299 'class' => CLAS,
1300 'name' => FUNC,
1301 );
1302 }
function_call(A)1303 function_call(A) ::= fully_qualified_class_name(CLAS) T_PAAMAYIM_NEKUDOTAYIM variable_without_objects(V) LPAREN function_call_parameter_list(PL) RPAREN. {
1304 A = new PHP_ParseryyToken(CLAS . '::' . (string) V . '(' . PL->string . ')', V);
1305 A[] = PL;
1306 A[] = array(
1307 'uses' => 'class',
1308 'name' => CLAS,
1309 );
1310 }
function_call(A)1311 function_call(A) ::= variable_without_objects(B) LPAREN function_call_parameter_list(PL) RPAREN. {
1312 A = new PHP_ParseryyToken((string) B . '(' . PL->string . ')', B);
1313 A[] = PL;
1314 }
1315
scalar(A)1316 scalar(A) ::= T_STRING(B). {A = new PHP_ParseryyToken(B);}
scalar(A)1317 scalar(A) ::= T_STRING_VARNAME(B). {A = new PHP_ParseryyToken(B);}
scalar(A)1318 scalar(A) ::= class_constant(B). {A = new PHP_ParseryyToken(B);}
scalar(A)1319 scalar(A) ::= common_scalar(B). {A = new PHP_ParseryyToken(B);}
scalar(A)1320 scalar(A) ::= DOUBLEQUOTE encaps_list(B) DOUBLEQUOTE. {
1321 A = new PHP_ParseryyToken('"' . B->string . '"', B);
1322 }
scalar(A)1323 scalar(A) ::= SINGLEQUOTE encaps_list(B) SINGLEQUOTE. {
1324 A = new PHP_ParseryyToken("'" . B->string . "'", B);
1325 }
scalar(A)1326 scalar(A) ::= T_START_HEREDOC(HERE) encaps_list(B) T_END_HEREDOC(DOC). {
1327 A = new PHP_ParseryyToken(HERE->string . B->string . DOC->string, B);
1328 }
1329
class_name_reference(A)1330 class_name_reference(A) ::= T_STRING(B). {A = B;}
class_name_reference(A)1331 class_name_reference(A) ::= dynamic_class_name_reference(B). {A = B;}
1332
dynamic_class_name_reference(A)1333 dynamic_class_name_reference(A) ::= base_variable(B) T_OBJECT_OPERATOR object_property(C) dynamic_class_name_variable_properties(D). {
1334 A = new PHP_ParseryyToken(B->string . '->' . C->string . D->string, B);
1335 A[] = array('usedmember' => array(B->string, C->string));
1336 A[] = D;
1337 }
dynamic_class_name_reference(A)1338 dynamic_class_name_reference(A) ::= base_variable(B). {A = B;}
1339
dynamic_class_name_variable_properties(A)1340 dynamic_class_name_variable_properties(A) ::= dynamic_class_name_variable_properties(B) dynamic_class_name_variable_property(C). {
1341 A = B;
1342 B[] = C;
1343 }
dynamic_class_name_variable_properties(A)1344 dynamic_class_name_variable_properties(A) ::= . {A = new PHP_ParseryyToken('');}
1345
dynamic_class_name_variable_property(A)1346 dynamic_class_name_variable_property(A) ::= T_OBJECT_OPERATOR object_property(B). {
1347 A = new PHP_ParseryyToken('->' . B->string, array('usedmember' => B->string));
1348 }
1349
ctor_arguments(A)1350 ctor_arguments(A) ::= LPAREN function_call_parameter_list(B) RPAREN. {
1351 A = new PHP_ParseryyToken('(' . B->string . ')', B);
1352 }
ctor_arguments(A)1353 ctor_arguments(A) ::= . {A = new PHP_ParseryyToken('');}
1354
possible_comma(A)1355 possible_comma(A) ::= COMMA. {A = ',';}
possible_comma(A)1356 possible_comma(A) ::= . {A = '';}
1357
for_expr(A)1358 for_expr(A) ::= non_empty_for_expr(B). {A = B;}
for_expr(A)1359 for_expr(A) ::= . {A = new PHP_ParseryyToken('');}
1360
non_empty_for_expr(A)1361 non_empty_for_expr(A) ::= non_empty_for_expr(B) COMMA expr(C). {
1362 A = new PHP_ParseryyToken(B->string . ', ' . C->string, B);
1363 A[] = C;
1364 }
non_empty_for_expr(A)1365 non_empty_for_expr(A) ::= expr(B). {A = B;}
1366
is_reference(A)1367 is_reference(A) ::= AMPERSAND. {A = true;}
is_reference(A)1368 is_reference(A) ::= . {A = false;}
1369