Two interfaces added for outlineable objects
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / parser / Parser.java
1 /**********************************************************************
2 Copyright (c) 2002 Klaus Hartlage - www.eclipseproject.de
3 All rights reserved. This program and the accompanying materials
4 are made available under the terms of the Common Public License v1.0
5 which accompanies this distribution, and is available at
6 http://www.eclipse.org/legal/cpl-v10.html
7
8 Contributors:
9     Klaus Hartlage - www.eclipseproject.de
10 **********************************************************************/
11 package net.sourceforge.phpdt.internal.compiler.parser;
12
13 import java.util.ArrayList;
14 import java.util.Hashtable;
15
16 import net.sourceforge.phpdt.core.compiler.*;
17 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
18 import net.sourceforge.phpeclipse.phpeditor.PHPString;
19
20 import org.eclipse.core.resources.IFile;
21 import org.eclipse.core.resources.IMarker;
22 import org.eclipse.core.runtime.CoreException;
23 import org.eclipse.jface.preference.IPreferenceStore;
24 import org.eclipse.ui.texteditor.MarkerUtilities;
25 import test.PHPParserSuperclass;
26
27 public class Parser extends PHPParserSuperclass implements ITerminalSymbols {
28
29   //scanner token
30   public Scanner scanner;
31
32   private IFile fileToParse;
33   private ArrayList phpList;
34
35   private int currentPHPString;
36   private boolean phpEnd;
37
38   // private static HashMap keywordMap = null;
39   private String str;
40
41   // current character
42   //  char ch;
43   // current token
44   int token;
45
46   // row counter for syntax errors:
47   //int rowCount;
48   // column counter for syntax errors:
49   //int columnCount;
50
51   //int chIndx;
52   //
53   //    // current identifier
54   //    String identifier;
55
56   Long longNumber;
57   Double doubleNumber;
58
59   private String stringValue;
60
61   /** Contains the current expression. */
62   // private StringBuffer expression;
63
64   private boolean phpMode;
65
66   //    final static int TokenNameEOF = 0;
67   //    final static int TokenNameERROR = 1;
68   //    final static int TokenNameHTML = 2;
69   //
70   //    final static int TokenNameREMAINDER = 30;
71   //    final static int TokenNameNOT = 31;
72   //    final static int TokenNameDOT = 32;
73   //    final static int TokenNameXOR = 33;
74   //    final static int TokenNameDIVIDE = 34;
75   //    final static int TokenNameMULTIPLY = 35;
76   //    final static int TokenNameMINUS = 36;
77   //    final static int TokenNamePLUS = 37;
78   //    final static int TokenNameEQUAL_EQUAL = 38;
79   //    final static int TokenNameNOT_EQUAL = 39;
80   //    final static int TokenNameGREATER = 40;
81   //    final static int TokenNameGREATER_EQUAL = 41;
82   //    final static int TokenNameLESS = 42;
83   //    final static int TokenNameLESS_EQUAL = 43;
84   //    final static int TokenNameAND_AND = 44;
85   //    final static int TokenNameOR_OR = 45;
86   //    // final static int TokenNameHASH = 46; 
87   //    final static int TokenNameCOLON = 47;
88   //    final static int TokenNameDOT_EQUAL = 48;
89   //
90   //    final static int TokenNameEQUAL = 49;
91   //    final static int TokenNameMINUS_GREATER = 50; // ->
92   //    final static int TokenNameFOREACH = 51;
93   //    final static int TokenNameAND = 52;
94   //    //final static int TokenNameDOLLARLISTOPEN = 53;
95   //    final static int TokenNameTWIDDLE = 54;
96   //    final static int TokenNameTWIDDLE_EQUAL = 55;
97   //    final static int TokenNameREMAINDER_EQUAL = 56;
98   //    final static int TokenNameXOR_EQUAL = 57;
99   //    final static int TokenNameRIGHT_SHIFT_EQUAL = 58;
100   //    final static int TokenNameLEFT_SHIFT_EQUAL = 59;
101   //    final static int TokenNameAND_EQUAL = 60;
102   //    final static int TokenNameOR_EQUAL = 61;
103   //    final static int TokenNameQUESTION = 62;
104   //    final static int TokenNameCOLON_COLON = 63;
105   //    final static int TokenNameAT = 63;
106   //    // final static int TokenNameHEREDOC = 64;
107   //
108   //    final static int TokenNameDOLLAROPEN = 127;
109   //    final static int TokenNameLPAREN = 128;
110   //    final static int TokenNameRPAREN = 129;
111   //    final static int TokenNameLBRACE = 130;
112   //    final static int TokenNameRBRACE = 131;
113   //    final static int TokenNameLBRACKET = 132;
114   //    final static int TokenNameRBRACKET = 133;
115   //    final static int TokenNameCOMMA = 134;
116   //
117   //    final static int TokenNameStringLiteral = 136;
118   //    final static int TokenNameIdentifier = 138;
119   //    // final static int TokenNameDIGIT = 139;
120   //    final static int TokenNameSEMICOLON = 140;
121   //    // final static int TokenNameSLOT = 141;
122   //    // final static int TokenNameSLOTSEQUENCE = 142;
123   //    final static int TokenNameMINUS_MINUS = 144;
124   //    final static int TokenNamePLUS_PLUS = 145;
125   //    final static int TokenNamePLUS_EQUAL = 146;
126   //    final static int TokenNameDIVIDE_EQUAL = 147;
127   //    final static int TokenNameMINUS_EQUAL = 148;
128   //    final static int TokenNameMULTIPLY_EQUAL = 149;
129   //    final static int TokenNameVariable = 150;
130   //    final static int TokenNameIntegerLiteral = 151;
131   //    final static int TokenNameDoubleLiteral = 152;
132   //    final static int TokenNameStringInterpolated = 153;
133   //    final static int TokenNameStringConstant = 154;
134   //
135   //    final static int TokenNameLEFT_SHIFT = 155;
136   //    final static int TokenNameRIGHT_SHIFT = 156;
137   //    final static int TokenNameEQUAL_EQUAL_EQUAL = 157;
138   //    final static int TokenNameNOT_EQUAL_EQUAL = 158;
139   //    final static int TokenNameOR = 159;
140   //  final static int TokenNameAT = 153; // @
141
142   public Parser() {
143   }
144
145   public void setFileToParse(IFile fileToParse) {
146     this.currentPHPString = 0;
147     this.fileToParse = fileToParse;
148     this.phpList = null;
149     this.str = "";
150     this.token = TokenNameEOF;
151     this.phpEnd = false;
152     this.initializeScanner();
153   }
154   /**
155    *  ClassDeclaration Constructor.
156    *
157    *@param  s
158    *@param  sess  Description of Parameter
159    *@see
160    */
161   public Parser(IFile fileToParse) {
162     //    if (keywordMap == null) {
163     //      keywordMap = new HashMap();
164     //      for (int i = 0; i < PHP_KEYWORS.length; i++) {
165     //        keywordMap.put(PHP_KEYWORS[i], new Integer(PHP_KEYWORD_TOKEN[i]));
166     //      }
167     //    }
168     this.currentPHPString = 0;
169     this.fileToParse = fileToParse;
170     this.phpList = null;
171     this.str = "";
172     this.token = TokenNameEOF;
173     //    this.chIndx = 0;
174     //    this.rowCount = 1;
175     //    this.columnCount = 0;
176     this.phpEnd = false;
177     //   getNextToken();
178
179     this.initializeScanner();
180   }
181
182   public void initializeScanner() {
183     this.scanner = new Scanner(false, false, false, false);
184   }
185   /**
186    * Create marker for the parse error
187    */
188   private void setMarker(
189     String message,
190     int charStart,
191     int charEnd,
192     int errorLevel)
193     throws CoreException {
194     setMarker(fileToParse, message, charStart, charEnd, errorLevel);
195   }
196
197   /**
198    * This method will throw the SyntaxError.
199    * It will add the good lines and columns to the Error
200    * @param error the error message
201    * @throws SyntaxError the error raised
202    */
203   private void throwSyntaxError(String error) {
204
205     //    if (str.length() < chIndx) {
206     //      chIndx--;
207     //    }
208     //    // read until end-of-line
209     //    int eol = chIndx;
210     //    while (str.length() > eol) {
211     //      ch = str.charAt(eol++);
212     //      if (ch == '\n') {
213     //        eol--;
214     //        break;
215     //      }
216     //    }
217     //    throw new SyntaxError(
218     //      rowCount,
219     //      chIndx - columnCount + 1,
220     //      str.substring(columnCount, eol),
221     //      error);
222     throw new SyntaxError(1, 1, "", error);
223   }
224
225   /**
226    * This method will throw the SyntaxError.
227    * It will add the good lines and columns to the Error
228    * @param error the error message
229    * @throws SyntaxError the error raised
230    */
231   private void throwSyntaxError(String error, int startRow) {
232     throw new SyntaxError(startRow, 0, " ", error);
233   }
234
235   /**
236    *  Method Declaration.
237    *
238    *@see
239    */
240   //  private void getChar() {
241   //    if (str.length() > chIndx) {
242   //      ch = str.charAt(chIndx++);
243   //
244   //      return;
245   //    }
246   //
247   //    chIndx = str.length() + 1;
248   //    ch = ' ';
249   //    //  token = TokenNameEOF;
250   //    phpEnd = true;
251   //  }
252
253   /**
254    * gets the next token from input
255    */
256   private void getNextToken() throws CoreException {
257     try {
258       token = scanner.getNextToken();
259       if (Scanner.DEBUG) {
260         int currentEndPosition = scanner.getCurrentTokenEndPosition();
261         int currentStartPosition = scanner.getCurrentTokenStartPosition();
262
263         System.out.print(
264           currentStartPosition + "," + currentEndPosition + ": ");
265         System.out.println(scanner.toStringAction(token));
266       }
267     } catch (InvalidInputException e) {
268       token = TokenNameERROR;
269     }
270     return;
271
272     //          boolean phpFound = false;
273     //          char ch2;
274     //
275     //          phpEnd = false;
276     //          try {
277     //                  if (!phpMode) {
278     //
279     //                          while (str.length() > chIndx) {
280     //                                  token = TokenNameERROR;
281     //                                  ch = str.charAt(chIndx++);
282     //
283     //                                  if (ch == '\n') {
284     //                                          rowCount++;
285     //                                  }
286     //                                  if (ch == '<') {
287     //                                          ch2 = str.charAt(chIndx++);
288     //                                          if (ch2 == '?') {
289     //                                                  ch2 = str.charAt(chIndx++);
290     //                                                  if (Character.isWhitespace(ch2)) {
291     //                                                          // php start
292     //                                                          phpMode = true;
293     //                                                          phpFound = true;
294     //                                                          break;
295     //                                                  } else if (ch2 == 'p' || ch2 == 'P') {
296     //                                                          ch2 = str.charAt(chIndx++);
297     //                                                          if (ch2 == 'h' || ch2 == 'H') {
298     //                                                                  ch2 = str.charAt(chIndx++);
299     //                                                                  if (ch2 == 'p' || ch2 == 'P') {
300     //                                                                          phpMode = true;
301     //                                                                          phpFound = true;
302     //                                                                          break;
303     //                                                                  }
304     //                                                                  chIndx--;
305     //                                                          }
306     //                                                          chIndx--;
307     //                                                  }
308     //                                                  chIndx--;
309     //                                          }
310     //                                          chIndx--;
311     //                                  }
312     //                          }
313     //
314     //                  }
315     //
316     //                  if (phpMode) {
317     //                          while (str.length() > chIndx) {
318     //                                  ch = str.charAt(chIndx++);
319     //                                  token = TokenNameERROR;
320     //                                  if (ch == '\n') {
321     //                                          rowCount++;
322     //                                          columnCount = chIndx;
323     //                                          continue; // while loop
324     //                                  }
325     //                                  if (str.length() == chIndx) {
326     //                                          phpEnd = true;
327     //                                  }
328     //                                  if (!Character.isWhitespace(ch)) {
329     //                                          if (ch == '$') {
330     //                                                  if (str.length() > chIndx) {
331     //                                                          if (str.charAt(chIndx) == '{') {
332     //                                                                  chIndx++;
333     //                                                                  token = TokenNameDOLLAROPEN;
334     //                                                                  return;
335     //                                                          }
336     //                                                  }
337     //                                                  getIdentifier();
338     //                                                  return;
339     //                                          }
340     //                                          if ((ch >= 'a' && ch <= 'z')
341     //                                                  || (ch >= 'A' && ch <= 'Z')
342     //                                                  || (ch == '_')
343     //                                                  || (ch == '$')) {
344     //                                                  getIdentifier();
345     //                                                  return;
346     //                                          }
347     //                                          if (ch >= '0' && ch <= '9') {
348     //                                                  getNumber();
349     //                                                  return;
350     //                                          }
351     //                                          if (ch == '/') {
352     //                                                  if (str.length() > chIndx) {
353     //                                                          if (str.charAt(chIndx) == '/') {
354     //                                                                  ch = '/';
355     //                                                                  chIndx++;
356     //                                                                  // read comment until end of line:
357     //                                                                  while ((str.length() > chIndx)
358     //                                                                          && (ch != '\n')) {
359     //                                                                          ch = str.charAt(chIndx++);
360     //                                                                          if (ch == '?') {
361     //                                                                                  ch2 = str.charAt(chIndx);
362     //                                                                                  if (ch2 == '>') {
363     //                                                                                          chIndx++;
364     //                                                                                          token = TokenNameHTML;
365     //                                                                                          // php end
366     //                                                                                          phpMode = false;
367     //                                                                                          phpEnd = true;
368     //                                                                                          return;
369     //                                                                                  }
370     //                                                                          }
371     //                                                                  }
372     //                                                                  rowCount++;
373     //                                                                  continue;
374     //
375     //                                                          } else if (str.charAt(chIndx) == '*') {
376     //                                                                  chIndx++;
377     //                                                                  // multi line comment:
378     //                                                                  while (str.length() > chIndx) {
379     //                                                                          if (str.charAt(chIndx) == '*'
380     //                                                                                  && (str.length() > (chIndx + 1))
381     //                                                                                  && str.charAt(chIndx + 1) == '/') {
382     //                                                                                  chIndx += 2;
383     //                                                                                  break;
384     //                                                                          }
385     //                                                                          ch = str.charAt(chIndx++);
386     //                                                                          if (ch == '\n') {
387     //                                                                                  rowCount++;
388     //                                                                                  columnCount = chIndx;
389     //                                                                          }
390     //                                                                  }
391     //                                                                  continue;
392     //                                                          }
393     //                                                  }
394     //                                          } else if (ch == '#') {
395     //                                                  // read comment until end of line:
396     //                                                  while ((str.length() > chIndx) && (ch != '\n')) {
397     //                                                          ch = str.charAt(chIndx++);
398     //                                                          if (ch == '?') {
399     //                                                                  ch2 = str.charAt(chIndx);
400     //                                                                  if (ch2 == '>') {
401     //                                                                          chIndx++;
402     //                                                                          token = TokenNameHTML;
403     //                                                                          // php end
404     //                                                                          phpMode = false;
405     //                                                                          phpEnd = true;
406     //                                                                          return;
407     //                                                                  }
408     //                                                          }
409     //                                                  }
410     //                                                  rowCount++;
411     //                                                  continue;
412     //
413     //                                          } else if (ch == '"') {
414     //                                                  getString(
415     //                                                          '"',
416     //                                                          TokenNameStringInterpolated,
417     //                                                          "Open string character '\"' at end of file.");
418     //                                                  return;
419     //                                          } else if (ch == '\'') {
420     //                                                  getString(
421     //                                                          '\'',
422     //                                                          TokenNameStringConstant,
423     //                                                          "Open string character \"'\" at end of file.");
424     //                                                  return;
425     //                                          } else if (ch == '`') {
426     //                                                  getString(
427     //                                                          '`',
428     //                                                          TokenNameStringConstant,
429     //                                                          "Open string character \"`\" at end of file.");
430     //                                                  setMarker(
431     //                                                          "Other string delimiters prefered (found \"`\").",
432     //                                                          rowCount,
433     //                                                          PHPParser.INFO);
434     //                                                  return;
435     //                                          }
436     //
437     //                                          switch (ch) {
438     //
439     //                                                  case '(' :
440     //                                                          token = TokenNameLPAREN;
441     //
442     //                                                          break;
443     //                                                  case ')' :
444     //                                                          token = TokenNameRPAREN;
445     //
446     //                                                          break;
447     //                                                  case '{' :
448     //                                                          token = TokenNameLBRACE;
449     //
450     //                                                          break;
451     //                                                  case '}' :
452     //                                                          token = TokenNameRBRACE;
453     //
454     //                                                          break;
455     //                                                  case '[' :
456     //                                                          token = TokenNameLBRACKET;
457     //
458     //                                                          break;
459     //                                                  case ']' :
460     //                                                          token = TokenNameRBRACKET;
461     //
462     //                                                          break;
463     //                                                  case ',' :
464     //                                                          token = TokenNameCOMMA;
465     //
466     //                                                          break;
467     //                                                  case '?' :
468     //                                                          token = TokenNameQUESTION;
469     //                                                          if (str.length() > chIndx) {
470     //                                                                  if (str.charAt(chIndx) == '>') {
471     //                                                                          chIndx++;
472     //                                                                          token = TokenNameHTML;
473     //                                                                          // php end
474     //                                                                          phpMode = false;
475     //                                                                          phpEnd = true;
476     //                                                                          break;
477     //                                                                  }
478     //                                                          }
479     //
480     //                                                          break;
481     //                                                  case '@' :
482     //                                                          token = TokenNameAT;
483     //                                                          break;
484     //                                                  case '~' :
485     //                                                          token = TokenNameTWIDDLE;
486     //                                                          if (str.length() > chIndx) {
487     //                                                                  if (str.charAt(chIndx) == '=') {
488     //                                                                          chIndx++;
489     //                                                                          token = TokenNameTWIDDLE_EQUAL;
490     //
491     //                                                                          break;
492     //                                                                  }
493     //                                                          }
494     //                                                          break;
495     //                                                  case '.' :
496     //                                                          token = TokenNameDOT;
497     //                                                          if (str.length() > chIndx) {
498     //                                                                  if (str.charAt(chIndx) == '=') {
499     //                                                                          chIndx++;
500     //                                                                          token = TokenNameDOT_EQUAL;
501     //
502     //                                                                          break;
503     //                                                                  }
504     //                                                          }
505     //
506     //                                                          break;
507     //                                                  case '"' :
508     //                                                          token = TokenNameStringLiteral;
509     //
510     //                                                          break;
511     //                                                  case '%' :
512     //                                                          token = TokenNameREMAINDER;
513     //                                                          if (str.length() > chIndx) {
514     //                                                                  if (str.charAt(chIndx) == '=') {
515     //                                                                          chIndx++;
516     //                                                                          token = TokenNameREMAINDER_EQUAL;
517     //
518     //                                                                          break;
519     //                                                                  }
520     //                                                          }
521     //                                                          break;
522     //                                                  case ';' :
523     //                                                          token = TokenNameSEMICOLON;
524     //
525     //                                                          break;
526     //                                                  case '^' :
527     //                                                          token = TokenNameXOR;
528     //                                                          if (str.length() > chIndx) {
529     //                                                                  if (str.charAt(chIndx) == '=') {
530     //                                                                          chIndx++;
531     //                                                                          token = TokenNameXOR_EQUAL;
532     //
533     //                                                                          break;
534     //                                                                  }
535     //                                                          }
536     //                                                          break;
537     //                                                  case '/' :
538     //                                                          token = TokenNameDIVIDE;
539     //
540     //                                                          if (str.length() > chIndx) {
541     //                                                                  if (str.charAt(chIndx) == '=') {
542     //                                                                          chIndx++;
543     //                                                                          token = TokenNameDIVIDE_EQUAL;
544     //
545     //                                                                          break;
546     //                                                                  }
547     //                                                          }
548     //
549     //                                                          break;
550     //                                                  case '*' :
551     //                                                          token = TokenNameMULTIPLY;
552     //                                                          if (str.length() > chIndx) {
553     //                                                                  if (str.charAt(chIndx) == '*') {
554     //                                                                          chIndx++;
555     //                                                                          token = TokenNameXOR;
556     //
557     //                                                                          break;
558     //                                                                  }
559     //                                                                  if (str.charAt(chIndx) == '=') {
560     //                                                                          chIndx++;
561     //                                                                          token = TokenNameMULTIPLY_EQUAL;
562     //
563     //                                                                          break;
564     //                                                                  }
565     //                                                          }
566     //
567     //                                                          break;
568     //                                                  case '+' :
569     //                                                          token = TokenNamePLUS;
570     //                                                          if (str.length() > chIndx) {
571     //                                                                  if (str.charAt(chIndx) == '+') {
572     //                                                                          chIndx++;
573     //                                                                          token = TokenNamePLUS_PLUS;
574     //
575     //                                                                          break;
576     //                                                                  }
577     //                                                                  if (str.charAt(chIndx) == '=') {
578     //                                                                          chIndx++;
579     //                                                                          token = TokenNamePLUS_EQUAL;
580     //
581     //                                                                          break;
582     //                                                                  }
583     //                                                          }
584     //                                                          break;
585     //                                                  case '-' :
586     //                                                          token = TokenNameMINUS;
587     //                                                          if (str.length() > chIndx) {
588     //                                                                  if (str.charAt(chIndx) == '-') {
589     //                                                                          chIndx++;
590     //                                                                          token = TokenNameMINUS_MINUS;
591     //
592     //                                                                          break;
593     //                                                                  }
594     //                                                                  if (str.charAt(chIndx) == '=') {
595     //                                                                          chIndx++;
596     //                                                                          token = TokenNameMINUS_EQUAL;
597     //
598     //                                                                          break;
599     //                                                                  }
600     //                                                                  if (str.charAt(chIndx) == '>') {
601     //                                                                          chIndx++;
602     //                                                                          token = TokenNameMINUS_GREATER;
603     //
604     //                                                                          break;
605     //                                                                  }
606     //                                                          }
607     //
608     //                                                          break;
609     //                                                  case '=' :
610     //                                                          token = TokenNameEQUAL;
611     //
612     //                                                          if (str.length() > chIndx) {
613     //                                                                  ch = str.charAt(chIndx);
614     //
615     //                                                                  if (ch == '=') {
616     //                                                                          chIndx++;
617     //                                                                          token = TokenNameEQUAL_EQUAL;
618     //                                                                          if (str.length() > chIndx) {
619     //                                                                                  ch = str.charAt(chIndx);
620     //
621     //                                                                                  if (ch == '=') {
622     //                                                                                          chIndx++;
623     //                                                                                          token =
624     //                                                                                                  TokenNameEQUAL_EQUAL_EQUAL;
625     //                                                                                  }
626     //                                                                          }
627     //                                                                          break;
628     //                                                                  }
629     //                                                                  if (ch == '>') {
630     //                                                                          chIndx++;
631     //                                                                          token = TokenNameEQUAL_GREATER;
632     //
633     //                                                                          break;
634     //                                                                  }
635     //                                                          }
636     //
637     //                                                          break;
638     //                                                  case '!' :
639     //                                                          token = TokenNameNOT;
640     //
641     //                                                          if (str.length() > chIndx) {
642     //                                                                  if (str.charAt(chIndx) == '=') {
643     //                                                                          chIndx++;
644     //                                                                          token = TokenNameNOT_EQUAL;
645     //                                                                          if (str.length() > chIndx) {
646     //                                                                                  ch = str.charAt(chIndx);
647     //
648     //                                                                                  if (ch == '=') {
649     //                                                                                          chIndx++;
650     //                                                                                          token =
651     //                                                                                                  TokenNameNOT_EQUAL_EQUAL;
652     //                                                                                  }
653     //                                                                          }
654     //                                                                          break;
655     //                                                                  }
656     //                                                          }
657     //
658     //                                                          break;
659     //                                                  case '>' :
660     //                                                          token = TokenNameGREATER;
661     //
662     //                                                          if (str.length() > chIndx) {
663     //                                                                  if (str.charAt(chIndx) == '=') {
664     //                                                                          chIndx++;
665     //                                                                          token = TokenNameGREATER_EQUAL;
666     //                                                                          break;
667     //                                                                  }
668     //                                                                  if (str.charAt(chIndx) == '>') {
669     //                                                                          chIndx++;
670     //                                                                          token = TokenNameRIGHT_SHIFT;
671     //                                                                          if (str.length() > chIndx) {
672     //                                                                                  if (str.charAt(chIndx) == '=') {
673     //                                                                                          chIndx++;
674     //                                                                                          token =
675     //                                                                                                  TokenNameRIGHT_SHIFT_EQUAL;
676     //                                                                                          break;
677     //                                                                                  }
678     //                                                                          }
679     //                                                                          break;
680     //                                                                  }
681     //                                                          }
682     //
683     //                                                          break;
684     //                                                  case '<' :
685     //                                                          token = TokenNameLESS;
686     //
687     //                                                          if (str.length() > chIndx) {
688     //                                                                  if (str.charAt(chIndx) == '=') {
689     //                                                                          chIndx++;
690     //                                                                          token = TokenNameLESS_EQUAL;
691     //
692     //                                                                          break;
693     //                                                                  }
694     //                                                                  if (str.charAt(chIndx) == '<') {
695     //                                                                          chIndx++;
696     //                                                                          token = TokenNameLEFT_SHIFT;
697     //                                                                          if (str.charAt(chIndx) == '<') {
698     //                                                                                  // heredoc
699     //                                                                                  int startRow = rowCount;
700     //                                                                                  if (str.length() > chIndx) {
701     //
702     //                                                                                          ch = str.charAt(++chIndx);
703     //                                                                                          if ((ch >= 'a' && ch <= 'z')
704     //                                                                                                  || (ch >= 'A' && ch <= 'Z')
705     //                                                                                                  || (ch == '_')) {
706     //                                                                                                  chIndx++;
707     //                                                                                                  getIdentifier();
708     //                                                                                                  token =
709     //                                                                                                          TokenNameStringConstant;
710     //                                                                                                  while (str.length()
711     //                                                                                                          > chIndx) {
712     //                                                                                                          ch =
713     //                                                                                                                  str.charAt(
714     //                                                                                                                          chIndx++);
715     //                                                                                                          if (ch == '\n') {
716     //                                                                                                                  if (str.length()
717     //                                                                                                                          >= chIndx
718     //                                                                                                                                  + identifier
719     //                                                                                                                                          .length()) {
720     //                                                                                                                          if (str
721     //                                                                                                                                  .substring(
722     //                                                                                                                                          chIndx,
723     //                                                                                                                                          chIndx
724     //                                                                                                                                                  + identifier
725     //                                                                                                                                                          .length())
726     //                                                                                                                                  .equals(identifier)) {
727     //                                                                                                                                  chIndx
728     //                                                                                                                                          += identifier
729     //                                                                                                                                                  .length();
730     //                                                                                                                                  return;
731     //                                                                                                                          }
732     //                                                                                                                  }
733     //                                                                                                          }
734     //                                                                                                  }
735     //                                                                                          }
736     //                                                                                  }
737     //                                                                                  throwSyntaxError(
738     //                                                                                          "Open heredoc syntax after operator '<<<'.",
739     //                                                                                          startRow);
740     //                                                                          } else if (str.charAt(chIndx) == '=') {
741     //                                                                                  chIndx++;
742     //                                                                                  token = TokenNameLEFT_SHIFT_EQUAL;
743     //                                                                                  break;
744     //                                                                          }
745     //                                                                          break;
746     //                                                                  }
747     //                                                          }
748     //
749     //                                                          break;
750     //
751     //                                                  case '|' :
752     //                                                          token = TokenNameOR;
753     //
754     //                                                          if (str.length() > chIndx) {
755     //                                                                  if (str.charAt(chIndx) == '|') {
756     //                                                                          chIndx++;
757     //                                                                          token = TokenNameOR_OR;
758     //                                                                          break;
759     //                                                                  }
760     //                                                                  if (str.charAt(chIndx) == '=') {
761     //                                                                          chIndx++;
762     //                                                                          token = TokenNameOR_EQUAL;
763     //                                                                          break;
764     //                                                                  }
765     //                                                          }
766     //
767     //                                                          break;
768     //                                                  case '&' :
769     //                                                          token = TokenNameAND;
770     //                                                          if (str.length() > chIndx) {
771     //                                                                  if (str.charAt(chIndx) == '&') {
772     //                                                                          chIndx++;
773     //                                                                          token = TokenNameAND_AND;
774     //                                                                          break;
775     //                                                                  }
776     //                                                                  if (str.charAt(chIndx) == '=') {
777     //                                                                          chIndx++;
778     //                                                                          token = TokenNameAND_EQUAL;
779     //                                                                          break;
780     //                                                                  }
781     //                                                                  break;
782     //                                                          }
783     //
784     //                                                          break;
785     //                                                  case ':' :
786     //                                                          token = TokenNameCOLON;
787     //                                                          if (str.length() > chIndx) {
788     //                                                                  if (str.charAt(chIndx) == ':') {
789     //                                                                          chIndx++;
790     //                                                                          token = TokenNameCOLON_COLON;
791     //                                                                  }
792     //                                                          }
793     //                                                          break;
794     //                                                          //              case '#' :
795     //                                                          //                token = TokenNameHASH;
796     //                                                          //
797     //                                                          //                break;
798     //                                                          //          case '@' :
799     //                                                          //            token = TokenNameAT;
800     //                                                          //
801     //                                                          //            break;
802     //                                                  default :
803     //                                                          throwSyntaxError(
804     //                                                                  "unexpected character: '" + ch + "'");
805     //                                          }
806     //
807     //                                          if (token == TokenNameERROR) {
808     //                                                  throwSyntaxError("token not found");
809     //                                          }
810     //
811     //                                          return;
812     //                                  }
813     //                          }
814     //                  }
815     //          } catch (StringIndexOutOfBoundsException e) {
816     //                  // catched from charAt
817     //          }
818     //
819     //          chIndx = str.length() + 1;
820     //          ch = ' ';
821     //          token = TokenNameEOF;
822     //          phpEnd = true;
823     //          //PHPString temp;
824     //          //    if (phpList != null) {
825     //          //      if (currentPHPString < phpList.size()) {
826     //          //        token = TokenNameUNDEFINED;
827     //          //        temp = (PHPString) phpList.get(currentPHPString++);
828     //          //        this.str = temp.getPHPString();
829     //          //        this.token = TokenNameEOF;
830     //          //        this.chIndx = 0;
831     //          //        this.rowCount = temp.getLineNumber();
832     //          //        this.columnCount = 0;
833     //          //        getNextToken();
834     //          //        phpEnd = true;
835     //          //      } else {
836     //          //        token = TokenNameUNDEFINED;
837     //          //        return;
838     //          //      }
839     //          //    }
840   }
841
842   //    /**
843   //     * Get an identifier.
844   //     */
845   //    private void getIdentifier() {
846   //            //  StringBuffer ident = new StringBuffer();
847   //            int startPosition = chIndx - 1;
848   //            //    ident.append(ch);
849   //            if (ch == '$') {
850   //                    getChar();
851   //                    // attention recursive call:
852   //                    getIdentifier();
853   //                    token = TokenNameVariable;
854   //                    return;
855   //            } else {
856   //                    token = TokenNameIdentifier;
857   //            }
858   //
859   //            getChar();
860   //
861   //            //this will read the buffer until the next character is a forbidden character for identifier
862   //            while ((ch >= 'a' && ch <= 'z')
863   //                    || (ch >= 'A' && ch <= 'Z')
864   //                    || (ch >= '0' && ch <= '9')
865   //                    || (ch == '_')) {
866   //                    //    ident.append(ch);
867   //                    getChar();
868   //            }
869   //            int endPosition = chIndx--;
870   //            int length = (--endPosition) - startPosition;
871   //
872   //            identifier = str.substring(startPosition, endPosition);
873   //            // System.out.println(identifier);
874   //
875   //            // determine if this identitfer is a keyword
876   //            // @todo improve this in future version
877   //            Integer i = (Integer) keywordMap.get(identifier.toLowerCase());
878   //            if (i != null) {
879   //                    token = i.intValue();
880   //            }
881   //    }
882
883   /**
884    * Get a number.
885    * if it's a <code>double</code> the number will be stored in <code>doubleNumber</code> and the token will have the
886    * value {@link Parser#TokenNameDOUBLE_NUMBER}<br />
887    * if it's a <code>double</code> the number will be stored in <code>longNumber</code> and the token will have the
888    * value {@link Parser#TokenNameINT_NUMBER}
889    */
890   //  private void getNumber() {
891   //    StringBuffer inum = new StringBuffer();
892   //    char dFlag = ' ';
893   //    int numFormat = 10;
894   //
895   //    // save first digit
896   //    char firstCh = ch;
897   //    inum.append(ch);
898   //
899   //    getChar();
900   //    // determine number conversions:
901   //    if (firstCh == '0') {
902   //      switch (ch) {
903   //        case 'b' :
904   //          numFormat = 2;
905   //          getChar();
906   //          break;
907   //        case 'B' :
908   //          numFormat = 2;
909   //          getChar();
910   //          break;
911   //        case 'o' :
912   //          numFormat = 8;
913   //          getChar();
914   //          break;
915   //        case 'O' :
916   //          numFormat = 8;
917   //          getChar();
918   //          break;
919   //        case 'x' :
920   //          numFormat = 16;
921   //          getChar();
922   //          break;
923   //        case 'X' :
924   //          numFormat = 16;
925   //          getChar();
926   //          break;
927   //      }
928   //    }
929   //
930   //    if (numFormat == 16) {
931   //      while ((ch >= '0' && ch <= '9')
932   //        || (ch >= 'a' && ch <= 'f')
933   //        || (ch >= 'A' && ch <= 'F')) {
934   //        inum.append(ch);
935   //        getChar();
936   //      }
937   //    } else {
938   //      while ((ch >= '0' && ch <= '9')
939   //        || (ch == '.')
940   //        || (ch == 'E')
941   //        || (ch == 'e')) {
942   //        if ((ch == '.') || (ch == 'E') || (ch == 'e')) {
943   //          if (ch == '.' && dFlag != ' ') {
944   //            break;
945   //          }
946   //          if ((dFlag == 'E') || (dFlag == 'e')) {
947   //            break;
948   //          }
949   //          dFlag = ch;
950   //          inum.append(ch);
951   //          getChar();
952   //          if ((ch == '-') || (ch == '+')) {
953   //            inum.append(ch);
954   //            getChar();
955   //          }
956   //        } else {
957   //          inum.append(ch);
958   //          getChar();
959   //        }
960   //      }
961   //    }
962   //    chIndx--;
963   //
964   //    try {
965   //      if (dFlag != ' ') {
966   //        doubleNumber = new Double(inum.toString());
967   //        token = TokenNameDoubleLiteral;
968   //        return;
969   //      } else {
970   //        longNumber = Long.valueOf(inum.toString(), numFormat);
971   //        token = TokenNameIntegerLiteral;
972   //        return;
973   //      }
974   //
975   //    } catch (Throwable e) {
976   //      throwSyntaxError("Number format error: " + inum.toString());
977   //    }
978   //  }
979   //
980   //  /**
981   //   * Get a String.
982   //   * @param openChar the opening char ('\'', '"', '`')
983   //   * @param typeString the type of string {@link #TokenNameSTRING_CONSTANT},{@link #TokenNameINTERPOLATED_STRING}
984   //   * @param errorMsg the error message in case of parse error in the string
985   //   */
986   //  private void getString(
987   //    final char openChar,
988   //    final int typeString,
989   //    final String errorMsg) {
990   //    StringBuffer sBuffer = new StringBuffer();
991   //    boolean openString = true;
992   //    int startRow = rowCount;
993   //    while (str.length() > chIndx) {
994   //      ch = str.charAt(chIndx++);
995   //      if (ch == '\\') {
996   //        sBuffer.append(ch);
997   //        if (str.length() > chIndx) {
998   //          ch = str.charAt(chIndx++);
999   //          sBuffer.append(ch);
1000   //        }
1001   //      } else if (ch == openChar) {
1002   //        openString = false;
1003   //        break;
1004   //      } else if (ch == '\n') {
1005   //        rowCount++;
1006   //        columnCount = chIndx;
1007   //      } else {
1008   //        sBuffer.append(ch);
1009   //      }
1010   //    }
1011   //    if (openString) {
1012   //      if (typeString == TokenNameStringConstant) {
1013   //        throwSyntaxError(errorMsg, startRow);
1014   //      } else {
1015   //        throwSyntaxError(errorMsg);
1016   //      }
1017   //    }
1018   //    token = typeString;
1019   //    stringValue = sBuffer.toString();
1020   //  }
1021
1022   //    public void htmlParserTester(String input) {
1023   //            int lineNumber = 1;
1024   //            int startLineNumber = 1;
1025   //            int startIndex = 0;
1026   //            char ch;
1027   //            char ch2;
1028   //            boolean phpMode = false;
1029   //            boolean phpFound = false;
1030   //
1031   //            phpList = new ArrayList();
1032   //            currentPHPString = 0;
1033   //
1034   //            try {
1035   //                    int i = 0;
1036   //                    while (i < input.length()) {
1037   //                            ch = input.charAt(i++);
1038   //                            if (ch == '\n') {
1039   //                                    lineNumber++;
1040   //                            }
1041   //                            if ((!phpMode) && ch == '<') {
1042   //                                    ch2 = input.charAt(i++);
1043   //                                    if (ch2 == '?') {
1044   //                                            ch2 = input.charAt(i++);
1045   //                                            if (Character.isWhitespace(ch2)) {
1046   //                                                    // php start
1047   //                                                    phpMode = true;
1048   //                                                    phpFound = true;
1049   //                                                    startIndex = i;
1050   //                                                    startLineNumber = lineNumber;
1051   //                                                    continue;
1052   //                                            } else if (ch2 == 'p') {
1053   //                                                    ch2 = input.charAt(i++);
1054   //                                                    if (ch2 == 'h') {
1055   //                                                            ch2 = input.charAt(i++);
1056   //                                                            if (ch2 == 'p') {
1057   //                                                                    phpMode = true;
1058   //                                                                    phpFound = true;
1059   //                                                                    startIndex = i;
1060   //                                                                    startLineNumber = lineNumber;
1061   //                                                                    continue;
1062   //                                                            }
1063   //                                                            i--;
1064   //                                                    }
1065   //                                                    i--;
1066   //                                            } else if (ch2 == 'P') {
1067   //                                                    ch2 = input.charAt(i++);
1068   //                                                    if (ch2 == 'H') {
1069   //                                                            ch2 = input.charAt(i++);
1070   //                                                            if (ch2 == 'P') {
1071   //                                                                    phpMode = true;
1072   //                                                                    phpFound = true;
1073   //                                                                    startIndex = i;
1074   //                                                                    startLineNumber = lineNumber;
1075   //                                                                    continue;
1076   //                                                            }
1077   //                                                            i--;
1078   //                                                    }
1079   //                                                    i--;
1080   //                                            }
1081   //                                            i--;
1082   //                                    }
1083   //                                    i--;
1084   //                            }
1085   //
1086   //                            if (phpMode) {
1087   //                                    if (ch == '/' && i < input.length()) {
1088   //                                            ch2 = input.charAt(i++);
1089   //                                            if (ch2 == '/') {
1090   //                                                    while (i < input.length()) {
1091   //                                                            ch = input.charAt(i++);
1092   //                                                            if (ch == '?' && i < input.length()) {
1093   //                                                                    ch2 = input.charAt(i++);
1094   //                                                                    if (ch2 == '>') {
1095   //                                                                            // php end
1096   //                                                                            phpMode = false;
1097   //                                                                            phpList.add(
1098   //                                                                                    new PHPString(
1099   //                                                                                            input.substring(
1100   //                                                                                                    startIndex,
1101   //                                                                                                    i - 2),
1102   //                                                                                            startLineNumber));
1103   //                                                                            continue;
1104   //                                                                    }
1105   //                                                                    i--;
1106   //                                                            } else if (ch == '\n') {
1107   //                                                                    lineNumber++;
1108   //                                                                    break;
1109   //                                                            }
1110   //                                                    }
1111   //                                                    continue;
1112   //                                            } else if (ch2 == '*') {
1113   //                                                    // multi-line comment
1114   //                                                    while (i < input.length()) {
1115   //                                                            ch = input.charAt(i++);
1116   //                                                            if (ch == '\n') {
1117   //                                                                    lineNumber++;
1118   //                                                            } else if (ch == '*' && i < input.length()) {
1119   //                                                                    ch2 = input.charAt(i++);
1120   //                                                                    if (ch2 == '/') {
1121   //                                                                            break;
1122   //                                                                    }
1123   //                                                                    i--;
1124   //                                                            }
1125   //                                                    }
1126   //                                                    continue;
1127   //                                            } else {
1128   //                                                    i--;
1129   //                                            }
1130   //                                    } else if (ch == '#') {
1131   //                                            while (i < input.length()) {
1132   //                                                    ch = input.charAt(i++);
1133   //                                                    if (ch == '?' && i < input.length()) {
1134   //                                                            ch2 = input.charAt(i++);
1135   //                                                            if (ch2 == '>') {
1136   //                                                                    // php end
1137   //                                                                    phpMode = false;
1138   //                                                                    phpList.add(
1139   //                                                                            new PHPString(
1140   //                                                                                    input.substring(startIndex, i - 2),
1141   //                                                                                    startLineNumber));
1142   //                                                                    continue;
1143   //                                                            }
1144   //                                                            i--;
1145   //                                                    } else if (ch == '\n') {
1146   //                                                            lineNumber++;
1147   //                                                            break;
1148   //                                                    }
1149   //                                            }
1150   //                                            continue;
1151   //                                    } else if (ch == '"') {
1152   //                                            ch = ' ';
1153   //                                            while (i < input.length()) {
1154   //                                                    ch = input.charAt(i++);
1155   //                                                    if (ch == '\n') {
1156   //                                                            lineNumber++;
1157   //                                                    } else if (
1158   //                                                            ch == '\\' && i < input.length()) { // escape
1159   //                                                            i++;
1160   //                                                    } else if (ch == '"') {
1161   //                                                            break;
1162   //                                                    }
1163   //                                            }
1164   //                                            continue;
1165   //                                    } else if (ch == '\'') {
1166   //                                            ch = ' ';
1167   //                                            while (i < input.length()) {
1168   //                                                    ch = input.charAt(i++);
1169   //                                                    if (ch == '\n') {
1170   //                                                            lineNumber++;
1171   //                                                    } else if (
1172   //                                                            ch == '\\' && i < input.length()) { // escape
1173   //                                                            i++;
1174   //                                                    } else if (ch == '\'') {
1175   //                                                            break;
1176   //                                                    }
1177   //                                            }
1178   //                                            continue;
1179   //                                    }
1180   //
1181   //                                    if (ch == '?' && i < input.length()) {
1182   //                                            ch2 = input.charAt(i++);
1183   //                                            if (ch2 == '>') {
1184   //                                                    // php end
1185   //                                                    phpMode = false;
1186   //                                                    phpList.add(
1187   //                                                            new PHPString(
1188   //                                                                    input.substring(startIndex, i - 2),
1189   //                                                                    startLineNumber));
1190   //                                                    continue;
1191   //                                            }
1192   //                                            i--;
1193   //                                    }
1194   //                            }
1195   //                    }
1196   //
1197   //                    if (!phpFound) {
1198   //                            setMarker(
1199   //                                    "No PHP source code found.",
1200   //                                    lineNumber,
1201   //                                    PHPParser.INFO);
1202   //                    } else {
1203   //                            if (phpMode) {
1204   //                                    setMarker(
1205   //                                            "Open PHP tag at end of file.",
1206   //                                            lineNumber,
1207   //                                            PHPParser.INFO);
1208   //                                    phpList.add(
1209   //                                            new PHPString(
1210   //                                                    input.substring(startIndex, i - 2),
1211   //                                                    startLineNumber));
1212   //                            }
1213   //                            //        for (int j=0;j<phpList.size();j++) {
1214   //                            //          String temp = ((PHPString)phpList.get(j)).getPHPString();
1215   //                            //          int startIndx = temp.length()-10;
1216   //                            //          if (startIndx<0) {
1217   //                            //            startIndx = 0;
1218   //                            //          }
1219   //                            //          System.out.println(temp.substring(startIndx)+"?>");
1220   //                            //        }
1221   //                            phpParserTester(null, 1);
1222   //                            //        PHPString temp;
1223   //                            //        for(int j=0;j<phpList.size();j++) {
1224   //                            //          temp = (PHPString) phpList.get(j);
1225   //                            //          parser.start(temp.getPHPString(), temp.getLineNumber());
1226   //                            //        }
1227   //                    }
1228   //            } catch (CoreException e) {
1229   //            }
1230   //    }
1231
1232   public void phpParserTester(String s, int rowCount) throws CoreException {
1233     this.str = s;
1234     if (s == null) {
1235       if (phpList.size() != 0) {
1236         this.str = ((PHPString) phpList.get(currentPHPString++)).getPHPString();
1237       }
1238     }
1239     this.token = TokenNameEOF;
1240     //    this.chIndx = 0;
1241     //    this.rowCount = rowCount;
1242     //    this.columnCount = 0;
1243     this.phpEnd = false;
1244     this.phpMode = true;
1245     scanner.setSource(s.toCharArray());
1246     scanner.setPHPMode(true);
1247     getNextToken();
1248     do {
1249       try {
1250         if (token != TokenNameEOF && token != TokenNameERROR) {
1251           statementList();
1252         }
1253         if (token != TokenNameEOF) {
1254           if (token == TokenNameERROR) {
1255             throwSyntaxError(
1256               "Scanner error (Found unknown token: "
1257                 + scanner.toStringAction(token)
1258                 + ")");
1259           }
1260           if (token == TokenNameRPAREN) {
1261             throwSyntaxError("Too many closing ')'; end-of-file not reached.");
1262           }
1263           if (token == TokenNameRBRACE) {
1264             throwSyntaxError("Too many closing '}'; end-of-file not reached.");
1265           }
1266           if (token == TokenNameRBRACKET) {
1267             throwSyntaxError("Too many closing ']'; end-of-file not reached.");
1268           }
1269
1270           if (token == TokenNameLPAREN) {
1271             throwSyntaxError("Read character '('; end-of-file not reached.");
1272           }
1273           if (token == TokenNameLBRACE) {
1274             throwSyntaxError("Read character '{';  end-of-file not reached.");
1275           }
1276           if (token == TokenNameLBRACKET) {
1277             throwSyntaxError("Read character '[';  end-of-file not reached.");
1278           }
1279
1280           throwSyntaxError("End-of-file not reached.");
1281         }
1282         return;
1283       } catch (SyntaxError err) {
1284         if (s != null) {
1285           throw err;
1286         } else {
1287           //   setMarker(err.getMessage(), err.getLine(), ERROR);
1288           setMarker(
1289             err.getMessage(),
1290             scanner.getCurrentTokenStartPosition(),
1291             scanner.getCurrentTokenEndPosition(),
1292             ERROR);
1293         }
1294         // if an error occured,
1295         // try to find keywords 'class' or 'function'
1296         // to parse the rest of the string
1297         while (token != TokenNameEOF && token != TokenNameERROR) {
1298           if (token == TokenNameclass || token == TokenNamefunction) {
1299             break;
1300           }
1301           getNextToken();
1302         }
1303         if (token == TokenNameEOF || token == TokenNameERROR) {
1304           return;
1305         }
1306       }
1307     }
1308     while (true);
1309   }
1310
1311   /**
1312    * Parses a string with php tags
1313    * i.e. '&lt;body&gt; &lt;?php phpinfo() ?&gt; &lt;/body&gt;'
1314    */
1315   public void parse(String s) throws CoreException {
1316     this.str = s;
1317     this.token = TokenNameEOF;
1318     //    this.chIndx = 0;
1319     //    this.rowCount = 1;
1320     //    this.columnCount = 0;
1321     this.phpEnd = false;
1322     this.phpMode = false;
1323     /* scanner initialization */
1324     scanner.setSource(s.toCharArray());
1325     scanner.setPHPMode(false);
1326     getNextToken();
1327     do {
1328       try {
1329         if (token != TokenNameEOF && token != TokenNameERROR) {
1330           statementList();
1331         }
1332         if (token != TokenNameEOF) {
1333           if (token == TokenNameERROR) {
1334             throwSyntaxError(
1335               "Scanner error (Found unknown token: "
1336                 + scanner.toStringAction(token)
1337                 + ")");
1338           }
1339           if (token == TokenNameRPAREN) {
1340             throwSyntaxError("Too many closing ')'; end-of-file not reached.");
1341           }
1342           if (token == TokenNameRBRACE) {
1343             throwSyntaxError("Too many closing '}'; end-of-file not reached.");
1344           }
1345           if (token == TokenNameRBRACKET) {
1346             throwSyntaxError("Too many closing ']'; end-of-file not reached.");
1347           }
1348
1349           if (token == TokenNameLPAREN) {
1350             throwSyntaxError("Read character '('; end-of-file not reached.");
1351           }
1352           if (token == TokenNameLBRACE) {
1353             throwSyntaxError("Read character '{';  end-of-file not reached.");
1354           }
1355           if (token == TokenNameLBRACKET) {
1356             throwSyntaxError("Read character '[';  end-of-file not reached.");
1357           }
1358
1359           throwSyntaxError("End-of-file not reached.");
1360         }
1361         return;
1362       } catch (SyntaxError sytaxErr1) {
1363         // setMarker(sytaxErr1.getMessage(), sytaxErr1.getLine(), ERROR);
1364         setMarker(
1365           sytaxErr1.getMessage(),
1366           scanner.getCurrentTokenStartPosition(),
1367           scanner.getCurrentTokenEndPosition(),
1368           ERROR);
1369         try {
1370           // if an error occured,
1371           // try to find keywords 'class' or 'function'
1372           // to parse the rest of the string
1373           while (token != TokenNameEOF && token != TokenNameERROR) {
1374             if (token == TokenNameclass || token == TokenNamefunction) {
1375               break;
1376             }
1377             getNextToken();
1378           }
1379           if (token == TokenNameEOF || token == TokenNameERROR) {
1380             return;
1381           }
1382         } catch (SyntaxError sytaxErr2) {
1383           //    setMarker(sytaxErr2.getMessage(), sytaxErr2.getLine(), ERROR);
1384           setMarker(
1385             sytaxErr2.getMessage(),
1386             scanner.getCurrentTokenStartPosition(),
1387             scanner.getCurrentTokenEndPosition(),
1388             ERROR);
1389           return;
1390         }
1391       }
1392     }
1393     while (true);
1394   }
1395
1396   public PHPOutlineInfo parseInfo(Object parent, String s) {
1397     PHPOutlineInfo outlineInfo = new PHPOutlineInfo(parent);
1398     //    Stack stack = new Stack();
1399     //    stack.push(outlineInfo.getDeclarations());
1400
1401     this.str = s;
1402     this.token = TokenNameEOF;
1403     //    this.chIndx = 0;
1404     //    this.rowCount = 1;
1405     //    this.columnCount = 0;
1406     this.phpEnd = false;
1407     this.phpMode = false;
1408     scanner.setSource(s.toCharArray());
1409     scanner.setPHPMode(false);
1410
1411     try {
1412       getNextToken();
1413       parseDeclarations(outlineInfo, outlineInfo.getDeclarations(), false);
1414     } catch (CoreException e) {
1415     }
1416     return outlineInfo;
1417   }
1418
1419   private void parseDeclarations(
1420     PHPOutlineInfo outlineInfo,
1421     OutlineableWithChildren current,
1422     boolean goBack) {
1423     char[] ident;
1424     //   PHPClassDeclaration current = (PHPClassDeclaration) stack.peek();
1425     PHPSegmentWithChildren temp;
1426     int counter = 0;
1427
1428     IPreferenceStore store = PHPeclipsePlugin.getDefault().getPreferenceStore();
1429     try {
1430       while (token != TokenNameEOF && token != TokenNameERROR) {
1431         if (token == TokenNameVariable) {
1432           ident = scanner.getCurrentIdentifierSource();
1433           outlineInfo.addVariable(new String(ident));
1434           getNextToken();
1435         } else if (token == TokenNamevar) {
1436           getNextToken();
1437           if (token == TokenNameVariable
1438             && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_VAR)) {
1439             ident = scanner.getCurrentIdentifierSource();
1440             //substring(1) added because PHPVarDeclaration doesn't need the $ anymore
1441             String variableName = new String(ident).substring(1);
1442             outlineInfo.addVariable(variableName);
1443             getNextToken();
1444             if (token != TokenNameSEMICOLON) {
1445
1446               getNextToken();
1447               ident = scanner.getCurrentTokenSource();
1448               if (token > TokenNameKEYWORD) {
1449                 current.add(new PHPVarDeclaration(current, variableName,
1450                 //                      chIndx - ident.length,
1451                 scanner.getCurrentTokenStartPosition(), new String(ident)));
1452               } else {
1453                 switch (token) {
1454                   case TokenNameVariable :
1455                     current.add(new PHPVarDeclaration(current, variableName,
1456                     //                      chIndx - ident.length,
1457                     scanner.getCurrentTokenStartPosition(), new String(ident)));
1458                     break;
1459                   case TokenNameIdentifier :
1460                     current.add(new PHPVarDeclaration(current, variableName,
1461                     //                    chIndx - ident.length,
1462                     scanner.getCurrentTokenStartPosition(), new String(ident)));
1463                     break;
1464                   case TokenNameDoubleLiteral :
1465                     current
1466                       .add(new PHPVarDeclaration(
1467                         current,
1468                         variableName + doubleNumber,
1469                     //   chIndx - ident.length,
1470                     scanner.getCurrentTokenStartPosition(), new String(ident)));
1471                     break;
1472                   case TokenNameIntegerLiteral :
1473                     current.add(new PHPVarDeclaration(current, variableName,
1474                     //                 chIndx - ident.length,
1475                     scanner.getCurrentTokenStartPosition(), new String(ident)));
1476                     break;
1477                   case TokenNameStringInterpolated :
1478                   case TokenNameStringLiteral :
1479                     current.add(new PHPVarDeclaration(current, variableName,
1480                     //              chIndx - ident.length,
1481                     scanner.getCurrentTokenStartPosition(), new String(ident)));
1482                     break;
1483                   case TokenNameStringConstant :
1484                     current.add(new PHPVarDeclaration(current, variableName,
1485                     //   chIndx - ident.length,
1486                     scanner.getCurrentTokenStartPosition(), new String(ident)));
1487                     break;
1488                   default :
1489                     current.add(new PHPVarDeclaration(current, variableName,
1490                     //               chIndx - ident.length
1491                     scanner.getCurrentTokenStartPosition()));
1492                     break;
1493                 }
1494               }
1495
1496             } else {
1497               ident = scanner.getCurrentIdentifierSource();
1498
1499               current.add(new PHPVarDeclaration(current, variableName,
1500               //          chIndx - ident.length
1501               scanner.getCurrentTokenStartPosition()));
1502             }
1503           }
1504         } else if (token == TokenNamefunction) {
1505           getNextToken();
1506           if (token == TokenNameAND) {
1507             getNextToken();
1508           }
1509           if (token == TokenNameIdentifier
1510             && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_FUNC)) {
1511             ident = scanner.getCurrentIdentifierSource();
1512             outlineInfo.addVariable(new String(ident));
1513             temp = new PHPFunctionDeclaration(current, new String(ident),
1514               // chIndx - ident.length
1515   scanner.getCurrentTokenStartPosition());
1516             current.add(temp);
1517             getNextToken();
1518             parseDeclarations(outlineInfo, temp, true);
1519           }
1520         } else if (token == TokenNameclass) {
1521           getNextToken();
1522           if (token == TokenNameIdentifier
1523             && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_CLASS)) {
1524             ident = scanner.getCurrentIdentifierSource();
1525             outlineInfo.addVariable(new String(ident));
1526             temp = new PHPClassDeclaration(current, new String(ident),
1527               //      chIndx - ident.len
1528   scanner.getCurrentTokenStartPosition());
1529             current.add(temp);
1530             //        stack.push(temp);
1531             getNextToken();
1532
1533             //skip tokens for classname, extends and others until we have the opening '{'
1534             while (token != TokenNameLBRACE
1535               && token != TokenNameEOF
1536               && token != TokenNameERROR) {
1537               getNextToken();
1538             }
1539             parseDeclarations(outlineInfo, temp, true);
1540             //        stack.pop();
1541           }
1542         } else if (token == TokenNameLBRACE) {
1543           getNextToken();
1544           counter++;
1545         } else if (token == TokenNameRBRACE) {
1546           getNextToken();
1547           --counter;
1548           if (counter == 0 && goBack) {
1549             return;
1550           }
1551         } else if (
1552           token == TokenNamerequire
1553             || token == TokenNamerequire_once
1554             || token == TokenNameinclude
1555             || token == TokenNameinclude_once) {
1556           ident = scanner.getCurrentTokenSource();
1557
1558           getNextToken();
1559           int startPosition = scanner.getCurrentTokenStartPosition();
1560           expression();
1561           char[] expr = scanner.getCurrentTokenSource(startPosition);
1562           outlineInfo.addVariable(new String(ident));
1563           current.add(new PHPReqIncDeclaration(current, new String(ident),
1564           //    chIndx - ident.length,
1565           startPosition, new String(expr)));
1566           getNextToken();
1567         } else {
1568           getNextToken();
1569         }
1570       }
1571     } catch (CoreException e) {
1572     } catch (SyntaxError sytaxErr) {
1573       try {
1574         //  setMarker(sytaxErr.getMessage(), sytaxErr.getLine(), ERROR);
1575         setMarker(
1576           sytaxErr.getMessage(),
1577           scanner.getCurrentTokenStartPosition(),
1578           scanner.getCurrentTokenEndPosition(),
1579           ERROR);
1580       } catch (CoreException e) {
1581       }
1582     }
1583   }
1584
1585   private void statementList() throws CoreException {
1586     do {
1587       statement();
1588       if ((token == TokenNameRBRACE)
1589         || (token == TokenNamecase)
1590         || (token == TokenNamedefault)
1591         || (token == TokenNameelseif)
1592         || (token == TokenNameendif)
1593         || (token == TokenNameendfor)
1594         || (token == TokenNameendforeach)
1595         || (token == TokenNameendwhile)
1596         || (token == TokenNameendswitch)
1597         || (token == TokenNameEOF)
1598         || (token == TokenNameERROR)) {
1599         return;
1600       }
1601     } while (true);
1602   }
1603
1604   private void compoundStatement() throws CoreException {
1605     // '{' [statement-list] '}'
1606     if (token == TokenNameLBRACE) {
1607       getNextToken();
1608     } else {
1609       throwSyntaxError("'{' expected in compound-statement.");
1610     }
1611     if (token != TokenNameRBRACE) {
1612       statementList();
1613     }
1614     if (token == TokenNameRBRACE) {
1615       getNextToken();
1616     } else {
1617       throwSyntaxError("'}' expected in compound-statement.");
1618     }
1619   }
1620
1621   private void statement() throws CoreException {
1622     //   if (token > TokenNameKEYWORD && token != TokenNamelist && token != TokenNamenew) {
1623     //  char[] ident = scanner.getCurrentIdentifierSource();
1624     //  String keyword = new String(ident);
1625     if (token == TokenNameinclude || token == TokenNameinclude_once) {
1626       getNextToken();
1627       expression();
1628       if (token == TokenNameSEMICOLON) {
1629         getNextToken();
1630       } else {
1631         if (token != TokenNameStopPHP) {
1632           throwSyntaxError("';' character after 'include' or 'include_once' expected.");
1633         }
1634         getNextToken();
1635       }
1636       return;
1637     } else if (token == TokenNamerequire || token == TokenNamerequire_once) {
1638       getNextToken();
1639       //constant();
1640       expression();
1641       if (token == TokenNameSEMICOLON) {
1642         getNextToken();
1643       } else {
1644         if (token != TokenNameStopPHP) {
1645           throwSyntaxError("';' character after 'require' or 'require_once' expected.");
1646         }
1647         getNextToken();
1648       }
1649       return;
1650     } else if (token == TokenNameif) {
1651       getNextToken();
1652       if (token == TokenNameLPAREN) {
1653         getNextToken();
1654       } else {
1655         throwSyntaxError("'(' expected after 'if' keyword.");
1656       }
1657       expression();
1658       if (token == TokenNameRPAREN) {
1659         getNextToken();
1660       } else {
1661         throwSyntaxError("')' expected after 'if' condition.");
1662       }
1663       ifStatement();
1664       return;
1665
1666     } else if (token == TokenNameswitch) {
1667       getNextToken();
1668       if (token == TokenNameLPAREN) {
1669         getNextToken();
1670       } else {
1671         throwSyntaxError("'(' expected after 'switch' keyword.");
1672       }
1673       expression();
1674       if (token == TokenNameRPAREN) {
1675         getNextToken();
1676       } else {
1677         throwSyntaxError("')' expected after 'switch' condition.");
1678       }
1679       switchStatement();
1680       return;
1681     } else if (token == TokenNamefor) {
1682       getNextToken();
1683       if (token == TokenNameLPAREN) {
1684         getNextToken();
1685       } else {
1686         throwSyntaxError("'(' expected after 'for' keyword.");
1687       }
1688       if (token == TokenNameSEMICOLON) {
1689         getNextToken();
1690       } else {
1691         expressionList();
1692         if (token == TokenNameSEMICOLON) {
1693           getNextToken();
1694         } else {
1695           throwSyntaxError("';' expected after 'for'.");
1696         }
1697       }
1698       if (token == TokenNameSEMICOLON) {
1699         getNextToken();
1700       } else {
1701         expressionList();
1702         if (token == TokenNameSEMICOLON) {
1703           getNextToken();
1704         } else {
1705           throwSyntaxError("';' expected after 'for'.");
1706         }
1707       }
1708       if (token == TokenNameRPAREN) {
1709         getNextToken();
1710       } else {
1711         expressionList();
1712         if (token == TokenNameRPAREN) {
1713           getNextToken();
1714         } else {
1715           throwSyntaxError("')' expected after 'for'.");
1716         }
1717       }
1718       forStatement();
1719       return;
1720     } else if (token == TokenNamewhile) {
1721       getNextToken();
1722       if (token == TokenNameLPAREN) {
1723         getNextToken();
1724       } else {
1725         throwSyntaxError("'(' expected after 'while' keyword.");
1726       }
1727       expression();
1728       if (token == TokenNameRPAREN) {
1729         getNextToken();
1730       } else {
1731         throwSyntaxError("')' expected after 'while' condition.");
1732       }
1733       whileStatement();
1734       return;
1735     } else if (token == TokenNamedo) {
1736       getNextToken();
1737       if (token == TokenNameLBRACE) {
1738         getNextToken();
1739       } else {
1740         throwSyntaxError("'{' expected after 'do' keyword.");
1741       }
1742       if (token != TokenNameRBRACE) {
1743         statementList();
1744       }
1745       if (token == TokenNameRBRACE) {
1746         getNextToken();
1747       } else {
1748         throwSyntaxError("'}' expected after 'do' keyword.");
1749       }
1750       if (token == TokenNamewhile) {
1751         getNextToken();
1752         if (token == TokenNameLPAREN) {
1753           getNextToken();
1754         } else {
1755           throwSyntaxError("'(' expected after 'while' keyword.");
1756         }
1757         expression();
1758         if (token == TokenNameRPAREN) {
1759           getNextToken();
1760         } else {
1761           throwSyntaxError("')' expected after 'while' condition.");
1762         }
1763       } else {
1764         throwSyntaxError("'while' expected after 'do' keyword.");
1765       }
1766       if (token == TokenNameSEMICOLON) {
1767         getNextToken();
1768       } else {
1769         if (token != TokenNameStopPHP) {
1770           throwSyntaxError("';' expected after do-while statement.");
1771         }
1772         getNextToken();
1773       }
1774       return;
1775     } else if (token == TokenNameforeach) {
1776       getNextToken();
1777       if (token == TokenNameLPAREN) {
1778         getNextToken();
1779       } else {
1780         throwSyntaxError("'(' expected after 'foreach' keyword.");
1781       }
1782       expression();
1783       if (token == TokenNameas) {
1784         getNextToken();
1785       } else {
1786         throwSyntaxError("'as' expected after 'foreach' exxpression.");
1787       }
1788       variable();
1789       if (token == TokenNameEQUAL_GREATER) {
1790         getNextToken();
1791         variable();
1792       }
1793       if (token == TokenNameRPAREN) {
1794         getNextToken();
1795       } else {
1796         throwSyntaxError("')' expected after 'foreach' expression.");
1797       }
1798       foreachStatement();
1799       return;
1800
1801     } else if (
1802       token == TokenNamecontinue
1803         || token == TokenNamebreak
1804         || token == TokenNamereturn) {
1805       getNextToken();
1806       if (token != TokenNameSEMICOLON) {
1807         expression();
1808       }
1809       if (token == TokenNameSEMICOLON) {
1810         getNextToken();
1811       } else {
1812         if (token != TokenNameStopPHP) {
1813           throwSyntaxError("';' expected after 'continue', 'break' or 'return'.");
1814         }
1815         getNextToken();
1816       }
1817       return;
1818
1819     } else if (token == TokenNameecho) {
1820       getNextToken();
1821       expressionList();
1822       if (token == TokenNameSEMICOLON) {
1823         getNextToken();
1824       } else {
1825         if (token != TokenNameStopPHP) {
1826           throwSyntaxError("';' expected after 'echo' statement.");
1827         }
1828         getNextToken();
1829       }
1830       return;
1831       //    } else if (token == TokenNameprint) {
1832       //      getNextToken();
1833       //      expression();
1834       //      if (token == TokenNameSEMICOLON) {
1835       //        getNextToken();
1836       //      } else {
1837       //        if (token != TokenNameStopPHP) {
1838       //          throwSyntaxError("';' expected after 'print' statement.");
1839       //        }
1840       //        getNextToken();
1841       //      }
1842       //      return;
1843
1844     } else if (token == TokenNameglobal || token == TokenNamestatic) {
1845       getNextToken();
1846       variableList();
1847       if (token == TokenNameSEMICOLON) {
1848         getNextToken();
1849       } else {
1850         if (token != TokenNameStopPHP) {
1851           throwSyntaxError("';' expected after 'global' or 'static' statement.");
1852         }
1853         getNextToken();
1854       }
1855       return;
1856
1857       //      } else if (token == TokenNameunset) {
1858       //        getNextToken();
1859       //        if (token == TokenNameARGOPEN) {
1860       //          getNextToken();
1861       //        } else {
1862       //          throwSyntaxError("'(' expected after 'unset' keyword.");
1863       //        }
1864       //        variableList();
1865       //        if (token == TokenNameARGCLOSE) {
1866       //          getNextToken();
1867       //        } else {
1868       //          throwSyntaxError("')' expected after 'unset' statement.");
1869       //        }
1870       //        if (token == TokenNameSEMICOLON) {
1871       //          getNextToken();
1872       //        } else {
1873       //          if (token != TokenNameStopPHP) {
1874       //            throwSyntaxError("';' expected after 'unset' statement.");
1875       //          }
1876       //          getNextToken();
1877       //        }
1878       //        return;
1879
1880       //      } else if (token == TokenNameexit || token == TokenNamedie) {
1881       //        getNextToken();
1882       //        if (token != TokenNameSEMICOLON) {
1883       //          exitStatus();
1884       //        }
1885       //        if (token == TokenNameSEMICOLON) {
1886       //          getNextToken();
1887       //        } else {
1888       //          if (token != TokenNameStopPHP) {
1889       //            throwSyntaxError("';' expected after 'exit' or 'die' statement.");
1890       //          }
1891       //          getNextToken();
1892       //        }
1893       //        return;
1894
1895     } else if (token == TokenNamedefine) {
1896       getNextToken();
1897       if (token == TokenNameLPAREN) {
1898         getNextToken();
1899       } else {
1900         throwSyntaxError("'(' expected after 'define' keyword.");
1901       }
1902       expression();
1903       if (token == TokenNameCOMMA) {
1904         getNextToken();
1905       } else {
1906         throwSyntaxError("',' expected after first 'define' constant.");
1907       }
1908       expression();
1909       if (token == TokenNameCOMMA) {
1910         getNextToken();
1911         expression();
1912       }
1913       if (token == TokenNameRPAREN) {
1914         getNextToken();
1915       } else {
1916         throwSyntaxError("')' expected after 'define' statement.");
1917       }
1918       if (token == TokenNameSEMICOLON) {
1919         getNextToken();
1920       } else {
1921         if (token != TokenNameStopPHP) {
1922           throwSyntaxError("';' expected after 'define' statement.");
1923         }
1924         getNextToken();
1925       }
1926       return;
1927     } else if (token == TokenNamefunction) {
1928       getNextToken();
1929       functionDefinition();
1930       return;
1931     } else if (token == TokenNameclass) {
1932       getNextToken();
1933       classDeclarator();
1934       classBody();
1935       return;
1936       //      } else {
1937       //        throwSyntaxError("Unexpected keyword '" + keyword + "'");
1938     } else if (token == TokenNameLBRACE) {
1939       // compoundStatement
1940       getNextToken();
1941       if (token != TokenNameRBRACE) {
1942         statementList();
1943       }
1944       if (token == TokenNameRBRACE) {
1945         getNextToken();
1946         return;
1947       } else {
1948         throwSyntaxError("'}' expected.");
1949       }
1950     } else {
1951       if (token != TokenNameSEMICOLON) {
1952         expression();
1953       }
1954       if (token == TokenNameSEMICOLON) {
1955         getNextToken();
1956         return;
1957       } else {
1958         if (token != TokenNameStopPHP && token != TokenNameEOF) {
1959           throwSyntaxError(
1960             "';' expected after expression (Found token: "
1961               + scanner.toStringAction(token)
1962               + ")");
1963         }
1964         getNextToken();
1965       }
1966     }
1967   }
1968
1969   private void classDeclarator() throws CoreException {
1970     //identifier
1971     //identifier 'extends' identifier
1972     if (token == TokenNameIdentifier) {
1973       getNextToken();
1974       if (token == TokenNameextends) {
1975         getNextToken();
1976         if (token == TokenNameIdentifier) {
1977           getNextToken();
1978         } else {
1979           throwSyntaxError("ClassDeclaration name expected after keyword 'extends'.");
1980         }
1981       }
1982     } else {
1983       if (token > TokenNameKEYWORD) {
1984         throwSyntaxError(
1985           "Don't use keyword for class declaration [" + token + "].");
1986       }
1987       throwSyntaxError("ClassDeclaration name expected after keyword 'class'.");
1988     }
1989   }
1990
1991   private void classBody() throws CoreException {
1992     //'{' [class-element-list] '}'
1993     if (token == TokenNameLBRACE) {
1994       getNextToken();
1995       if (token != TokenNameRBRACE) {
1996         classElementList();
1997       }
1998       if (token == TokenNameRBRACE) {
1999         getNextToken();
2000       } else {
2001         throwSyntaxError("'}' expected at end of class body.");
2002       }
2003     } else {
2004       throwSyntaxError("'{' expected at start of class body.");
2005     }
2006   }
2007
2008   private void classElementList() throws CoreException {
2009     do {
2010       classElement();
2011     } while (token == TokenNamefunction || token == TokenNamevar);
2012   }
2013
2014   private void classElement() throws CoreException {
2015     //class-property
2016     //function-definition
2017     if (token == TokenNamefunction) {
2018       getNextToken();
2019       functionDefinition();
2020     } else if (token == TokenNamevar) {
2021       getNextToken();
2022       classProperty();
2023     } else {
2024       throwSyntaxError("'function' or 'var' expected.");
2025     }
2026   }
2027
2028   private void classProperty() throws CoreException {
2029     //'var' variable ';'
2030     //'var' variable '=' constant ';'
2031     do {
2032       if (token == TokenNameVariable) {
2033         getNextToken();
2034         if (token == TokenNameEQUAL) {
2035           getNextToken();
2036           constant();
2037         }
2038       } else {
2039         throwSyntaxError("Variable expected after keyword 'var'.");
2040       }
2041       if (token != TokenNameCOMMA) {
2042         break;
2043       }
2044       getNextToken();
2045     } while (true);
2046     if (token == TokenNameSEMICOLON) {
2047       getNextToken();
2048     } else {
2049       throwSyntaxError("';' expected after variable declaration.");
2050     }
2051   }
2052
2053   private void functionDefinition() throws CoreException {
2054     functionDeclarator();
2055     compoundStatement();
2056   }
2057
2058   private void functionDeclarator() throws CoreException {
2059     //identifier '(' [parameter-list] ')'
2060     if (token == TokenNameAND) {
2061       getNextToken();
2062     }
2063     if (token == TokenNameIdentifier) {
2064       getNextToken();
2065       if (token == TokenNameLPAREN) {
2066         getNextToken();
2067       } else {
2068         throwSyntaxError("'(' expected in function declaration.");
2069       }
2070       if (token != TokenNameRPAREN) {
2071         parameterList();
2072       }
2073       if (token != TokenNameRPAREN) {
2074         throwSyntaxError("')' expected in function declaration.");
2075       } else {
2076         getNextToken();
2077       }
2078     } else {
2079       if (token > TokenNameKEYWORD) {
2080         throwSyntaxError(
2081           "Don't use keyword for function declaration [" + token + "].");
2082       }
2083       throwSyntaxError("Function name expected after keyword 'function'.");
2084     }
2085   }
2086   //
2087   private void parameterList() throws CoreException {
2088     //parameter-declaration
2089     //parameter-list ',' parameter-declaration
2090     do {
2091       parameterDeclaration();
2092       if (token != TokenNameCOMMA) {
2093         break;
2094       }
2095       getNextToken();
2096     } while (true);
2097   }
2098
2099   private void parameterDeclaration() throws CoreException {
2100     //variable
2101     //variable-reference
2102     if (token == TokenNameAND) {
2103       getNextToken();
2104       if (token == TokenNameVariable) {
2105         getNextToken();
2106       } else {
2107         throwSyntaxError("Variable expected after reference operator '&'.");
2108       }
2109     }
2110     //variable '=' constant
2111     if (token == TokenNameVariable) {
2112       getNextToken();
2113       if (token == TokenNameEQUAL) {
2114         getNextToken();
2115         constant();
2116       }
2117       return;
2118     }
2119   }
2120
2121   private void labeledStatementList() throws CoreException {
2122     if (token != TokenNamecase && token != TokenNamedefault) {
2123       throwSyntaxError("'case' or 'default' expected.");
2124     }
2125     do {
2126       if (token == TokenNamecase) {
2127         getNextToken();
2128         constant();
2129         if (token == TokenNameCOLON) {
2130           getNextToken();
2131           if (token == TokenNamecase
2132             || token == TokenNamedefault) { // empty case statement ?
2133             continue;
2134           }
2135           statementList();
2136         } else if (token == TokenNameSEMICOLON) {
2137           //          setMarker(
2138           //            "':' expected after 'case' keyword (Found token: "
2139           //              + scanner.toStringAction(token)
2140           //              + ")",
2141           //            rowCount,
2142           //            PHPParser.INFO);
2143           setMarker(
2144             "':' expected after 'case' keyword (Found token: "
2145               + scanner.toStringAction(token)
2146               + ")",
2147             scanner.getCurrentTokenStartPosition(),
2148             scanner.getCurrentTokenEndPosition(),
2149             INFO);
2150           getNextToken();
2151           if (token == TokenNamecase) { // empty case statement ?
2152             continue;
2153           }
2154           statementList();
2155         } else {
2156           throwSyntaxError(
2157             "':' character after 'case' constant expected (Found token: "
2158               + scanner.toStringAction(token)
2159               + ")");
2160         }
2161       } else { // TokenNamedefault
2162         getNextToken();
2163         if (token == TokenNameCOLON) {
2164           getNextToken();
2165           statementList();
2166         } else {
2167           throwSyntaxError("':' character after 'default' expected.");
2168         }
2169       }
2170     } while (token == TokenNamecase || token == TokenNamedefault);
2171   }
2172
2173   //  public void labeledStatement() {
2174   //    if (token == TokenNamecase) {
2175   //      getNextToken();
2176   //      constant();
2177   //      if (token == TokenNameDDOT) {
2178   //        getNextToken();
2179   //        statement();
2180   //      } else {
2181   //        throwSyntaxError("':' character after 'case' constant expected.");
2182   //      }
2183   //      return;
2184   //    } else if (token == TokenNamedefault) {
2185   //      getNextToken();
2186   //      if (token == TokenNameDDOT) {
2187   //        getNextToken();
2188   //        statement();
2189   //      } else {
2190   //        throwSyntaxError("':' character after 'default' expected.");
2191   //      }
2192   //      return;
2193   //    }
2194   //  }
2195
2196   //  public void expressionStatement() {
2197   //  }
2198
2199   //  private void inclusionStatement() {
2200   //  }
2201
2202   //  public void compoundStatement() {
2203   //  }
2204
2205   //  public void selectionStatement() {
2206   //  }
2207   //
2208   //  public void iterationStatement() {
2209   //  }
2210   //
2211   //  public void jumpStatement() {
2212   //  }
2213   //
2214   //  public void outputStatement() {
2215   //  }
2216   //
2217   //  public void scopeStatement() {
2218   //  }
2219   //
2220   //  public void flowStatement() {
2221   //  }
2222   //
2223   //  public void definitionStatement() {
2224   //  }
2225
2226   private void ifStatement() throws CoreException {
2227     // ':' statement-list [elseif-list] [else-colon-statement] 'endif' ';'
2228     if (token == TokenNameCOLON) {
2229       getNextToken();
2230       statementList();
2231       switch (token) {
2232         case TokenNameelse :
2233           getNextToken();
2234           if (token == TokenNameCOLON) {
2235             getNextToken();
2236             statementList();
2237           } else {
2238             if (token == TokenNameif) { //'else if'
2239               getNextToken();
2240               elseifStatementList();
2241             } else {
2242               throwSyntaxError("':' expected after 'else'.");
2243             }
2244           }
2245           break;
2246         case TokenNameelseif :
2247           getNextToken();
2248           elseifStatementList();
2249           break;
2250       }
2251
2252       if (token != TokenNameendif) {
2253         throwSyntaxError("'endif' expected.");
2254       }
2255       getNextToken();
2256       if (token != TokenNameSEMICOLON) {
2257         throwSyntaxError("';' expected after if-statement.");
2258       }
2259       getNextToken();
2260     } else {
2261       // statement [else-statement]
2262       statement();
2263       if (token == TokenNameelseif) {
2264         getNextToken();
2265         if (token == TokenNameLPAREN) {
2266           getNextToken();
2267         } else {
2268           throwSyntaxError("'(' expected after 'elseif' keyword.");
2269         }
2270         expression();
2271         if (token == TokenNameRPAREN) {
2272           getNextToken();
2273         } else {
2274           throwSyntaxError("')' expected after 'elseif' condition.");
2275         }
2276         ifStatement();
2277       } else if (token == TokenNameelse) {
2278         getNextToken();
2279         statement();
2280       }
2281     }
2282   }
2283
2284   private void elseifStatementList() throws CoreException {
2285     do {
2286       elseifStatement();
2287       switch (token) {
2288         case TokenNameelse :
2289           getNextToken();
2290           if (token == TokenNameCOLON) {
2291             getNextToken();
2292             statementList();
2293             return;
2294           } else {
2295             if (token == TokenNameif) { //'else if'
2296               getNextToken();
2297             } else {
2298               throwSyntaxError("':' expected after 'else'.");
2299             }
2300           }
2301           break;
2302         case TokenNameelseif :
2303           getNextToken();
2304           break;
2305         default :
2306           return;
2307       }
2308     } while (true);
2309   }
2310
2311   private void elseifStatement() throws CoreException {
2312     if (token == TokenNameLPAREN) {
2313       getNextToken();
2314       expression();
2315       if (token != TokenNameLPAREN) {
2316         throwSyntaxError("')' expected in else-if-statement.");
2317       }
2318       getNextToken();
2319       if (token != TokenNameCOLON) {
2320         throwSyntaxError("':' expected in else-if-statement.");
2321       }
2322       getNextToken();
2323       statementList();
2324     }
2325   }
2326
2327   private void switchStatement() throws CoreException {
2328     if (token == TokenNameCOLON) {
2329       // ':' [labeled-statement-list] 'endswitch' ';'
2330       getNextToken();
2331       labeledStatementList();
2332       if (token != TokenNameendswitch) {
2333         throwSyntaxError("'endswitch' expected.");
2334       }
2335       getNextToken();
2336       if (token != TokenNameSEMICOLON) {
2337         throwSyntaxError("';' expected after switch-statement.");
2338       }
2339       getNextToken();
2340     } else {
2341       // '{' [labeled-statement-list] '}'
2342       if (token != TokenNameLBRACE) {
2343         throwSyntaxError("'{' expected in switch statement.");
2344       }
2345       getNextToken();
2346       if (token != TokenNameRBRACE) {
2347         labeledStatementList();
2348       }
2349       if (token != TokenNameRBRACE) {
2350         throwSyntaxError("'}' expected in switch statement.");
2351       }
2352       getNextToken();
2353
2354     }
2355   }
2356
2357   private void forStatement() throws CoreException {
2358     if (token == TokenNameCOLON) {
2359       getNextToken();
2360       statementList();
2361       if (token != TokenNameendfor) {
2362         throwSyntaxError("'endfor' expected.");
2363       }
2364       getNextToken();
2365       if (token != TokenNameSEMICOLON) {
2366         throwSyntaxError("';' expected after for-statement.");
2367       }
2368       getNextToken();
2369     } else {
2370       statement();
2371     }
2372   }
2373
2374   private void whileStatement() throws CoreException {
2375     // ':' statement-list 'endwhile' ';'
2376     if (token == TokenNameCOLON) {
2377       getNextToken();
2378       statementList();
2379       if (token != TokenNameendwhile) {
2380         throwSyntaxError("'endwhile' expected.");
2381       }
2382       getNextToken();
2383       if (token != TokenNameSEMICOLON) {
2384         throwSyntaxError("';' expected after while-statement.");
2385       }
2386       getNextToken();
2387     } else {
2388       statement();
2389     }
2390   }
2391
2392   private void foreachStatement() throws CoreException {
2393     if (token == TokenNameCOLON) {
2394       getNextToken();
2395       statementList();
2396       if (token != TokenNameendforeach) {
2397         throwSyntaxError("'endforeach' expected.");
2398       }
2399       getNextToken();
2400       if (token != TokenNameSEMICOLON) {
2401         throwSyntaxError("';' expected after foreach-statement.");
2402       }
2403       getNextToken();
2404     } else {
2405       statement();
2406     }
2407   }
2408
2409   private void exitStatus() throws CoreException {
2410     if (token == TokenNameLPAREN) {
2411       getNextToken();
2412     } else {
2413       throwSyntaxError("'(' expected in 'exit-status'.");
2414     }
2415     if (token != TokenNameRPAREN) {
2416       expression();
2417     }
2418     if (token == TokenNameRPAREN) {
2419       getNextToken();
2420     } else {
2421       throwSyntaxError("')' expected after 'exit-status'.");
2422     }
2423   }
2424
2425   private void expressionList() throws CoreException {
2426     do {
2427       expression();
2428       if (token == TokenNameCOMMA) {
2429         getNextToken();
2430       } else {
2431         break;
2432       }
2433     } while (true);
2434   }
2435
2436   private void expression() throws CoreException {
2437     //todo: find a better way to get the expression
2438     //    expression = new StringBuffer();
2439     //    for (int i = chIndx; i < str.length(); i++) {
2440     //      if (str.charAt(i) == ';') {
2441     //        break;
2442     //      }
2443     //      expression.append(str.charAt(i));
2444     //    }
2445
2446     //    if (token == TokenNameSTRING_CONSTANT || token == TokenNameINTERPOLATED_STRING) {
2447     //      getNextToken();
2448     //    } else {
2449     logicalinclusiveorExpression();
2450     //      while (token != TokenNameSEMICOLON) {
2451     //        getNextToken();
2452     //      //      }
2453     //    }
2454   }
2455
2456   private void postfixExpression() throws CoreException {
2457     //  String ident;
2458     char[] ident;
2459     boolean castFlag = false;
2460     switch (token) {
2461       case TokenNamenew :
2462         getNextToken();
2463         expression();
2464         break;
2465       case TokenNamenull :
2466         getNextToken();
2467         break;
2468       case TokenNamefalse :
2469         getNextToken();
2470         break;
2471       case TokenNametrue :
2472         getNextToken();
2473         break;
2474       case TokenNameStringConstant :
2475         getNextToken();
2476         break;
2477       case TokenNameHEREDOC :
2478       case TokenNameStringInterpolated :
2479       case TokenNameStringLiteral :
2480         getNextToken();
2481         break;
2482       case TokenNameLPAREN :
2483         getNextToken();
2484         if (token == TokenNameIdentifier) {
2485           // check if identifier is a type:
2486           //    ident = identifier;
2487           ident = scanner.getCurrentIdentifierSource();
2488           String str = new String(ident).toLowerCase();
2489           for (int i = 0; i < PHP_TYPES.length; i++) {
2490             if (PHP_TYPES[i].equals(str)) {
2491               castFlag = true;
2492               break;
2493             }
2494           }
2495           if (castFlag) {
2496             getNextToken();
2497             if (token != TokenNameRPAREN) {
2498               throwSyntaxError(") expected after cast-type '" + str + "'.");
2499             }
2500             getNextToken();
2501             expression();
2502             break;
2503           }
2504         }
2505         if (!castFlag) {
2506           expression();
2507         }
2508         if (token != TokenNameRPAREN) {
2509           throwSyntaxError(") expected in postfix-expression.");
2510         }
2511         getNextToken();
2512         break;
2513       case TokenNameDoubleLiteral :
2514         getNextToken();
2515         break;
2516       case TokenNameIntegerLiteral :
2517         getNextToken();
2518         break;
2519       case TokenNameDOLLAR_LBRACE :
2520         getNextToken();
2521         expression();
2522         if (token != TokenNameRBRACE) {
2523           throwSyntaxError("'}' expected after indirect variable token '${'.");
2524         }
2525         getNextToken();
2526         break;
2527       case TokenNameVariable :
2528         ident = scanner.getCurrentIdentifierSource();
2529         getNextToken();
2530         if (token == TokenNameLBRACE) {
2531           getNextToken();
2532           expression();
2533           if (token != TokenNameRBRACE) {
2534             throwSyntaxError(
2535               "'}' expected after variable '"
2536                 + new String(ident)
2537                 + "' in variable-expression.");
2538           }
2539           getNextToken();
2540         } else if (token == TokenNameLPAREN) {
2541           getNextToken();
2542           if (token != TokenNameRPAREN) {
2543             expressionList();
2544             if (token != TokenNameRPAREN) {
2545               throwSyntaxError(
2546                 "')' expected after variable '"
2547                   + new String(ident)
2548                   + "' in postfix-expression.");
2549             }
2550           }
2551           getNextToken();
2552         }
2553         break;
2554       case TokenNameIdentifier :
2555         ident = scanner.getCurrentIdentifierSource();
2556         getNextToken();
2557         if (token == TokenNameLPAREN) {
2558           getNextToken();
2559           if (token != TokenNameRPAREN) {
2560             expressionList();
2561             if (token != TokenNameRPAREN) {
2562               throwSyntaxError(
2563                 "')' expected after identifier '"
2564                   + new String(ident)
2565                   + "' in postfix-expression."
2566                   + "(Found token: "
2567                   + scanner.toStringAction(token)
2568                   + ")");
2569             }
2570           }
2571           getNextToken();
2572         }
2573         break;
2574       case TokenNameprint :
2575         getNextToken();
2576         expression();
2577         //        if (token == TokenNameSEMICOLON) {
2578         //          getNextToken();
2579         //        } else {
2580         //          if (token != TokenNameStopPHP) {
2581         //            throwSyntaxError("';' expected after 'print' statement.");
2582         //          }
2583         //          getNextToken();
2584         //        }
2585         break;
2586       case TokenNamelist :
2587         getNextToken();
2588         if (token == TokenNameLPAREN) {
2589           getNextToken();
2590           if (token == TokenNameCOMMA) {
2591             getNextToken();
2592           }
2593           expressionList();
2594           if (token != TokenNameRPAREN) {
2595             throwSyntaxError("')' expected after 'list' keyword.");
2596           }
2597           getNextToken();
2598           //          if (token == TokenNameSET) {
2599           //            getNextToken();
2600           //            logicalinclusiveorExpression();
2601           //          }
2602         } else {
2603           throwSyntaxError("'(' expected after 'list' keyword.");
2604         }
2605         break;
2606         //      case TokenNameexit :
2607         //        getNextToken();
2608         //        if (token != TokenNameSEMICOLON) {
2609         //          exitStatus();
2610         //        }
2611         //        if (token == TokenNameSEMICOLON) {
2612         //          getNextToken();
2613         //        } else {
2614         //          if (token != TokenNameStopPHP) {
2615         //            throwSyntaxError("';' expected after 'exit' expression.");
2616         //          }
2617         //          getNextToken();
2618         //        }
2619         //        break;
2620         //      case TokenNamedie :
2621         //        getNextToken();
2622         //        if (token != TokenNameSEMICOLON) {
2623         //          exitStatus();
2624         //        }
2625         //        if (token == TokenNameSEMICOLON) {
2626         //          getNextToken();
2627         //        } else {
2628         //          if (token != TokenNameStopPHP) {
2629         //            throwSyntaxError("';' expected after 'die' expression.");
2630         //          }
2631         //        }
2632         //        break;
2633
2634         //      case TokenNamearray :
2635         //        getNextToken();
2636         //        if (token == TokenNameARGOPEN) {
2637         //          getNextToken();
2638         //          if (token == TokenNameCOMMA) {
2639         //            getNextToken();
2640         //          }
2641         //          expressionList();
2642         //          if (token != TokenNameARGCLOSE) {
2643         //            throwSyntaxError("')' expected after 'list' keyword.");
2644         //          }
2645         //          getNextToken();
2646         //          if (token == TokenNameSET) {
2647         //            getNextToken();
2648         //            logicalinclusiveorExpression();
2649         //          }
2650         //        } else {
2651         //          throwSyntaxError("'(' expected after 'list' keyword.");
2652         //        }
2653         //        break;
2654     }
2655     boolean while_flag = true;
2656     do {
2657       switch (token) {
2658         case TokenNameLBRACKET :
2659           getNextToken();
2660           expression();
2661           if (token != TokenNameRBRACKET) {
2662             throwSyntaxError("] expected in postfix-expression.");
2663           }
2664           getNextToken();
2665           break;
2666         case TokenNameCOLON_COLON : // ::
2667         case TokenNameMINUS_GREATER : // ->
2668           getNextToken();
2669           if (token > TokenNameKEYWORD) {
2670             ident = scanner.getCurrentIdentifierSource();
2671             //            setMarker(
2672             //              "Avoid using keyword '"
2673             //                + new String(ident)
2674             //                + "' as variable name.",
2675             //              rowCount,
2676             //              PHPParser.INFO);
2677             setMarker(
2678               "Avoid using keyword '"
2679                 + new String(ident)
2680                 + "' as variable name.",
2681               scanner.getCurrentTokenStartPosition(),
2682               scanner.getCurrentTokenEndPosition(),
2683               INFO);
2684           }
2685           switch (token) {
2686             case TokenNameVariable :
2687               ident = scanner.getCurrentIdentifierSource();
2688               getNextToken();
2689               //              if (token == TokenNameARGOPEN) {
2690               //                getNextToken();
2691               //                expressionList();
2692               //                if (token != TokenNameARGCLOSE) {
2693               //                  throwSyntaxError(") expected after variable '" + ident + "'.");
2694               //                }
2695               //                getNextToken();
2696               //              }
2697               break;
2698             case TokenNameIdentifier :
2699               //ident = scanner.getCurrentIdentifierSource();
2700               getNextToken();
2701               break;
2702             case TokenNameLBRACE :
2703               getNextToken();
2704               expression();
2705               if (token != TokenNameRBRACE) {
2706                 throwSyntaxError("} expected in postfix-expression.");
2707               }
2708               getNextToken();
2709               break;
2710             default :
2711               throwSyntaxError("Syntax error after '->' token.");
2712           } while (
2713             token == TokenNameLBRACKET
2714               || token == TokenNameLPAREN
2715               || token == TokenNameLBRACE) {
2716               if (token == TokenNameLBRACKET) {
2717                 getNextToken();
2718                 expressionList();
2719                 if (token != TokenNameRBRACKET) {
2720                   throwSyntaxError("] expected after '->'.");
2721                 }
2722                 getNextToken();
2723               }
2724               if (token == TokenNameLPAREN) {
2725                 getNextToken();
2726                 expressionList();
2727                 if (token != TokenNameRPAREN) {
2728                   throwSyntaxError(") expected after '->'.");
2729                 }
2730                 getNextToken();
2731               }
2732               if (token == TokenNameLBRACE) {
2733                 getNextToken();
2734                 expression();
2735                 if (token != TokenNameRBRACE) {
2736                   throwSyntaxError("} expected after '->'.");
2737                 }
2738                 getNextToken();
2739               }
2740             }
2741           break;
2742         case TokenNamePLUS_PLUS :
2743           getNextToken();
2744           break;
2745         case TokenNameMINUS_MINUS :
2746           getNextToken();
2747           break;
2748         default :
2749           while_flag = false;
2750       }
2751
2752     }
2753     while (while_flag);
2754   }
2755
2756   private void unaryExpression() throws CoreException {
2757     switch (token) {
2758       case TokenNamePLUS_PLUS :
2759         getNextToken();
2760         unaryExpression();
2761         break;
2762       case TokenNameMINUS_MINUS :
2763         getNextToken();
2764         unaryExpression();
2765         break;
2766         // '@' '&' '*' '+' '-' '~' '!'
2767       case TokenNameAT :
2768         getNextToken();
2769         castExpression();
2770         break;
2771       case TokenNameAND :
2772         getNextToken();
2773         castExpression();
2774         break;
2775       case TokenNameMULTIPLY :
2776         getNextToken();
2777         castExpression();
2778         break;
2779       case TokenNamePLUS :
2780         getNextToken();
2781         castExpression();
2782         break;
2783       case TokenNameMINUS :
2784         getNextToken();
2785         castExpression();
2786         break;
2787       case TokenNameTWIDDLE :
2788         getNextToken();
2789         castExpression();
2790         break;
2791       case TokenNameNOT :
2792         getNextToken();
2793         castExpression();
2794         break;
2795       default :
2796         postfixExpression();
2797     }
2798   }
2799
2800   private void castExpression() throws CoreException {
2801     //    if (token == TokenNameARGOPEN) {
2802     //      getNextToken();
2803     //      typeName();
2804     //      if (token != TokenNameARGCLOSE) {
2805     //        throwSyntaxError(") expected after cast-expression.");
2806     //      }
2807     //      getNextToken();
2808     //    }
2809     unaryExpression();
2810   }
2811
2812   //  private void typeName() throws CoreException {
2813   //    //'string' 'unset' 'array' 'object'
2814   //    //'bool' 'boolean'
2815   //    //'real' 'double' 'float'
2816   //    //'int' 'integer'
2817   //    String identifier = "";
2818   //    if (token == TokenNameIdentifier) {
2819   //      char[] ident = scanner.getCurrentIdentifierSource();
2820   //      identifier = new String(ident);
2821   //      String str = identifier.toLowerCase();
2822   //      getNextToken();
2823   //      for (int i = 0; i < PHP_TYPES.length; i++) {
2824   //        if (PHP_TYPES[i].equals(str)) {
2825   //          return;
2826   //        }
2827   //      }
2828   //    }
2829   //    throwSyntaxError(
2830   //      "Expected type cast '( <type-name> )'; Got '" + identifier + "'.");
2831   //  }
2832
2833   private void assignExpression() throws CoreException {
2834     castExpression();
2835     if (token == TokenNameEQUAL) { // =
2836       getNextToken();
2837       logicalinclusiveorExpression();
2838     } else if (token == TokenNameDOT_EQUAL) { // .=
2839       getNextToken();
2840       logicalinclusiveorExpression();
2841     } else if (token == TokenNameEQUAL_GREATER) { // =>
2842       getNextToken();
2843       logicalinclusiveorExpression();
2844     } else if (token == TokenNamePLUS_EQUAL) { // +=
2845       getNextToken();
2846       logicalinclusiveorExpression();
2847     } else if (token == TokenNameMINUS_EQUAL) { // -=
2848       getNextToken();
2849       logicalinclusiveorExpression();
2850     } else if (token == TokenNameMULTIPLY_EQUAL) { // *=
2851       getNextToken();
2852       logicalinclusiveorExpression();
2853     } else if (token == TokenNameDIVIDE_EQUAL) { // *=
2854       getNextToken();
2855       logicalinclusiveorExpression();
2856     } else if (token == TokenNameREMAINDER_EQUAL) { // %=
2857       getNextToken();
2858       logicalinclusiveorExpression();
2859     } else if (token == TokenNameAND_EQUAL) { // &=
2860       getNextToken();
2861       logicalinclusiveorExpression();
2862     } else if (token == TokenNameOR_EQUAL) { // |=
2863       getNextToken();
2864       logicalinclusiveorExpression();
2865     } else if (token == TokenNameXOR_EQUAL) { // ^=
2866       getNextToken();
2867       logicalinclusiveorExpression();
2868     } else if (token == TokenNameLEFT_SHIFT_EQUAL) { // <<=
2869       getNextToken();
2870       logicalinclusiveorExpression();
2871     } else if (token == TokenNameRIGHT_SHIFT_EQUAL) { // >>=
2872       getNextToken();
2873       logicalinclusiveorExpression();
2874     } else if (token == TokenNameTWIDDLE_EQUAL) { // ~=
2875       getNextToken();
2876       logicalinclusiveorExpression();
2877     }
2878   }
2879
2880   private void multiplicativeExpression() throws CoreException {
2881     do {
2882       assignExpression();
2883       if (token != TokenNameMULTIPLY
2884         && token != TokenNameDIVIDE
2885         && token != TokenNameREMAINDER) {
2886         return;
2887       }
2888       getNextToken();
2889     } while (true);
2890   }
2891
2892   private void concatenationExpression() throws CoreException {
2893     do {
2894       multiplicativeExpression();
2895       if (token != TokenNameDOT) {
2896         return;
2897       }
2898       getNextToken();
2899     } while (true);
2900   }
2901
2902   private void additiveExpression() throws CoreException {
2903     do {
2904       concatenationExpression();
2905       if (token != TokenNamePLUS && token != TokenNameMINUS) {
2906         return;
2907       }
2908       getNextToken();
2909     } while (true);
2910   }
2911
2912   private void shiftExpression() throws CoreException {
2913     do {
2914       additiveExpression();
2915       if (token != TokenNameLEFT_SHIFT && token != TokenNameRIGHT_SHIFT) {
2916         return;
2917       }
2918       getNextToken();
2919     } while (true);
2920   }
2921
2922   private void relationalExpression() throws CoreException {
2923     do {
2924       shiftExpression();
2925       if (token != TokenNameLESS
2926         && token != TokenNameGREATER
2927         && token != TokenNameLESS_EQUAL
2928         && token != TokenNameGREATER_EQUAL) {
2929         return;
2930       }
2931       getNextToken();
2932     } while (true);
2933   }
2934
2935   private void identicalExpression() throws CoreException {
2936     do {
2937       relationalExpression();
2938       if (token != TokenNameEQUAL_EQUAL_EQUAL
2939         && token != TokenNameNOT_EQUAL_EQUAL) {
2940         return;
2941       }
2942       getNextToken();
2943     } while (true);
2944   }
2945
2946   private void equalityExpression() throws CoreException {
2947     do {
2948       identicalExpression();
2949       if (token != TokenNameEQUAL_EQUAL && token != TokenNameNOT_EQUAL) {
2950         return;
2951       }
2952       getNextToken();
2953     } while (true);
2954   }
2955
2956   private void ternaryExpression() throws CoreException {
2957     equalityExpression();
2958     if (token == TokenNameQUESTION) {
2959       getNextToken();
2960       expression();
2961       if (token == TokenNameCOLON) {
2962         getNextToken();
2963         expression();
2964       } else {
2965         throwSyntaxError("':' expected in ternary operator '? :'.");
2966       }
2967     }
2968   }
2969
2970   private void andExpression() throws CoreException {
2971     do {
2972       ternaryExpression();
2973       if (token != TokenNameAND) {
2974         return;
2975       }
2976       getNextToken();
2977     } while (true);
2978   }
2979
2980   private void exclusiveorExpression() throws CoreException {
2981     do {
2982       andExpression();
2983       if (token != TokenNameXOR) {
2984         return;
2985       }
2986       getNextToken();
2987     } while (true);
2988   }
2989
2990   private void inclusiveorExpression() throws CoreException {
2991     do {
2992       exclusiveorExpression();
2993       if (token != TokenNameOR) {
2994         return;
2995       }
2996       getNextToken();
2997     } while (true);
2998   }
2999
3000   private void booleanandExpression() throws CoreException {
3001     do {
3002       inclusiveorExpression();
3003       if (token != TokenNameAND_AND) {
3004         return;
3005       }
3006       getNextToken();
3007     } while (true);
3008   }
3009
3010   private void booleanorExpression() throws CoreException {
3011     do {
3012       booleanandExpression();
3013       if (token != TokenNameOR_OR) {
3014         return;
3015       }
3016       getNextToken();
3017     } while (true);
3018   }
3019
3020   private void logicalandExpression() throws CoreException {
3021     do {
3022       booleanorExpression();
3023       if (token != TokenNameAND) {
3024         return;
3025       }
3026       getNextToken();
3027     } while (true);
3028   }
3029
3030   private void logicalexclusiveorExpression() throws CoreException {
3031     do {
3032       logicalandExpression();
3033       if (token != TokenNameXOR) {
3034         return;
3035       }
3036       getNextToken();
3037     } while (true);
3038   }
3039
3040   private void logicalinclusiveorExpression() throws CoreException {
3041     do {
3042       logicalexclusiveorExpression();
3043       if (token != TokenNameOR) {
3044         return;
3045       }
3046       getNextToken();
3047     } while (true);
3048   }
3049
3050   //  public void assignmentExpression() {
3051   //    if (token == TokenNameVARIABLE) {
3052   //      getNextToken();
3053   //      if (token == TokenNameSET) {
3054   //        getNextToken();
3055   //        logicalinclusiveorExpression();
3056   //      }
3057   //    } else {
3058   //      logicalinclusiveorExpression();
3059   //    }
3060   //  }
3061
3062   private void variableList() throws CoreException {
3063     do {
3064       variable();
3065       if (token == TokenNameCOMMA) {
3066         getNextToken();
3067       } else {
3068         break;
3069       }
3070     } while (true);
3071   }
3072
3073   private void variable() throws CoreException {
3074     if (token == TokenNameDOLLAR_LBRACE) {
3075       getNextToken();
3076       expression();
3077       ;
3078       if (token != TokenNameRBRACE) {
3079         throwSyntaxError("'}' expected after indirect variable token '${'.");
3080       }
3081       getNextToken();
3082     } else {
3083       if (token == TokenNameVariable) {
3084         getNextToken();
3085         if (token == TokenNameLBRACKET) {
3086           getNextToken();
3087           expression();
3088           if (token != TokenNameRBRACKET) {
3089             throwSyntaxError("']' expected in variable-list.");
3090           }
3091           getNextToken();
3092         } else if (token == TokenNameEQUAL) {
3093           getNextToken();
3094           constant();
3095         }
3096       } else {
3097         throwSyntaxError("$-variable expected in variable-list.");
3098       }
3099     }
3100   }
3101
3102   /**
3103    * It will look for a value (after a '=' for example)
3104    * @throws CoreException
3105    */
3106   private void constant() throws CoreException {
3107     //   String ident;
3108     switch (token) {
3109       case TokenNamePLUS :
3110         getNextToken();
3111         switch (token) {
3112           case TokenNameDoubleLiteral :
3113             getNextToken();
3114             break;
3115           case TokenNameIntegerLiteral :
3116             getNextToken();
3117             break;
3118           default :
3119             throwSyntaxError("Constant expected after '+' presign.");
3120         }
3121         break;
3122       case TokenNameMINUS :
3123         getNextToken();
3124         switch (token) {
3125           case TokenNameDoubleLiteral :
3126             getNextToken();
3127             break;
3128           case TokenNameIntegerLiteral :
3129             getNextToken();
3130             break;
3131           default :
3132             throwSyntaxError("Constant expected after '-' presign.");
3133         }
3134         break;
3135       case TokenNamenull :
3136         getNextToken();
3137         break;
3138       case TokenNamefalse :
3139         getNextToken();
3140         break;
3141       case TokenNametrue :
3142         getNextToken();
3143         break;
3144       case TokenNameIdentifier :
3145         //   ident = identifier;
3146         char[] ident = scanner.getCurrentIdentifierSource();
3147         getNextToken();
3148         if (token == TokenNameLPAREN) {
3149           getNextToken();
3150           if (token != TokenNameRPAREN) {
3151             expressionList();
3152             if (token != TokenNameRPAREN) {
3153               throwSyntaxError(
3154                 "')' expected after identifier '"
3155                   + new String(ident)
3156                   + "' in postfix-expression.");
3157             }
3158           }
3159           getNextToken();
3160         }
3161         break;
3162       case TokenNameStringLiteral :
3163         getNextToken();
3164         break;
3165       case TokenNameStringConstant :
3166         getNextToken();
3167         break;
3168       case TokenNameStringInterpolated :
3169         getNextToken();
3170         break;
3171       case TokenNameDoubleLiteral :
3172         getNextToken();
3173         break;
3174       case TokenNameIntegerLiteral :
3175         getNextToken();
3176         break;
3177       default :
3178         throwSyntaxError("Constant expected.");
3179     }
3180   }
3181
3182 }