Created a separated 'externaltools' plugin
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / parser / Parser.java
index 4777170..f7000aa 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;
@@ -193,8 +194,14 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
    */
   private void throwSyntaxError(String error) {
     int problemStartPosition = scanner.getCurrentTokenStartPosition();
-    int problemEndPosition = scanner.getCurrentTokenEndPosition();
-    throwSyntaxError(error, problemStartPosition, problemEndPosition + 1);
+    int problemEndPosition = scanner.getCurrentTokenEndPosition() + 1;
+    if (scanner.source.length <= problemEndPosition && problemEndPosition > 0) {
+      problemEndPosition = scanner.source.length - 1;
+      if (problemStartPosition > 0 && problemStartPosition >= problemEndPosition && problemEndPosition > 0) {
+        problemStartPosition = problemEndPosition - 1;
+      }
+    }
+    throwSyntaxError(error, problemStartPosition, problemEndPosition);
   }
 
   /**
@@ -308,6 +315,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
    */
   public void parse(String s, HashMap variables) {
     fMethodVariables = variables;
+    fStackUnassigned = new ArrayList();
     init(s);
     parse();
   }
@@ -354,30 +362,9 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
           throwSyntaxError("End-of-file not reached.");
         }
         break;
-      } catch (SyntaxError sytaxErr1) {
+      } catch (SyntaxError syntaxError) {
+        //          syntaxError.printStackTrace();
         break;
-        //        // if an error occured,
-        //        // try to find keywords 'abstract' 'final' 'class' or 'function'
-        //        // to parse the rest of the string
-        //        boolean tokenize = scanner.tokenizeStrings;
-        //        if (!tokenize) {
-        //          scanner.tokenizeStrings = true;
-        //        }
-        //        try {
-        //          while (token != TokenNameEOF) {
-        //            if (token == TokenNameabstract || token == TokenNamefinal || token == TokenNameclass || token == TokenNamefunction) {
-        //              break;
-        //            }
-        //            getNextToken();
-        //          }
-        //          if (token == TokenNameEOF) {
-        //            break;
-        //          }
-        //        } catch (SyntaxError sytaxErr2) {
-        //          break;
-        //        } finally {
-        //          scanner.tokenizeStrings = tokenize;
-        //        }
       }
     } while (true);
 
@@ -415,10 +402,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;
       }
     }
