Simplified parsing for double quoted strings
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / parser / Parser.java
index d3e2a3c..fb1b3cc 100644 (file)
@@ -10,7 +10,6 @@ package net.sourceforge.phpdt.internal.compiler.parser;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Stack;
 
 import net.sourceforge.phpdt.core.compiler.CharOperation;
 import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
@@ -195,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);
   }
 
   /**
@@ -310,7 +315,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
    */
   public void parse(String s, HashMap variables) {
     fMethodVariables = variables;
-    fStackUnassigned = new Stack();
+    fStackUnassigned = new ArrayList();
     init(s);
     parse();
   }
@@ -357,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);
 
@@ -418,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;
       }
     }
@@ -474,9 +459,9 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
         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);
+          //          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)
@@ -554,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.");
     }
   }
@@ -723,7 +710,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
       foreach_optional_arg();
       if (token == TokenNameEQUAL_GREATER) {
         getNextToken();
-        variable(false);
+        variable(false, false);
       }
       if (token == TokenNameRPAREN) {
         getNextToken();
@@ -796,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();
@@ -865,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) {
@@ -1129,7 +1129,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
         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) {
@@ -1153,7 +1153,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
     //    unset_variable:
     //                 variable
     while (true) {
-      variable(false);
+      variable(false, false);
       if (token != TokenNameCOMMA) {
         break;
       }
@@ -1427,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) {
@@ -1617,10 +1618,11 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
       }
     }
     try {
-      pushVariableSet();
+      pushFunctionVariableSet();
       functionDeclarator(methodDecl);
       if (token == TokenNameSEMICOLON) {
         if (!isAbstract) {
+          methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1;
           throwSyntaxError("Body declaration expected for method: " + new String(methodDecl.selector));
         }
         getNextToken();
@@ -1628,7 +1630,9 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
       }
       functionBody(methodDecl);
     } finally {
-      fStackUnassigned.pop();
+      if (!fStackUnassigned.isEmpty()) {
+        fStackUnassigned.remove(fStackUnassigned.size() - 1);
+      }
     }
   }
 
@@ -1649,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;
@@ -1662,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'.");
     }
   }
@@ -1810,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);
+      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);
+        }
+      }
     }
-    new_else_single(iState);
     if (token != TokenNameendif) {
       throwSyntaxError("'endif' expected.");
     }
@@ -1832,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) {
@@ -2217,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:
@@ -2278,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());
@@ -2436,17 +2518,28 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
       case TokenNameVariable:
       case TokenNameDOLLAR:
         boolean rememberedVar = false;
-//        char[] lhsVar = null;
-//        if (token==TokenNameVariable) {
-//          lhsVar = scanner.getCurrentTokenSource();
-//        }
-        Expression lhs = variable(true);
+        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 (lhsVar != null) {
-//            addVariableSet(lhsVar);
-//          }
+          if (lhs != null && lhs instanceof FieldReference) {
+            addVariableSet(((FieldReference) lhs).token);
+          }
+          //          if (lhsVar != null) {
+          //            addVariableSet(lhsVar);
+          //          }
           getNextToken();
           if (token == TokenNameAND) {
             getNextToken();
@@ -2470,7 +2563,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
                 }
               }
             } else {
-              Expression rhs = variable(false);
+              Expression rhs = variable(false, false);
               if (rhs != null && rhs instanceof FieldReference && lhs != null && lhs instanceof FieldReference) {
                 // example:
                 // $var = &$ref;
@@ -2533,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;
@@ -2555,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) + "').");
           }
         }
