the parser is no longer static
[phpeclipse.git] / net.sourceforge.phpeclipse / src / test / PHPParser.jj
index 10ba3a9..c1d2e52 100644 (file)
@@ -3,7 +3,7 @@ options {
   LOOKAHEAD = 1;
   CHOICE_AMBIGUITY_CHECK = 2;
   OTHER_AMBIGUITY_CHECK = 1;
-  STATIC = true;
+  STATIC = false;
   DEBUG_PARSER = false;
   DEBUG_LOOKAHEAD = false;
   DEBUG_TOKEN_MANAGER = false;
@@ -101,24 +101,26 @@ public final class PHPParser extends PHPParserSuperclass {
     PHPParser.fileToParse = fileToParse;
   }
 
-  public static final void phpParserTester(final String strEval) throws ParseException {
+  public final void phpParserTester(final String strEval) throws ParseException {
     final StringReader stream = new StringReader(strEval);
     if (jj_input_stream == null) {
       jj_input_stream = new SimpleCharStream(stream, 1, 1);
+      token_source = new PHPParserTokenManager(jj_input_stream);
     }
     ReInit(new StringReader(strEval));
     init();
     phpDocument = new PHPDocument(null,"_root".toCharArray());
     currentSegment = phpDocument;
     outlineInfo = new PHPOutlineInfo(null, currentSegment);
-    PHPParserTokenManager.SwitchTo(PHPParserTokenManager.PHPPARSING);
+    token_source.SwitchTo(PHPParserTokenManager.PHPPARSING);
     phpTest();
   }
 
-  public static final void htmlParserTester(final File fileName) throws FileNotFoundException, ParseException {
+  public final void htmlParserTester(final File fileName) throws FileNotFoundException, ParseException {
     final Reader stream = new FileReader(fileName);
     if (jj_input_stream == null) {
       jj_input_stream = new SimpleCharStream(stream, 1, 1);
+      token_source = new PHPParserTokenManager(jj_input_stream);
     }
     ReInit(stream);
     init();
@@ -128,10 +130,11 @@ public final class PHPParser extends PHPParserSuperclass {
     phpFile();
   }
 
-  public static final void htmlParserTester(final String strEval) throws ParseException {
+  public final void htmlParserTester(final String strEval) throws ParseException {
     final StringReader stream = new StringReader(strEval);
     if (jj_input_stream == null) {
       jj_input_stream = new SimpleCharStream(stream, 1, 1);
+      token_source = new PHPParserTokenManager(jj_input_stream);
     }
     ReInit(stream);
     init();
@@ -174,6 +177,7 @@ public final class PHPParser extends PHPParserSuperclass {
     final StringReader stream = new StringReader(s);
     if (jj_input_stream == null) {
       jj_input_stream = new SimpleCharStream(stream, 1, 1);
+      token_source = new PHPParserTokenManager(jj_input_stream);
     }
     ReInit(stream);
     init();
@@ -232,14 +236,14 @@ public final class PHPParser extends PHPParserSuperclass {
                   e.currentToken.sourceStart,
                   e.currentToken.sourceEnd,
                   errorLevel,
-                  "Line " + e.currentToken.beginLine+", "+e.currentToken.sourceStart+":"+e.currentToken.sourceEnd);
+                  "Line " + e.currentToken.beginLine+", "+e.currentToken.sourceStart+':'+e.currentToken.sourceEnd);
       } else {
         setMarker(fileToParse,
                   errorMessage,
                   errorStart,
                   errorEnd,
                   errorLevel,
-                  "Line " + e.currentToken.beginLine+", "+errorStart+":"+errorEnd);
+                  "Line " + e.currentToken.beginLine+", "+errorStart+':'+errorEnd);
         errorStart = -1;
         errorEnd = -1;
       }
@@ -293,6 +297,7 @@ public final class PHPParser extends PHPParserSuperclass {
     final StringReader stream = new StringReader(s);
     if (jj_input_stream == null) {
       jj_input_stream = new SimpleCharStream(stream, 1, 1);
+      token_source = new PHPParserTokenManager(jj_input_stream);
     }
     ReInit(stream);
     init();
@@ -328,37 +333,36 @@ public final class PHPParser extends PHPParserSuperclass {
   /**
    * Put a new html block in the stack.
    */
-  public static final void createNewHTMLCode() {
+  public final void createNewHTMLCode() {
     final int currentPosition = token.sourceStart;
     if (currentPosition == htmlStart ||
           currentPosition < htmlStart ||
-          currentPosition > SimpleCharStream.currentBuffer.length()) {
+          currentPosition > jj_input_stream.getCurrentBuffer().length()) {
       return;
     }
-    final char[] chars = SimpleCharStream.currentBuffer.substring(htmlStart,
-                                                                  currentPosition).toCharArray();
-    pushOnAstNodes(new HTMLCode(chars, htmlStart,currentPosition));
+    final String html = jj_input_stream.getCurrentBuffer().substring(htmlStart, currentPosition);
+    pushOnAstNodes(new HTMLCode(html, htmlStart,currentPosition));
   }
 
   /** Create a new task. */
-  public static final void createNewTask(final int todoStart) {
-    final String  todo = SimpleCharStream.currentBuffer.substring(todoStart,
-                                                                  SimpleCharStream.currentBuffer.indexOf("\n",
+  public final void createNewTask(final int todoStart) {
+    final String  todo = jj_input_stream.getCurrentBuffer().substring(todoStart,
+                                                                  jj_input_stream.getCurrentBuffer().indexOf("\n",
                                                                                                          todoStart)-1);
     if (!PARSER_DEBUG) {
       try {
         setMarker(fileToParse,
                   todo,
-                  SimpleCharStream.getBeginLine(),
+                  jj_input_stream.getBeginLine(),
                   TASK,
-                  "Line "+SimpleCharStream.getBeginLine());
+                  "Line "+jj_input_stream.getBeginLine());
       } catch (CoreException e) {
         PHPeclipsePlugin.log(e);
       }
     }
   }
 
-  private static final void parse() throws ParseException {
+  private final void parse() throws ParseException {
          phpFile();
   }
 }
@@ -371,9 +375,9 @@ TOKEN_MGR_DECLS:
   // CharStream class to set corresponding fields in each Token (which was
   // also extended with new fields). By default Jack doesn't supply absolute
   // offsets, just line/column offsets
-  static void CommonTokenAction(Token t) {
-    t.sourceStart = input_stream.beginOffset;
-    t.sourceEnd = input_stream.endOffset;
+  void CommonTokenAction(Token t) {
+    t.sourceStart = input_stream.getBeginOffset();
+    t.sourceEnd = input_stream.getBeginOffset();
   } // CommonTokenAction
 } // TOKEN_MGR_DECLS
 
@@ -742,11 +746,11 @@ void phpFile() :
 {
   try {
     (PhpBlock())*
-    {PHPParser.createNewHTMLCode();}
+    {createNewHTMLCode();}
   } catch (TokenMgrError e) {
     PHPeclipsePlugin.log(e);
-    errorStart   = SimpleCharStream.beginOffset;
-    errorEnd     = SimpleCharStream.endOffset;
+    errorStart   = jj_input_stream.getBeginOffset();
+    errorEnd     = jj_input_stream.getEndOffset();
     errorMessage = e.getMessage();
     errorLevel   = ERROR;
     throw generateParseException();
@@ -780,7 +784,7 @@ void PhpBlock() :
       PHPeclipsePlugin.log(e);
     }}
   ]
-  {PHPParser.createNewHTMLCode();}
+  {createNewHTMLCode();}
   Php()
   try {
     phpEnd = <PHPEND>
@@ -788,8 +792,8 @@ void PhpBlock() :
   } catch (ParseException e) {
     errorMessage = "'?>' expected";
     errorLevel   = ERROR;
-    errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
-    errorEnd   = SimpleCharStream.getPosition() + 1;
+    errorStart = e.currentToken.sourceStart;
+    errorEnd   = e.currentToken.sourceEnd;
     processParseExceptionDebug(e);
   }
 }
@@ -801,7 +805,7 @@ PHPEchoBlock phpEchoBlock() :
   final Token token, token2;
 }
 {
-  token = <PHPECHOSTART> {PHPParser.createNewHTMLCode();}
+  token = <PHPECHOSTART> {createNewHTMLCode();}
   expr = Expression() [ <SEMICOLON> ] token2 = <PHPEND>
   {
   htmlStart = token2.sourceEnd;
@@ -894,8 +898,8 @@ Token token;
   } catch (ParseException e) {
     errorMessage = "unexpected token : '"+ e.currentToken.next.image + "'. '{' expected";
     errorLevel   = ERROR;
-    errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
-    errorEnd   = SimpleCharStream.getPosition() + 1;
+    errorStart = e.currentToken.sourceStart;
+    errorEnd   = e.currentToken.sourceEnd;
     processParseExceptionDebug(e);
   }
   ( ClassBodyDeclaration(classDeclaration) )*
@@ -905,10 +909,10 @@ Token token;
   } catch (ParseException e) {
     errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. 'var', 'function' or '}' expected";
     errorLevel   = ERROR;
-    errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
-    errorEnd   = SimpleCharStream.getPosition() + 1;
+    errorStart = e.currentToken.sourceStart;
+    errorEnd   = e.currentToken.sourceEnd;
     processParseExceptionDebug(e);
-    return PHPParser.token.sourceEnd;
+    return this.token.sourceEnd;
   }
 }
 
@@ -943,7 +947,6 @@ FieldDeclaration FieldDeclaration() :
   token = <VAR> variableDeclaration = VariableDeclaratorNoSuffix()
   {
     arrayList.add(variableDeclaration);
-    outlineInfo.addVariable(variableDeclaration.name());
     pos = variableDeclaration.sourceEnd;
   }
   (
@@ -1088,8 +1091,8 @@ AbstractVariable VariableDeclaratorId() :
   } catch (ParseException e) {
     errorMessage = "'$' expected for variable identifier";
     errorLevel   = ERROR;
-    errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
-    errorEnd   = SimpleCharStream.getPosition() + 1;
+    errorStart = e.currentToken.sourceStart;
+    errorEnd   = e.currentToken.sourceEnd;
     throw e;
   }
 }
@@ -1125,7 +1128,10 @@ Variable Var() :
   }
 |
   token = <IDENTIFIER>
-  {return new Variable(token.image,token.sourceStart,token.sourceEnd);}
+  {
+   outlineInfo.addVariable('$' + token.image);
+   return new Variable(token.image,token.sourceStart,token.sourceEnd);
+  }
 }
 
 Expression VariableInitializer() :
@@ -1164,7 +1170,7 @@ final Expression expr,expr2;
     <ARRAYASSIGN> expr2 = Expression()
     {return new ArrayVariableDeclaration(expr,expr2);}
   ]
-  {return new ArrayVariableDeclaration(expr,SimpleCharStream.getPosition());}
+  {return new ArrayVariableDeclaration(expr,jj_input_stream.getPosition());}
 }
 
 ArrayVariableDeclaration[] ArrayInitializer() :