@@ -464,18 +452,16 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
   private Block statementList() {
     boolean branchStatement = false;
     Statement statement;
-    int sourceStart;
-    int sourceEnd;
     int blockStart = scanner.getCurrentTokenStartPosition();
     ArrayList blockStatements = new ArrayList();
     do {
       try {
-        sourceStart = scanner.getCurrentTokenStartPosition();
         statement = statement();
         blockStatements.add(statement);
-        if (branchStatement) {
-          sourceEnd = scanner.getCurrentTokenEndPosition();
-          reportSyntaxError("Unreachable code", sourceStart, sourceEnd);
+        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)
@@ -484,7 +470,6 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
           return createBlock(blockStart, blockStatements);
         }
         branchStatement = checkUnreachableStatements(statement);
-//        return createBlock(blockStart, blockStatements);
       } catch (SyntaxError sytaxErr1) {
         // if an error occured,
         // try to find keywords
@@ -528,13 +513,12 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
    * @return
    */
   private boolean checkUnreachableStatements(Statement statement) {
-    boolean branchStatement = false;
     if (statement instanceof ReturnStatement || statement instanceof ContinueStatement || statement instanceof BreakStatement) {
-      branchStatement = true;
-    } else if (statement instanceof IfStatement && ((IfStatement)statement).checkUnreachable) {
-      branchStatement = true;
+      return true;
+    } else if (statement instanceof IfStatement && ((IfStatement) statement).checkUnreachable) {
+      return true;
     }
-    return branchStatement;
+    return false;
   }
 
   /**
@@ -555,15 +539,17 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
     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.");
     }
   }
@@ -724,7 +710,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
       foreach_optional_arg();
       if (token == TokenNameEQUAL_GREATER) {
         getNextToken();
-        variable();
+        variable(false, false);
       }
       if (token == TokenNameRPAREN) {
         getNextToken();
@@ -797,7 +783,19 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
       }
       return statement;
     } else if (token == TokenNameINLINE_HTML) {
-      getNextToken();
+      if (scanner.phpExpressionTag) {
+        // start of <?= ... ?> block
+        getNextToken();
+        expr();
+        if (token == TokenNameSEMICOLON) {
+          getNextToken();
+        }
+        if (token != TokenNameINLINE_HTML) {
+          throwSyntaxError("Missing '?>' for open PHP expression block ('<?=').");
+        }
+      } else {
+        getNextToken();
+      }
       return statement;
       //    } else if (token == TokenNameprint) {
       //      getNextToken();
@@ -866,11 +864,12 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
         getNextToken();
         functionDefinition(methodDecl);
       } finally {
-        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) {
@@ -1065,7 +1064,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
     if (token == TokenNameAND) {
       getNextToken();
     }
-    w_variable();
+    w_variable(true);
   }
 
   private void foreach_optional_arg() {
@@ -1081,8 +1080,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;
       }
@@ -1090,16 +1090,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();
@@ -1121,13 +1122,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();
@@ -1150,7 +1153,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
     //    unset_variable:
     //                 variable
     while (true) {
-      variable();
+      variable(false, false);
       if (token != TokenNameCOMMA) {
         break;
       }
@@ -1424,11 +1427,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) {
@@ -1613,15 +1617,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) {
@@ -1641,12 +1653,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;
@@ -1654,6 +1668,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'.");
     }
   }
@@ -1678,6 +1693,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();
@@ -1697,6 +1713,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();
@@ -1800,13 +1817,38 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
 
   private void ifStatementColon(IfStatement iState) {
     // T_IF '(' expr ')' ':' inner_statement_list new_elseif_list new_else_single T_ENDIF ';'
-    Block b = inner_statement_list();
-    iState.thenStatement = b;
-    checkUnreachable(iState, b);
+    HashSet assignedVariableSet = null;
+    try {
+      Block b = inner_statement_list();
+      iState.thenStatement = b;
+      checkUnreachable(iState, b);
+    } finally {
+      assignedVariableSet = removeIfVariableSet();
+    }
     if (token == TokenNameelseif) {
-      new_elseif_list(iState);
-    } 
-    new_else_single(iState);
+      try {
+        pushIfVariableSet();
+        new_elseif_list(iState);
+      } finally {
+        HashSet set = removeIfVariableSet();
+        if (assignedVariableSet != null) {
+          assignedVariableSet.addAll(set);
+        }
+      }
+    }
+    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.");
     }
@@ -1822,13 +1864,40 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
 
   private void ifStatement(IfStatement iState) {
     //  T_IF '(' expr ')' statement elseif_list else_single
-    Statement s = statement();
-    iState.thenStatement = s;
-    checkUnreachable(iState, s);
+    HashSet assignedVariableSet = null;
+    try {
+      pushIfVariableSet();
+      Statement s = statement();
+      iState.thenStatement = s;
+      checkUnreachable(iState, s);
+    } finally {
+      assignedVariableSet = removeIfVariableSet();
+    }
+
     if (token == TokenNameelseif) {
-      elseif_list(iState);
+      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);
+        }
+      }
     }
-    else_single(iState);
   }
 
   private void elseif_list(IfStatement iState) {
@@ -1949,12 +2018,16 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
         int off = b.statements.length - 1;
         if (!(b.statements[off] instanceof ReturnStatement) && !(b.statements[off] instanceof ContinueStatement)
             && !(b.statements[off] instanceof BreakStatement)) {
-          iState.checkUnreachable = false;
+          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)) {
-        iState.checkUnreachable = false;
+        if (!(s instanceof IfStatement) || !((IfStatement) s).checkUnreachable) {
+          iState.checkUnreachable = false;
+        }
       }
     }
   }
@@ -2203,7 +2276,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:
@@ -2264,68 +2360,68 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
       //       | '`' encaps_list '`'
       //  | common_scalar
       //       | '`' encaps_list '`'
-      case TokenNameEncapsedString0:
-        scanner.encapsedStringStack.push(new Character('`'));
-        getNextToken();
-        try {
-          if (token == TokenNameEncapsedString0) {
-          } else {
-            encaps_list();
-            if (token != TokenNameEncapsedString0) {
-              throwSyntaxError("\'`\' expected at end of string" + "(Found token: " + scanner.toStringAction(token) + " )");
-            }
-          }
-        } finally {
-          scanner.encapsedStringStack.pop();
-          getNextToken();
-        }
-        break;
-      //      | '\'' encaps_list '\''
-      case TokenNameEncapsedString1:
-        scanner.encapsedStringStack.push(new Character('\''));
-        getNextToken();
-        try {
-          exprSourceStart = scanner.getCurrentTokenStartPosition();
-          if (token == TokenNameEncapsedString1) {
-            expression = new StringLiteralSQ(scanner.getCurrentStringLiteralSource(exprSourceStart), exprSourceStart, scanner
-                .getCurrentTokenEndPosition());
-          } else {
-            encaps_list();
-            if (token != TokenNameEncapsedString1) {
-              throwSyntaxError("\'\'\' expected at end of string" + "(Found token: " + scanner.toStringAction(token) + " )");
-            } else {
-              expression = new StringLiteralSQ(scanner.getCurrentStringLiteralSource(exprSourceStart), exprSourceStart, scanner
-                  .getCurrentTokenEndPosition());
-            }
-          }
-        } finally {
-          scanner.encapsedStringStack.pop();
-          getNextToken();
-        }
-        break;
-      //| '"' encaps_list '"'
-      case TokenNameEncapsedString2:
-        scanner.encapsedStringStack.push(new Character('"'));
-        getNextToken();
-        try {
-          exprSourceStart = scanner.getCurrentTokenStartPosition();
-          if (token == TokenNameEncapsedString2) {
-            expression = new StringLiteralDQ(scanner.getCurrentStringLiteralSource(exprSourceStart), exprSourceStart, scanner
-                .getCurrentTokenEndPosition());
-          } else {
-            encaps_list();
-            if (token != TokenNameEncapsedString2) {
-              throwSyntaxError("'\"' expected at end of string" + "(Found token: " + scanner.toStringAction(token) + " )");
-            } else {
-              expression = new StringLiteralDQ(scanner.getCurrentStringLiteralSource(exprSourceStart), exprSourceStart, scanner
-                  .getCurrentTokenEndPosition());
-            }
-          }
-        } finally {
-          scanner.encapsedStringStack.pop();
-          getNextToken();
-        }
-        break;
+      //      case TokenNameEncapsedString0:
+      //        scanner.encapsedStringStack.push(new Character('`'));
+      //        getNextToken();
+      //        try {
+      //          if (token == TokenNameEncapsedString0) {
+      //          } else {
+      //            encaps_list();
+      //            if (token != TokenNameEncapsedString0) {
+      //              throwSyntaxError("\'`\' expected at end of string" + "(Found token: " + scanner.toStringAction(token) + " )");
+      //            }
+      //          }
+      //        } finally {
+      //          scanner.encapsedStringStack.pop();
+      //          getNextToken();
+      //        }
+      //        break;
+      //      // | '\'' encaps_list '\''
+      //      case TokenNameEncapsedString1:
+      //        scanner.encapsedStringStack.push(new Character('\''));
+      //        getNextToken();
+      //        try {
+      //          exprSourceStart = scanner.getCurrentTokenStartPosition();
+      //          if (token == TokenNameEncapsedString1) {
+      //            expression = new StringLiteralSQ(scanner.getCurrentStringLiteralSource(exprSourceStart), exprSourceStart, scanner
+      //                .getCurrentTokenEndPosition());
+      //          } else {
+      //            encaps_list();
+      //            if (token != TokenNameEncapsedString1) {
+      //              throwSyntaxError("\'\'\' expected at end of string" + "(Found token: " + scanner.toStringAction(token) + " )");
+      //            } else {
+      //              expression = new StringLiteralSQ(scanner.getCurrentStringLiteralSource(exprSourceStart), exprSourceStart, scanner
+      //                  .getCurrentTokenEndPosition());
+      //            }
+      //          }
+      //        } finally {
+      //          scanner.encapsedStringStack.pop();
+      //          getNextToken();
+      //        }
+      //        break;
+      //      //| '"' encaps_list '"'
+      //      case TokenNameEncapsedString2:
+      //        scanner.encapsedStringStack.push(new Character('"'));
+      //        getNextToken();
+      //        try {
+      //          exprSourceStart = scanner.getCurrentTokenStartPosition();
+      //          if (token == TokenNameEncapsedString2) {
+      //            expression = new StringLiteralDQ(scanner.getCurrentStringLiteralSource(exprSourceStart), exprSourceStart, scanner
+      //                .getCurrentTokenEndPosition());
+      //          } else {
+      //            encaps_list();
+      //            if (token != TokenNameEncapsedString2) {
+      //              throwSyntaxError("'\"' expected at end of string" + "(Found token: " + scanner.toStringAction(token) + " )");
+      //            } else {
+      //              expression = new StringLiteralDQ(scanner.getCurrentStringLiteralSource(exprSourceStart), exprSourceStart, scanner
+      //                  .getCurrentTokenEndPosition());
+      //            }
+      //          }
+      //        } finally {
+      //          scanner.encapsedStringStack.pop();
+      //          getNextToken();
+      //        }
+      //        break;
       case TokenNameStringDoubleQuote:
         expression = new StringLiteralDQ(scanner.getCurrentStringLiteralSource(), scanner.getCurrentTokenStartPosition(), scanner
             .getCurrentTokenEndPosition());
@@ -2422,9 +2518,28 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
       case TokenNameVariable:
       case TokenNameDOLLAR:
         boolean rememberedVar = false;
-        Expression lhs = variable();
+        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();
@@ -2448,7 +2563,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;
@@ -2511,6 +2626,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;
@@ -2533,6 +2651,9 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
             getNextToken();
             break;
           } else {
+            //            System.out.println(scanner.getCurrentTokenStartPosition());
+            //            System.out.println(scanner.getCurrentTokenEndPosition());
+
             throwSyntaxError("Error in expression (found token '" + scanner.toStringAction(token) + "').");
           }
         }
@@ -2736,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();
@@ -2778,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();
           }
@@ -2814,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
@@ -2824,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 ')'
@@ -2857,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) {
@@ -2933,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
@@ -2970,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
@@ -2995,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();
     //    }
@@ -3016,7 +3139,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
       while (token == TokenNameDOLLAR) {
         getNextToken();
       }
-      reference_variable();
+      reference_variable(false, false);
     }
     return ref;
   }
@@ -3026,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 '}'
@@ -3035,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;
@@ -3046,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) {
@@ -3063,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 '}'
@@ -3071,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;
@@ -3091,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();
   //  }
@@ -3107,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();
     }
@@ -3173,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();
@@ -3264,223 +3401,223 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
     getNextToken();
   }
 
-  private void encaps_list() {
-    //                 encaps_list encaps_var
-    //         | encaps_list T_STRING
-    //         | encaps_list T_NUM_STRING
-    //         | encaps_list T_ENCAPSED_AND_WHITESPACE
-    //         | encaps_list T_CHARACTER
-    //         | encaps_list T_BAD_CHARACTER
-    //         | encaps_list '['
-    //         | encaps_list ']'
-    //         | encaps_list '{'
-    //         | encaps_list '}'
-    //         | encaps_list T_OBJECT_OPERATOR
-    //         | /* empty */
-    while (true) {
-      switch (token) {
-      case TokenNameSTRING:
-        getNextToken();
-        break;
-      case TokenNameLBRACE:
-        //          scanner.encapsedStringStack.pop();
-        getNextToken();
-        break;
-      case TokenNameRBRACE:
-        //          scanner.encapsedStringStack.pop();
-        getNextToken();
-        break;
-      case TokenNameLBRACKET:
-        //          scanner.encapsedStringStack.pop();
-        getNextToken();
-        break;
-      case TokenNameRBRACKET:
-        //          scanner.encapsedStringStack.pop();
-        getNextToken();
-        break;
-      case TokenNameMINUS_GREATER:
-        //          scanner.encapsedStringStack.pop();
-        getNextToken();
-        break;
-      case TokenNameVariable:
-      case TokenNameDOLLAR_LBRACE:
-      case TokenNameLBRACE_DOLLAR:
-        encaps_var();
-        break;
-      default:
-        char encapsedChar = ((Character) scanner.encapsedStringStack.peek()).charValue();
-        if (encapsedChar == '$') {
-          scanner.encapsedStringStack.pop();
-          encapsedChar = ((Character) scanner.encapsedStringStack.peek()).charValue();
-          switch (encapsedChar) {
-          case '`':
-            if (token == TokenNameEncapsedString0) {
-              return;
-            }
-            token = TokenNameSTRING;
-            continue;
-          case '\'':
-            if (token == TokenNameEncapsedString1) {
-              return;
-            }
-            token = TokenNameSTRING;
-            continue;
-          case '"':
-            if (token == TokenNameEncapsedString2) {
-              return;
-            }
-            token = TokenNameSTRING;
-            continue;
-          }
-        }
-        return;
-      }
-    }
-  }
+  //  private void encaps_list() {
+  //    // encaps_list encaps_var
+  //    // | encaps_list T_STRING
+  //    // | encaps_list T_NUM_STRING
+  //    // | encaps_list T_ENCAPSED_AND_WHITESPACE
+  //    // | encaps_list T_CHARACTER
+  //    // | encaps_list T_BAD_CHARACTER
+  //    // | encaps_list '['
+  //    // | encaps_list ']'
+  //    // | encaps_list '{'
+  //    // | encaps_list '}'
+  //    // | encaps_list T_OBJECT_OPERATOR
+  //    // | /* empty */
+  //    while (true) {
+  //      switch (token) {
+  //      case TokenNameSTRING:
+  //        getNextToken();
+  //        break;
+  //      case TokenNameLBRACE:
+  //        // scanner.encapsedStringStack.pop();
+  //        getNextToken();
+  //        break;
+  //      case TokenNameRBRACE:
+  //        // scanner.encapsedStringStack.pop();
+  //        getNextToken();
+  //        break;
+  //      case TokenNameLBRACKET:
+  //        // scanner.encapsedStringStack.pop();
+  //        getNextToken();
+  //        break;
+  //      case TokenNameRBRACKET:
+  //        // scanner.encapsedStringStack.pop();
+  //        getNextToken();
+  //        break;
+  //      case TokenNameMINUS_GREATER:
+  //        // scanner.encapsedStringStack.pop();
+  //        getNextToken();
+  //        break;
+  //      case TokenNameVariable:
+  //      case TokenNameDOLLAR_LBRACE:
+  //      case TokenNameLBRACE_DOLLAR:
+  //        encaps_var();
+  //        break;
+  //      default:
+  //        char encapsedChar = ((Character) scanner.encapsedStringStack.peek()).charValue();
+  //        if (encapsedChar == '$') {
+  //          scanner.encapsedStringStack.pop();
+  //          encapsedChar = ((Character) scanner.encapsedStringStack.peek()).charValue();
+  //          switch (encapsedChar) {
+  //          case '`':
+  //            if (token == TokenNameEncapsedString0) {
+  //              return;
+  //            }
+  //            token = TokenNameSTRING;
+  //            continue;
+  //          case '\'':
+  //            if (token == TokenNameEncapsedString1) {
+  //              return;
+  //            }
+  //            token = TokenNameSTRING;
+  //            continue;
+  //          case '"':
+  //            if (token == TokenNameEncapsedString2) {
+  //              return;
+  //            }
+  //            token = TokenNameSTRING;
+  //            continue;
+  //          }
+  //        }
+  //        return;
+  //      }
+  //    }
+  //  }
 
-  private void encaps_var() {
-    //                 T_VARIABLE
-    //         | T_VARIABLE '[' encaps_var_offset ']'
-    //         | T_VARIABLE T_OBJECT_OPERATOR T_STRING
-    //         | T_DOLLAR_OPEN_CURLY_BRACES expr '}'
-    //         | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '[' expr ']' '}'
-    //         | T_CURLY_OPEN variable '}'
-    switch (token) {
-    case TokenNameVariable:
-      getNextToken();
-      if (token == TokenNameLBRACKET) {
-        getNextToken();
-        expr(); //encaps_var_offset();
-        if (token != TokenNameRBRACKET) {
-          throwSyntaxError("']' expected after variable.");
-        }
-        //          scanner.encapsedStringStack.pop();
-        getNextToken();
-        //          }
-      } else if (token == TokenNameMINUS_GREATER) {
-        getNextToken();
-        if (token != TokenNameIdentifier) {
-          throwSyntaxError("Identifier expected after '->'.");
-        }
-        //          scanner.encapsedStringStack.pop();
-        getNextToken();
-      }
-      //        else {
-      //          // scanner.encapsedStringStack.pop();
-      //          int tempToken = TokenNameSTRING;
-      //          if (!scanner.encapsedStringStack.isEmpty()
-      //              && (token == TokenNameEncapsedString0
-      //                  || token == TokenNameEncapsedString1
-      //                  || token == TokenNameEncapsedString2 || token ==
-      // TokenNameERROR)) {
-      //            char encapsedChar = ((Character)
-      // scanner.encapsedStringStack.peek())
-      //                .charValue();
-      //            switch (token) {
-      //              case TokenNameEncapsedString0 :
-      //                if (encapsedChar == '`') {
-      //                  tempToken = TokenNameEncapsedString0;
-      //                }
-      //                break;
-      //              case TokenNameEncapsedString1 :
-      //                if (encapsedChar == '\'') {
-      //                  tempToken = TokenNameEncapsedString1;
-      //                }
-      //                break;
-      //              case TokenNameEncapsedString2 :
-      //                if (encapsedChar == '"') {
-      //                  tempToken = TokenNameEncapsedString2;
-      //                }
-      //                break;
-      //              case TokenNameERROR :
-      //                if (scanner.source[scanner.currentPosition - 1] == '\\') {
-      //                  scanner.currentPosition--;
-      //                  getNextToken();
-      //                }
-      //                break;
-      //            }
-      //          }
-      //          token = tempToken;
-      //        }
-      break;
-    case TokenNameDOLLAR_LBRACE:
-      getNextToken();
-      if (token == TokenNameDOLLAR_LBRACE) {
-        encaps_var();
-      } else if (token == TokenNameIdentifier) {
-        getNextToken();
-        if (token == TokenNameLBRACKET) {
-          getNextToken();
-          //            if (token == TokenNameRBRACKET) {
-          //              getNextToken();
-          //            } else {
-          expr();
-          if (token != TokenNameRBRACKET) {
-            throwSyntaxError("']' expected after '${'.");
-          }
-          getNextToken();
-          //            }
-        }
-      } else {
-        expr();
-      }
-      if (token != TokenNameRBRACE) {
-        throwSyntaxError("'}' expected.");
-      }
-      getNextToken();
-      break;
-    case TokenNameLBRACE_DOLLAR:
-      getNextToken();
-      if (token == TokenNameLBRACE_DOLLAR) {
-        encaps_var();
-      } else if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
-        getNextToken();
-        if (token == TokenNameLBRACKET) {
-          getNextToken();
-          //            if (token == TokenNameRBRACKET) {
-          //              getNextToken();
-          //            } else {
-          expr();
-          if (token != TokenNameRBRACKET) {
-            throwSyntaxError("']' expected.");
-          }
-          getNextToken();
-          //            }
-        } else if (token == TokenNameMINUS_GREATER) {
-          getNextToken();
-          if (token != TokenNameIdentifier && token != TokenNameVariable) {
-            throwSyntaxError("String or Variable token expected.");
-          }
-          getNextToken();
-          if (token == TokenNameLBRACKET) {
-            getNextToken();
-            //            if (token == TokenNameRBRACKET) {
-            //              getNextToken();
-            //            } else {
-            expr();
-            if (token != TokenNameRBRACKET) {
-              throwSyntaxError("']' expected after '${'.");
-            }
-            getNextToken();
-            //            }
-          }
-        }
-        //          if (token != TokenNameRBRACE) {
-        //            throwSyntaxError("'}' expected after '{$'.");
-        //          }
-        //          // scanner.encapsedStringStack.pop();
-        //          getNextToken();
-      } else {
-        expr();
-        if (token != TokenNameRBRACE) {
-          throwSyntaxError("'}' expected.");
-        }
-        //          scanner.encapsedStringStack.pop();
-        getNextToken();
-      }
-      break;
-    }
-  }
+  //  private void encaps_var() {
+  //    // T_VARIABLE
+  //    // | T_VARIABLE '[' encaps_var_offset ']'
+  //    // | T_VARIABLE T_OBJECT_OPERATOR T_STRING
+  //    // | T_DOLLAR_OPEN_CURLY_BRACES expr '}'
+  //    // | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '[' expr ']' '}'
+  //    // | T_CURLY_OPEN variable '}'
+  //    switch (token) {
+  //    case TokenNameVariable:
+  //      getNextToken();
+  //      if (token == TokenNameLBRACKET) {
+  //        getNextToken();
+  //        expr(); //encaps_var_offset();
+  //        if (token != TokenNameRBRACKET) {
+  //          throwSyntaxError("']' expected after variable.");
+  //        }
+  //        // scanner.encapsedStringStack.pop();
+  //        getNextToken();
+  //        // }
+  //      } else if (token == TokenNameMINUS_GREATER) {
+  //        getNextToken();
+  //        if (token != TokenNameIdentifier) {
+  //          throwSyntaxError("Identifier expected after '->'.");
+  //        }
+  //        // scanner.encapsedStringStack.pop();
+  //        getNextToken();
+  //      }
+  //      // else {
+  //      // // scanner.encapsedStringStack.pop();
+  //      // int tempToken = TokenNameSTRING;
+  //      // if (!scanner.encapsedStringStack.isEmpty()
+  //      // && (token == TokenNameEncapsedString0
+  //      // || token == TokenNameEncapsedString1
+  //      // || token == TokenNameEncapsedString2 || token ==
+  //      // TokenNameERROR)) {
+  //      // char encapsedChar = ((Character)
+  //      // scanner.encapsedStringStack.peek())
+  //      // .charValue();
+  //      // switch (token) {
+  //      // case TokenNameEncapsedString0 :
+  //      // if (encapsedChar == '`') {
+  //      // tempToken = TokenNameEncapsedString0;
+  //      // }
+  //      // break;
+  //      // case TokenNameEncapsedString1 :
+  //      // if (encapsedChar == '\'') {
+  //      // tempToken = TokenNameEncapsedString1;
+  //      // }
+  //      // break;
+  //      // case TokenNameEncapsedString2 :
+  //      // if (encapsedChar == '"') {
+  //      // tempToken = TokenNameEncapsedString2;
+  //      // }
+  //      // break;
+  //      // case TokenNameERROR :
+  //      // if (scanner.source[scanner.currentPosition - 1] == '\\') {
+  //      // scanner.currentPosition--;
+  //      // getNextToken();
+  //      // }
+  //      // break;
+  //      // }
+  //      // }
+  //      // token = tempToken;
+  //      // }
+  //      break;
+  //    case TokenNameDOLLAR_LBRACE:
+  //      getNextToken();
+  //      if (token == TokenNameDOLLAR_LBRACE) {
+  //        encaps_var();
+  //      } else if (token == TokenNameIdentifier) {
+  //        getNextToken();
+  //        if (token == TokenNameLBRACKET) {
+  //          getNextToken();
+  //          // if (token == TokenNameRBRACKET) {
+  //          // getNextToken();
+  //          // } else {
+  //          expr();
+  //          if (token != TokenNameRBRACKET) {
+  //            throwSyntaxError("']' expected after '${'.");
+  //          }
+  //          getNextToken();
+  //          // }
+  //        }
+  //      } else {
+  //        expr();
+  //      }
+  //      if (token != TokenNameRBRACE) {
+  //        throwSyntaxError("'}' expected.");
+  //      }
+  //      getNextToken();
+  //      break;
+  //    case TokenNameLBRACE_DOLLAR:
+  //      getNextToken();
+  //      if (token == TokenNameLBRACE_DOLLAR) {
+  //        encaps_var();
+  //      } else if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
+  //        getNextToken();
+  //        if (token == TokenNameLBRACKET) {
+  //          getNextToken();
+  //          // if (token == TokenNameRBRACKET) {
+  //          // getNextToken();
+  //          // } else {
+  //          expr();
+  //          if (token != TokenNameRBRACKET) {
+  //            throwSyntaxError("']' expected.");
+  //          }
+  //          getNextToken();
+  //          // }
+  //        } else if (token == TokenNameMINUS_GREATER) {
+  //          getNextToken();
+  //          if (token != TokenNameIdentifier && token != TokenNameVariable) {
+  //            throwSyntaxError("String or Variable token expected.");
+  //          }
+  //          getNextToken();
+  //          if (token == TokenNameLBRACKET) {
+  //            getNextToken();
+  //            // if (token == TokenNameRBRACKET) {
+  //            // getNextToken();
+  //            // } else {
+  //            expr();
+  //            if (token != TokenNameRBRACKET) {
+  //              throwSyntaxError("']' expected after '${'.");
+  //            }
+  //            getNextToken();
+  //            // }
+  //          }
+  //        }
+  //        // if (token != TokenNameRBRACE) {
+  //        // throwSyntaxError("'}' expected after '{$'.");
+  //        // }
+  //        // // scanner.encapsedStringStack.pop();
+  //        // getNextToken();
+  //      } else {
+  //        expr();
+  //        if (token != TokenNameRBRACE) {
+  //          throwSyntaxError("'}' expected.");
+  //        }
+  //        // scanner.encapsedStringStack.pop();
+  //        getNextToken();
+  //      }
+  //      break;
+  //    }
+  //  }
 
   private void encaps_var_offset() {
     //                 T_STRING
@@ -3508,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);
@@ -3566,6 +3703,11 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
     }
   }
 
