Organized imports
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / parser / Parser.java
index b1ddd61..50dc61f 100644 (file)
@@ -9,6 +9,7 @@ package net.sourceforge.phpdt.internal.compiler.parser;
 
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.HashSet;
 
 import net.sourceforge.phpdt.core.compiler.CharOperation;
 import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
@@ -26,9 +27,11 @@ import net.sourceforge.phpeclipse.internal.compiler.ast.AND_AND_Expression;
 import net.sourceforge.phpeclipse.internal.compiler.ast.ASTNode;
 import net.sourceforge.phpeclipse.internal.compiler.ast.AbstractMethodDeclaration;
 import net.sourceforge.phpeclipse.internal.compiler.ast.BinaryExpression;
+import net.sourceforge.phpeclipse.internal.compiler.ast.Block;
+import net.sourceforge.phpeclipse.internal.compiler.ast.BreakStatement;
 import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration;
 import net.sourceforge.phpeclipse.internal.compiler.ast.ConditionalExpression;
-import net.sourceforge.phpeclipse.internal.compiler.ast.EmptyStatement;
+import net.sourceforge.phpeclipse.internal.compiler.ast.ContinueStatement;
 import net.sourceforge.phpeclipse.internal.compiler.ast.EqualExpression;
 import net.sourceforge.phpeclipse.internal.compiler.ast.Expression;
 import net.sourceforge.phpeclipse.internal.compiler.ast.FieldDeclaration;
@@ -39,6 +42,7 @@ import net.sourceforge.phpeclipse.internal.compiler.ast.InstanceOfExpression;
 import net.sourceforge.phpeclipse.internal.compiler.ast.MethodDeclaration;
 import net.sourceforge.phpeclipse.internal.compiler.ast.OR_OR_Expression;
 import net.sourceforge.phpeclipse.internal.compiler.ast.OperatorIds;
+import net.sourceforge.phpeclipse.internal.compiler.ast.ReturnStatement;
 import net.sourceforge.phpeclipse.internal.compiler.ast.SingleTypeReference;
 import net.sourceforge.phpeclipse.internal.compiler.ast.Statement;
 import net.sourceforge.phpeclipse.internal.compiler.ast.StringLiteral;
@@ -305,6 +309,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
    */
   public void parse(String s, HashMap variables) {
     fMethodVariables = variables;
+    fStackUnassigned = new ArrayList();
     init(s);
     parse();
   }
@@ -412,10 +417,11 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
       } catch (SyntaxError sytaxErr1) {
         return;
       } finally {
-        int sourceEnd = scanner.getCurrentTokenStartPosition();
+        int sourceEnd = methodDecl.sourceEnd;
         if (sourceEnd <= 0 || methodDecl.declarationSourceStart > sourceEnd) {
           sourceEnd = methodDecl.declarationSourceStart + 1;
         }
+        methodDecl.sourceEnd = sourceEnd;
         methodDecl.declarationSourceEnd = sourceEnd;
       }
     }
@@ -458,20 +464,27 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
     return compilationUnit;
   }
 