@@ -1211,8 +1217,8 @@ MethodDeclaration MethodDeclaration() :
     if (errorMessage != null)  throw e;
     errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', function identifier expected";
     errorLevel   = ERROR;
-    errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
-    errorEnd   = SimpleCharStream.getPosition() + 1;
+    errorStart = e.currentToken.sourceStart;
+    errorEnd   = e.currentToken.sourceEnd;
     throw e;
   }
   {currentSegment = functionDeclaration;}
@@ -1231,7 +1237,7 @@ MethodDeclaration MethodDeclarator(final int start) :
 {
   Token identifier = null;
   Token reference = null;
-  final Hashtable formalParameters = new Hashtable();
+  final ArrayList formalParameters = new ArrayList();
   String identifierChar = SYNTAX_ERROR_CHAR;
   int end = start;
 }
@@ -1280,11 +1286,11 @@ MethodDeclaration MethodDeclarator(final int start) :
  * FormalParameters follows method identifier.
  * (FormalParameter())
  */
-int FormalParameters(final Hashtable parameters) :
+int FormalParameters(final ArrayList parameters) :
 {
   VariableDeclaration var;
   final Token token;
-  Token tok = PHPParser.token;
+  Token tok = this.token;
   int end = tok.sourceEnd;
 }
 {
@@ -1300,10 +1306,10 @@ int FormalParameters(final Hashtable parameters) :
   }
   [
     var = FormalParameter()
-    {parameters.put(var.name(),var);end = var.sourceEnd;}
+    {parameters.add(var);end = var.sourceEnd;}
     (
       <COMMA> var = FormalParameter()
-      {parameters.put(var.name(),var);end = var.sourceEnd;}
+      {parameters.add(var);end = var.sourceEnd;}
     )*
   ]
   try {
@@ -1331,6 +1337,7 @@ VariableDeclaration FormalParameter() :
 {
   [token = <BIT_AND>] variableDeclaration = VariableDeclaratorNoSuffix()
   {
+    outlineInfo.addVariable('$'+variableDeclaration.name());
     if (token != null) {
       variableDeclaration.setReference(true);
     }
@@ -1370,7 +1377,7 @@ Expression Expression() :
       }
       errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', expression expected";
       errorLevel   = ERROR;
-      errorEnd   = SimpleCharStream.getPosition();
+      errorEnd   = jj_input_stream.getPosition();
       throw e;
     }
   ]
