Partially fixed highlight bug for php block in html comment.
[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       throwSyntaxError("Class name expected after keyword 'class'.");
1983     }
1984   }
1985
1986   private void classBody() throws CoreException {
1987     //'{' [class-element-list] '}'
1988     if (token == TokenNameLBRACE) {
1989       getNextToken();
1990       if (token != TokenNameRBRACE) {
1991         classElementList();
1992       }
1993       if (token == TokenNameRBRACE) {
1994         getNextToken();
1995       } else {
1996         throwSyntaxError("'}' expected at end of class body.");
1997       }
1998     } else {
1999       throwSyntaxError("'{' expected at start of class body.");
2000     }
2001   }
2002
2003   private void classElementList() throws CoreException {
2004     do {
2005       classElement();
2006     } while (token == TokenNamefunction || token == TokenNamevar);
2007   }
2008
2009   private void classElement() throws CoreException {
2010     //class-property
2011     //function-definition
2012     if (token == TokenNamefunction) {
2013       getNextToken();
2014       functionDefinition();
2015     } else if (token == TokenNamevar) {
2016       getNextToken();
2017       classProperty();
2018     } else {
2019       throwSyntaxError("'function' or 'var' expected.");
2020     }
2021   }
2022
2023   private void classProperty() throws CoreException {
2024     //'var' variable ';'
2025     //'var' variable '=' constant ';'
2026     do {
2027       if (token == TokenNameVariable) {
2028         getNextToken();
2029         if (token == TokenNameEQUAL) {
2030           getNextToken();
2031           constant();
2032         }
2033       } else {
2034         throwSyntaxError("Variable expected after keyword 'var'.");
2035       }
2036       if (token != TokenNameCOMMA) {
2037         break;
2038       }
2039       getNextToken();
2040     } while (true);
2041     if (token == TokenNameSEMICOLON) {
2042       getNextToken();
2043     } else {
2044       throwSyntaxError("';' expected after variable declaration.");
2045     }
2046   }
2047
2048   private void functionDefinition() throws CoreException {
2049     functionDeclarator();
2050     compoundStatement();
2051   }
2052
2053   private void functionDeclarator() throws CoreException {
2054     //identifier '(' [parameter-list] ')'
2055     if (token == TokenNameAND) {
2056       getNextToken();
2057     }
2058     if (token == TokenNameIdentifier) {
2059       getNextToken();
2060       if (token == TokenNameLPAREN) {
2061         getNextToken();
2062       } else {
2063         throwSyntaxError("'(' expected in function declaration.");
2064       }
2065       if (token != TokenNameRPAREN) {
2066         parameterList();
2067       }
2068       if (token != TokenNameRPAREN) {
2069         throwSyntaxError("')' expected in function declaration.");
2070       } else {
2071         getNextToken();
2072       }
2073     }
2074   }
2075   //
2076   private void parameterList() throws CoreException {
2077     //parameter-declaration
2078     //parameter-list ',' parameter-declaration
2079     do {
2080       parameterDeclaration();
2081       if (token != TokenNameCOMMA) {
2082         break;
2083       }
2084       getNextToken();
2085     } while (true);
2086   }
2087
2088   private void parameterDeclaration() throws CoreException {
2089     //variable
2090     //variable-reference
2091     if (token == TokenNameAND) {
2092       getNextToken();
2093       if (token == TokenNameVariable) {
2094         getNextToken();
2095       } else {
2096         throwSyntaxError("Variable expected after reference operator '&'.");
2097       }
2098     }
2099     //variable '=' constant
2100     if (token == TokenNameVariable) {
2101       getNextToken();
2102       if (token == TokenNameEQUAL) {
2103         getNextToken();
2104         constant();
2105       }
2106       return;
2107     }
2108   }
2109
2110   private void labeledStatementList() throws CoreException {
2111     if (token != TokenNamecase && token != TokenNamedefault) {
2112       throwSyntaxError("'case' or 'default' expected.");
2113     }
2114     do {
2115       if (token == TokenNamecase) {
2116         getNextToken();
2117         constant();
2118         if (token == TokenNameCOLON) {
2119           getNextToken();
2120           if (token == TokenNamecase
2121             || token == TokenNamedefault) { // empty case statement ?
2122             continue;
2123           }
2124           statementList();
2125         } else if (token == TokenNameSEMICOLON) {
2126           //          setMarker(
2127           //            "':' expected after 'case' keyword (Found token: "
2128           //              + scanner.toStringAction(token)
2129           //              + ")",
2130           //            rowCount,
2131           //            PHPParser.INFO);
2132           setMarker(
2133             "':' expected after 'case' keyword (Found token: "
2134               + scanner.toStringAction(token)
2135               + ")",
2136             scanner.getCurrentTokenStartPosition(),
2137             scanner.getCurrentTokenEndPosition(),
2138             INFO);
2139           getNextToken();
2140           if (token == TokenNamecase) { // empty case statement ?
2141             continue;
2142           }
2143           statementList();
2144         } else {
2145           throwSyntaxError(
2146             "':' character after 'case' constant expected (Found token: "
2147               + scanner.toStringAction(token)
2148               + ")");
2149         }
2150       } else { // TokenNamedefault
2151         getNextToken();
2152         if (token == TokenNameCOLON) {
2153           getNextToken();
2154           statementList();
2155         } else {
2156           throwSyntaxError("':' character after 'default' expected.");
2157         }
2158       }
2159     } while (token == TokenNamecase || token == TokenNamedefault);
2160   }
2161
2162   //  public void labeledStatement() {
2163   //    if (token == TokenNamecase) {
2164   //      getNextToken();
2165   //      constant();
2166   //      if (token == TokenNameDDOT) {
2167   //        getNextToken();
2168   //        statement();
2169   //      } else {
2170   //        throwSyntaxError("':' character after 'case' constant expected.");
2171   //      }
2172   //      return;
2173   //    } else if (token == TokenNamedefault) {
2174   //      getNextToken();
2175   //      if (token == TokenNameDDOT) {
2176   //        getNextToken();
2177   //        statement();
2178   //      } else {
2179   //        throwSyntaxError("':' character after 'default' expected.");
2180   //      }
2181   //      return;
2182   //    }
2183   //  }
2184
2185   //  public void expressionStatement() {
2186   //  }
2187
2188   //  private void inclusionStatement() {
2189   //  }
2190
2191   //  public void compoundStatement() {
2192   //  }
2193
2194   //  public void selectionStatement() {
2195   //  }
2196   //
2197   //  public void iterationStatement() {
2198   //  }
2199   //
2200   //  public void jumpStatement() {
2201   //  }
2202   //
2203   //  public void outputStatement() {
2204   //  }
2205   //
2206   //  public void scopeStatement() {
2207   //  }
2208   //
2209   //  public void flowStatement() {
2210   //  }
2211   //
2212   //  public void definitionStatement() {
2213   //  }
2214
2215   private void ifStatement() throws CoreException {
2216     // ':' statement-list [elseif-list] [else-colon-statement] 'endif' ';'
2217     if (token == TokenNameCOLON) {
2218       getNextToken();
2219       statementList();
2220       switch (token) {
2221         case TokenNameelse :
2222           getNextToken();
2223           if (token == TokenNameCOLON) {
2224             getNextToken();
2225             statementList();
2226           } else {
2227             if (token == TokenNameif) { //'else if'
2228               getNextToken();
2229               elseifStatementList();
2230             } else {
2231               throwSyntaxError("':' expected after 'else'.");
2232             }
2233           }
2234           break;
2235         case TokenNameelseif :
2236           getNextToken();
2237           elseifStatementList();
2238           break;
2239       }
2240
2241       if (token != TokenNameendif) {
2242         throwSyntaxError("'endif' expected.");
2243       }
2244       getNextToken();
2245       if (token != TokenNameSEMICOLON) {
2246         throwSyntaxError("';' expected after if-statement.");
2247       }
2248       getNextToken();
2249     } else {
2250       // statement [else-statement]
2251       statement();
2252       if (token == TokenNameelseif) {
2253         getNextToken();
2254         if (token == TokenNameLPAREN) {
2255           getNextToken();
2256         } else {
2257           throwSyntaxError("'(' expected after 'elseif' keyword.");
2258         }
2259         expression();
2260         if (token == TokenNameRPAREN) {
2261           getNextToken();
2262         } else {
2263           throwSyntaxError("')' expected after 'elseif' condition.");
2264         }
2265         ifStatement();
2266       } else if (token == TokenNameelse) {
2267         getNextToken();
2268         statement();
2269       }
2270     }
2271   }
2272
2273   private void elseifStatementList() throws CoreException {
2274     do {
2275       elseifStatement();
2276       switch (token) {
2277         case TokenNameelse :
2278           getNextToken();
2279           if (token == TokenNameCOLON) {
2280             getNextToken();
2281             statementList();
2282             return;
2283           } else {
2284             if (token == TokenNameif) { //'else if'
2285               getNextToken();
2286             } else {
2287               throwSyntaxError("':' expected after 'else'.");
2288             }
2289           }
2290           break;
2291         case TokenNameelseif :
2292           getNextToken();
2293           break;
2294         default :
2295           return;
2296       }
2297     } while (true);
2298   }
2299
2300   private void elseifStatement() throws CoreException {
2301     if (token == TokenNameLPAREN) {
2302       getNextToken();
2303       expression();
2304       if (token != TokenNameLPAREN) {
2305         throwSyntaxError("')' expected in else-if-statement.");
2306       }
2307       getNextToken();
2308       if (token != TokenNameCOLON) {
2309         throwSyntaxError("':' expected in else-if-statement.");
2310       }
2311       getNextToken();
2312       statementList();
2313     }
2314   }
2315
2316   private void switchStatement() throws CoreException {
2317     if (token == TokenNameCOLON) {
2318       // ':' [labeled-statement-list] 'endswitch' ';'
2319       getNextToken();
2320       labeledStatementList();
2321       if (token != TokenNameendswitch) {
2322         throwSyntaxError("'endswitch' expected.");
2323       }
2324       getNextToken();
2325       if (token != TokenNameSEMICOLON) {
2326         throwSyntaxError("';' expected after switch-statement.");
2327       }
2328       getNextToken();
2329     } else {
2330       // '{' [labeled-statement-list] '}'
2331       if (token != TokenNameLBRACE) {
2332         throwSyntaxError("'{' expected in switch statement.");
2333       }
2334       getNextToken();
2335       if (token != TokenNameRBRACE) {
2336         labeledStatementList();
2337       }
2338       if (token != TokenNameRBRACE) {
2339         throwSyntaxError("'}' expected in switch statement.");
2340       }
2341       getNextToken();
2342
2343     }
2344   }
2345
2346   private void forStatement() throws CoreException {
2347     if (token == TokenNameCOLON) {
2348       getNextToken();
2349       statementList();
2350       if (token != TokenNameendfor) {
2351         throwSyntaxError("'endfor' expected.");
2352       }
2353       getNextToken();
2354       if (token != TokenNameSEMICOLON) {
2355         throwSyntaxError("';' expected after for-statement.");
2356       }
2357       getNextToken();
2358     } else {
2359       statement();
2360     }
2361   }
2362
2363   private void whileStatement() throws CoreException {
2364     // ':' statement-list 'endwhile' ';'
2365     if (token == TokenNameCOLON) {
2366       getNextToken();
2367       statementList();
2368       if (token != TokenNameendwhile) {
2369         throwSyntaxError("'endwhile' expected.");
2370       }
2371       getNextToken();
2372       if (token != TokenNameSEMICOLON) {
2373         throwSyntaxError("';' expected after while-statement.");
2374       }
2375       getNextToken();
2376     } else {
2377       statement();
2378     }
2379   }
2380
2381   private void foreachStatement() throws CoreException {
2382     if (token == TokenNameCOLON) {
2383       getNextToken();
2384       statementList();
2385       if (token != TokenNameendforeach) {
2386         throwSyntaxError("'endforeach' expected.");
2387       }
2388       getNextToken();
2389       if (token != TokenNameSEMICOLON) {
2390         throwSyntaxError("';' expected after foreach-statement.");
2391       }
2392       getNextToken();
2393     } else {
2394       statement();
2395     }
2396   }
2397
2398   private void exitStatus() throws CoreException {
2399     if (token == TokenNameLPAREN) {
2400       getNextToken();
2401     } else {
2402       throwSyntaxError("'(' expected in 'exit-status'.");
2403     }
2404     if (token != TokenNameRPAREN) {
2405       expression();
2406     }
2407     if (token == TokenNameRPAREN) {
2408       getNextToken();
2409     } else {
2410       throwSyntaxError("')' expected after 'exit-status'.");
2411     }
2412   }
2413
2414   private void expressionList() throws CoreException {
2415     do {
2416       expression();
2417       if (token == TokenNameCOMMA) {
2418         getNextToken();
2419       } else {
2420         break;
2421       }
2422     } while (true);
2423   }
2424
2425   private void expression() throws CoreException {
2426     //todo: find a better way to get the expression
2427     //    expression = new StringBuffer();
2428     //    for (int i = chIndx; i < str.length(); i++) {
2429     //      if (str.charAt(i) == ';') {
2430     //        break;
2431     //      }
2432     //      expression.append(str.charAt(i));
2433     //    }
2434
2435     //    if (token == TokenNameSTRING_CONSTANT || token == TokenNameINTERPOLATED_STRING) {
2436     //      getNextToken();
2437     //    } else {
2438     logicalinclusiveorExpression();
2439     //      while (token != TokenNameSEMICOLON) {
2440     //        getNextToken();
2441     //      //      }
2442     //    }
2443   }
2444
2445   private void postfixExpression() throws CoreException {
2446     //  String ident;
2447     char[] ident;
2448     boolean castFlag = false;
2449     switch (token) {
2450       case TokenNamenew :
2451         getNextToken();
2452         expression();
2453         break;
2454       case TokenNamenull :
2455         getNextToken();
2456         break;
2457       case TokenNamefalse :
2458         getNextToken();
2459         break;
2460       case TokenNametrue :
2461         getNextToken();
2462         break;
2463       case TokenNameStringConstant :
2464         getNextToken();
2465         break;
2466       case TokenNameHEREDOC :
2467       case TokenNameStringInterpolated :
2468       case TokenNameStringLiteral :
2469         getNextToken();
2470         break;
2471       case TokenNameLPAREN :
2472         getNextToken();
2473         if (token == TokenNameIdentifier) {
2474           // check if identifier is a type:
2475           //    ident = identifier;
2476           ident = scanner.getCurrentIdentifierSource();
2477           String str = new String(ident).toLowerCase();
2478           for (int i = 0; i < PHP_TYPES.length; i++) {
2479             if (PHP_TYPES[i].equals(str)) {
2480               castFlag = true;
2481               break;
2482             }
2483           }
2484           if (castFlag) {
2485             getNextToken();
2486             if (token != TokenNameRPAREN) {
2487               throwSyntaxError(") expected after cast-type '" + str + "'.");
2488             }
2489             getNextToken();
2490             expression();
2491             break;
2492           }
2493         }
2494         if (!castFlag) {
2495           expression();
2496         }
2497         if (token != TokenNameRPAREN) {
2498           throwSyntaxError(") expected in postfix-expression.");
2499         }
2500         getNextToken();
2501         break;
2502       case TokenNameDoubleLiteral :
2503         getNextToken();
2504         break;
2505       case TokenNameIntegerLiteral :
2506         getNextToken();
2507         break;
2508       case TokenNameDOLLAR_LBRACE :
2509         getNextToken();
2510         expression();
2511         if (token != TokenNameRBRACE) {
2512           throwSyntaxError("'}' expected after indirect variable token '${'.");
2513         }
2514         getNextToken();
2515         break;
2516       case TokenNameVariable :
2517         ident = scanner.getCurrentIdentifierSource();
2518         getNextToken();
2519         if (token == TokenNameLBRACE) {
2520           getNextToken();
2521           expression();
2522           if (token != TokenNameRBRACE) {
2523             throwSyntaxError(
2524               "'}' expected after variable '"
2525                 + new String(ident)
2526                 + "' in variable-expression.");
2527           }
2528           getNextToken();
2529         } else if (token == TokenNameLPAREN) {
2530           getNextToken();
2531           if (token != TokenNameRPAREN) {
2532             expressionList();
2533             if (token != TokenNameRPAREN) {
2534               throwSyntaxError(
2535                 "')' expected after variable '"
2536                   + new String(ident)
2537                   + "' in postfix-expression.");
2538             }
2539           }
2540           getNextToken();
2541         }
2542         break;
2543       case TokenNameIdentifier :
2544         ident = scanner.getCurrentIdentifierSource();
2545         getNextToken();
2546         if (token == TokenNameLPAREN) {
2547           getNextToken();
2548           if (token != TokenNameRPAREN) {
2549             expressionList();
2550             if (token != TokenNameRPAREN) {
2551               throwSyntaxError(
2552                 "')' expected after identifier '"
2553                   + new String(ident)
2554                   + "' in postfix-expression."
2555                   + "(Found token: "
2556                   + scanner.toStringAction(token)
2557                   + ")");
2558             }
2559           }
2560           getNextToken();
2561         }
2562         break;
2563       case TokenNameprint :
2564         getNextToken();
2565         expression();
2566         //        if (token == TokenNameSEMICOLON) {
2567         //          getNextToken();
2568         //        } else {
2569         //          if (token != TokenNameStopPHP) {
2570         //            throwSyntaxError("';' expected after 'print' statement.");
2571         //          }
2572         //          getNextToken();
2573         //        }
2574         break;
2575       case TokenNamelist :
2576         getNextToken();
2577         if (token == TokenNameLPAREN) {
2578           getNextToken();
2579           if (token == TokenNameCOMMA) {
2580             getNextToken();
2581           }
2582           expressionList();
2583           if (token != TokenNameRPAREN) {
2584             throwSyntaxError("')' expected after 'list' keyword.");
2585           }
2586           getNextToken();
2587           //          if (token == TokenNameSET) {
2588           //            getNextToken();
2589           //            logicalinclusiveorExpression();
2590           //          }
2591         } else {
2592           throwSyntaxError("'(' expected after 'list' keyword.");
2593         }
2594         break;
2595         //      case TokenNameexit :
2596         //        getNextToken();
2597         //        if (token != TokenNameSEMICOLON) {
2598         //          exitStatus();
2599         //        }
2600         //        if (token == TokenNameSEMICOLON) {
2601         //          getNextToken();
2602         //        } else {
2603         //          if (token != TokenNameStopPHP) {
2604         //            throwSyntaxError("';' expected after 'exit' expression.");
2605         //          }
2606         //          getNextToken();
2607         //        }
2608         //        break;
2609         //      case TokenNamedie :
2610         //        getNextToken();
2611         //        if (token != TokenNameSEMICOLON) {
2612         //          exitStatus();
2613         //        }
2614         //        if (token == TokenNameSEMICOLON) {
2615         //          getNextToken();
2616         //        } else {
2617         //          if (token != TokenNameStopPHP) {
2618         //            throwSyntaxError("';' expected after 'die' expression.");
2619         //          }
2620         //        }
2621         //        break;
2622
2623         //      case TokenNamearray :
2624         //        getNextToken();
2625         //        if (token == TokenNameARGOPEN) {
2626         //          getNextToken();
2627         //          if (token == TokenNameCOMMA) {
2628         //            getNextToken();
2629         //          }
2630         //          expressionList();
2631         //          if (token != TokenNameARGCLOSE) {
2632         //            throwSyntaxError("')' expected after 'list' keyword.");
2633         //          }
2634         //          getNextToken();
2635         //          if (token == TokenNameSET) {
2636         //            getNextToken();
2637         //            logicalinclusiveorExpression();
2638         //          }
2639         //        } else {
2640         //          throwSyntaxError("'(' expected after 'list' keyword.");
2641         //        }
2642         //        break;
2643     }
2644     boolean while_flag = true;
2645     do {
2646       switch (token) {
2647         case TokenNameLBRACKET :
2648           getNextToken();
2649           expression();
2650           if (token != TokenNameRBRACKET) {
2651             throwSyntaxError("] expected in postfix-expression.");
2652           }
2653           getNextToken();
2654           break;
2655         case TokenNameCOLON_COLON : // ::
2656         case TokenNameMINUS_GREATER : // ->
2657           getNextToken();
2658           if (token > TokenNameKEYWORD) {
2659             ident = scanner.getCurrentIdentifierSource();
2660             //            setMarker(
2661             //              "Avoid using keyword '"
2662             //                + new String(ident)
2663             //                + "' as variable name.",
2664             //              rowCount,
2665             //              PHPParser.INFO);
2666             setMarker(
2667               "Avoid using keyword '"
2668                 + new String(ident)
2669                 + "' as variable name.",
2670               scanner.getCurrentTokenStartPosition(),
2671               scanner.getCurrentTokenEndPosition(),
2672               INFO);
2673           }
2674           switch (token) {
2675             case TokenNameVariable :
2676               ident = scanner.getCurrentIdentifierSource();
2677               getNextToken();
2678               //              if (token == TokenNameARGOPEN) {
2679               //                getNextToken();
2680               //                expressionList();
2681               //                if (token != TokenNameARGCLOSE) {
2682               //                  throwSyntaxError(") expected after variable '" + ident + "'.");
2683               //                }
2684               //                getNextToken();
2685               //              }
2686               break;
2687             case TokenNameIdentifier :
2688               //ident = scanner.getCurrentIdentifierSource();
2689               getNextToken();
2690               break;
2691             case TokenNameLBRACE :
2692               getNextToken();
2693               expression();
2694               if (token != TokenNameRBRACE) {
2695                 throwSyntaxError("} expected in postfix-expression.");
2696               }
2697               getNextToken();
2698               break;
2699             default :
2700               throwSyntaxError("Syntax error after '->' token.");
2701           } while (
2702             token == TokenNameLBRACKET
2703               || token == TokenNameLPAREN
2704               || token == TokenNameLBRACE) {
2705               if (token == TokenNameLBRACKET) {
2706                 getNextToken();
2707                 expressionList();
2708                 if (token != TokenNameRBRACKET) {
2709                   throwSyntaxError("] expected after '->'.");
2710                 }
2711                 getNextToken();
2712               }
2713               if (token == TokenNameLPAREN) {
2714                 getNextToken();
2715                 expressionList();
2716                 if (token != TokenNameRPAREN) {
2717                   throwSyntaxError(") expected after '->'.");
2718                 }
2719                 getNextToken();
2720               }
2721               if (token == TokenNameLBRACE) {
2722                 getNextToken();
2723                 expression();
2724                 if (token != TokenNameRBRACE) {
2725                   throwSyntaxError("} expected after '->'.");
2726                 }
2727                 getNextToken();
2728               }
2729             }
2730           break;
2731         case TokenNamePLUS_PLUS :
2732           getNextToken();
2733           break;
2734         case TokenNameMINUS_MINUS :
2735           getNextToken();
2736           break;
2737         default :
2738           while_flag = false;
2739       }
2740
2741     }
2742     while (while_flag);
2743   }
2744
2745   private void unaryExpression() throws CoreException {
2746     switch (token) {
2747       case TokenNamePLUS_PLUS :
2748         getNextToken();
2749         unaryExpression();
2750         break;
2751       case TokenNameMINUS_MINUS :
2752         getNextToken();
2753         unaryExpression();
2754         break;
2755         // '@' '&' '*' '+' '-' '~' '!'
2756       case TokenNameAT :
2757         getNextToken();
2758         castExpression();
2759         break;
2760       case TokenNameAND :
2761         getNextToken();
2762         castExpression();
2763         break;
2764       case TokenNameMULTIPLY :
2765         getNextToken();
2766         castExpression();
2767         break;
2768       case TokenNamePLUS :
2769         getNextToken();
2770         castExpression();
2771         break;
2772       case TokenNameMINUS :
2773         getNextToken();
2774         castExpression();
2775         break;
2776       case TokenNameTWIDDLE :
2777         getNextToken();
2778         castExpression();
2779         break;
2780       case TokenNameNOT :
2781         getNextToken();
2782         castExpression();
2783         break;
2784       default :
2785         postfixExpression();
2786     }
2787   }
2788
2789   private void castExpression() throws CoreException {
2790     //    if (token == TokenNameARGOPEN) {
2791     //      getNextToken();
2792     //      typeName();
2793     //      if (token != TokenNameARGCLOSE) {
2794     //        throwSyntaxError(") expected after cast-expression.");
2795     //      }
2796     //      getNextToken();
2797     //    }
2798     unaryExpression();
2799   }
2800
2801   //  private void typeName() throws CoreException {
2802   //    //'string' 'unset' 'array' 'object'
2803   //    //'bool' 'boolean'
2804   //    //'real' 'double' 'float'
2805   //    //'int' 'integer'
2806   //    String identifier = "";
2807   //    if (token == TokenNameIdentifier) {
2808   //      char[] ident = scanner.getCurrentIdentifierSource();
2809   //      identifier = new String(ident);
2810   //      String str = identifier.toLowerCase();
2811   //      getNextToken();
2812   //      for (int i = 0; i < PHP_TYPES.length; i++) {
2813   //        if (PHP_TYPES[i].equals(str)) {
2814   //          return;
2815   //        }
2816   //      }
2817   //    }
2818   //    throwSyntaxError(
2819   //      "Expected type cast '( <type-name> )'; Got '" + identifier + "'.");
2820   //  }
2821
2822   private void assignExpression() throws CoreException {
2823     castExpression();
2824     if (token == TokenNameEQUAL) { // =
2825       getNextToken();
2826       logicalinclusiveorExpression();
2827     } else if (token == TokenNameDOT_EQUAL) { // .=
2828       getNextToken();
2829       logicalinclusiveorExpression();
2830     } else if (token == TokenNameEQUAL_GREATER) { // =>
2831       getNextToken();
2832       logicalinclusiveorExpression();
2833     } else if (token == TokenNamePLUS_EQUAL) { // +=
2834       getNextToken();
2835       logicalinclusiveorExpression();
2836     } else if (token == TokenNameMINUS_EQUAL) { // -=
2837       getNextToken();
2838       logicalinclusiveorExpression();
2839     } else if (token == TokenNameMULTIPLY_EQUAL) { // *=
2840       getNextToken();
2841       logicalinclusiveorExpression();
2842     } else if (token == TokenNameDIVIDE_EQUAL) { // *=
2843       getNextToken();
2844       logicalinclusiveorExpression();
2845     } else if (token == TokenNameREMAINDER_EQUAL) { // %=
2846       getNextToken();
2847       logicalinclusiveorExpression();
2848     } else if (token == TokenNameAND_EQUAL) { // &=
2849       getNextToken();
2850       logicalinclusiveorExpression();
2851     } else if (token == TokenNameOR_EQUAL) { // |=
2852       getNextToken();
2853       logicalinclusiveorExpression();
2854     } else if (token == TokenNameXOR_EQUAL) { // ^=
2855       getNextToken();
2856       logicalinclusiveorExpression();
2857     } else if (token == TokenNameLEFT_SHIFT_EQUAL) { // <<=
2858       getNextToken();
2859       logicalinclusiveorExpression();
2860     } else if (token == TokenNameRIGHT_SHIFT_EQUAL) { // >>=
2861       getNextToken();
2862       logicalinclusiveorExpression();
2863     } else if (token == TokenNameTWIDDLE_EQUAL) { // ~=
2864       getNextToken();
2865       logicalinclusiveorExpression();
2866     }
2867   }
2868
2869   private void multiplicativeExpression() throws CoreException {
2870     do {
2871       assignExpression();
2872       if (token != TokenNameMULTIPLY
2873         && token != TokenNameDIVIDE
2874         && token != TokenNameREMAINDER) {
2875         return;
2876       }
2877       getNextToken();
2878     } while (true);
2879   }
2880
2881   private void concatenationExpression() throws CoreException {
2882     do {
2883       multiplicativeExpression();
2884       if (token != TokenNameDOT) {
2885         return;
2886       }
2887       getNextToken();
2888     } while (true);
2889   }
2890
2891   private void additiveExpression() throws CoreException {
2892     do {
2893       concatenationExpression();
2894       if (token != TokenNamePLUS && token != TokenNameMINUS) {
2895         return;
2896       }
2897       getNextToken();
2898     } while (true);
2899   }
2900
2901   private void shiftExpression() throws CoreException {
2902     do {
2903       additiveExpression();
2904       if (token != TokenNameLEFT_SHIFT && token != TokenNameRIGHT_SHIFT) {
2905         return;
2906       }
2907       getNextToken();
2908     } while (true);
2909   }
2910
2911   private void relationalExpression() throws CoreException {
2912     do {
2913       shiftExpression();
2914       if (token != TokenNameLESS
2915         && token != TokenNameGREATER
2916         && token != TokenNameLESS_EQUAL
2917         && token != TokenNameGREATER_EQUAL) {
2918         return;
2919       }
2920       getNextToken();
2921     } while (true);
2922   }
2923
2924   private void identicalExpression() throws CoreException {
2925     do {
2926       relationalExpression();
2927       if (token != TokenNameEQUAL_EQUAL_EQUAL
2928         && token != TokenNameNOT_EQUAL_EQUAL) {
2929         return;
2930       }
2931       getNextToken();
2932     } while (true);
2933   }
2934
2935   private void equalityExpression() throws CoreException {
2936     do {
2937       identicalExpression();
2938       if (token != TokenNameEQUAL_EQUAL && token != TokenNameNOT_EQUAL) {
2939         return;
2940       }
2941       getNextToken();
2942     } while (true);
2943   }
2944
2945   private void ternaryExpression() throws CoreException {
2946     equalityExpression();
2947     if (token == TokenNameQUESTION) {
2948       getNextToken();
2949       expression();
2950       if (token == TokenNameCOLON) {
2951         getNextToken();
2952         expression();
2953       } else {
2954         throwSyntaxError("':' expected in ternary operator '? :'.");
2955       }
2956     }
2957   }
2958
2959   private void andExpression() throws CoreException {
2960     do {
2961       ternaryExpression();
2962       if (token != TokenNameAND) {
2963         return;
2964       }
2965       getNextToken();
2966     } while (true);
2967   }
2968
2969   private void exclusiveorExpression() throws CoreException {
2970     do {
2971       andExpression();
2972       if (token != TokenNameXOR) {
2973         return;
2974       }
2975       getNextToken();
2976     } while (true);
2977   }
2978
2979   private void inclusiveorExpression() throws CoreException {
2980     do {
2981       exclusiveorExpression();
2982       if (token != TokenNameOR) {
2983         return;
2984       }
2985       getNextToken();
2986     } while (true);
2987   }
2988
2989   private void booleanandExpression() throws CoreException {
2990     do {
2991       inclusiveorExpression();
2992       if (token != TokenNameAND_AND) {
2993         return;
2994       }
2995       getNextToken();
2996     } while (true);
2997   }
2998
2999   private void booleanorExpression() throws CoreException {
3000     do {
3001       booleanandExpression();
3002       if (token != TokenNameOR_OR) {
3003         return;
3004       }
3005       getNextToken();
3006     } while (true);
3007   }
3008
3009   private void logicalandExpression() throws CoreException {
3010     do {
3011       booleanorExpression();
3012       if (token != TokenNameAND) {
3013         return;
3014       }
3015       getNextToken();
3016     } while (true);
3017   }
3018
3019   private void logicalexclusiveorExpression() throws CoreException {
3020     do {
3021       logicalandExpression();
3022       if (token != TokenNameXOR) {
3023         return;
3024       }
3025       getNextToken();
3026     } while (true);
3027   }
3028
3029   private void logicalinclusiveorExpression() throws CoreException {
3030     do {
3031       logicalexclusiveorExpression();
3032       if (token != TokenNameOR) {
3033         return;
3034       }
3035       getNextToken();
3036     } while (true);
3037   }
3038
3039   //  public void assignmentExpression() {
3040   //    if (token == TokenNameVARIABLE) {
3041   //      getNextToken();
3042   //      if (token == TokenNameSET) {
3043   //        getNextToken();
3044   //        logicalinclusiveorExpression();
3045   //      }
3046   //    } else {
3047   //      logicalinclusiveorExpression();
3048   //    }
3049   //  }
3050
3051   private void variableList() throws CoreException {
3052     do {
3053       variable();
3054       if (token == TokenNameCOMMA) {
3055         getNextToken();
3056       } else {
3057         break;
3058       }
3059     } while (true);
3060   }
3061
3062   private void variable() throws CoreException {
3063     if (token == TokenNameDOLLAR_LBRACE) {
3064       getNextToken();
3065       expression();
3066       ;
3067       if (token != TokenNameRBRACE) {
3068         throwSyntaxError("'}' expected after indirect variable token '${'.");
3069       }
3070       getNextToken();
3071     } else {
3072       if (token == TokenNameVariable) {
3073         getNextToken();
3074         if (token == TokenNameLBRACKET) {
3075           getNextToken();
3076           expression();
3077           if (token != TokenNameRBRACKET) {
3078             throwSyntaxError("']' expected in variable-list.");
3079           }
3080           getNextToken();
3081         } else if (token == TokenNameEQUAL) {
3082           getNextToken();
3083           constant();
3084         }
3085       } else {
3086         throwSyntaxError("$-variable expected in variable-list.");
3087       }
3088     }
3089   }
3090
3091   /**
3092    * It will look for a value (after a '=' for example)
3093    * @throws CoreException
3094    */
3095   private void constant() throws CoreException {
3096     //   String ident;
3097     switch (token) {
3098       case TokenNamePLUS :
3099         getNextToken();
3100         switch (token) {
3101           case TokenNameDoubleLiteral :
3102             getNextToken();
3103             break;
3104           case TokenNameIntegerLiteral :
3105             getNextToken();
3106             break;
3107           default :
3108             throwSyntaxError("Constant expected after '+' presign.");
3109         }
3110         break;
3111       case TokenNameMINUS :
3112         getNextToken();
3113         switch (token) {
3114           case TokenNameDoubleLiteral :
3115             getNextToken();
3116             break;
3117           case TokenNameIntegerLiteral :
3118             getNextToken();
3119             break;
3120           default :
3121             throwSyntaxError("Constant expected after '-' presign.");
3122         }
3123         break;
3124       case TokenNamenull :
3125         getNextToken();
3126         break;
3127       case TokenNamefalse :
3128         getNextToken();
3129         break;
3130       case TokenNametrue :
3131         getNextToken();
3132         break;
3133       case TokenNameIdentifier :
3134         //   ident = identifier;
3135         char[] ident = scanner.getCurrentIdentifierSource();
3136         getNextToken();
3137         if (token == TokenNameLPAREN) {
3138           getNextToken();
3139           if (token != TokenNameRPAREN) {
3140             expressionList();
3141             if (token != TokenNameRPAREN) {
3142               throwSyntaxError(
3143                 "')' expected after identifier '"
3144                   + new String(ident)
3145                   + "' in postfix-expression.");
3146             }
3147           }
3148           getNextToken();
3149         }
3150         break;
3151       case TokenNameStringLiteral :
3152         getNextToken();
3153         break;
3154       case TokenNameStringConstant :
3155         getNextToken();
3156         break;
3157       case TokenNameStringInterpolated :
3158         getNextToken();
3159         break;
3160       case TokenNameDoubleLiteral :
3161         getNextToken();
3162         break;
3163       case TokenNameIntegerLiteral :
3164         getNextToken();
3165         break;
3166       default :
3167         throwSyntaxError("Constant expected.");
3168     }
3169   }
3170
3171 }