public function advance($parser)
 {
     if ($this->pos >= 0) {
         $type = $this->tokens[$this->pos][0];
         switch ($type) {
             case T_FOR:
             case T_FOREACH:
                 $this->start_loop();
                 break;
             case T_DO:
                 $this->ignoreNextWhile = true;
                 $this->start_loop();
                 break;
             case T_WHILE:
                 if (!$this->ignoreNextWhile) {
                     $this->start_loop();
                 }
                 $this->ignoreNextWhile = false;
                 break;
             case T_SWITCH:
             case T_TRY:
                 $this->start_cond();
                 break;
             case T_IF:
                 if (!$this->lastWasElse) {
                     $this->start_cond();
                 } else {
                     // count the number of "T_ELSE T_IF" because for each of those we get another call
                     // to end_cond()
                     $this->vars->set_elseif();
                 }
                 break;
             case T_ELSEIF:
                 $this->start_cond(true, false);
                 break;
             case T_ELSE:
                 $this->start_cond(true, true);
                 break;
         }
         $this->lastWasElse = $type == T_ELSE;
     }
     $res = parent::advance($parser);
     if ($this->lastComment && $this->lastComment != $this->lastCheckComment) {
         // it was a comment, so lets see if it contains a "@var $<name> <type>" that gives us a
         // hint what type a variable has.
         $matches = array();
         if (preg_match('/\\@var\\s+\\$([a-z0-9_]+)\\s+(\\S+)/i', $this->lastComment, $matches)) {
             // do we know that variable?
             $scopename = $this->scope->get_name();
             if ($this->vars->exists($scopename, $matches[1])) {
                 // ok, determine type and set it
                 $type = PC_Obj_MultiType::get_type_by_name($matches[2]);
                 $var = $this->vars->get($scopename, $matches[1]);
                 $var->set_type($type);
             }
         }
         $this->lastCheckComment = $this->lastComment;
     }
     return $res;
 }
 /**
  * Protected constructor because its a bit ugly (without method-overloading)
  * 
  * @param string $str the file or string
  * @param bool $is_file whether $str is a file
  */
 protected function __construct($str, $is_file)
 {
     if ($is_file) {
         $this->file = $str;
         $str = FWS_FileUtils::read($str);
     }
     $this->tokens = token_get_all($str);
     $this->tokCount = count($this->tokens);
     for ($i = 0; $i < $this->tokCount; $i++) {
         if (!is_array($this->tokens[$i])) {
             $this->tokens[$i] = array(ord($this->tokens[$i]), $this->tokens[$i]);
         }
     }
     $this->pos = -1;
     $this->line = 1;
     self::$T_DOC_COMMENT = defined('T_DOC_COMMENT') ? constant('T_DOC_COMMENT') : 10000;
 }
 public function advance($parser)
 {
     // do it before because if e.g. after a class-declaration follows immediatly another one
     // we would get this token here BEFORE the class-declaration is handled in our parser
     // therefore we check it for the previous token
     if ($this->pos >= 0) {
         $type = $this->tokens[$this->pos][0];
         if ($type == T_CLASS || $type == T_INTERFACE) {
             $this->lastClassLine = $this->get_line();
         } else {
             if ($type == T_FUNCTION) {
                 $this->lastFunctionLine = $this->get_line();
                 // save the last comment for this function so that we don't loose it
                 $this->funcComments[$this->get_name_for_comment()] = $this->lastComment;
                 $this->lastComment = '';
             } else {
                 if ($type == T_CONST) {
                     $this->constComments[$this->get_name_for_comment()] = $this->lastComment;
                     $this->lastComment = '';
                 } else {
                     if ($type == T_VAR || $type == T_PUBLIC || $type == T_PRIVATE || $type == T_PROTECTED) {
                         // save the last comment for this field so that we don't loose it
                         for ($i = $this->pos + 1; $i < $this->tokCount; $i++) {
                             // seems that this was no field..
                             if ($this->tokens[$i][0] == T_FUNCTION) {
                                 break;
                             }
                             if ($this->tokens[$i][0] == T_VARIABLE) {
                                 $this->fieldComments[substr($this->tokens[$i][1], 1)] = $this->lastComment;
                                 $this->lastComment = '';
                                 break;
                             }
                         }
                     }
                 }
             }
         }
     }
     return parent::advance($parser);
 }