@@ -1640,10 +1647,10 @@ Expression MultiplicativeExpression() :
     expr = UnaryExpression()
   } catch (ParseException e) {
     if (errorMessage != null) throw e;
-    errorMessage = "unexpected token '"+e.currentToken.next.image+"'";
+    errorMessage = "unexpected token '"+e.currentToken.next.image+'\'';
     errorLevel   = ERROR;
-    errorStart = PHPParser.token.sourceStart;
-    errorEnd   = PHPParser.token.sourceEnd;
+    errorStart = this.token.sourceStart;
+    errorEnd   = this.token.sourceEnd;
     throw e;
   }
   (
@@ -1893,7 +1900,7 @@ ArrayInitializer ArrayDeclarator() :
   token = <ARRAY> vars = ArrayInitializer()
   {return new ArrayInitializer(vars,
                                token.sourceStart,
-                               PHPParser.token.sourceEnd);}
+                               this.token.sourceEnd);}
 }
 
 Expression ClassIdentifier():
@@ -2019,7 +2026,7 @@ StringLiteral evaluableString() :
   {
   AbstractVariable[] vars = new AbstractVariable[list.size()];
   list.toArray(vars);
-  return new StringLiteral(SimpleCharStream.currentBuffer.substring(start.sourceEnd,end.sourceStart),
+  return new StringLiteral(jj_input_stream.getCurrentBuffer().substring(start.sourceEnd,end.sourceStart),
                            start.sourceStart,
                            end.sourceEnd,
                            vars);
@@ -2246,12 +2253,12 @@ HTMLBlock htmlBlock() :
   (phpEchoBlock())*
   try {
     (<PHPSTARTLONG> | <PHPSTARTSHORT>)
-    {PHPParser.createNewHTMLCode();}
+    {createNewHTMLCode();}
   } catch (ParseException e) {
     errorMessage = "unexpected end of file , '<?php' expected";
     errorLevel   = ERROR;
-    errorStart   = SimpleCharStream.getPosition();
-    errorEnd     = SimpleCharStream.getPosition();
+    errorStart = e.currentToken.sourceStart;
+    errorEnd   = e.currentToken.sourceEnd;
     throw e;
   }
   {
@@ -2526,7 +2533,7 @@ Block Block() :
   } catch (ParseException e) {
     errorMessage = "'{' expected";
     errorLevel   = ERROR;
-    pos = PHPParser.token.sourceEnd+1;
+    pos = this.token.sourceEnd+1;
     start=pos;
     errorStart = pos;
     errorEnd   = pos;
@@ -2537,7 +2544,7 @@ Block Block() :
                                     list.add(statement);
                                     pos = statement.sourceEnd+1;
                                   }
-                                  pos = PHPParser.token.sourceEnd+1;
+                                  pos = this.token.sourceEnd+1;
                                  }
   )*
   try {
@@ -2714,7 +2721,7 @@ SwitchStatement SwitchStatement() :
   {return new SwitchStatement(variable,
                               cases,
                               switchToken.sourceStart,
-                              PHPParser.token.sourceEnd);}
+                              this.token.sourceEnd);}
 }
 
 AbstractCase[] switchStatementBrace() :