+  /**
+   * Parse and check the include file name
+   * 
+   * @param includeToken
+   */
   private void checkFileName(int includeToken) {
     //<include-token> expr
     int start = scanner.getCurrentTokenStartPosition();
@@ -3628,15 +3770,12 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
           IPath path = PHPFileUtil.determineFilePath(includeNameString, file, project);
 
           if (path == null) {
-            //              reportSyntaxError("File: " + expression.toStringExpression() + " doesn't exist in project: "
-            //                  + project.getLocation().toString(), literal.sourceStart, literal.sourceEnd);
+            // SyntaxError: "File: << >> doesn't exist in project."
             String[] args = { expression.toStringExpression(), project.getLocation().toString() };
             problemReporter.phpIncludeNotExistWarning(args, literal.sourceStart, literal.sourceEnd, referenceContext,
                 compilationUnit.compilationResult);
           } else {
             try {
-              //              String projectPath = ProjectPrefUtil.getDocumentRoot(file.getProject()).toString();
-              //              String filePath = file.getRawLocation().toString();
               String filePath = path.toString();
               String ext = file.getRawLocation().getFileExtension();
               int fileExtensionLength = ext == null ? 0 : ext.length() + 1;
@@ -3660,7 +3799,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 {
@@ -3765,33 +3904,39 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
         throwSyntaxError("'`' expected at end of static string.");
       }
       break;
-    case TokenNameEncapsedString1:
-      try {
-        scanner.currentCharacter = scanner.source[scanner.currentPosition++];
-        while (scanner.currentCharacter != '\'') {
-          if (scanner.currentCharacter == '\\') {
-            scanner.currentPosition++;
-          }
-          scanner.currentCharacter = scanner.source[scanner.currentPosition++];
-        }
-        getNextToken();
-      } catch (IndexOutOfBoundsException e) {
-        throwSyntaxError("'\'' expected at end of static string.");
-      }
+    //    case TokenNameEncapsedString1:
+    //      try {
+    //        scanner.currentCharacter = scanner.source[scanner.currentPosition++];
+    //        while (scanner.currentCharacter != '\'') {
+    //          if (scanner.currentCharacter == '\\') {
+    //            scanner.currentPosition++;
+    //          }
+    //          scanner.currentCharacter = scanner.source[scanner.currentPosition++];
+    //        }
+    //        getNextToken();
+    //      } catch (IndexOutOfBoundsException e) {
+    //        throwSyntaxError("'\'' expected at end of static string.");
+    //      }
+    //      break;
+    //    case TokenNameEncapsedString2:
+    //      try {
+    //        scanner.currentCharacter = scanner.source[scanner.currentPosition++];
+    //        while (scanner.currentCharacter != '"') {
+    //          if (scanner.currentCharacter == '\\') {
+    //            scanner.currentPosition++;
+    //          }
+    //          scanner.currentCharacter = scanner.source[scanner.currentPosition++];
+    //        }
+    //        getNextToken();
+    //      } catch (IndexOutOfBoundsException e) {
+    //        throwSyntaxError("'\"' expected at end of static string.");
+    //      }
+    //      break;
+    case TokenNameStringSingleQuote:
+      getNextToken();
       break;
-    case TokenNameEncapsedString2:
-      try {
-        scanner.currentCharacter = scanner.source[scanner.currentPosition++];
-        while (scanner.currentCharacter != '"') {
-          if (scanner.currentCharacter == '\\') {
-            scanner.currentPosition++;
-          }
-          scanner.currentCharacter = scanner.source[scanner.currentPosition++];
-        }
-        getNextToken();
-      } catch (IndexOutOfBoundsException e) {
-        throwSyntaxError("'\"' expected at end of static string.");
-      }
+    case TokenNameStringDoubleQuote:
+      getNextToken();
       break;
     case TokenNamePLUS:
       getNextToken();
@@ -3978,6 +4123,8 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
 
   HashMap fMethodVariables = null;
 
+  ArrayList fStackUnassigned = new ArrayList();
+
   //ast stack
   final static int AstStackIncrement = 100;
 
@@ -4345,8 +4492,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++) {
@@ -4482,4 +4628,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