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