@@ -2799,7 +2806,8 @@ AbstractCase switchLabel0() :
   final Expression expr;
   Statement statement;
   final ArrayList stmts = new ArrayList();
-  final Token token = PHPParser.token;
+  final Token token = this.token;
+  final int start = this.token.next.sourceStart;
 }
 {
   expr = SwitchLabel()
@@ -2812,7 +2820,8 @@ AbstractCase switchLabel0() :
     final Statement[] stmtsArray = new Statement[listSize];
     stmts.toArray(stmtsArray);
     if (expr == null) {//it's a default
-      return new DefaultCase(stmtsArray,token.sourceStart,stmtsArray[listSize-1].sourceEnd);
+      final int end = this.token.next.sourceStart;
+      return new DefaultCase(stmtsArray,start,end);
     }
     if (listSize != 0) {
       return new Case(expr,stmtsArray,expr.sourceStart,stmtsArray[listSize-1].sourceEnd);
@@ -2846,7 +2855,6 @@ Expression SwitchLabel() :
   }
   try {
     token = <COLON>
-    {return expr;}
   } catch (ParseException e) {
     errorMessage = "':' expected after case expression";
     errorLevel   = ERROR;
@@ -2854,6 +2862,7 @@ Expression SwitchLabel() :
     errorEnd   = expr.sourceEnd+1;
     processParseExceptionDebug(e);
   }
+  {return expr;}
 |
   token = <_DEFAULT>
   try {
@@ -2913,8 +2922,8 @@ Expression Condition(final String keyword) :
   } catch (ParseException e) {
     errorMessage = "'(' expected after " + keyword + " keyword";
     errorLevel   = ERROR;
-    errorStart = PHPParser.token.sourceEnd + 1;
-    errorEnd   = PHPParser.token.sourceEnd + 1;
+    errorStart = this.token.sourceEnd + 1;
+    errorEnd   = this.token.sourceEnd + 1;
     processParseExceptionDebug(e);
   }
   condition = Expression()
@@ -2940,7 +2949,7 @@ IfStatement IfStatement0(final Expression condition, final int start,final int e
   final ArrayList stmts;
   final ArrayList elseIfList = new ArrayList();
   final ElseIf[] elseIfs;
-  int pos = SimpleCharStream.getPosition();
+  int pos = jj_input_stream.getPosition();
   final int endStatements;
 }
 {
@@ -2948,7 +2957,7 @@ IfStatement IfStatement0(final Expression condition, final int start,final int e
   {stmts = new ArrayList();}
   (  statement = Statement() {stmts.add(statement);}
    | statement = htmlBlock() {if (statement != null) {stmts.add(statement);}})*
-   {endStatements = SimpleCharStream.getPosition();}
+   {endStatements = jj_input_stream.getPosition();}
    (elseifStatement = ElseIfStatementColon() {elseIfList.add(elseifStatement);})*
    [elseStatement = ElseStatementColon()]
 
@@ -2967,8 +2976,8 @@ IfStatement IfStatement0(final Expression condition, final int start,final int e
   } catch (ParseException e) {
     errorMessage = "'endif' expected";
     errorLevel   = ERROR;
-    errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
-    errorEnd   = SimpleCharStream.getPosition() + 1;
+    errorStart = e.currentToken.sourceStart;
+    errorEnd   = e.currentToken.sourceEnd;
     throw e;
   }
   try {
@@ -2976,8 +2985,8 @@ IfStatement IfStatement0(final Expression condition, final int start,final int e
   } catch (ParseException e) {
     errorMessage = "';' expected after 'endif' keyword";
     errorLevel   = ERROR;
-    errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
-    errorEnd   = SimpleCharStream.getPosition() + 1;
+    errorStart = e.currentToken.sourceStart;
+    errorEnd   = e.currentToken.sourceEnd;
     throw e;
   }
     {
@@ -2989,7 +2998,7 @@ IfStatement IfStatement0(final Expression condition, final int start,final int e
                               elseIfs,
                               elseStatement,
                               pos,
-                              SimpleCharStream.getPosition());
+                              jj_input_stream.getPosition());
     } else {
       statementsArray = new Statement[stmts.size()];
       stmts.toArray(statementsArray);
@@ -2998,7 +3007,7 @@ IfStatement IfStatement0(final Expression condition, final int start,final int e
                              elseIfs,
                              elseStatement,
                              pos,
-                             SimpleCharStream.getPosition());
+                             jj_input_stream.getPosition());
     }
     }
 
@@ -3008,17 +3017,17 @@ IfStatement IfStatement0(final Expression condition, final int start,final int e
   [ LOOKAHEAD(1)
     <ELSE>
     try {
-      {pos = SimpleCharStream.getPosition();}
+      {pos = jj_input_stream.getPosition();}
       statement = Statement()
-      {elseStatement = new Else(statement,pos,SimpleCharStream.getPosition());}
+      {elseStatement = new Else(statement,pos,jj_input_stream.getPosition());}
     } catch (ParseException e) {
       if (errorMessage != null) {
         throw e;
       }
       errorMessage = "unexpected token '"+e.currentToken.next.image+"', a statement was expected";
       errorLevel   = ERROR;
-      errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
-      errorEnd   = SimpleCharStream.getPosition() + 1;
+      errorStart = e.currentToken.sourceStart;
+      errorEnd   = e.currentToken.sourceEnd;
       throw e;
     }
   ]
@@ -3030,7 +3039,7 @@ IfStatement IfStatement0(final Expression condition, final int start,final int e
                            elseIfs,
                            elseStatement,
                            pos,
-                           SimpleCharStream.getPosition());}
+                           jj_input_stream.getPosition());}
 }
 
 ElseIf ElseIfStatementColon() :
