tagua_parser/
tokens.rs

1// Tagua VM
2//
3//
4// New BSD License
5//
6// Copyright © 2016-2016, Ivan Enderlin.
7// All rights reserved.
8//
9// Redistribution and use in source and binary forms, with or without
10// modification, are permitted provided that the following conditions are met:
11//     * Redistributions of source code must retain the above copyright
12//       notice, this list of conditions and the following disclaimer.
13//     * Redistributions in binary form must reproduce the above copyright
14//       notice, this list of conditions and the following disclaimer in the
15//       documentation and/or other materials provided with the distribution.
16//     * Neither the name of the Hoa nor the names of its contributors may be
17//       used to endorse or promote products derived from this software without
18//       specific prior written permission.
19//
20// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE
24// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30// POSSIBILITY OF SUCH DAMAGE.
31
32//! List of lexemes.
33//!
34//! The list of all lexemes, aka tokens, is provided by the PHP Language
35//! Specification in the [Grammar
36//! chapter](https://github.com/php/php-langspec/blob/master/spec/19-grammar.md#lexical-grammar).
37//!
38//! All lexemes are declared as static bytes constants.
39
40use rules::whitespaces::whitespace;
41
42/// Helper to declare a token.
43///
44/// ### Examples
45///
46/// The following example declares the `FOO_BAR` token:
47///
48/// ```
49/// token!(FOO_BAR: b"foobar"; "The `FOO_BAR` token, mostly used in example.");
50/// ```
51macro_rules! token {
52    ($name:ident: $value:expr; $documentation:expr) => (
53        #[doc=$documentation]
54        const $name: &'static [u8] = $value;
55    );
56
57    (pub $name:ident: $value:expr; $documentation:expr) => (
58        #[doc=$documentation]
59        pub const $name: &'static [u8] = $value;
60    )
61}
62
63token!(
64    pub ABSTRACT: b"abstract";
65    "The `ABSTRACT` token.\n\nRepresent an abstract entity, e.g. `abstract class C { … }`."
66);
67token!(
68    pub ADD: b"+";
69    "The `ADD` token.\n\nRepresent the addition operator, e.g. `$x + $y`."
70);
71token!(
72    pub ADD_AND_ASSIGN: b"+=";
73    "The `ADD_AND_ASSIGN` token.\n\nRepresent the addition assignment operator, e.g. `$x += $y;`."
74);
75token!(
76    pub AND: b"and";
77    "The `AND` token.\n\nRepresent the conjunction operator, used in a logical expression, e.g. `$x and $y`."
78);
79token!(
80    pub ARRAY: b"array";
81    "The `ARRAY` token.\n\nRepresent the array constructor, e.g. `array($x, $y)`."
82);
83token!(
84    pub AS: b"as";
85    "The `AS` token.\n\nRepresent the alias operator, e.g. `use Foo\\Bar as Baz`."
86);
87token!(
88    pub ASSIGN: b"=";
89    "The `ASSIGN` token.\n\nRepresent a binding of a value to a variable, e.g. `$x = 42`."
90);
91token!(
92    pub BITWISE_AND: b"&";
93    "The `BITWISE_AND` token.\n\nRepresent the bitwise conjunction operator, e.g. `$x & $y`."
94);
95token!(
96    pub BITWISE_AND_AND_ASSIGN: b"&=";
97    "The `BITWISE_AND_AND_ASSIGN` token.\n\nRepresent the bitwise conjunction assignment operator, e.g. `$x &= $y;`."
98);
99token!(
100    pub BITWISE_LEFT_SHIFT: b"<<";
101    "The `BITWISE_LEFT_SHIFT` token.\n\nRepresent the bitwise left shift operator, e.g. `$x << $y`."
102);
103token!(
104    pub BITWISE_LEFT_SHIFT_AND_ASSIGN: b"<<=";
105    "The `BITWISE_LEFT_SHIFT_AND_ASSIGN` token.\n\nRepresent the bitwise left shift assignment operator, e.g. `$x <<= $y;`."
106);
107token!(
108    pub BITWISE_NOT: b"~";
109    "The `BITWISE_NOT` token.\n\nRepresent the bitwise negation operator, e.g. `~$x`."
110);
111token!(
112    pub BITWISE_OR: b"|";
113    "The `BITWISE_OR` token.\n\nRepresent the inclusive bitwise disjunction operator, e.g. `$x | $y`."
114);
115token!(
116    pub BITWISE_OR_AND_ASSIGN: b"|=";
117    "The `BITWISE_OR_AND_ASSIGN` token.\n\nRepresent the inclusive bitwise disjunction assignment operator, e.g. `$x |= $y;`."
118);
119token!(
120    pub BITWISE_RIGHT_SHIFT: b">>";
121    "The `BITWISE_RIGHT_SHIFT` token.\n\nRepresent the bitwise right shift operator, e.g. `$x >> $y`."
122);
123token!(
124    pub BITWISE_RIGHT_SHIFT_AND_ASSIGN: b"<<=";
125    "The `BITWISE_RIGHT_SHIFT_AND_ASSIGN` token.\n\nRepresent the bitwise right shift assignment operator, e.g. `$x >>= $y;`."
126);
127token!(
128    pub BITWISE_XOR: b"^";
129    "The `BITWISE_XOR` token.\n\nRepresent the exclusive bitwise disjunction operator, e.g. `$x ^ $y`."
130);
131token!(
132    pub BITWISE_XOR_AND_ASSIGN: b"^=";
133    "The `BITWISE_XOR_AND_ASSIGN` token.\n\nRepresent the exclusive bitwise disjunction assignment operator, e.g. `$x ^= $y;`."
134);
135token!(
136    pub BOOLEAN_AND: b"&&";
137    "The `BOOLEAN_AND` token.\n\nRepresent the boolean conjunction operator, e.g. `$x && $y`."
138);
139token!(
140    pub BOOLEAN_NOT: b"!";
141    "The `NOT` token.\n\nRepresent the boolean negation operator, e.g. `!$x`."
142);
143token!(
144    pub BOOLEAN_OR: b"||";
145    "The `BOOLEAN_OR` token.\n\nRepresent the boolean disjunction operator, e.g. `$x || $y`."
146);
147token!(
148    pub BREAK: b"break";
149    "The `BREAK` token.\n\nRepresent the control flow breaker operator, e.g. `break 2`."
150);
151token!(
152    pub CALLABLE: b"callable";
153    "The `CALLABLE` token.\n\nRepresent the callable type, e.g. `function f(callable $x) { … }`."
154);
155token!(
156    pub CASE: b"case";
157    "The `CASE` token.\n\nRepresent a case in a `switch` control structure, e.g. `switch (…) { case …: …; }`."
158);
159token!(
160    pub CATCH: b"catch";
161    "The `CATCH` token.\n\nRepresent the `catch` block of a `try`/`catch` control structure, e.g. `try { … } catch (Exception $e) { … }`."
162);
163token!(
164    pub CLASS: b"class";
165    "The `CLASS` token.\n\nRepresent the class declaration operator, e.g. `class C { … }`."
166);
167token!(
168    pub CLONE: b"clone";
169    "The `CLONE` token.\n\nRepresent the clone operator, e.g. `clone $x`."
170);
171token!(
172    pub COALESCE: b"??";
173    "The `COALESCE` token.\n\nRepresent the null coalescing operator, e.g. `$x ?? $y`."
174);
175token!(
176    pub COMMA: b",";
177    "The `COMMA` token.\n\nRepresent the list item separator, e.g. `($x, $y, $z)`."
178);
179token!(
180    pub COMPARE: b"<=>";
181    "The `COMPARE` token.\n\nRepresent the comparison operator, e.g. `$x <=> $y`."
182);
183token!(
184    pub CONCATENATE: b".";
185    "The `CONCATENATE` token.\n\nRepresent the concatenation operator, e.g. `'foo' . 'bar'`."
186);
187token!(
188    pub CONCATENATE_AND_ASSIGN: b".=";
189    "The `CONCATENATE_AND_ASSIGN` token.\n\nRepresent the concatenation assignment operator, e.g. `$x .= $y;`."
190);
191token!(
192    pub CONST: b"const";
193    "The `CONST` token.\n\nRepresent the constant declaration operator, e.g. `const ANSWER = 42;`."
194);
195token!(
196    pub CONTINUE: b"continue";
197    "The `CONTINUE` token.\n\nRepresent the control flow continuer operator, e.g. `continue 2;`."
198);
199token!(
200    pub DECLARE: b"declare";
201    "The `DECLARE` token.\n\nRepresent the declaration operator, e.g. `declare(foo='bar');`."
202);
203token!(
204    pub DECREMENT: b"--";
205    "The `DECREMENT` token.\n\nRepresent the decrement operator, e.g. `$number--`."
206);
207token!(
208    pub DEFAULT: b"default";
209    "The `DEFAULT` token.\n\nRepresent the default case in a `switch` control structure, e.g. `switch (…) { … default: …; }`."
210);
211token!(
212    pub DIE: b"die";
213    "The `DIE` token.\n\nRepresent the termination operator, e.g. `die(42);`."
214);
215token!(
216    pub DIVIDE: b"/";
217    "The `DIVIDE` token.\n\nRepresent the division operator, e.g. `$x / $y`."
218);
219token!(
220    pub DIVIDE_AND_ASSIGN: b"/=";
221    "The `DIVIDE_AND_ASSIGN` token.\n\nRepresent the division assignment operator, e.g. `$x /= $y`."
222);
223token!(
224    pub DO: b"do";
225    "The `DO` token.\n\nRepresent the body of a `do`/`while` loop, e.g. `do { … } while (…);`."
226);
227token!(
228    pub DYNAMIC_CALL: b"->";
229    "The `DYNAMIC_CALL` token.\n\nRepresent the dynamic method call operator, e.g. `$object->method()`."
230);
231token!(
232    pub ECHO: b"echo";
233    "The `ECHO` token.\n\nRepresent the output writer operator, e.g. `echo 'foobar';`."
234);
235token!(
236    pub ELLIPSIS: b"...";
237    "The `ELLIPSIS` token.\n\nRepresent the ellipsis operator, e.g. `$x...`."
238);
239token!(
240    pub ELSE: b"else";
241    "The `ELSE` token.\n\nRepresent the falsy block of a condition control structure, e.g. `if (…) { … } else { … }`."
242);
243token!(
244    pub ELSEIF: b"elseif";
245    "The `ELSEIF` token.\n\nRepresent a `else if` block, e.g. `if (…) { … } elseif { … } else { … }`."
246);
247token!(
248    pub EMPTY: b"empty";
249    "The `EMPTY` token.\n\nRepresent the emptiness operator, e.g. `empty($x)`."
250);
251token!(
252    pub ENDDECLARE: b"enddeclare";
253    "The `ENDDECLARE` token.\n\nRepresent the end of a `declare` block, e.g. `declare: … enddeclare`."
254);
255token!(
256    pub ENDFOR: b"endfor";
257    "The `ENDFOR` token.\n\nRepresent the end of a `for` block, e.g. `for (…; …; …): … endfor`."
258);
259token!(
260    pub ENDFOREACH: b"endforeach";
261    "The `ENDFOREACH` token.\n\nRepresent the end of a `foreach` block, e.g. `foreach ($i as $k => $v): … endforeach`."
262);
263token!(
264    pub ENDIF: b"endif";
265    "The `ENDIF` token.\n\nRepresent the end of an `if` block, e.g. `if (…): … endif`."
266);
267token!(
268    pub ENDSWITCH: b"endswitch";
269    "The `ENDSWITCH` token.\n\nRepresent the end of a `switch` block, e.g. `switch(…): … endswitch`."
270);
271token!(
272    pub ENDWHILE: b"endwhile";
273    "The `ENDWHILE` token.\n\nRepresent the end of a `while` block, e.g. `while(…): … endwhile`."
274);
275token!(
276    pub EQUAL: b"==";
277    "The `EQUAL` token.\n\nRepresent the equality comparison operator, e.g. `$x == $y`."
278);
279token!(
280    pub EVAL: b"eval";
281    "The `EVAL` token.\n\nRepresent the late-evaluation operator, e.g. `eval($x)`."
282);
283token!(
284    pub EXIT: b"exit";
285    "The `EXIT` token.\n\nRepresent the termination operator, e.g. `exit(42);`."
286);
287token!(
288    pub EXTENDS: b"extends";
289    "The `EXTENDS` token.\n\nRepresent the inheritance operator, e.g. `class C extends D { … }`."
290);
291token!(
292    pub FINAL: b"final";
293    "The `FINAL` token.\n\nRepresent a final entity, e.g. `final class C { … }`."
294);
295token!(
296    pub FINALLY: b"finally";
297    "The `FINALLY` token.\n\nRepresent the finally block of a `try`/`catch` control structure, e.g. `try { … } catch (…) { … } finally { … }`."
298);
299token!(
300    pub FOR: b"for";
301    "The `FOR` token.\n\nRepresent a `for` loop, e.g. `for (…; …; …) { … }`."
302);
303token!(
304    pub FOREACH: b"foreach";
305    "The `FOREACH` token.\n\nRepresent a `foreach` loop, e.g. `foreach ($i as $k => $v) { … }`."
306);
307token!(
308    pub FUNCTION: b"function";
309    "The `FUNCTION` token.\n\nRepresent the function declaration operator, e.g. `function f(…) { … }`."
310);
311token!(
312    pub FUNCTION_OUTPUT: COLON;
313    "The `FUNCTION_OUTPUT` token.\n\nRepresent the function return type declaration operator, e.g. `function f(…): … { … }`."
314);
315token!(
316    pub GLOBAL: b"global";
317    "The `GLOBAL` token.\n\nRepresent the global visibility modifier, e.g. `global $x`."
318);
319token!(
320    pub GOTO: b"goto";
321    "The `GOTO` token.\n\nRepresent the jump operator, e.g. `goto x;`."
322);
323token!(
324    pub GREATER_THAN: b">";
325    "The `GREATER_THAN` token.\n\nRepresent the greater than comparison operator, e.g. `$x > $y`."
326);
327token!(
328    pub GREATER_THAN_OR_EQUAL_TO: b">=";
329    "The `GREATER_THAN_OR_EQUAL_TO` token.\n\nRepresent the greater than or equal to comparison operator, e.g. `$x >= $y`."
330);
331token!(
332    pub IDENTICAL: b"===";
333    "The `IDENTICAL` token.\n\nRepresent the strict equality comparison operator, e.g. `$x === $y`."
334);
335token!(
336    pub IF: b"if";
337    "The `IF` token.\n\nRepresent the truly block of a condition control structure, e.g. `if (…) { … }`."
338);
339token!(
340    pub IMPLEMENTS: b"implements";
341    "The `IMPLEMENTS` token.\n\nRepresent the implementation operator, e.g. `class C implements I { … }`."
342);
343token!(
344    pub INCLUDE: b"include";
345    "The `INCLUDE` token.\n\nRepresent the import operator, e.g. `include $x;`."
346);
347token!(
348    pub INCLUDE_ONCE: b"include_once";
349    "The `INCLUDE_ONCE` token.\n\nRepresent the import once operator, e.g. `include_once $x;`."
350);
351token!(
352    pub INCREMENT: b"++";
353    "The `INCREMENT` token.\n\nRepresent the increment operator, e.g. `$number++`."
354);
355token!(
356    pub INSTANCEOF: b"instanceof";
357    "The `INSTANCEOF` token.\n\nRepresent the subset operator, e.g. `$o instanceof C`."
358);
359token!(
360    pub INSTEADOF: b"insteadof";
361    "The `INSTEADOF` token.\n\nRepresent the conflict resolution operator, `use C, D { C::f insteadof D }`."
362);
363token!(
364    pub INTERFACE: b"interface";
365    "The `INTERFACE` token.\n\nRepresent the interface declaration operator, e.g. `interface I { … }`."
366);
367token!(
368    pub ISSET: b"isset";
369    "The `ISSET` token.\n\nRepresent the existence operator, e.g. `isset($x)`."
370);
371token!(
372    pub LEFT_CURLY_BRACKET: b"{";
373    "The `LEFT_CURLY_BRACKET` token.\n\nUsed to open a block, e.g. `if (…) { … }`."
374);
375token!(
376    pub LEFT_PARENTHESIS: b"]";
377    "The `LEFT_PARENTHESIS` token.\n\nUsed to open a group of something, e.g. `if (…)`."
378);
379token!(
380    pub LEFT_SQUARE_BRACKET: b"[";
381    "The `LEFT_SQUARE_BRACKET` token.\n\nUsed to open an array construction or an array access for instance, e.g. `[2, 4, 6, 9][0]`."
382);
383token!(
384    pub LESS_THAN: b"<";
385    "The `LESS_THAN` token.\n\nRepresent the less than comparison operator, e.g. `$x < $y`."
386);
387token!(
388    pub LESS_THAN_OR_EQUAL_TO: b"<=";
389    "The `LESS_THAN_OR_EQUAL_TO` token.\n\nRepresent the less than or equal to comparison operator, e.g. `$x <= $y`."
390);
391token!(
392    pub LIST: b"list";
393    "The `LIST` token.\n\nRepresent the destructuring operator, e.g. `list($x, $y) = $a`."
394);
395token!(
396    pub MODULO: b"%";
397    "The `MODULO` token.\n\nRepresent the modulus operator, e.g. `$x % $y`."
398);
399token!(
400    pub MODULO_AND_ASSIGN: b"%=";
401    "The `MODULO_AND_ASSIGN` token.\n\nRepresent the modulus assignment operator, e.g. `$x %= $y;`."
402);
403token!(
404    pub MULTIPLY: b"*";
405    "The `MULTIPLY` token.\n\nRepresent the multiplication operator, e.g. `$x * $y`."
406);
407token!(
408    pub MULTIPLY_AND_ASSIGN: b"*=";
409    "The `MULTIPLY_AND_ASSIGN` token.\n\nRepresent the multiplication assignment operator, e.g. `$x *= $y;`."
410);
411token!(
412    pub NAMESPACE: b"namespace";
413    "The `NAMESPACE` token.\n\nRepresent the namespace declaration operator or the current namespace name, e.g. `namespace N;`."
414);
415token!(
416    pub NAMESPACE_SEPARATOR: b"\\";
417    "The `NAMESPACE_SEPARATOR` token.\n\nRepresent the namespace separator, e.g. `A\\B\\C`."
418);
419token!(
420    pub NEW: b"new";
421    "The `NEW` token.\n\nRepresent the instanciation operator, e.g. `new C()`."
422);
423token!(
424    pub NOT_EQUAL: b"!=";
425    "The `NOT_EQUAL` token.\n\nRepresent the not equal comparison operator, e.g. `$x != $y`."
426);
427token!(
428    pub NOT_IDENTICAL: b"!==";
429    "The `NOT_IDENTICAL` token.\n\nRepresent the strict not equal comparison operator, e.g. `$x !== $y`."
430);
431token!(
432    pub NULLABLE: QUESTION_MARK;
433    "The `NULLABLE` token.\n\nRepresent the nullable operation, e.g. `function f(?int $x) { … }`."
434);
435token!(
436    pub OR: b"or";
437    "The `OR` token.\n\nRepresent the inclusive disjunction operator, used in a logical expression, e.g. `$x or $y`."
438);
439token!(
440    pub POW: b"**";
441    "The `POW` token.\n\nRepresent the power operator, e.g. `$x ** $y`."
442);
443token!(
444    pub POW_AND_ASSIGN: b"**=";
445    "The `POW_AND_ASSIGN` token.\n\nRepresent the power assignment operator, e.g. `$x **= $y;`."
446);
447token!(
448    pub PRINT: b"print";
449    "The `PRINT` token.\n\nRepresent another output writer operator, e.g. `print 'foobar';`, see `echo`."
450);
451token!(
452    pub PRIVATE: b"private";
453    "The `PRIVATE` token.\n\nRepresent the private visibility operator, e.g. `private $x`."
454);
455token!(
456    pub PROTECTED: b"protected";
457    "The `PROTECTED` token.\n\nRepresent the protected visibility operator, e.g. `protected $x`."
458);
459token!(
460    pub PUBLIC: b"public";
461    "The `PUBLIC` token.\n\nRepresent the public visibility operator, e.g. `public $x`."
462);
463token!(
464    pub REFERENCE: b"&";
465    "The `REFERENCE` token.\n\nRepresent the reference operator, e.g. `&$x`."
466);
467token!(
468    pub REQUIRE: b"require";
469    "The `REQUIRE` token.\n\nRepresent the import operator, e.g. `require $x;`."
470);
471token!(
472    pub REQUIRE_ONCE: b"require_once";
473    "The `REQUIRE_ONCE` token.\n\nRepresent the import once operator, e.g. `require_once $x;`."
474);
475token!(
476    pub RETURN: b"return";
477    "The `RETURN` token.\n\nRepresent the return operator, e.g. `return $x;`."
478);
479token!(
480    pub RIGHT_CURLY_BRACKET: b"{";
481    "The `RIGHT_CURLY_BRACKET` token.\n\nUsed to close a block, e.g. `if (…) { … }`."
482);
483token!(
484    pub RIGHT_PARENTHESIS: b")";
485    "The `RIGHT_PARENTHESIS` token.\n\nUsed to close a group of something, e.g. `if (…)`."
486);
487token!(
488    pub RIGHT_SQUARE_BRACKET: b"]";
489    "The `RIGHT_SQUARE_BRACKET` token.\n\nUsed to close an array construction or an array access for instance, e.g. `[2, 4, 6, 9][0]`."
490);
491token!(
492    pub SEMICOLON: b";";
493    "The `SEMICOLON` token.\n\nRepresent the end of an instruction, e.g. `$x = …;`."
494);
495token!(
496    pub STATIC: b"static";
497    "The `STATIC` token.\n\nRepresent the stack declaration operator, e.g. `static $x`."
498);
499token!(
500    pub STATIC_CALL: b"::";
501    "The `STATIC_CALL` token.\n\nRepresent the static method call operator, e.g. `class::method()`."
502);
503token!(
504    pub SUBTRACT: b"-";
505    "The `SUBTRACT` token.\n\nRepresent the subtraction operator, e.g. `$x - $y`."
506);
507token!(
508    pub SUBTRACT_AND_ASSIGN: b"-=";
509    "The `SUBTRACT_AND_ASSIGN` token.\n\nRepresent the subtraction assignment operator, e.g. `$x -= $y;`."
510);
511token!(
512    pub SWITCH: b"switch";
513    "The `SWITCH` token.\n\nRepresent the switch control structure, e.g. `switch ($x) { … }`."
514);
515token!(
516    pub TERNARY_ELSE: COLON;
517    "The `TERNARY_ELSE` token.\n\nRepresent the falsy block of a ternary condition, e.g. `$x ? … : …`."
518);
519token!(
520    pub TERNARY_THEN: QUESTION_MARK;
521    "The `TERNARY_THEN` token.\n\nRepresent the truly block of a ternary condition, e.g. `$x ? … : …`."
522);
523token!(
524    pub THROW: b"throw";
525    "The `THROW` token.\n\nRepresent the throw exception operator, e.g. `throw $e;`."
526);
527token!(
528    pub TRAIT: b"trait";
529    "The `TRAIT` token.\n\nRepresent the trait declaration operator, e.g. `trait T { … }`."
530);
531token!(
532    pub TRY: b"try";
533    "The `TRY` token.\n\nRepresent the `try` block of a `try`/`catch` control structure, e.g. `try { … } catch (Exception $e) { … }`."
534);
535token!(
536    pub UNSET: b"unset";
537    "The `UNSET` token.\n\nRepresent the destruction operator, e.g. `unset($x);`."
538);
539token!(
540    pub USE: b"use";
541    "The `USE` token.\n\nRepresent the importing operator (for namespaces or traits for instance), e.g. `use C\\D;`."
542);
543token!(
544    pub VAR: b"var";
545    "The `VAR` token.\n\nRepresent the variable declaration operator (for old PHP versions), e.g. `var $x = …;`."
546);
547token!(
548    pub VARIABLE: b"$";
549    "The `VARIABLE` token.\n\nRepresent the variable declaration operator, e.g. `$foo`."
550);
551token!(
552    pub WHILE: b"while";
553    "The `WHILE` token.\n\nRepresent a `while` loop, e.g. `while (…) { … }`."
554);
555token!(
556    pub XOR: b"xor";
557    "The `XOR` token.\n\nRepresent the exclusive disjunction operator, used in a logical expression, e.g. `$x xor $y`."
558);
559token!(
560    pub YIELD: b"yield";
561    "The `YIELD` token.\n\nRepresent the generator operator, e.g. `yield …;`."
562);
563token!(
564    pub YIELD_FROM: b"yield from";
565    "The `YIELD_FROM` token.\n\nRepresent the delegated generator operator, e.g. `yield from …;`."
566);
567
568token!(
569    COLON: b":";
570    "The `COLON` private token.\n\nSee `FUNCTION_OUTPUT` and `TERNARY_ELSE`."
571);
572token!(
573    QUESTION_MARK: b"?";
574    "The `QUESTION_MARK` private token.\n\nSee `NULLABLE` and `TERNARY_THEN`."
575);
576
577named!(
578    pub keywords,
579    alt_complete!(
580        keyword!(ABSTRACT)
581      | keyword!(AND)
582      | keyword!(ARRAY)
583      | keyword!(AS)
584      | keyword!(BREAK)
585      | keyword!(CALLABLE)
586      | keyword!(CASE)
587      | keyword!(CATCH)
588      | keyword!(CLASS)
589      | keyword!(CLONE)
590      | keyword!(CONST)
591      | keyword!(CONTINUE)
592      | keyword!(DECLARE)
593      | keyword!(DEFAULT)
594      | keyword!(DIE)
595      | keyword!(DO)
596      | keyword!(ECHO)
597      | keyword!(ELSEIF)
598      | keyword!(ELSE)
599      | keyword!(EMPTY)
600      | keyword!(ENDDECLARE)
601      | keyword!(ENDFOREACH)
602      | keyword!(ENDFOR)
603      | keyword!(ENDIF)
604      | keyword!(ENDSWITCH)
605      | keyword!(ENDWHILE)
606      | keyword!(EVAL)
607      | keyword!(EXIT)
608      | keyword!(EXTENDS)
609      | keyword!(FINALLY)
610      | keyword!(FINAL)
611      | keyword!(FOREACH)
612      | keyword!(FOR)
613      | keyword!(FUNCTION)
614      | keyword!(GLOBAL)
615      | keyword!(GOTO)
616      | keyword!(IF)
617      | keyword!(IMPLEMENTS)
618      | keyword!(INCLUDE_ONCE)
619      | keyword!(INCLUDE)
620      | keyword!(INSTANCEOF)
621      | keyword!(INSTEADOF)
622      | keyword!(INTERFACE)
623      | keyword!(ISSET)
624      | keyword!(LIST)
625      | keyword!(NAMESPACE)
626      | keyword!(NEW)
627      | keyword!(OR)
628      | keyword!(PRINT)
629      | keyword!(PRIVATE)
630      | keyword!(PROTECTED)
631      | keyword!(PUBLIC)
632      | keyword!(REQUIRE_ONCE)
633      | keyword!(REQUIRE)
634      | keyword!(RETURN)
635      | keyword!(STATIC)
636      | keyword!(SWITCH)
637      | keyword!(THROW)
638      | keyword!(TRAIT)
639      | keyword!(TRY)
640      | keyword!(UNSET)
641      | keyword!(USE)
642      | keyword!(VAR)
643      | keyword!(WHILE)
644      | keyword!(XOR)
645      | chain!(
646            keyword!("yield") ~
647            whitespace ~
648            keyword!("from"),
649            || { YIELD_FROM }
650        )
651      | keyword!(YIELD)
652    )
653);
654
655
656#[cfg(test)]
657mod tests {
658    use super::keywords;
659    use super::super::internal::{
660        Error,
661        ErrorKind,
662        Result
663    };
664
665    macro_rules! test_keyword {
666        ($test_case_name:ident: ($string:expr, $expect:expr)) => (
667            #[test]
668            fn $test_case_name() {
669                use std::ascii::AsciiExt;
670                use std::str;
671
672                let output     = Result::Done(&b""[..], $expect);
673                let uppercased = str::from_utf8($string).unwrap().to_ascii_uppercase();
674
675                assert_eq!(keywords($string), output);
676                assert_eq!(keywords(uppercased.as_bytes()), output);
677            }
678        )
679    }
680
681    test_keyword!(case_keyword_abstract:     (b"abstract", super::ABSTRACT));
682    test_keyword!(case_keyword_and:          (b"and", super::AND));
683    test_keyword!(case_keyword_array:        (b"array", super::ARRAY));
684    test_keyword!(case_keyword_as:           (b"as", super::AS));
685    test_keyword!(case_keyword_break:        (b"break", super::BREAK));
686    test_keyword!(case_keyword_callable:     (b"callable", super::CALLABLE));
687    test_keyword!(case_keyword_case:         (b"case", super::CASE));
688    test_keyword!(case_keyword_catch:        (b"catch", super::CATCH));
689    test_keyword!(case_keyword_class:        (b"class", super::CLASS));
690    test_keyword!(case_keyword_clone:        (b"clone", super::CLONE));
691    test_keyword!(case_keyword_const:        (b"const", super::CONST));
692    test_keyword!(case_keyword_continue:     (b"continue", super::CONTINUE));
693    test_keyword!(case_keyword_declare:      (b"declare", super::DECLARE));
694    test_keyword!(case_keyword_default:      (b"default", super::DEFAULT));
695    test_keyword!(case_keyword_die:          (b"die", super::DIE));
696    test_keyword!(case_keyword_do:           (b"do", super::DO));
697    test_keyword!(case_keyword_echo:         (b"echo", super::ECHO));
698    test_keyword!(case_keyword_else:         (b"else", super::ELSE));
699    test_keyword!(case_keyword_elseif:       (b"elseif", super::ELSEIF));
700    test_keyword!(case_keyword_empty:        (b"empty", super::EMPTY));
701    test_keyword!(case_keyword_enddeclare:   (b"enddeclare", super::ENDDECLARE));
702    test_keyword!(case_keyword_endfor:       (b"endfor", super::ENDFOR));
703    test_keyword!(case_keyword_endforeach:   (b"endforeach", super::ENDFOREACH));
704    test_keyword!(case_keyword_endif:        (b"endif", super::ENDIF));
705    test_keyword!(case_keyword_endswitch:    (b"endswitch", super::ENDSWITCH));
706    test_keyword!(case_keyword_endwhile:     (b"endwhile", super::ENDWHILE));
707    test_keyword!(case_keyword_eval:         (b"eval", super::EVAL));
708    test_keyword!(case_keyword_exit:         (b"exit", super::EXIT));
709    test_keyword!(case_keyword_extends:      (b"extends", super::EXTENDS));
710    test_keyword!(case_keyword_final:        (b"final", super::FINAL));
711    test_keyword!(case_keyword_finally:      (b"finally", super::FINALLY));
712    test_keyword!(case_keyword_for:          (b"for", super::FOR));
713    test_keyword!(case_keyword_foreach:      (b"foreach", super::FOREACH));
714    test_keyword!(case_keyword_function:     (b"function", super::FUNCTION));
715    test_keyword!(case_keyword_global:       (b"global", super::GLOBAL));
716    test_keyword!(case_keyword_goto:         (b"goto", super::GOTO));
717    test_keyword!(case_keyword_if:           (b"if", super::IF));
718    test_keyword!(case_keyword_implements:   (b"implements", super::IMPLEMENTS));
719    test_keyword!(case_keyword_include:      (b"include", super::INCLUDE));
720    test_keyword!(case_keyword_include_once: (b"include_once", super::INCLUDE_ONCE));
721    test_keyword!(case_keyword_instanceof:   (b"instanceof", super::INSTANCEOF));
722    test_keyword!(case_keyword_insteadof:    (b"insteadof", super::INSTEADOF));
723    test_keyword!(case_keyword_interface:    (b"interface", super::INTERFACE));
724    test_keyword!(case_keyword_isset:        (b"isset", super::ISSET));
725    test_keyword!(case_keyword_list:         (b"list", super::LIST));
726    test_keyword!(case_keyword_namespace:    (b"namespace", super::NAMESPACE));
727    test_keyword!(case_keyword_new:          (b"new", super::NEW));
728    test_keyword!(case_keyword_or:           (b"or", super::OR));
729    test_keyword!(case_keyword_print:        (b"print", super::PRINT));
730    test_keyword!(case_keyword_private:      (b"private", super::PRIVATE));
731    test_keyword!(case_keyword_protected:    (b"protected", super::PROTECTED));
732    test_keyword!(case_keyword_public:       (b"public", super::PUBLIC));
733    test_keyword!(case_keyword_require:      (b"require", super::REQUIRE));
734    test_keyword!(case_keyword_require_once: (b"require_once", super::REQUIRE_ONCE));
735    test_keyword!(case_keyword_return:       (b"return", super::RETURN));
736    test_keyword!(case_keyword_static:       (b"static", super::STATIC));
737    test_keyword!(case_keyword_switch:       (b"switch", super::SWITCH));
738    test_keyword!(case_keyword_throw:        (b"throw", super::THROW));
739    test_keyword!(case_keyword_trait:        (b"trait", super::TRAIT));
740    test_keyword!(case_keyword_try:          (b"try", super::TRY));
741    test_keyword!(case_keyword_unset:        (b"unset", super::UNSET));
742    test_keyword!(case_keyword_use:          (b"use", super::USE));
743    test_keyword!(case_keyword_var:          (b"var", super::VAR));
744    test_keyword!(case_keyword_while:        (b"while", super::WHILE));
745    test_keyword!(case_keyword_xor:          (b"xor", super::XOR));
746    test_keyword!(case_keyword_yield:        (b"yield", super::YIELD));
747    test_keyword!(case_keyword_yield_from:   (b"yield from", super::YIELD_FROM));
748
749    test_keyword!(case_keyword_yield_from_with_many_whitespaces: (b"yield  \t \t \n \n \r \r  from", super::YIELD_FROM));
750
751    #[test]
752    fn case_invalid_keyword() {
753        assert_eq!(keywords(b"hello"), Result::Error(Error::Position(ErrorKind::Alt, &b"hello"[..])));
754    }
755}