added a builder to parse files with eclipse's build mechanisms
[phpeclipse.git] / net.sourceforge.phpeclipse / src / test / PHPParser.jj
index 3156846..530693d 100644 (file)
@@ -40,6 +40,7 @@ import net.sourceforge.phpdt.internal.compiler.ast.*;
 import net.sourceforge.phpdt.internal.compiler.parser.OutlineableWithChildren;
 import net.sourceforge.phpdt.internal.compiler.parser.Outlineable;
 import net.sourceforge.phpdt.internal.compiler.parser.PHPOutlineInfo;
+import junit.framework.Assert;
 
 /**
  * A new php parser.
@@ -47,13 +48,9 @@ import net.sourceforge.phpdt.internal.compiler.parser.PHPOutlineInfo;
  * given with JavaCC. You can get JavaCC at http://www.webgain.com
  * You can test the parser with the PHPParserTestCase2.java
  * @author Matthieu Casanova
- * @version $Reference: 1.0$
  */
 public final class PHPParser extends PHPParserSuperclass {
 
-  /** The file that is parsed. */
-  private static IFile fileToParse;
-
   /** The current segment. */
   private static OutlineableWithChildren currentSegment;
 
@@ -84,8 +81,10 @@ public final class PHPParser extends PHPParserSuperclass {
   /** The cursor in expression stack. */
   private static int nodePtr;
 
+  private static final boolean PARSER_DEBUG = false;
+
   public final void setFileToParse(final IFile fileToParse) {
-    this.fileToParse = fileToParse;
+    PHPParser.fileToParse = fileToParse;
   }
 
   public PHPParser() {
@@ -93,7 +92,7 @@ public final class PHPParser extends PHPParserSuperclass {
 
   public PHPParser(final IFile fileToParse) {
     this(new StringReader(""));
-    this.fileToParse = fileToParse;
+    PHPParser.fileToParse = fileToParse;
   }
 
   /**
@@ -151,6 +150,10 @@ public final class PHPParser extends PHPParserSuperclass {
    * @param e the ParseException
    */
   private static void processParseException(final ParseException e) {
+    if (PARSER_DEBUG) {
+      e.printStackTrace();
+      Assert.assertTrue(false);
+    }
     if (errorMessage == null) {
       PHPeclipsePlugin.log(e);
       errorMessage = "this exception wasn't handled by the parser please tell us how to reproduce it";
@@ -231,7 +234,7 @@ public final class PHPParser extends PHPParserSuperclass {
     }
   }
 
-  public final void parse(final String s) throws CoreException {
+  public final void parse(final String s) {
     final StringReader stream = new StringReader(s);
     if (jj_input_stream == null) {
       jj_input_stream = new SimpleCharStream(stream, 1, 1);
@@ -744,12 +747,14 @@ void ClassBodyDeclaration(final ClassDeclaration classDeclaration) :
   final FieldDeclaration field;
 }
 {
-  method = MethodDeclaration() {classDeclaration.addMethod(method);}
+  method = MethodDeclaration() {method.analyzeCode();
+                                classDeclaration.addMethod(method);}
 | field = FieldDeclaration()   {classDeclaration.addField(field);}
 }
 
 /**
  * A class field declaration : it's var VariableDeclarator() (, VariableDeclarator())*;.
+ * it is only used by ClassBodyDeclaration()
  */
 FieldDeclaration FieldDeclaration() :
 {
@@ -759,12 +764,13 @@ FieldDeclaration FieldDeclaration() :
   final int pos = SimpleCharStream.getPosition();
 }
 {
-  <VAR> variableDeclaration = VariableDeclarator()
+  <VAR> variableDeclaration = VariableDeclaratorNoSuffix()
   {arrayList.add(variableDeclaration);
-   outlineInfo.addVariable(new String(variableDeclaration.name));}
-  ( <COMMA> variableDeclaration = VariableDeclarator()
+   outlineInfo.addVariable(new String(variableDeclaration.name()));}
+  (
+    <COMMA> variableDeclaration = VariableDeclaratorNoSuffix()
       {arrayList.add(variableDeclaration);
-       outlineInfo.addVariable(new String(variableDeclaration.name));}
+       outlineInfo.addVariable(new String(variableDeclaration.name()));}
   )*
   try {
     <SEMICOLON>
@@ -784,6 +790,48 @@ FieldDeclaration FieldDeclaration() :
                                currentSegment);}
 }
 
+/**
+ * a strict variable declarator : there cannot be a suffix here.
+ * It will be used by fields and formal parameters
+ */
+VariableDeclaration VariableDeclaratorNoSuffix() :
+{
+  final Token varName;
+  Expression initializer = null;
+  final int pos = SimpleCharStream.getPosition();
+}
+{
+  varName = <DOLLAR_ID>
+  [
+    <ASSIGN>
+    try {
+      initializer = VariableInitializer()
+    } catch (ParseException e) {
+      errorMessage = "Literal expression expected in variable initializer";
+      errorLevel   = ERROR;
+      errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
+      errorEnd   = SimpleCharStream.getPosition() + 1;
+      processParseException(e);
+    }
+  ]
+  {
+  if (initializer == null) {
+    return new VariableDeclaration(currentSegment,
+                                   new Variable(varName.image.substring(1).toCharArray(),SimpleCharStream.getPosition()-varName.image.length()-1,SimpleCharStream.getPosition()),
+                                   pos,
+                                   SimpleCharStream.getPosition());
+  }
+  return new VariableDeclaration(currentSegment,
+                                   new Variable(varName.image.substring(1).toCharArray(),SimpleCharStream.getPosition()-varName.image.length()-1,SimpleCharStream.getPosition()),
+                                 initializer,
+                                 VariableDeclaration.EQUAL,
+                                 pos);
+  }
+}
+
+/**
+ * this will be used by static statement
+ */
 VariableDeclaration VariableDeclarator() :
 {
   final String varName;
@@ -807,14 +855,15 @@ VariableDeclaration VariableDeclarator() :
   {
   if (initializer == null) {
     return new VariableDeclaration(currentSegment,
-                                  varName.toCharArray(),
+                                   new Variable(varName.substring(1).toCharArray(),SimpleCharStream.getPosition()-varName.length()-1,SimpleCharStream.getPosition()),
                                   pos,
                                   SimpleCharStream.getPosition());
   }
     return new VariableDeclaration(currentSegment,
-                                    varName.toCharArray(),
-                                    initializer,
-                                    pos);
+                                   new Variable(varName.substring(1).toCharArray(),SimpleCharStream.getPosition()-varName.length()-1,SimpleCharStream.getPosition()),
+                                   initializer,
+                                   VariableDeclaration.EQUAL,
+                                   pos);
   }
 }
 
@@ -824,23 +873,24 @@ VariableDeclaration VariableDeclarator() :
  */
 String VariableDeclaratorId() :
 {
-  final String expr;
+  final String var;
   Expression expression = null;
   final int pos = SimpleCharStream.getPosition();
   ConstantIdentifier ex;
 }
 {
   try {
-    expr = Variable()
-    ( LOOKAHEAD(2)
-      {ex = new ConstantIdentifier(expr.toCharArray(),
+    var = Variable()
+    (
+      LOOKAHEAD(2)
+      {ex = new ConstantIdentifier(var.toCharArray(),
                                    pos,
                                    SimpleCharStream.getPosition());}
       expression = VariableSuffix(ex)
     )*
     {
      if (expression == null) {
-       return expr;
+       return var;
      }
      return expression.toStringExpression();
     }
@@ -958,8 +1008,9 @@ final Expression expr,expr2;
 }
 {
   expr = Expression()
-  [<ARRAYASSIGN> expr2 = Expression()
-  {return new ArrayVariableDeclaration(expr,expr2);}
+  [
+    <ARRAYASSIGN> expr2 = Expression()
+    {return new ArrayVariableDeclaration(expr,expr2);}
   ]
   {return new ArrayVariableDeclaration(expr,SimpleCharStream.getPosition());}
 }
@@ -970,13 +1021,17 @@ ArrayVariableDeclaration[] ArrayInitializer() :
   final ArrayList list = new ArrayList();
 }
 {
-  <LPAREN> [ expr = ArrayVariable()
-            {list.add(expr);}
-            ( LOOKAHEAD(2) <COMMA> expr = ArrayVariable()
-            {list.add(expr);}
-            )*
-           ]
-           [<COMMA> {list.add(null);}]
+  <LPAREN>
+    [
+      expr = ArrayVariable()
+      {list.add(expr);}
+      ( LOOKAHEAD(2) <COMMA> expr = ArrayVariable()
+      {list.add(expr);}
+      )*
+    ]
+    [
+      <COMMA> {list.add(null);}
+    ]
   <RPAREN>
   {
   final ArrayVariableDeclaration[] vars = new ArrayVariableDeclaration[list.size()];
@@ -1040,12 +1095,13 @@ MethodDeclaration MethodDeclarator() :
     processParseException(e);
   }
   formalParameters = FormalParameters()
-  {return new MethodDeclaration(currentSegment,
-                                identifierChar,
-                                formalParameters,
-                                reference != null,
-                                pos,
-                                SimpleCharStream.getPosition());}
+  {MethodDeclaration method =  new MethodDeclaration(currentSegment,
+                                                     identifierChar,
+                                                     formalParameters,
+                                                     reference != null,
+                                                     pos,
+                                                     SimpleCharStream.getPosition());
+   return method;}
 }
 
 /**
@@ -1067,13 +1123,14 @@ Hashtable FormalParameters() :
     errorEnd   = SimpleCharStream.getPosition() + 1;
     processParseException(e);
   }
-            [ var = FormalParameter()
-              {parameters.put(new String(var.name),var);}
-              (
-                <COMMA> var = FormalParameter()
-                {parameters.put(new String(var.name),var);}
-              )*
-            ]
+  [
+    var = FormalParameter()
+    {parameters.put(new String(var.name()),var);}
+    (
+      <COMMA> var = FormalParameter()
+      {parameters.put(new String(var.name()),var);}
+    )*
+  ]
   try {
     <RPAREN>
   } catch (ParseException e) {
@@ -1096,7 +1153,7 @@ VariableDeclaration FormalParameter() :
   Token token = null;
 }
 {
-  [token = <BIT_AND>] variableDeclaration = VariableDeclarator()
+  [token = <BIT_AND>] variableDeclaration = VariableDeclaratorNoSuffix()
   {
     if (token != null) {
       variableDeclaration.setReference(true);
@@ -1131,13 +1188,14 @@ Expression Expression() :
 {
   final Expression expr;
   Expression initializer = null;
-  int assignOperator = -1;
   final int pos = SimpleCharStream.getPosition();
+  int assignOperator = -1;
 }
 {
   LOOKAHEAD(1)
   expr = ConditionalExpression()
-  [ assignOperator = AssignmentOperator()
+  [
+    assignOperator = AssignmentOperator()
     try {
       initializer = Expression()
     } catch (ParseException e) {
@@ -1151,13 +1209,21 @@ Expression Expression() :
     }
   ]
   {
-    if (assignOperator == -1) return expr;
-    return new VarAssignation(expr,
-                               initializer,
-                               assignOperator,
-                               pos,
-                               SimpleCharStream.getPosition());
-  return expr;}
+    char[] varName = expr.toStringExpression().substring(1).toCharArray();
+    if (assignOperator == -1) {
+        return new VariableDeclaration(currentSegment,
+                                       new Variable(varName,SimpleCharStream.getPosition()-varName.length-1,SimpleCharStream.getPosition()),
+                                       pos,
+                                       SimpleCharStream.getPosition());
+      return expr;
+    }
+    return new VariableDeclaration(currentSegment,
+                                   new Variable(varName,SimpleCharStream.getPosition()-varName.length-1,SimpleCharStream.getPosition()),
+                                   initializer,
+                                   assignOperator,
+                                   pos);
+    }
+  {return expr;}
 | expr = ExpressionWBang()       {return expr;}
 }
 
@@ -1173,11 +1239,11 @@ Expression ExpressionWBang() :
 
 Expression ExpressionNoBang() :
 {
-  final Expression expr;
+  Expression expr;
 }
 {
-  expr = PrintExpression()       {return expr;}
-| expr = ListExpression()        {return expr;}
+  expr = PrintExpression()   {return expr;}
+| expr = ListExpression()    {return expr;}
 }
 
 /**
@@ -1187,19 +1253,19 @@ Expression ExpressionNoBang() :
 int AssignmentOperator() :
 {}
 {
-  <ASSIGN>             {return VarAssignation.EQUAL;}
-| <STARASSIGN>         {return VarAssignation.STAR_EQUAL;}
-| <SLASHASSIGN>        {return VarAssignation.SLASH_EQUAL;}
-| <REMASSIGN>          {return VarAssignation.REM_EQUAL;}
-| <PLUSASSIGN>         {return VarAssignation.PLUS_EQUAL;}
-| <MINUSASSIGN>        {return VarAssignation.MINUS_EQUAL;}
-| <LSHIFTASSIGN>       {return VarAssignation.LSHIFT_EQUAL;}
-| <RSIGNEDSHIFTASSIGN> {return VarAssignation.RSIGNEDSHIFT_EQUAL;}
-| <ANDASSIGN>          {return VarAssignation.AND_EQUAL;}
-| <XORASSIGN>          {return VarAssignation.XOR_EQUAL;}
-| <ORASSIGN>           {return VarAssignation.OR_EQUAL;}
-| <DOTASSIGN>          {return VarAssignation.DOT_EQUAL;}
-| <TILDEEQUAL>         {return VarAssignation.TILDE_EQUAL;}
+  <ASSIGN>             {return VariableDeclaration.EQUAL;}
+| <STARASSIGN>         {return VariableDeclaration.STAR_EQUAL;}
+| <SLASHASSIGN>        {return VariableDeclaration.SLASH_EQUAL;}
+| <REMASSIGN>          {return VariableDeclaration.REM_EQUAL;}
+| <PLUSASSIGN>         {return VariableDeclaration.PLUS_EQUAL;}
+| <MINUSASSIGN>        {return VariableDeclaration.MINUS_EQUAL;}
+| <LSHIFTASSIGN>       {return VariableDeclaration.LSHIFT_EQUAL;}
+| <RSIGNEDSHIFTASSIGN> {return VariableDeclaration.RSIGNEDSHIFT_EQUAL;}
+| <ANDASSIGN>          {return VariableDeclaration.AND_EQUAL;}
+| <XORASSIGN>          {return VariableDeclaration.XOR_EQUAL;}
+| <ORASSIGN>           {return VariableDeclaration.OR_EQUAL;}
+| <DOTASSIGN>          {return VariableDeclaration.DOT_EQUAL;}
+| <TILDEEQUAL>         {return VariableDeclaration.TILDE_EQUAL;}
 }
 
 Expression ConditionalExpression() :
@@ -1229,7 +1295,8 @@ Expression ConditionalOrExpression() :
     (
         <OR_OR> {operator = OperatorIds.OR_OR;}
       | <_ORL>  {operator = OperatorIds.ORL;}
-    ) expr2 = ConditionalAndExpression()
+    )
+    expr2 = ConditionalAndExpression()
     {
       expr = new BinaryExpression(expr,expr2,operator);
     }
@@ -1297,6 +1364,7 @@ Expression AndExpression() :
 {
   expr = EqualityExpression()
   (
+    LOOKAHEAD(1)
     <BIT_AND> expr2 = EqualityExpression()
     {expr = new BinaryExpression(expr,expr2,OperatorIds.AND);}
   )*
@@ -1379,6 +1447,7 @@ Expression AdditiveExpression() :
 {
   expr = MultiplicativeExpression()
   (
+  LOOKAHEAD(1)
    ( <PLUS>  {operator = OperatorIds.PLUS;}
    | <MINUS> {operator = OperatorIds.MINUS;} )
    expr2 = MultiplicativeExpression()
@@ -1425,19 +1494,27 @@ Expression UnaryExpression() :
   <BIT_AND> expr = UnaryExpressionNoPrefix()
   {return new PrefixedUnaryExpression(expr,OperatorIds.AND,pos);}
 |
-  expr = AtUnaryExpression() {return expr;}
+  expr = AtNotUnaryExpression() {return expr;}
 }
 
-Expression AtUnaryExpression() :
+/**
+ * An expression prefixed (or not) by one or more @ and !.
+ * @return the expression
+ */
+Expression AtNotUnaryExpression() :
 {
   final Expression expr;
   final int pos = SimpleCharStream.getPosition();
 }
 {
   <AT>
-  expr = AtUnaryExpression()
+  expr = AtNotUnaryExpression()
   {return new PrefixedUnaryExpression(expr,OperatorIds.AT,pos);}
 |
+  <BANG>
+  expr = AtNotUnaryExpression()
+  {return new PrefixedUnaryExpression(expr,OperatorIds.NOT,pos);}
+|
   expr = UnaryExpressionNoPrefix()
   {return expr;}
 }
@@ -1450,9 +1527,12 @@ Expression UnaryExpressionNoPrefix() :
   final int pos = SimpleCharStream.getPosition();
 }
 {
-  (  <PLUS>  {operator = OperatorIds.PLUS;}
-   | <MINUS> {operator = OperatorIds.MINUS;})
-   expr = UnaryExpression()
+  (
+      <PLUS>  {operator = OperatorIds.PLUS;}
+    |
+      <MINUS> {operator = OperatorIds.MINUS;}
+  )
+  expr = UnaryExpression()
   {return new PrefixedUnaryExpression(expr,operator,pos);}
 |
   expr = PreIncDecExpression()
@@ -1460,6 +1540,9 @@ Expression UnaryExpressionNoPrefix() :
 |
   expr = UnaryExpressionNotPlusMinus()
   {return expr;}
+/*|
+  LOOKAHEAD(2)
+  expr = PrintExpression()   {return expr;}*/
 }
 
 
@@ -1470,9 +1553,12 @@ final int operator;
   final int pos = SimpleCharStream.getPosition();
 }
 {
-  (  <PLUS_PLUS> {operator = OperatorIds.PLUS_PLUS;}
-   | <MINUS_MINUS> {operator = OperatorIds.MINUS_MINUS;})
-   expr = PrimaryExpression()
+  (
+      <PLUS_PLUS>   {operator = OperatorIds.PLUS_PLUS;}
+    |
+      <MINUS_MINUS> {operator = OperatorIds.MINUS_MINUS;}
+  )
+  expr = PrimaryExpression()
   {return new PrefixedUnaryExpression(expr,operator,pos);}
 }
 
@@ -1484,7 +1570,6 @@ Expression UnaryExpressionNotPlusMinus() :
 {
   LOOKAHEAD( <LPAREN> (Type() | <ARRAY>) <RPAREN> )
   expr = CastExpression()         {return expr;}
-| <BANG> expr = UnaryExpression() {return new PrefixedUnaryExpression(expr,OperatorIds.NOT,pos);}
 | expr = PostfixExpression()      {return expr;}
 | expr = Literal()                {return expr;}
 | <LPAREN> expr = Expression()
@@ -1508,8 +1593,11 @@ final int pos = SimpleCharStream.getPosition();
 }
 {
   <LPAREN>
-  (type = Type()
-  | <ARRAY> {type = new ConstantIdentifier(Types.ARRAY,pos,SimpleCharStream.getPosition());})
+  (
+      type = Type()
+    |
+      <ARRAY> {type = new ConstantIdentifier(Types.ARRAY,pos,SimpleCharStream.getPosition());}
+  )
   <RPAREN> expr = UnaryExpression()
   {return new CastExpression(type,expr,pos,SimpleCharStream.getPosition());}
 }
@@ -1522,8 +1610,11 @@ Expression PostfixExpression() :
 }
 {
   expr = PrimaryExpression()
-  [ <PLUS_PLUS> {operator = OperatorIds.PLUS_PLUS;}
-  | <MINUS_MINUS> {operator = OperatorIds.MINUS_MINUS;}]
+  [
+      <PLUS_PLUS>   {operator = OperatorIds.PLUS_PLUS;}
+    |
+      <MINUS_MINUS> {operator = OperatorIds.MINUS_MINUS;}
+  ]
   {
     if (operator == -1) {
       return expr;
@@ -1535,13 +1626,23 @@ Expression PostfixExpression() :
 Expression PrimaryExpression() :
 {
   Expression expr;
+  int assignOperator = -1;
+  final Token identifier;
+  final String var;
+  final int pos = SimpleCharStream.getPosition();
 }
 {
   expr = PrimaryPrefix()
-  (
-  LOOKAHEAD(PrimarySuffix())
-  expr = PrimarySuffix(expr)
-  )*
+  (expr = PrimarySuffix(expr))*
+  [ expr = Arguments(expr) ]
+  {return expr;}
+|
+  <NEW> expr = ClassIdentifier()
+  {expr = new PrefixedUnaryExpression(expr,
+                                      OperatorIds.NEW,
+                                      pos);
+  }
+  [ expr = Arguments(expr) ]
   {return expr;}
 |
   expr = ArrayDeclarator()
@@ -1559,13 +1660,10 @@ Expression PrimaryPrefix() :
   token = <IDENTIFIER>           {return new ConstantIdentifier(token.image.toCharArray(),
                                                                 pos,
                                                                 SimpleCharStream.getPosition());}
-| <NEW> expr = ClassIdentifier() {return new PrefixedUnaryExpression(expr,
-                                                                     OperatorIds.NEW,
-                                                                     pos);}
-| var = VariableDeclaratorId()  {return new VariableDeclaration(currentSegment,
-                                                                var.toCharArray(),
-                                                                pos,
-                                                                SimpleCharStream.getPosition());}
+|
+  var = VariableDeclaratorId()   {return new Variable(var.toCharArray(),
+                                                      pos,
+                                                      SimpleCharStream.getPosition());}
 }
 
 AbstractSuffixExpression PrimarySuffix(final Expression prefix) :
@@ -1574,12 +1672,11 @@ AbstractSuffixExpression PrimarySuffix(final Expression prefix) :
   final Expression expr;
 }
 {
-  suffix = Arguments(prefix)      {return suffix;}
-| suffix = VariableSuffix(prefix) {return suffix;}
+  suffix = VariableSuffix(prefix) {return suffix;}
 | <STATICCLASSACCESS> expr = ClassIdentifier()
   {suffix = new ClassAccess(prefix,
-                          expr,
-                          ClassAccess.STATIC);
+                            expr,
+                            ClassAccess.STATIC);
    return suffix;}
 }
 
@@ -1741,6 +1838,7 @@ final ArrayList list = new ArrayList();
 
 /**
  * A Statement without break.
+ * @return a statement
  */
 Statement StatementNoBreak() :
 {
@@ -1749,34 +1847,11 @@ Statement StatementNoBreak() :
 }
 {
   LOOKAHEAD(2)
-  statement = Expression()
-  try {
-    <SEMICOLON>
-  } catch (ParseException e) {
-    if (e.currentToken.next.kind != PHPParserConstants.PHPEND) {
-      errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. A ';' was expected";
-      errorLevel   = ERROR;
-      errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
-      errorEnd   = SimpleCharStream.getPosition() + 1;
-      throw e;
-    }
-  }
-  {return statement;}
-| LOOKAHEAD(2)
-  statement = LabeledStatement() {return statement;}
-| statement = Block()            {return statement;}
-| statement = EmptyStatement()   {return statement;}
-| statement = StatementExpression()
-  try {
-    <SEMICOLON>
-  } catch (ParseException e) {
-    errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. A ';' was expected";
-    errorLevel   = ERROR;
-    errorStart   = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
-    errorEnd     = SimpleCharStream.getPosition() + 1;
-    throw e;
-  }
-  {return statement;}
+  statement = expressionStatement()     {return statement;}
+| LOOKAHEAD(1)
+  statement = LabeledStatement()        {return statement;}
+| statement = Block()                   {return statement;}
+| statement = EmptyStatement()          {return statement;}
 | statement = SwitchStatement()         {return statement;}
 | statement = IfStatement()             {return statement;}
 | statement = WhileStatement()          {return statement;}
@@ -1796,6 +1871,31 @@ Statement StatementNoBreak() :
 | statement = defineStatement()         {currentSegment.add((Outlineable)statement);return statement;}
 }
 
+/**
+ * A statement expression.
+ * expression ;
+ * @return an expression
+ */
+Statement expressionStatement() :
+{
+  final Statement statement;
+}
+{
+  statement = Expression()
+  try {
+    <SEMICOLON>
+  } catch (ParseException e) {
+    if (e.currentToken.next.kind != PHPParserConstants.PHPEND) {
+      errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. A ';' was expected";
+      errorLevel   = ERROR;
+      errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
+      errorEnd   = SimpleCharStream.getPosition() + 1;
+      throw e;
+    }
+  }
+  {return statement;}
+}
+
 Define defineStatement() :
 {
   final int start = SimpleCharStream.getPosition();
@@ -2083,8 +2183,8 @@ StaticStatement StaticStatement() :
   VariableDeclaration expr;
 }
 {
-  <STATIC> expr = VariableDeclarator() {vars.add(new String(expr.name));}
-  (<COMMA> expr = VariableDeclarator() {vars.add(new String(expr.name));})*
+  <STATIC> expr = VariableDeclarator() {vars.add(new String(expr.name()));}
+  (<COMMA> expr = VariableDeclarator() {vars.add(new String(expr.name()));})*
   try {
     <SEMICOLON>
     {
@@ -2163,6 +2263,7 @@ Statement BlockStatement() :
 | statement = ClassDeclaration()  {return statement;}
 | statement = MethodDeclaration() {if (phpDocument == currentSegment) pushOnAstNodes(statement);
                                    currentSegment.add((MethodDeclaration) statement);
+                                   ((MethodDeclaration) statement).analyzeCode();
                                    return statement;}
 }
 
@@ -2177,9 +2278,13 @@ Statement BlockStatementNoBreak() :
   statement = StatementNoBreak()  {return statement;}
 | statement = ClassDeclaration()  {return statement;}
 | statement = MethodDeclaration() {currentSegment.add((MethodDeclaration) statement);
+                                   ((MethodDeclaration) statement).analyzeCode();
                                    return statement;}
 }
 
+/**
+ * used only by ForInit()
+ */
 VariableDeclaration[] LocalVariableDeclaration() :
 {
   final ArrayList list = new ArrayList();
@@ -2195,6 +2300,9 @@ VariableDeclaration[] LocalVariableDeclaration() :
   return vars;}
 }
 
+/**
+ * used only by LocalVariableDeclaration().
+ */
 VariableDeclaration LocalVariableDeclarator() :
 {
   final String varName;
@@ -2206,13 +2314,14 @@ VariableDeclaration LocalVariableDeclarator() :
   {
    if (initializer == null) {
     return new VariableDeclaration(currentSegment,
-                                  varName.toCharArray(),
+                                  new Variable(varName.toCharArray(),SimpleCharStream.getPosition()-varName.length(),SimpleCharStream.getPosition()),
                                   pos,
                                   SimpleCharStream.getPosition());
    }
     return new VariableDeclaration(currentSegment,
-                                    varName.toCharArray(),
+                                    new Variable(varName.toCharArray(),SimpleCharStream.getPosition()-varName.length(),SimpleCharStream.getPosition()),
                                     initializer,
+                                    VariableDeclaration.EQUAL,
                                     pos);
   }
 }
@@ -2227,6 +2336,9 @@ EmptyStatement EmptyStatement() :
    return new EmptyStatement(pos-1,pos);}
 }
 
+/**
+ * used only by StatementExpressionList() which is used only by ForInit() and ForStatement()
+ */
 Expression StatementExpression() :
 {
   final Expression expr,expr2;
@@ -2242,8 +2354,6 @@ Expression StatementExpression() :
   | <MINUS_MINUS> {return new PostfixedUnaryExpression(expr,
                                                 OperatorIds.MINUS_MINUS,
                                                 SimpleCharStream.getPosition());}
-  | operator = AssignmentOperator() expr2 = Expression()
-    {return new BinaryExpression(expr,expr2,operator);}
   ]
   {return expr;}
 }