@@ -3099,7 +3108,7 @@ Statement WhileStatement0(final int start, final int end) :
 {
   Statement statement;
   final ArrayList stmts = new ArrayList();
-  final int pos = SimpleCharStream.getPosition();
+  final int pos = jj_input_stream.getPosition();
 }
 {
   <COLON> (statement = Statement() {stmts.add(statement);})*
@@ -3118,8 +3127,8 @@ Statement WhileStatement0(final int start, final int end) :
   } catch (ParseException e) {
     errorMessage = "'endwhile' expected";
     errorLevel   = ERROR;
-    errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
-    errorEnd   = SimpleCharStream.getPosition() + 1;
+    errorStart = e.currentToken.sourceStart;
+    errorEnd   = e.currentToken.sourceEnd;
     throw e;
   }
   try {
@@ -3127,12 +3136,12 @@ Statement WhileStatement0(final int start, final int end) :
     {
     final Statement[] stmtsArray = new Statement[stmts.size()];
     stmts.toArray(stmtsArray);
-    return new Block(stmtsArray,pos,SimpleCharStream.getPosition());}
+    return new Block(stmtsArray,pos,jj_input_stream.getPosition());}
   } catch (ParseException e) {
     errorMessage = "';' expected after 'endwhile' keyword";
     errorLevel   = ERROR;
-    errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
-    errorEnd   = SimpleCharStream.getPosition() + 1;
+    errorStart = e.currentToken.sourceStart;
+    errorEnd   = e.currentToken.sourceEnd;
     throw e;
   }
 |