-  private boolean isVariable() {
-    return token == TokenNameVariable; //  || token == TokenNamethis;
-  }
-
-  private void statementList() {
+  private Block statementList() {
+    boolean branchStatement = false;
+    Statement statement;
+    int blockStart = scanner.getCurrentTokenStartPosition();
+    ArrayList blockStatements = new ArrayList();
     do {
       try {
-        statement(TokenNameEOF);
+        statement = statement();
+        blockStatements.add(statement);
+        if (branchStatement && statement != null) {
+          //          reportSyntaxError("Unreachable code", statement.sourceStart, statement.sourceEnd);
+          problemReporter.unreachableCode(new String(scanner.getCurrentIdentifierSource()), statement.sourceStart,
+              statement.sourceEnd, referenceContext, compilationUnit.compilationResult);
+        }
         if ((token == TokenNameRBRACE) || (token == TokenNamecase) || (token == TokenNamedefault) || (token == TokenNameelse)
             || (token == TokenNameelseif) || (token == TokenNameendif) || (token == TokenNameendfor)
             || (token == TokenNameendforeach) || (token == TokenNameendwhile) || (token == TokenNameendswitch)
             || (token == TokenNameenddeclare) || (token == TokenNameEOF) || (token == TokenNameERROR)) {
-          return;
+          return createBlock(blockStart, blockStatements);
         }
+        branchStatement = checkUnreachableStatements(statement);
       } catch (SyntaxError sytaxErr1) {
         // if an error occured,
         // try to find keywords
@@ -486,7 +499,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
                 || (token == TokenNameelseif) || (token == TokenNameendif) || (token == TokenNameendfor)
                 || (token == TokenNameendforeach) || (token == TokenNameendwhile) || (token == TokenNameendswitch)
                 || (token == TokenNameenddeclare) || (token == TokenNameEOF) || (token == TokenNameERROR)) {
-              return;
+              return createBlock(blockStart, blockStatements);
             }
             if (token == TokenNameif || token == TokenNameswitch || token == TokenNamefor || token == TokenNamewhile
                 || token == TokenNamedo || token == TokenNameforeach || token == TokenNamecontinue || token == TokenNamebreak
@@ -510,29 +523,60 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
     } while (true);
   }
 
+  /**
+   * @param statement
+   * @return
+   */
+  private boolean checkUnreachableStatements(Statement statement) {
+    if (statement instanceof ReturnStatement || statement instanceof ContinueStatement || statement instanceof BreakStatement) {
+      return true;
+    } else if (statement instanceof IfStatement && ((IfStatement) statement).checkUnreachable) {
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   * @param blockStart
+   * @param blockStatements
+   * @return
+   */
+  private Block createBlock(int blockStart, ArrayList blockStatements) {
+    int blockEnd = scanner.getCurrentTokenEndPosition();
+    Block b = Block.EmptyWith(blockStart, blockEnd);
+    b.statements = new Statement[blockStatements.size()];
+    blockStatements.toArray(b.statements);
+    return b;
+  }
+
   private void functionBody(MethodDeclaration methodDecl) {
     // '{' [statement-list] '}'
     if (token == TokenNameLBRACE) {
       getNextToken();
     } else {
+      methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1;
       throwSyntaxError("'{' expected in compound-statement.");
     }
     if (token != TokenNameRBRACE) {
       statementList();
     }
     if (token == TokenNameRBRACE) {
-      //      methodDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
+      methodDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
       getNextToken();
     } else {
+      methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1;
       throwSyntaxError("'}' expected in compound-statement.");
     }
   }
 
-  private Statement statement(int previousToken) {
+  private Statement statement() {
     Statement statement = null;
     Expression expression;
     int sourceStart = scanner.getCurrentTokenStartPosition();
+    int sourceEnd;
     if (token == TokenNameif) {
+      // T_IF '(' expr ')' statement elseif_list else_single
+      // T_IF '(' expr ')' ':' inner_statement_list new_elseif_list new_else_single T_ENDIF ';'
       getNextToken();
       if (token == TokenNameLPAREN) {
         getNextToken();
@@ -545,8 +589,15 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
       } else {
         throwSyntaxError("')' expected after 'if' condition.");
       }
-      ifStatement();
-      return new IfStatement(expression, statement, sourceStart, scanner.getCurrentTokenEndPosition());
+      // create basic IfStatement
+      IfStatement ifStatement = new IfStatement(expression, null, null, sourceStart, -1);
+      if (token == TokenNameCOLON) {
+        getNextToken();
+        ifStatementColon(ifStatement);
+      } else {
+        ifStatement(ifStatement);
+      }
+      return ifStatement;
     } else if (token == TokenNameswitch) {
       getNextToken();
       if (token == TokenNameLPAREN) {
@@ -629,7 +680,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
           throwSyntaxError("'}' expected after 'do' keyword.");
         }
       } else {
-        statement(TokenNameEOF);
+        statement();
       }
       if (token == TokenNamewhile) {
         getNextToken();
@@ -674,7 +725,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
       foreach_optional_arg();
       if (token == TokenNameEQUAL_GREATER) {
         getNextToken();
-        variable();
+        variable(false, false);
       }
       if (token == TokenNameRPAREN) {
         getNextToken();
@@ -683,20 +734,57 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
       }
       foreachStatement();
       return statement;
-    } else if (token == TokenNamecontinue || token == TokenNamebreak || token == TokenNamereturn) {
+    } else if (token == TokenNamebreak) {
+      expression = null;
       getNextToken();
       if (token != TokenNameSEMICOLON) {
-        expr();
+        expression = expr();
       }
       if (token == TokenNameSEMICOLON) {
+        sourceEnd = scanner.getCurrentTokenEndPosition();
         getNextToken();
       } else {
         if (token != TokenNameINLINE_HTML) {
-          throwSyntaxError("';' expected after 'continue', 'break' or 'return'.");
+          throwSyntaxError("';' expected after 'break'.");
         }
+        sourceEnd = scanner.getCurrentTokenEndPosition();
         getNextToken();
       }
-      return statement;
+      return new BreakStatement(null, sourceStart, sourceEnd);
+    } else if (token == TokenNamecontinue) {
+      expression = null;
+      getNextToken();
+      if (token != TokenNameSEMICOLON) {
+        expression = expr();
+      }
+      if (token == TokenNameSEMICOLON) {
+        sourceEnd = scanner.getCurrentTokenEndPosition();
+        getNextToken();
+      } else {
+        if (token != TokenNameINLINE_HTML) {
+          throwSyntaxError("';' expected after 'continue'.");
+        }
+        sourceEnd = scanner.getCurrentTokenEndPosition();
+        getNextToken();
+      }
+      return new ContinueStatement(null, sourceStart, sourceEnd);
+    } else if (token == TokenNamereturn) {
+      expression = null;
+      getNextToken();
+      if (token != TokenNameSEMICOLON) {
+        expression = expr();
+      }
+      if (token == TokenNameSEMICOLON) {
+        sourceEnd = scanner.getCurrentTokenEndPosition();
+        getNextToken();
+      } else {
+        if (token != TokenNameINLINE_HTML) {
+          throwSyntaxError("';' expected after 'return'.");
+        }
+        sourceEnd = scanner.getCurrentTokenEndPosition();
+        getNextToken();
+      }
+      return new ReturnStatement(expression, sourceStart, sourceEnd);
     } else if (token == TokenNameecho) {
       getNextToken();
       expressionList();
@@ -779,11 +867,12 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
         getNextToken();
         functionDefinition(methodDecl);
       } finally {
-        int sourceEnd = scanner.getCurrentTokenStartPosition();
+        sourceEnd = methodDecl.sourceEnd;
         if (sourceEnd <= 0 || methodDecl.declarationSourceStart > sourceEnd) {
           sourceEnd = methodDecl.declarationSourceStart + 1;
         }
         methodDecl.declarationSourceEnd = sourceEnd;
+        methodDecl.sourceEnd = sourceEnd;
       }
       return statement;
     } else if (token == TokenNamedeclare) {
@@ -871,7 +960,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
     } else if (token == TokenNameLBRACE) {
       getNextToken();
       if (token != TokenNameRBRACE) {
-        statementList();
+        statement = statementList();
       }
       if (token == TokenNameRBRACE) {
         getNextToken();
@@ -918,7 +1007,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
       }
       getNextToken();
     } else {
-      statement(TokenNameRPAREN);
+      statement();
     }
   }
 
@@ -978,7 +1067,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
     if (token == TokenNameAND) {
       getNextToken();
     }
-    w_variable();
+    w_variable(true);
   }
 
   private void foreach_optional_arg() {
@@ -994,8 +1083,9 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
     //  global_var_list:
     // global_var_list ',' global_var
     //| global_var
+    HashSet set = peekVariableSet();
     while (true) {
-      global_var();
+      global_var(set);
       if (token != TokenNameCOMMA) {
         break;
       }
@@ -1003,16 +1093,17 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
     }
   }
 
-  private void global_var() {
+  private void global_var(HashSet set) {
     //global_var:
     // T_VARIABLE
     //| '$' r_variable
     //| '$' '{' expr '}'
     if (token == TokenNameVariable) {
-      VariableInfo info = new VariableInfo(scanner.getCurrentTokenStartPosition(), VariableInfo.LEVEL_GLOBAL_VAR);
       if (fMethodVariables != null) {
+        VariableInfo info = new VariableInfo(scanner.getCurrentTokenStartPosition(), VariableInfo.LEVEL_GLOBAL_VAR);
         fMethodVariables.put(new String(scanner.getCurrentIdentifierSource()), info);
       }
+      addVariableSet(set);
       getNextToken();
     } else if (token == TokenNameDOLLAR) {
       getNextToken();
@@ -1034,13 +1125,15 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
     // static_var_list ',' T_VARIABLE
     //| static_var_list ',' T_VARIABLE '=' static_scalar
     //| T_VARIABLE
-    //| T_VARIABLE '=' static_scalar
+    //| T_VARIABLE '=' static_scalar,
+    HashSet set = peekVariableSet();
     while (true) {
       if (token == TokenNameVariable) {
-        VariableInfo info = new VariableInfo(scanner.getCurrentTokenStartPosition(), VariableInfo.LEVEL_STATIC_VAR);
         if (fMethodVariables != null) {
+          VariableInfo info = new VariableInfo(scanner.getCurrentTokenStartPosition(), VariableInfo.LEVEL_STATIC_VAR);
           fMethodVariables.put(new String(scanner.getCurrentIdentifierSource()), info);
         }
+        addVariableSet(set);
         getNextToken();
         if (token == TokenNameEQUAL) {
           getNextToken();
@@ -1063,7 +1156,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
     //    unset_variable:
     //                 variable
     while (true) {
-      variable();
+      variable(false, false);
       if (token != TokenNameCOMMA) {
         break;
       }
@@ -1337,11 +1430,12 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
           getNextToken();
           functionDefinition(methodDecl);
         } finally {
-          int sourceEnd = scanner.getCurrentTokenStartPosition();
+          int sourceEnd = methodDecl.sourceEnd;
           if (sourceEnd <= 0 || methodDecl.declarationSourceStart > sourceEnd) {
             sourceEnd = methodDecl.declarationSourceStart + 1;
           }
           methodDecl.declarationSourceEnd = sourceEnd;
+          methodDecl.sourceEnd = sourceEnd;
         }
       } else {
         if (!hasModifiers) {
@@ -1526,15 +1620,23 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
         }
       }
     }
-    functionDeclarator(methodDecl);
-    if (token == TokenNameSEMICOLON) {
-      if (!isAbstract) {
-        throwSyntaxError("Body declaration expected for method: " + new String(methodDecl.selector));
+    try {
+      pushFunctionVariableSet();
+      functionDeclarator(methodDecl);
+      if (token == TokenNameSEMICOLON) {
+        if (!isAbstract) {
+          methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1;
+          throwSyntaxError("Body declaration expected for method: " + new String(methodDecl.selector));
+        }
+        getNextToken();
+        return;
+      }
+      functionBody(methodDecl);
+    } finally {
+      if (!fStackUnassigned.isEmpty()) {
+        fStackUnassigned.remove(fStackUnassigned.size() - 1);
       }
-      getNextToken();
-      return;
     }
-    functionBody(methodDecl);
   }
 
   private void functionDeclarator(MethodDeclaration methodDecl) {
@@ -1554,12 +1656,14 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
       if (token == TokenNameLPAREN) {
         getNextToken();
       } else {
+        methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1;
         throwSyntaxError("'(' expected in function declaration.");
       }
       if (token != TokenNameRPAREN) {
         parameter_list(methodDecl);
       }
       if (token != TokenNameRPAREN) {
+        methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1;
         throwSyntaxError("')' expected in function declaration.");
       } else {
         methodDecl.bodyStart = scanner.getCurrentTokenEndPosition() + 1;
@@ -1567,6 +1671,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
       }
     } else {
       methodDecl.selector = "<undefined>".toCharArray();
+      methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1;
       throwSyntaxError("Function name expected after keyword 'function'.");
     }
   }
@@ -1591,6 +1696,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
     // static_scalar
     char[] typeIdentifier = null;
     if (token == TokenNameIdentifier || token == TokenNameVariable || token == TokenNameAND) {
+      HashSet set = peekVariableSet();
       while (true) {
         if (token == TokenNameIdentifier) {
           typeIdentifier = scanner.getCurrentIdentifierSource();
@@ -1610,6 +1716,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
             info.typeIdentifier = typeIdentifier;
             fMethodVariables.put(new String(scanner.getCurrentIdentifierSource()), info);
           }
+          addVariableSet(set);
           getNextToken();
           if (token == TokenNameEQUAL) {
             getNextToken();
@@ -1711,162 +1818,270 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
     } while (token == TokenNamecase || token == TokenNamedefault);
   }
 
-  //  public void labeledStatement() {
-  //    if (token == TokenNamecase) {
-  //      getNextToken();
-  //      constant();
-  //      if (token == TokenNameDDOT) {
-  //        getNextToken();
-  //        statement();
-  //      } else {
-  //        throwSyntaxError("':' character after 'case' constant expected.");
-  //      }
-  //      return;
-  //    } else if (token == TokenNamedefault) {
-  //      getNextToken();
-  //      if (token == TokenNameDDOT) {
-  //        getNextToken();
-  //        statement();
-  //      } else {
-  //        throwSyntaxError("':' character after 'default' expected.");
-  //      }
-  //      return;
-  //    }
-  //  }
-  //  public void expressionStatement() {
-  //  }
-  //  private void inclusionStatement() {
-  //  }
-  //  public void compoundStatement() {
-  //  }
-  //  public void selectionStatement() {
-  //  }
-  //
-  //  public void iterationStatement() {
-  //  }
-  //
-  //  public void jumpStatement() {
-  //  }
-  //
-  //  public void outputStatement() {
-  //  }
-  //
-  //  public void scopeStatement() {
-  //  }
-  //
-  //  public void flowStatement() {
-  //  }
-  //
-  //  public void definitionStatement() {
-  //  }
-  private void ifStatement() {
-    // ':' statement-list [elseif-list] [else-colon-statement] 'endif' ';'
-    if (token == TokenNameCOLON) {
-      getNextToken();
-      if (token != TokenNameendif) {
-        statementList();
-        switch (token) {
-        case TokenNameelse:
-          getNextToken();
-          if (token == TokenNameCOLON) {
-            getNextToken();
-            if (token != TokenNameendif) {
-              statementList();
-            }
-          } else {
-            if (token == TokenNameif) { //'else if'
-              getNextToken();
-              elseifStatementList();
-            } else {
-              throwSyntaxError("':' expected after 'else'.");
-            }
-          }
-          break;
-        case TokenNameelseif:
-          getNextToken();
-          elseifStatementList();
-          break;
+  private void ifStatementColon(IfStatement iState) {
+    // T_IF '(' expr ')' ':' inner_statement_list new_elseif_list new_else_single T_ENDIF ';'
+    HashSet assignedVariableSet = null;
+    try {
+      Block b = inner_statement_list();
+      iState.thenStatement = b;
+      checkUnreachable(iState, b);
+    } finally {
+      assignedVariableSet = removeIfVariableSet();
+    }
+    if (token == TokenNameelseif) {
+      try {
+        pushIfVariableSet();
+        new_elseif_list(iState);
+      } finally {
+        HashSet set = removeIfVariableSet();
+        if (assignedVariableSet != null) {
+          assignedVariableSet.addAll(set);
         }
       }
-      if (token != TokenNameendif) {
-        throwSyntaxError("'endif' expected.");
+    }
+    try {
+      pushIfVariableSet();
+      new_else_single(iState);
+    } finally {
+      HashSet set = removeIfVariableSet();
+      if (assignedVariableSet != null) {
+        HashSet topSet = peekVariableSet();
+        if (topSet != null) {
+          topSet.addAll(set);
+          topSet.addAll(assignedVariableSet);
+        }
       }
+    }
+    if (token != TokenNameendif) {
+      throwSyntaxError("'endif' expected.");
+    }
+    getNextToken();
+    if (token != TokenNameSEMICOLON) {
+      reportSyntaxError("';' expected after if-statement.");
+      iState.sourceEnd = scanner.getCurrentTokenStartPosition();
+    } else {
+      iState.sourceEnd = scanner.getCurrentTokenEndPosition();
       getNextToken();
-      if (token != TokenNameSEMICOLON) {
-        throwSyntaxError("';' expected after if-statement.");
+    }
+  }
+
+  private void ifStatement(IfStatement iState) {
+    //  T_IF '(' expr ')' statement elseif_list else_single
+    HashSet assignedVariableSet = null;
+    try {
+      pushIfVariableSet();
+      Statement s = statement();
+      iState.thenStatement = s;
+      checkUnreachable(iState, s);
+    } finally {
+      assignedVariableSet = removeIfVariableSet();
+    }
+
+    if (token == TokenNameelseif) {
+      try {
+        pushIfVariableSet();
+        elseif_list(iState);
+      } finally {
+        HashSet set = removeIfVariableSet();
+        if (assignedVariableSet != null) {
+          assignedVariableSet.addAll(set);
+        }
+      }
+    }
+    try {
+      pushIfVariableSet();
+      else_single(iState);
+    } finally {
+      HashSet set = removeIfVariableSet();
+      if (assignedVariableSet != null) {
+        HashSet topSet = peekVariableSet();
+        if (topSet != null) {
+          topSet.addAll(set);
+          topSet.addAll(assignedVariableSet);
+        }
       }
+    }
+  }
+
+  private void elseif_list(IfStatement iState) {
+    // /* empty */
+    //| elseif_list T_ELSEIF '(' expr ')' statement
+    ArrayList conditionList = new ArrayList();
+    ArrayList statementList = new ArrayList();
+    Expression e;
+    Statement s;
+    while (token == TokenNameelseif) {
       getNextToken();
-    } else {
-      // statement [else-statement]
-      statement(TokenNameEOF);
-      if (token == TokenNameelseif) {
+      if (token == TokenNameLPAREN) {
         getNextToken();
-        if (token == TokenNameLPAREN) {
-          getNextToken();
-        } else {
-          throwSyntaxError("'(' expected after 'elseif' keyword.");
-        }
-        expr();
-        if (token == TokenNameRPAREN) {
-          getNextToken();
-        } else {
-          throwSyntaxError("')' expected after 'elseif' condition.");
-        }
-        ifStatement();
-      } else if (token == TokenNameelse) {
+      } else {
+        throwSyntaxError("'(' expected after 'elseif' keyword.");
+      }
+      e = expr();
+      conditionList.add(e);
+      if (token == TokenNameRPAREN) {
         getNextToken();
-        statement(TokenNameEOF);
+      } else {
+        throwSyntaxError("')' expected after 'elseif' condition.");
       }
+      s = statement();
+      statementList.add(s);
+      checkUnreachable(iState, s);
     }
+    iState.elseifConditions = new Expression[conditionList.size()];
+    iState.elseifStatements = new Statement[statementList.size()];
+    conditionList.toArray(iState.elseifConditions);
+    statementList.toArray(iState.elseifStatements);
   }
 
-  private void elseifStatementList() {
-    do {
-      elseifStatement();
-      switch (token) {
-      case TokenNameelse:
+  private void new_elseif_list(IfStatement iState) {
+    // /* empty */
+    //| new_elseif_list T_ELSEIF '(' expr ')' ':' inner_statement_list
+    ArrayList conditionList = new ArrayList();
+    ArrayList statementList = new ArrayList();
+    Expression e;
+    Block b;
+    while (token == TokenNameelseif) {
+      getNextToken();
+      if (token == TokenNameLPAREN) {
         getNextToken();
-        if (token == TokenNameCOLON) {
-          getNextToken();
-          if (token != TokenNameendif) {
-            statementList();
-          }
-          return;
-        } else {
-          if (token == TokenNameif) { //'else if'
-            getNextToken();
-          } else {
-            throwSyntaxError("':' expected after 'else'.");
-          }
-        }
-        break;
-      case TokenNameelseif:
+      } else {
+        throwSyntaxError("'(' expected after 'elseif' keyword.");
+      }
+      e = expr();
+      conditionList.add(e);
+      if (token == TokenNameRPAREN) {
         getNextToken();
-        break;
-      default:
-        return;
+      } else {
+        throwSyntaxError("')' expected after 'elseif' condition.");
       }
-    } while (true);
+      if (token == TokenNameCOLON) {
+        getNextToken();
+      } else {
+        throwSyntaxError("':' expected after 'elseif' keyword.");
+      }
+      b = inner_statement_list();
+      statementList.add(b);
+      checkUnreachable(iState, b);
+    }
+    iState.elseifConditions = new Expression[conditionList.size()];
+    iState.elseifStatements = new Statement[statementList.size()];
+    conditionList.toArray(iState.elseifConditions);
+    statementList.toArray(iState.elseifStatements);
   }
 
-  private void elseifStatement() {
-    if (token == TokenNameLPAREN) {
+  private void else_single(IfStatement iState) {
+    // /* empty */
+    // T_ELSE statement
+    if (token == TokenNameelse) {
       getNextToken();
-      expr();
-      if (token != TokenNameRPAREN) {
-        throwSyntaxError("')' expected in else-if-statement.");
-      }
+      Statement s = statement();
+      iState.elseStatement = s;
+      checkUnreachable(iState, s);
+    } else {
+      iState.checkUnreachable = false;
+    }
+    iState.sourceEnd = scanner.getCurrentTokenStartPosition();
+  }
+
+  private void new_else_single(IfStatement iState) {
+    // /* empty */
+    //| T_ELSE ':' inner_statement_list
+    if (token == TokenNameelse) {
       getNextToken();
-      if (token != TokenNameCOLON) {
-        throwSyntaxError("':' expected in else-if-statement.");
+      if (token == TokenNameCOLON) {
+        getNextToken();
+      } else {
+        throwSyntaxError("':' expected after 'else' keyword.");
       }
-      getNextToken();
-      if (token != TokenNameendif) {
-        statementList();
+      Block b = inner_statement_list();
+      iState.elseStatement = b;
+      checkUnreachable(iState, b);
+    } else {
+      iState.checkUnreachable = false;
+    }
+  }
+
+  private Block inner_statement_list() {
+    // inner_statement_list inner_statement
+    // /* empty */
+    return statementList();
+  }
+
+  /**
+   * @param iState
+   * @param b
+   */
+  private void checkUnreachable(IfStatement iState, Statement s) {
+    if (s instanceof Block) {
+      Block b = (Block) s;
+      if (b.statements == null || b.statements.length == 0) {
+        iState.checkUnreachable = false;
+      } else {
+        int off = b.statements.length - 1;
+        if (!(b.statements[off] instanceof ReturnStatement) && !(b.statements[off] instanceof ContinueStatement)
+            && !(b.statements[off] instanceof BreakStatement)) {
+          if (!(b.statements[off] instanceof IfStatement) || !((IfStatement) b.statements[off]).checkUnreachable) {
+            iState.checkUnreachable = false;
+          }
+        }
+      }
+    } else {
+      if (!(s instanceof ReturnStatement) && !(s instanceof ContinueStatement) && !(s instanceof BreakStatement)) {
+        if (!(s instanceof IfStatement) || !((IfStatement) s).checkUnreachable) {
+          iState.checkUnreachable = false;
+        }
       }
     }
   }
 
+  //  private void elseifStatementList() {
+  //    do {
+  //      elseifStatement();
+  //      switch (token) {
+  //      case TokenNameelse:
+  //        getNextToken();
+  //        if (token == TokenNameCOLON) {
+  //          getNextToken();
+  //          if (token != TokenNameendif) {
+  //            statementList();
+  //          }
+  //          return;
+  //        } else {
+  //          if (token == TokenNameif) { //'else if'
+  //            getNextToken();
+  //          } else {
+  //            throwSyntaxError("':' expected after 'else'.");
+  //          }
+  //        }
+  //        break;
+  //      case TokenNameelseif:
+  //        getNextToken();
+  //        break;
+  //      default:
+  //        return;
+  //      }
+  //    } while (true);
+  //  }
+
+  //  private void elseifStatement() {
+  //    if (token == TokenNameLPAREN) {
+  //      getNextToken();
+  //      expr();
+  //      if (token != TokenNameRPAREN) {
+  //        throwSyntaxError("')' expected in else-if-statement.");
+  //      }
+  //      getNextToken();
+  //      if (token != TokenNameCOLON) {
+  //        throwSyntaxError("':' expected in else-if-statement.");
+  //      }
+  //      getNextToken();
+  //      if (token != TokenNameendif) {
+  //        statementList();
+  //      }
+  //    }
+  //  }
+
   private void switchStatement() {
     if (token == TokenNameCOLON) {
       // ':' [labeled-statement-list] 'endswitch' ';'
@@ -1909,7 +2124,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
       }
       getNextToken();
     } else {
-      statement(TokenNameEOF);
+      statement();
     }
   }
 
@@ -1927,7 +2142,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
       }
       getNextToken();
     } else {
-      statement(TokenNameEOF);
+      statement();
     }
   }
 
@@ -1944,7 +2159,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
       }
       getNextToken();
     } else {
-      statement(TokenNameEOF);
+      statement();
     }
   }
 
@@ -2064,7 +2279,30 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
       }
       switch (token) {
       case TokenNameisset:
+        //     T_ISSET '(' isset_variables ')'
+        getNextToken();
+        if (token != TokenNameLPAREN) {
+          throwSyntaxError("'(' expected after keyword 'isset'");
+        }
+        getNextToken();
+        isset_variables();
+        if (token != TokenNameRPAREN) {
+          throwSyntaxError("')' expected after keyword 'isset'");
+        }
+        getNextToken();
+        break;
       case TokenNameempty:
+        getNextToken();
+        if (token != TokenNameLPAREN) {
+          throwSyntaxError("'(' expected after keyword 'empty'");
+        }
+        getNextToken();
+        variable(true, false);
+        if (token != TokenNameRPAREN) {
+          throwSyntaxError("')' expected after keyword 'empty'");
+        }
+        getNextToken();
+        break;
       case TokenNameeval:
       case TokenNameinclude:
       case TokenNameinclude_once:
@@ -2282,10 +2520,29 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
       case TokenNameIdentifier:
       case TokenNameVariable:
       case TokenNameDOLLAR:
-        boolean rememberedVar = false;
-        Expression lhs = variable();
+        boolean rememberedVar = false; 
+        Expression lhs = variable(true, true);
+        if (lhs != null && lhs instanceof FieldReference && token != TokenNameEQUAL && token != TokenNamePLUS_EQUAL
+            && token != TokenNameMINUS_EQUAL && token != TokenNameMULTIPLY_EQUAL && token != TokenNameDIVIDE_EQUAL
+            && token != TokenNameDOT_EQUAL && token != TokenNameREMAINDER_EQUAL && token != TokenNameAND_EQUAL
+            && token != TokenNameOR_EQUAL && token != TokenNameXOR_EQUAL && token != TokenNameRIGHT_SHIFT_EQUAL
+            && token != TokenNameLEFT_SHIFT_EQUAL) {
+          FieldReference ref = (FieldReference) lhs;
+          if (!containsVariableSet(ref.token)) {
+            problemReporter.uninitializedLocalVariable(new String(ref.token), ref.sourceStart(), ref.sourceEnd(), referenceContext,
+                compilationUnit.compilationResult);
+            addVariableSet(ref.token);
+          }
+        }
+
         switch (token) {
         case TokenNameEQUAL:
+          if (lhs != null && lhs instanceof FieldReference) {
+            addVariableSet(((FieldReference) lhs).token);
+          }
+          //          if (lhsVar != null) {
+          //            addVariableSet(lhsVar);
+          //          }
           getNextToken();
           if (token == TokenNameAND) {
             getNextToken();
@@ -2309,7 +2566,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
                 }
               }
             } else {
-              Expression rhs = variable();
+              Expression rhs = variable(false, false);
               if (rhs != null && rhs instanceof FieldReference && lhs != null && lhs instanceof FieldReference) {
                 // example:
                 // $var = &$ref;
@@ -2372,6 +2629,9 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
         case TokenNameXOR_EQUAL:
         case TokenNameRIGHT_SHIFT_EQUAL:
         case TokenNameLEFT_SHIFT_EQUAL:
+          if (lhs != null && lhs instanceof FieldReference) {
+            addVariableSet(((FieldReference) lhs).token);
+          }
           getNextToken();
           expr();
           break;
@@ -2597,8 +2857,10 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
     // variable
     //| T_LIST '(' assignment_list ')'
     //| /* empty */
-    if (token == TokenNameVariable || token == TokenNameDOLLAR) {
-      variable();
+    if (token == TokenNameVariable) {
+      variable(true, false);
+    } else if (token == TokenNameDOLLAR) {
+      variable(false, false);
     } else {
       if (token == TokenNamelist) {
         getNextToken();
@@ -2639,17 +2901,17 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
     while (true) {
       if (token == TokenNameAND) {
         getNextToken();
-        variable();
+        variable(true, false);
       } else {
         expr();
         if (token == TokenNameAND) {
           getNextToken();
-          variable();
+          variable(true, false);
         } else if (token == TokenNameEQUAL_GREATER) {
           getNextToken();
           if (token == TokenNameAND) {
             getNextToken();
-            variable();
+            variable(true, false);
           } else {
             expr();
           }
@@ -2675,7 +2937,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
   //      }
   //    } while (true);
   //  }
-  private Expression variable_without_objects() {
+  private Expression variable_without_objects(boolean lefthandside, boolean ignoreVar) {
     //  variable_without_objects:
     //                 reference_variable
     //         | simple_indirect_reference reference_variable
@@ -2685,10 +2947,10 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
     while (token == TokenNameDOLLAR) {
       getNextToken();
     }
-    return reference_variable();
+    return reference_variable(lefthandside, ignoreVar);
   }
 
-  private Expression function_call() {
+  private Expression function_call(boolean lefthandside, boolean ignoreVar) {
     //  function_call:
     // T_STRING '(' function_call_parameter_list ')'
     //| class_constant '(' function_call_parameter_list ')'
@@ -2718,12 +2980,12 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
           getNextToken();
         } else {
           //        static member:
-          variable_without_objects();
+          variable_without_objects(true, false);
         }
         break;
       }
     } else {
-      ref = variable_without_objects();
+      ref = variable_without_objects(lefthandside, ignoreVar);
     }
     if (token != TokenNameLPAREN) {
       if (defineName != null) {
@@ -2794,7 +3056,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
     while (true) {
       if (token == TokenNameAND) {
         getNextToken();
-        w_variable();
+        w_variable(true);
       } else {
         //        if (token == TokenNameIdentifier || token ==
         // TokenNameVariable
@@ -2831,10 +3093,10 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
       throwSyntaxError("'::' expected after class name (static_member).");
     }
     getNextToken();
-    variable_without_objects();
+    variable_without_objects(false, false);
   }
 
-  private Expression base_variable_with_function_calls() {
+  private Expression base_variable_with_function_calls(boolean lefthandside, boolean ignoreVar) {
     //  base_variable_with_function_calls:
     // base_variable
     //| function_call
@@ -2856,7 +3118,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
     //      scanner.phpMode = true;
     //    }
     //    if (functionCall) {
-    return function_call();
+    return function_call(lefthandside, ignoreVar);
     //    } else {
     //      base_variable();
     //    }
@@ -2877,7 +3139,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
       while (token == TokenNameDOLLAR) {
         getNextToken();
       }
-      reference_variable();
+      reference_variable(false, false);
     }
     return ref;
   }
@@ -2887,7 +3149,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
   //    // '$'
   //    //| simple_indirect_reference '$'
   //  }
-  private Expression reference_variable() {
+  private Expression reference_variable(boolean lefthandside, boolean ignoreVar) {
     //  reference_variable:
     //                 reference_variable '[' dim_offset ']'
     //         | reference_variable '{' expr '}'
@@ -2896,7 +3158,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
     if (Scanner.TRACE) {
       System.out.println("TRACE: reference_variable()");
     }
-    ref = compound_variable();
+    ref = compound_variable(lefthandside, ignoreVar);
     while (true) {
       if (token == TokenNameLBRACE) {
         ref = null;
@@ -2907,6 +3169,10 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
         }
         getNextToken();
       } else if (token == TokenNameLBRACKET) {
+        if (ref != null && ref instanceof FieldReference) {
+          FieldReference fref = (FieldReference) ref;
+          addVariableSet(fref.token);
+        }
         ref = null;
         getNextToken();
         if (token != TokenNameRBRACKET) {
@@ -2924,7 +3190,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
     return ref;
   }
 
-  private Expression compound_variable() {
+  private Expression compound_variable(boolean lefthandside, boolean ignoreVar) {
     //  compound_variable:
     //                 T_VARIABLE
     //         | '$' '{' expr '}'
@@ -2932,6 +3198,19 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
       System.out.println("TRACE: compound_variable()");
     }
     if (token == TokenNameVariable) {
+      if (!lefthandside) {
+        if (!containsVariableSet()) {
+          //          reportSyntaxError("The local variable " + new String(scanner.getCurrentIdentifierSource())
+          //              + " may not have been initialized");
+          problemReporter.uninitializedLocalVariable(new String(scanner.getCurrentIdentifierSource()), scanner
+              .getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition(), referenceContext,
+              compilationUnit.compilationResult);
+        }
+      } else {
+        if (!ignoreVar) {
+          addVariableSet();
+        }
+      }
       FieldReference ref = new FieldReference(scanner.getCurrentIdentifierSource(), scanner.getCurrentTokenStartPosition());
       getNextToken();
       return ref;
@@ -2952,11 +3231,8 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
       getNextToken();
     }
     return null;
-  }
+  } //  private void dim_offset() { // // dim_offset: // // /* empty */
 
-  //  private void dim_offset() {
-  //    // dim_offset:
-  //    // /* empty */
   //    // | expr
   //    expr();
   //  }
@@ -2968,7 +3244,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
       System.out.println("TRACE: object_property()");
     }
     if (token == TokenNameVariable || token == TokenNameDOLLAR) {
-      variable_without_objects();
+      variable_without_objects(false, false);
     } else {
       object_dim_list();
     }
@@ -3034,23 +3310,23 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
   }
 
   private void r_variable() {
-    variable();
+    variable(false, false);
   }
 
-  private void w_variable() {
-    variable();
+  private void w_variable(boolean lefthandside) {
+    variable(lefthandside, false);
   }
 
   private void rw_variable() {
-    variable();
+    variable(false, false);
   }
 
-  private Expression variable() {
+  private Expression variable(boolean lefthandside, boolean ignoreVar) {
     //    variable:
     //         base_variable_with_function_calls T_OBJECT_OPERATOR
     //                 object_property method_or_not variable_properties
     // | base_variable_with_function_calls
-    Expression ref = base_variable_with_function_calls();
+    Expression ref = base_variable_with_function_calls(lefthandside, ignoreVar);
     if (token == TokenNameMINUS_GREATER) {
       ref = null;
       getNextToken();
@@ -3369,32 +3645,32 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
   private void internal_functions_in_yacc() {
     //    int start = 0;
     switch (token) {
-    case TokenNameisset:
-      //       T_ISSET '(' isset_variables ')'
-      getNextToken();
-      if (token != TokenNameLPAREN) {
-        throwSyntaxError("'(' expected after keyword 'isset'");
-      }
-      getNextToken();
-      isset_variables();
-      if (token != TokenNameRPAREN) {
-        throwSyntaxError("')' expected after keyword 'isset'");
-      }
-      getNextToken();
-      break;
-    case TokenNameempty:
-      //       T_EMPTY '(' variable ')'
-      getNextToken();
-      if (token != TokenNameLPAREN) {
-        throwSyntaxError("'(' expected after keyword 'empty'");
-      }
-      getNextToken();
-      variable();
-      if (token != TokenNameRPAREN) {
-        throwSyntaxError("')' expected after keyword 'empty'");
-      }
-      getNextToken();
-      break;
+    //    case TokenNameisset:
+    //      // T_ISSET '(' isset_variables ')'
+    //      getNextToken();
+    //      if (token != TokenNameLPAREN) {
+    //        throwSyntaxError("'(' expected after keyword 'isset'");
+    //      }
+    //      getNextToken();
+    //      isset_variables();
+    //      if (token != TokenNameRPAREN) {
+    //        throwSyntaxError("')' expected after keyword 'isset'");
+    //      }
+    //      getNextToken();
+    //      break;
+    //    case TokenNameempty:
+    //      // T_EMPTY '(' variable ')'
+    //      getNextToken();
+    //      if (token != TokenNameLPAREN) {
+    //        throwSyntaxError("'(' expected after keyword 'empty'");
+    //      }
+    //      getNextToken();
+    //      variable(false);
+    //      if (token != TokenNameRPAREN) {
+    //        throwSyntaxError("')' expected after keyword 'empty'");
+    //      }
+    //      getNextToken();
+    //      break;
     case TokenNameinclude:
       //T_INCLUDE expr
       checkFileName(token);
@@ -3521,7 +3797,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
       throwSyntaxError("Variable expected after keyword 'isset'");
     }
     while (true) {
-      variable();
+      variable(true, false);
       if (token == TokenNameCOMMA) {
         getNextToken();
       } else {
@@ -3839,6 +4115,8 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
 
   HashMap fMethodVariables = null;
 
+  ArrayList fStackUnassigned = new ArrayList();
+
   //ast stack
   final static int AstStackIncrement = 100;
 
@@ -4206,8 +4484,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
         }
       }
       if (scanner.recordLineSeparator) {
-        //                             compilationUnit.compilationResult.lineSeparatorPositions =
-        // scanner.getLineEnds();
+        compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds();
       }
       // check placement anomalies against other kinds of brackets
       for (int kind = 0; kind < BracketKinds; kind++) {
@@ -4332,7 +4609,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
     } else {
       String name = file.getName();
       tokens = new char[1][];
-      tokens[0] = name.substring(0, ext.length() - fileExtensionLength).toCharArray();
+      tokens[0] = name.substring(0, name.length() - fileExtensionLength).toCharArray();
     }
 
     this.compilationUnit.currentPackage = impt = new ImportReference(tokens, new char[0], 0, 0, true);
@@ -4343,4 +4620,123 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
     //endPosition is just before the ;
 
   }
+
+  public final static String[] GLOBALS = {
+      "$this",
+      "$_COOKIE",
+      "$_ENV",
+      "$_FILES",
+      "$_GET",
+      "$GLOBALS",
+      "$_POST",
+      "$_REQUEST",
+      "$_SESSION",
+      "$_SERVER" };
+
+  /**
+   *  
+   */
+  private void pushFunctionVariableSet() {
+    HashSet set = new HashSet();
+    if (fStackUnassigned.isEmpty()) {
+      for (int i = 0; i < GLOBALS.length; i++) {
+        set.add(GLOBALS[i]);
+      }
+    }
+    fStackUnassigned.add(set);
+  }
+
+  private void pushIfVariableSet() {
+    if (!fStackUnassigned.isEmpty()) {
+      HashSet set = new HashSet();
+      fStackUnassigned.add(set);
+    }
+  }
+
+  private HashSet removeIfVariableSet() {
+    if (!fStackUnassigned.isEmpty()) {
+      return (HashSet) fStackUnassigned.remove(fStackUnassigned.size() - 1);
+    }
+    return null;
+  }
+
+  /**
+   * Returns the <i>set of assigned variables </i> returns null if no Set is defined at the current scanner position
+   */
+  private HashSet peekVariableSet() {
+    if (!fStackUnassigned.isEmpty()) {
+      return (HashSet) fStackUnassigned.get(fStackUnassigned.size() - 1);
+    }
+    return null;
+  }
+
+  /**
+   * add the current identifier source to the <i>set of assigned variables </i>
+   * 
+   * @param set
+   */
+  private void addVariableSet(HashSet set) {
+    if (set != null) {
+      set.add(new String(scanner.getCurrentTokenSource()));
+    }
+  }
+
+  /**
+   * add the current identifier source to the <i>set of assigned variables </i>
+   *  
+   */
+  private void addVariableSet() {
+    HashSet set = peekVariableSet();
+    if (set != null) {
+      set.add(new String(scanner.getCurrentTokenSource()));
+    }
+  }
+
+  /**
+   * add the current identifier source to the <i>set of assigned variables </i>
+   *  
+   */
+  private void addVariableSet(char[] token) {
+    HashSet set = peekVariableSet();
+    if (set != null) {
+      set.add(new String(token));
+    }
+  }
+
+  /**
+   * check if the current identifier source is in the <i>set of assigned variables </i> Returns true, if no set is defined for the
+   * current scanner position
+   *  
+   */
+  private boolean containsVariableSet() {
+    return containsVariableSet(scanner.getCurrentTokenSource());
+    //    if (!fStackUnassigned.isEmpty()) {
+    //      HashSet set;
+    //      String str = new String(scanner.getCurrentTokenSource());
+    //      for (int i = 0; i < fStackUnassigned.size(); i++) {
+    //        set = (HashSet) fStackUnassigned.get(i);
+    //        if (set.contains(str)) {
+    //          return true;
+    //        }
+    //      }
+    //      return false;
+    //    }
+    //    return true;
+  }
+
+  private boolean containsVariableSet(char[] token) {
+
+    if (!fStackUnassigned.isEmpty()) {
+      HashSet set;
+      String str = new String(token);
+      for (int i = 0; i < fStackUnassigned.size(); i++) {
+        set = (HashSet) fStackUnassigned.get(i);
+        if (set.contains(str)) {
+          return true;
+        }
+      }
+      return false;
+    }
+    return true;
+  }
 }
\ No newline at end of file