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