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