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