@@ -2759,9 +2858,9 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
     //| T_LIST '(' assignment_list ')'
     //| /* empty */
     if (token == TokenNameVariable) {
-      variable(true);
+      variable(true, false);
     } else if (token == TokenNameDOLLAR) {
-      variable(false);
+      variable(false, false);
     } else {
       if (token == TokenNamelist) {
         getNextToken();
@@ -2802,17 +2901,17 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
     while (true) {
       if (token == TokenNameAND) {
         getNextToken();
-        variable(false);
+        variable(true, false);
       } else {
         expr();
         if (token == TokenNameAND) {
           getNextToken();
-          variable(false);
+          variable(true, false);
         } else if (token == TokenNameEQUAL_GREATER) {
           getNextToken();
           if (token == TokenNameAND) {
             getNextToken();
-            variable(false);
+            variable(true, false);
           } else {
             expr();
           }
@@ -2838,7 +2937,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
   //      }
   //    } while (true);
   //  }
-  private Expression variable_without_objects(boolean lefthandside) {
+  private Expression variable_without_objects(boolean lefthandside, boolean ignoreVar) {
     //  variable_without_objects:
     //                 reference_variable
     //         | simple_indirect_reference reference_variable
@@ -2848,10 +2947,10 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
     while (token == TokenNameDOLLAR) {
       getNextToken();
     }
-    return reference_variable(lefthandside);
+    return reference_variable(lefthandside, ignoreVar);
   }
 
-  private Expression function_call(boolean lefthandside) {
+  private Expression function_call(boolean lefthandside, boolean ignoreVar) {
     //  function_call:
     // T_STRING '(' function_call_parameter_list ')'
     //| class_constant '(' function_call_parameter_list ')'
@@ -2881,12 +2980,12 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
           getNextToken();
         } else {
           //        static member:
-          variable_without_objects(false);
+          variable_without_objects(true, false);
         }
         break;
       }
     } else {
-      ref = variable_without_objects(lefthandside);
+      ref = variable_without_objects(lefthandside, ignoreVar);
     }
     if (token != TokenNameLPAREN) {
       if (defineName != null) {
@@ -2957,7 +3056,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
     while (true) {
       if (token == TokenNameAND) {
         getNextToken();
-        w_variable(false);
+        w_variable(true);
       } else {
         //        if (token == TokenNameIdentifier || token ==
         // TokenNameVariable
@@ -2994,10 +3093,10 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
       throwSyntaxError("'::' expected after class name (static_member).");
     }
     getNextToken();
-    variable_without_objects(false);
+    variable_without_objects(false, false);
   }
 
-  private Expression base_variable_with_function_calls(boolean lefthandside) {
+  private Expression base_variable_with_function_calls(boolean lefthandside, boolean ignoreVar) {
     //  base_variable_with_function_calls:
     // base_variable
     //| function_call
@@ -3019,7 +3118,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
     //      scanner.phpMode = true;
     //    }
     //    if (functionCall) {
-    return function_call(lefthandside);
+    return function_call(lefthandside, ignoreVar);
     //    } else {
     //      base_variable();
     //    }
@@ -3040,7 +3139,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
       while (token == TokenNameDOLLAR) {
         getNextToken();
       }
-      reference_variable(false);
+      reference_variable(false, false);
     }
     return ref;
   }
@@ -3050,7 +3149,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
   //    // '$'
   //    //| simple_indirect_reference '$'
   //  }
-  private Expression reference_variable(boolean lefthandside) {
+  private Expression reference_variable(boolean lefthandside, boolean ignoreVar) {
     //  reference_variable:
     //                 reference_variable '[' dim_offset ']'
     //         | reference_variable '{' expr '}'
@@ -3059,7 +3158,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
     if (Scanner.TRACE) {
       System.out.println("TRACE: reference_variable()");
     }
-    ref = compound_variable(lefthandside);
+    ref = compound_variable(lefthandside, ignoreVar);
     while (true) {
       if (token == TokenNameLBRACE) {
         ref = null;
@@ -3070,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) {
@@ -3087,7 +3190,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
     return ref;
   }
 
-  private Expression compound_variable(boolean lefthandside) {
+  private Expression compound_variable(boolean lefthandside, boolean ignoreVar) {
     //  compound_variable:
     //                 T_VARIABLE
     //         | '$' '{' expr '}'
@@ -3097,13 +3200,16 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
     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);
+          //          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 {
-        addVariableSet();
+        if (!ignoreVar) {
+          addVariableSet();
+        }
       }
       FieldReference ref = new FieldReference(scanner.getCurrentIdentifierSource(), scanner.getCurrentTokenStartPosition());
       getNextToken();
@@ -3125,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();
   //  }
@@ -3141,7 +3244,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
       System.out.println("TRACE: object_property()");
     }
     if (token == TokenNameVariable || token == TokenNameDOLLAR) {
-      variable_without_objects(false);
+      variable_without_objects(false, false);
     } else {
       object_dim_list();
     }
@@ -3207,23 +3310,23 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
   }
 
   private void r_variable() {
-    variable(false);
+    variable(false, false);
   }
 
   private void w_variable(boolean lefthandside) {
-    variable(lefthandside);
+    variable(lefthandside, false);
   }
 
   private void rw_variable() {
-    variable(false);
+    variable(false, false);
   }
 
-  private Expression variable(boolean lefthandside) {
+  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(lefthandside);
+    Expression ref = base_variable_with_function_calls(lefthandside, ignoreVar);
     if (token == TokenNameMINUS_GREATER) {
       ref = null;
       getNextToken();
@@ -3298,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
@@ -3542,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(false);
-      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);
@@ -3694,7 +3797,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
       throwSyntaxError("Variable expected after keyword 'isset'");
     }
     while (true) {
-      variable(false);
+      variable(true, false);
       if (token == TokenNameCOMMA) {
         getNextToken();
       } else {
@@ -3799,33 +3902,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();
@@ -4012,7 +4121,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
 
   HashMap fMethodVariables = null;
 
-  Stack fStackUnassigned = new Stack();
+  ArrayList fStackUnassigned = new ArrayList();
 
   //ast stack
   final static int AstStackIncrement = 100;
@@ -4528,25 +4637,41 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
       "$_POST",
       "$_REQUEST",
       "$_SESSION",
-      "$_SERVER"
-  };
+      "$_SERVER" };
+
   /**
-   * 
+   *  
    */
-  private void pushVariableSet() {
-    HashSet set =new HashSet();
-    for (int i = 0; i < GLOBALS.length; i++) {
-      set.add(GLOBALS[i]);
+  private void pushFunctionVariableSet() {
+    HashSet set = new HashSet();
+    if (fStackUnassigned.isEmpty()) {
+      for (int i = 0; i < GLOBALS.length; i++) {
+        set.add(GLOBALS[i]);
+      }
     }
-    fStackUnassigned.push(set);
+    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.peek();
+      return (HashSet) fStackUnassigned.get(fStackUnassigned.size() - 1);
     }
     return null;
   }
@@ -4590,9 +4715,33 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
    *  
    */
   private boolean containsVariableSet() {
-    HashSet set = peekVariableSet();
-    if (set != null) {
-      return set.contains(new String(scanner.getCurrentTokenSource()));
+    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;
   }