fixed accelerator problem; slightly improved PHP Perspective
[phpeclipse.git] / net.sourceforge.phpeclipse / src / test / PHPParser2.jj
1 options {
2   LOOKAHEAD = 1;
3   CHOICE_AMBIGUITY_CHECK = 2;
4   OTHER_AMBIGUITY_CHECK = 1;
5   STATIC = true;
6   DEBUG_PARSER = false;
7   DEBUG_LOOKAHEAD = false;
8   DEBUG_TOKEN_MANAGER = false;
9   ERROR_REPORTING = true;
10   JAVA_UNICODE_ESCAPE = false;
11   UNICODE_INPUT = false;
12   IGNORE_CASE = true;
13   USER_TOKEN_MANAGER = false;
14   USER_CHAR_STREAM = false;
15   BUILD_PARSER = true;
16   BUILD_TOKEN_MANAGER = true;
17   SANITY_CHECK = true;
18   FORCE_LA_CHECK = false;
19 }
20
21 PARSER_BEGIN(PHPParser2)
22 package test;
23
24 import org.eclipse.core.resources.IFile;
25 import org.eclipse.core.runtime.CoreException;
26
27 /**
28  * A new php parser.
29  * This php parser is inspired by the Java 1.2 grammar example 
30  * given with JavaCC. You can get JavaCC at http://www.webgain.com
31  * You can test the parser with the PHPParserTestCase2.java
32  * @author Matthieu Casanova
33  */
34 public class PHPParser2 {
35   
36   public PHPParser2(IFile fileToParse) throws CoreException {
37           this(fileToParse.getContents());
38   }
39   
40   public void parse() throws ParseException {
41           phpFile();
42   }
43   public static void main(String args[]) throws ParseException {
44     PHPParser2 parser = new PHPParser2(System.in);
45   }
46
47 }
48
49 PARSER_END(PHPParser2)
50
51
52 /* WHITE SPACE */
53
54 SKIP :
55 {
56   " "
57 | "\t"
58 | "\n"
59 | "\r"
60 | "\f"
61 }
62
63 /* COMMENTS */
64
65 MORE :
66 {
67   "//" : IN_SINGLE_LINE_COMMENT
68 |
69   <"/**" ~["/"]> { input_stream.backup(1); } : IN_FORMAL_COMMENT
70 |
71   "/*" : IN_MULTI_LINE_COMMENT
72 }
73
74 <IN_SINGLE_LINE_COMMENT>
75 SPECIAL_TOKEN :
76 {
77   <SINGLE_LINE_COMMENT: "\n" | "\r" | "\r\n" > : DEFAULT
78 }
79
80 <IN_FORMAL_COMMENT>
81 SPECIAL_TOKEN :
82 {
83   <FORMAL_COMMENT: "*/" > : DEFAULT
84 }
85
86 <IN_MULTI_LINE_COMMENT>
87 SPECIAL_TOKEN :
88 {
89   <MULTI_LINE_COMMENT: "*/" > : DEFAULT
90 }
91
92 <IN_SINGLE_LINE_COMMENT,IN_FORMAL_COMMENT,IN_MULTI_LINE_COMMENT>
93 MORE :
94 {
95   < ~[] >
96 }
97
98 /* KEYWORDS */
99 TOKEN :
100 {
101   <CLASS : "class">
102 | <FUNCTION : "function">
103 | <VAR      : "var">
104 | <IF       : "if">
105 | <ELSEIF   : "elseif">
106 | <ELSE     : "else">
107 | <ARRAY    : "array">
108 }
109
110 /* LANGUAGE CONSTRUCT */
111 TOKEN :
112 {
113   <ECHO : "echo">
114 | <GLOBAL : "global">
115 | <STATIC : "static">
116 }
117
118 /* RESERVED WORDS AND LITERALS */
119
120 TOKEN :
121 {
122   < BREAK: "break" >
123 | < CASE: "case" >
124 | < CONST: "const" >
125 | < CONTINUE: "continue" >
126 | < _DEFAULT: "default" >
127 | < DO: "do" >
128 | < EXTENDS: "extends" >
129 | < FALSE: "false" >
130 | < FOR: "for" >
131 | < GOTO: "goto" >
132 | < NEW: "new" >
133 | < NULL: "null" >
134 | < RETURN: "return" >
135 | < SUPER: "super" >
136 | < SWITCH: "switch" >
137 | < THIS: "this" >
138 | < TRUE: "true" >
139 | < WHILE: "while" >
140 }
141
142 /* TYPES */
143
144 TOKEN :
145 {
146   <STRING : "string">
147 | <OBJECT : "object">
148 | <BOOL : "bool">
149 | <BOOLEAN : "boolean">
150 | <REAL : "real">
151 | <DOUBLE : "double">
152 | <FLOAT : "float">
153 | <INT : "int">
154 | <INTEGER : "integer">
155 }
156
157 TOKEN :
158 {
159   < _ORL: "OR" >
160 | < _ANDL: "AND" >
161 }
162
163 /* LITERALS */
164
165 TOKEN :
166 {
167   < INTEGER_LITERAL:
168         <DECIMAL_LITERAL> (["l","L"])?
169       | <HEX_LITERAL> (["l","L"])?
170       | <OCTAL_LITERAL> (["l","L"])?
171   >
172 |
173   < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* >
174 |
175   < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
176 |
177   < #OCTAL_LITERAL: "0" (["0"-"7"])* >
178 |
179   < FLOATING_POINT_LITERAL:
180         (["0"-"9"])+ "." (["0"-"9"])* (<EXPONENT>)? (["f","F","d","D"])?
181       | "." (["0"-"9"])+ (<EXPONENT>)? (["f","F","d","D"])?
182       | (["0"-"9"])+ <EXPONENT> (["f","F","d","D"])?
183       | (["0"-"9"])+ (<EXPONENT>)? ["f","F","d","D"]
184   >
185 |
186   < #EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
187 |
188   < STRING_LITERAL: (<STRING_1> | <STRING_2> | <STRING_3>)>
189 |    < STRING_1:
190       "\""
191       (   (~["\""])
192         | "\\\""
193       )*
194       "\""
195     >
196 |    < STRING_2:
197       "'"
198       (   (~["'"]))*
199
200       "'"
201     >
202 |   < STRING_3:
203       "`"
204       (   (~["`"]))*
205       "`"
206     >
207 }
208
209 /* IDENTIFIERS */
210
211 TOKEN :
212 {
213   < IDENTIFIER: (<LETTER>|<SPECIAL>) (<LETTER>|<DIGIT>|<SPECIAL>)* >
214 |
215   < #LETTER:
216       ["a"-"z"] | ["A"-"Z"]
217   >
218 |
219   < #DIGIT:
220       ["0"-"9"]
221   >
222 |
223   < #SPECIAL:
224     "_"
225   >
226 }
227
228 /* SEPARATORS */
229
230 TOKEN :
231 {
232   < LPAREN: "(" >
233 | < RPAREN: ")" >
234 | < LBRACE: "{" >
235 | < RBRACE: "}" >
236 | < LBRACKET: "[" >
237 | < RBRACKET: "]" >
238 | < SEMICOLON: ";" >
239 | < COMMA: "," >
240 | < DOT: "." >
241 }
242
243 /* OPERATORS */
244
245 TOKEN :
246 {
247   < ASSIGN: "=" >
248 | < GT: ">" >
249 | < LT: "<" >
250 | < BANG: "!" >
251 | < TILDE: "~" >
252 | < HOOK: "?" >
253 | < COLON: ":" >
254 | < EQ: "==" >
255 | < LE: "<=" >
256 | < GE: ">=" >
257 | < NE: "!=" >
258 | < SC_OR: "||" >
259 | < SC_AND: "&&" >
260 | < INCR: "++" >
261 | < DECR: "--" >
262 | < PLUS: "+" >
263 | < MINUS: "-" >
264 | < STAR: "*" >
265 | < SLASH: "/" >
266 | < BIT_AND: "&" >
267 | < BIT_OR: "|" >
268 | < XOR: "^" >
269 | < REM: "%" >
270 | < LSHIFT: "<<" >
271 | < RSIGNEDSHIFT: ">>" >
272 | < RUNSIGNEDSHIFT: ">>>" >
273 | < PLUSASSIGN: "+=" >
274 | < MINUSASSIGN: "-=" >
275 | < STARASSIGN: "*=" >
276 | < SLASHASSIGN: "/=" >
277 | < ANDASSIGN: "&=" >
278 | < ORASSIGN: "|=" >
279 | < XORASSIGN: "^=" >
280 | < REMASSIGN: "%=" >
281 | < LSHIFTASSIGN: "<<=" >
282 | < RSIGNEDSHIFTASSIGN: ">>=" >
283 | < RUNSIGNEDSHIFTASSIGN: ">>>=" >
284 }
285
286
287 /*****************************************
288  * THE JAVA LANGUAGE GRAMMAR STARTS HERE *
289  *****************************************/
290
291 /*
292  * Program structuring syntax follows.
293  */
294
295 void phpFile() :
296 {}
297 {
298   (BlockStatement())*
299   <EOF>
300 }
301
302 void ClassDeclaration() :
303 {}
304 {
305   "class" <IDENTIFIER> [ "extends" <IDENTIFIER> ]
306   ClassBody()
307 }
308
309 void ClassBody() :
310 {}
311 {
312   "{" ( ClassBodyDeclaration() )* "}"
313 }
314
315 void ClassBodyDeclaration() :
316 {}
317 {
318   MethodDeclaration()
319 |
320   FieldDeclaration()
321 }
322
323 void FieldDeclaration() :
324 {}
325 {
326   "var" VariableDeclarator() ( "," VariableDeclarator() )* ";"
327 }
328
329 void VariableDeclarator() :
330 {}
331 {
332   VariableDeclaratorId() [ "=" VariableInitializer() ]
333 }
334
335 void VariableDeclaratorId() :
336 {}
337 {
338   "$" VariableName() ( LOOKAHEAD(2) VariableSuffix() )*
339 }
340
341 void VariableName():
342 {}
343 {
344   "this"
345 |
346   "{" Expression() "}"
347 |
348   <IDENTIFIER> ("{" Expression() "}") *
349 |
350   "$" VariableName()
351 }
352
353 void VariableInitializer() :
354 {}
355 {
356   Expression()
357 }
358
359 void ArrayVariable() :
360 {}
361 {
362   Expression() ("=>" Expression())*
363 }
364
365 void ArrayInitializer() :
366 {}
367 {
368   "(" [ ArrayVariable() ( LOOKAHEAD(2) "," ArrayVariable() )* ] [ "," ] ")"
369 }
370
371 void MethodDeclaration() :
372 {}
373 {
374   "function" MethodDeclarator()
375   ( Block() | ";" )
376 }
377
378 void MethodDeclarator() :
379 {}
380 {
381   ["&"] <IDENTIFIER> FormalParameters()
382 }
383
384 void FormalParameters() :
385 {}
386 {
387   "(" [ FormalParameter() ( "," FormalParameter() )* ] ")"
388 }
389
390 void FormalParameter() :
391 {}
392 {
393   ["&"] VariableDeclarator()
394 }
395
396 void Type() :
397 {}
398 {
399   "string"
400 |
401   "bool"
402 |
403   "boolean"
404 |
405   "real"
406 |
407   "double"
408 |
409   "float"
410 |
411   "int"
412 |
413   "integer"
414 }
415
416 /*
417  * Expression syntax follows.
418  */
419
420 void Expression() :
421 /*
422  * This expansion has been written this way instead of:
423  *   Assignment() | ConditionalExpression()
424  * for performance reasons.
425  * However, it is a weakening of the grammar for it allows the LHS of
426  * assignments to be any conditional expression whereas it can only be
427  * a primary expression.  Consider adding a semantic predicate to work
428  * around this.
429  */
430 {}
431 {
432   ConditionalExpression()
433   [
434     AssignmentOperator() Expression()
435   ]
436 }
437
438 void AssignmentOperator() :
439 {}
440 {
441   "=" | "*=" | "/=" | "%=" | "+=" | "-=" | "<<=" | ">>=" | ">>>=" | "&=" | "^=" | "|=" | ".="
442 }
443
444 void ConditionalExpression() :
445 {}
446 {
447   ConditionalOrExpression() [ "?" Expression() ":" ConditionalExpression() ]
448 }
449
450 void ConditionalOrExpression() :
451 {}
452 {
453   ConditionalAndExpression() ( ("||" | "OR") ConditionalAndExpression() )*
454 }
455
456 void ConditionalAndExpression() :
457 {}
458 {
459   ConcatExpression() ( ("&&" | "AND") ConcatExpression() )*
460 }
461
462 void ConcatExpression() :
463 {}
464 {
465   InclusiveOrExpression() ( "." InclusiveOrExpression() )*
466 }
467
468 void InclusiveOrExpression() :
469 {}
470 {
471   ExclusiveOrExpression() ( "|" ExclusiveOrExpression() )*
472 }
473
474 void ExclusiveOrExpression() :
475 {}
476 {
477   AndExpression() ( "^" AndExpression() )*
478 }
479
480 void AndExpression() :
481 {}
482 {
483   EqualityExpression() ( "&" EqualityExpression() )*
484 }
485
486 void EqualityExpression() :
487 {}
488 {
489   RelationalExpression() ( ( "==" | "!=" ) RelationalExpression() )*
490 }
491
492 void RelationalExpression() :
493 {}
494 {
495   ShiftExpression() ( ( "<" | ">" | "<=" | ">=" ) ShiftExpression() )*
496 }
497
498 void ShiftExpression() :
499 {}
500 {
501   AdditiveExpression() ( ( "<<" | ">>" | ">>>" ) AdditiveExpression() )*
502 }
503
504 void AdditiveExpression() :
505 {}
506 {
507   MultiplicativeExpression() ( ( "+" | "-" ) MultiplicativeExpression() )*
508 }
509
510 void MultiplicativeExpression() :
511 {}
512 {
513   UnaryExpression() ( ( "*" | "/" | "%" ) UnaryExpression() )*
514 }
515
516 void UnaryExpression() :
517 {}
518 {
519   "@" UnaryExpression()
520 |
521   ( "+" | "-" ) UnaryExpression()
522 |
523   PreIncrementExpression()
524 |
525   PreDecrementExpression()
526 |
527   UnaryExpressionNotPlusMinus()
528 }
529
530 void PreIncrementExpression() :
531 {}
532 {
533   "++" PrimaryExpression()
534 }
535
536 void PreDecrementExpression() :
537 {}
538 {
539   "--" PrimaryExpression()
540 }
541
542 void UnaryExpressionNotPlusMinus() :
543 {}
544 {
545   ( "~" | "!" ) UnaryExpression()
546 |
547   LOOKAHEAD( "(" Type() ")" )
548   CastExpression()
549 |
550   PostfixExpression()
551 |
552   Literal()
553 |
554   "("Expression()")"
555 }
556
557 void CastExpression() :
558 {}
559 {
560   "(" Type() ")" UnaryExpression()
561 }
562
563 void PostfixExpression() :
564 {}
565 {
566   PrimaryExpression() [ "++" | "--" ]
567 }
568
569 void PrimaryExpression() :
570 {}
571 {
572   LOOKAHEAD(2)
573   <IDENTIFIER> "::" ClassIdentifier() (PrimarySuffix())*
574 |
575   PrimaryPrefix() ( PrimarySuffix() )*
576 |
577   "array" ArrayInitializer()
578 }
579
580 void PrimaryPrefix() :
581 {}
582 {
583   "$this"
584 |
585   <IDENTIFIER>
586 |
587   "new" ClassIdentifier()
588 |  
589   VariableDeclaratorId()
590 }
591
592 void ClassIdentifier():
593 {}
594 {
595   <IDENTIFIER>
596 |
597   VariableDeclaratorId()
598 |
599   "$this"
600 }
601
602 void PrimarySuffix() :
603 {}
604 {
605   Arguments()
606 |
607   VariableSuffix()
608 }
609
610 void VariableSuffix() :
611 {}
612 {
613   "->" VariableName()
614
615   "[" Expression() "]"
616 }
617
618 void Literal() :
619 {}
620 {
621   <INTEGER_LITERAL>
622 |
623   <FLOATING_POINT_LITERAL>
624 |
625   <STRING_LITERAL>
626 |
627   BooleanLiteral()
628 |
629   NullLiteral()
630 }
631
632 void BooleanLiteral() :
633 {}
634 {
635   "true"
636 |
637   "false"
638 }
639
640 void NullLiteral() :
641 {}
642 {
643   "null"
644 }
645
646 void Arguments() :
647 {}
648 {
649   "(" [ ArgumentList() ] ")"
650 }
651
652 void ArgumentList() :
653 {}
654 {
655   Expression() ( "," Expression() )*
656 }
657
658 /*
659  * Statement syntax follows.
660  */
661
662 void Statement() :
663 {}
664 {
665   LOOKAHEAD(2)
666   LabeledStatement()
667 |
668   LOOKAHEAD(2)
669   Expression() ";"
670 |
671   Block()
672 |
673   EmptyStatement()
674 |
675   StatementExpression() ";"
676 |
677   SwitchStatement()
678 |
679   IfStatement()
680 |
681   WhileStatement()
682 |
683   DoStatement()
684 |
685   ForStatement()
686 |
687   BreakStatement()
688 |
689   ContinueStatement()
690 |
691   ReturnStatement()
692 |
693   EchoStatement()
694 |
695   StaticStatement()
696 |
697   GlobalStatement()
698 }
699
700 void EchoStatement() :
701 {}
702 {
703   "echo" Expression() ("," Expression())* ";"
704 }
705
706 void GlobalStatement() :
707 {}
708 {
709   "global" VariableDeclaratorId() ("," VariableDeclaratorId())* ";"
710 }
711
712 void StaticStatement() :
713 {}
714 {
715   "static" VariableDeclarator() ("," VariableDeclarator())* ";"
716 }
717
718 void LabeledStatement() :
719 {}
720 {
721   <IDENTIFIER> ":" Statement()
722 }
723
724 void Block() :
725 {}
726 {
727   "{" ( BlockStatement() )* "}"
728 }
729
730 void BlockStatement() :
731 {}
732 {
733   Statement()
734 |
735   ClassDeclaration()
736 |
737   MethodDeclaration()
738 }
739
740 void LocalVariableDeclaration() :
741 {}
742 {
743   VariableDeclarator() ( "," VariableDeclarator() )*
744 }
745
746 void EmptyStatement() :
747 {}
748 {
749   ";"
750 }
751
752 void StatementExpression() :
753 /*
754  * The last expansion of this production accepts more than the legal
755  * Java expansions for StatementExpression.  This expansion does not
756  * use PostfixExpression for performance reasons.
757  */
758 {}
759 {
760   PreIncrementExpression()
761 |
762   PreDecrementExpression()
763 |
764   PrimaryExpression()
765   [
766     "++"
767   |
768     "--"
769   |
770     AssignmentOperator() Expression()
771   ]
772 }
773
774 void SwitchStatement() :
775 {}
776 {
777   "switch" "(" Expression() ")" "{"
778     ( SwitchLabel() ( BlockStatement() )* )*
779   "}"
780 }
781
782 void SwitchLabel() :
783 {}
784 {
785   "case" Expression() ":"
786 |
787   "default" ":"
788 }
789
790 void IfStatement() :
791 /*
792  * The disambiguating algorithm of JavaCC automatically binds dangling
793  * else's to the innermost if statement.  The LOOKAHEAD specification
794  * is to tell JavaCC that we know what we are doing.
795  */
796 {}
797 {
798   "if" "(" Expression() ")" Statement() [ LOOKAHEAD(1) ElseIfStatement() ] [ LOOKAHEAD(1) "else" Statement() ]
799 }
800
801 void ElseIfStatement() :
802 {}
803 {
804   "elseif" "(" Expression() ")" Statement()
805 }
806
807 void WhileStatement() :
808 {}
809 {
810   "while" "(" Expression() ")" Statement()
811 }
812
813 void WhileStatement0() :
814 {}
815 {
816   ":" Statement() "endwhile;"
817 |
818   Statement()
819 }
820
821 void DoStatement() :
822 {}
823 {
824   "do" Statement() "while" "(" Expression() ")" ";"
825 }
826
827 void ForStatement() :
828 {}
829 {
830   "for" "(" [ ForInit() ] ";" [ Expression() ] ";" [ ForUpdate() ] ")" Statement()
831 }
832
833 void ForInit() :
834 {}
835 {
836   LOOKAHEAD(LocalVariableDeclaration())
837   LocalVariableDeclaration()
838 |
839   StatementExpressionList()
840 }
841
842 void StatementExpressionList() :
843 {}
844 {
845   StatementExpression() ( "," StatementExpression() )*
846 }
847
848 void ForUpdate() :
849 {}
850 {
851   StatementExpressionList()
852 }
853
854 void BreakStatement() :
855 {}
856 {
857   "break" [ <IDENTIFIER> ] ";"
858 }
859
860 void ContinueStatement() :
861 {}
862 {
863   "continue" [ <IDENTIFIER> ] ";"
864 }
865
866 void ReturnStatement() :
867 {}
868 {
869   "return" [ Expression() ] ";"
870 }