@@ -3185,8 +3194,8 @@ ForeachStatement ForeachStatement() :
   } catch (ParseException e) {
     errorMessage = "'(' expected after 'foreach' keyword";
     errorLevel   = ERROR;
-    errorStart = foreachToken.sourceEnd+1;
-    errorEnd   = foreachToken.sourceEnd+1;
+    errorStart = e.currentToken.sourceStart;
+    errorEnd   = e.currentToken.sourceEnd;
     processParseExceptionDebug(e);
     {pos = foreachToken.sourceEnd+1;}
   }
@@ -3196,8 +3205,8 @@ ForeachStatement ForeachStatement() :
   } catch (ParseException e) {
     errorMessage = "variable expected";
     errorLevel   = ERROR;
-    errorStart = pos;
-    errorEnd   = pos;
+    errorStart = e.currentToken.sourceStart;
+    errorEnd   = e.currentToken.sourceEnd;
     processParseExceptionDebug(e);
   }
   try {
@@ -3206,8 +3215,8 @@ ForeachStatement ForeachStatement() :
   } catch (ParseException e) {
     errorMessage = "'as' expected";
     errorLevel   = ERROR;
-    errorStart = pos;
-    errorEnd   = pos;
+    errorStart = e.currentToken.sourceStart;
+    errorEnd   = e.currentToken.sourceEnd;
     processParseExceptionDebug(e);
   }
   try {
@@ -3217,8 +3226,8 @@ ForeachStatement ForeachStatement() :
     if (errorMessage != null) throw e;
     errorMessage = "variable expected";
     errorLevel   = ERROR;
-    errorStart = pos;
-    errorEnd   = pos;
+    errorStart = e.currentToken.sourceStart;
+    errorEnd   = e.currentToken.sourceEnd;
     processParseExceptionDebug(e);
   }
   try {
@@ -3227,26 +3236,27 @@ ForeachStatement ForeachStatement() :
   } catch (ParseException e) {
     errorMessage = "')' expected after 'foreach' keyword";
     errorLevel   = ERROR;
-    errorStart = pos;
-    errorEnd   = pos;
+    errorStart = e.currentToken.sourceStart;
+    errorEnd   = e.currentToken.sourceEnd;
     processParseExceptionDebug(e);
   }
   try {
     statement = Statement()
-    {pos = rparenToken.sourceEnd+1;}
+    {pos = statement.sourceEnd+1;}
   } catch (ParseException e) {
     if (errorMessage != null) throw e;
     errorMessage = "statement expected";
     errorLevel   = ERROR;
-    errorStart = pos;
-    errorEnd   = pos;
+    errorStart = e.currentToken.sourceStart;
+    errorEnd   = e.currentToken.sourceEnd;
     processParseExceptionDebug(e);
   }
-  {return new ForeachStatement(expression,
+  {
+   return new ForeachStatement(expression,
                                variable,
                                statement,
                                foreachToken.sourceStart,
-                               statement.sourceEnd);}
+                               pos);}
 
 }