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