Changeset 2555

Show
Ignore:
Timestamp:
12/06/07 13:17:06 (5 years ago)
Author:
tasuku
Message:

r283@dhcp158 (orig r26): tasuku | 2007-09-08 04:02:49 +0900
nest if/for nankani taiou...!?


Files:
1 modified

Legend:

Unmodified
Added
Removed
  • lang/php/mumu/trunk/GunyaTemplate.php

    r2554 r2555  
    155155    $this->block_dict = $block_dict; 
    156156    if ($parentPath) { 
    157       $p = new GTParser(); 
    158       if (($this->parent_tfile = $p->parse_from_file($parentPath)) === FALSE) { 
     157      if (($this->parent_tfile = GTParser::parse_from_file($parentPath)) === FALSE) { 
    159158        // TODO: ���顼���������ƥ�졼�������˶����Ƥ�����     } 
    160159    } 
     
    224223  function __construct($includePath) { 
    225224    // FIXME: �������ƥ�����å���̵�¥롼�ץ���å� 
    226     $p = new GTParser(); 
    227     if (($this->tplfile = $p->parse_from_file($includePath)) === FALSE) { 
     225    if (($this->tplfile = GTParser::parse_from_file($includePath)) === FALSE) { 
    228226      // TODO: ���顼���������ƥ�졼�������˶����Ƥ�����     $this->tplfile = new GTTextNode('include error'); 
    229227    } 
     
    479477 
    480478class GTParser { 
    481   private $template;             // �ѡ�����Υƥ�졼����� private $errorStr;             // ���顼ʸ�� private $block_dict = array(); // block���� => block�ؤλ���  private $extends = false;      // extends�ξ��Υե����� 
     479  private $template;             // �ѡ�����Υƥ�졼����� private $template_len;         // �ƥ�졼�����Ĺ�� 
     480  private $errorStr;             // ���顼ʸ�� private $block_dict = array(); // block���� => block�ؤλ���  private $extends = false;      // extends�ξ��Υե����� 
    482481 
    483482  # template syntax constants 
     
    497496  function __construct($template) { 
    498497    $this->template = $template; 
     498    $this->template_len = strlen($template); 
    499499  } 
    500500 
     
    598598 
    599599  // ��λ����(#}�Ȥ�)����ơ����ΰ�֤�� 
    600   private function find_closetag(&$spos, &$epos, $closetag) { 
    601     if (($fpos = strpos($this->template, $closetag, $spos)) === FALSE || $fpos >= $epos) { 
     600  private function find_closetag(&$spos, $closetag) { 
     601    if (($fpos = strpos($this->template, $closetag, $spos)) === FALSE) { 
    602602      $this->errorStr = "������������Ƥʤ��褦�Ǥ�($closetag�����Ĥ�������"; 
    603603      return FALSE; 
     
    606606  } 
    607607 
    608   // ľ��else��dblock��dif��dfor��� 
    609   private function find_endtags($spos, &$epos, $endtags) { 
    610     // �ޤ���ľ���֥������ϥ��������    while (($spos = strpos($this->template, self::BLOCK_TAG_START, $spos)) !== FALSE 
    611            && $spos < $epos) { 
    612       $spos += 2; 
    613       if (($lpos = $this->find_closetag($spos, $epos, self::BLOCK_TAG_END)) !== FALSE 
    614           && $lpos < $epos) { 
    615         // �������m���ƥ���å� 
    616         $c = trim(substr($this->template, $spos, $lpos - $spos)); 
    617         if (in_array($c, $endtags)) { 
    618           return array($spos - 2, $lpos + 2, $c); 
    619         } 
    620         $spos = $lpos + 2; 
    621       } 
    622     } 
    623     $this->errorStr = "block/if/for��������Ƥ��ʤ��褦�Ǥ���"; 
    624     return FALSE; 
    625   } 
    626  
    627608  // {% %}�����������ơ�GTNode����� 
    628609  // extends����˽񤫤ʤ��Ȥ����ʤ� 
    629   private function parse_block(&$spos, &$epos) { 
     610  private function parse_block(&$spos) { 
    630611    $spos += 2; 
    631     if (($lpos = $this->find_closetag($spos, $epos, self::BLOCK_TAG_END)) === FALSE) { 
     612    if (($lpos = $this->find_closetag($spos, self::BLOCK_TAG_END)) === FALSE) { 
    632613      return FALSE; 
    633614    } 
     
    673654          return FALSE; 
    674655        } 
    675         $lpos += 2; 
    676         if ((list($bepos, $blpos) = $this->find_endtags($lpos, $epos, array('endblock'))) === FALSE) { 
    677           return FALSE; 
    678         } 
    679         $nodelist = $this->_parse($lpos, $bepos); 
     656        $spos = $lpos + 2; 
     657        list($nodelist) = $this->_parse($spos, array('endblock')); 
    680658        $node = new GTBlockNode($blockname, $nodelist); 
    681659        $this->block_dict[$blockname] = &$node; // reference 
    682         $spos = $blpos; 
    683660        break; 
    684661      case 'for': // endfor 
     
    698675          $reversed = False; 
    699676        } 
    700         $lpos += 2; 
    701         if ((list($bepos, $blpos) = $this->find_endtags($lpos, $epos, array('endfor'))) === FALSE) { 
    702           return FALSE; 
    703         } 
    704         $nodelist = $this->_parse($lpos, $bepos); 
     677        $spos = $lpos + 2; 
     678        list($nodelist) = $this->_parse($spos, array('endfor')); 
    705679        $node = new GTForNode($in[1], $in[3], $reversed, $nodelist); 
    706         $spos = $blpos; 
    707680        break; 
    708681      case 'cycle': 
     
    753726          } 
    754727        } 
    755         $lpos += 2; 
    756         if ((list($bepos, $eblpos, $nexttag) = 
    757                $this->find_endtags($lpos, $epos, array('else', 'endif'))) === FALSE) { 
    758           return FALSE; 
    759         } 
    760         $nodelist_true = $this->_parse($lpos, $bepos); 
     728        $spos = $lpos + 2; 
     729        list($nodelist_true, $nexttag) = 
     730          $this->_parse($spos, array('else', 'endif')); 
    761731        if ($nexttag == 'else') { 
    762           if ((list($bepos, $blpos, $nexttag) = 
    763                     $this->find_endtags($eblpos, $epos, array('endif'))) === FALSE) { 
    764             return FALSE; 
    765           } 
    766           $nodelist_false = $this->_parse($eblpos, $bepos); 
    767           $spos = $blpos; 
     732          list($nodelist_false) = $this->_parse($spos, array('endif')); 
    768733        } else { 
    769734          $nodelist_false = new GTNodeList(); 
    770           $spos = $eblpos; 
    771735        } 
    772736        $node = new GTIfNode($boolvars, $nodelist_true, $nodelist_false, $link_type); 
     
    794758          return FALSE; 
    795759        } 
    796         $lpos += 2; 
    797         if ((list($bepos, $blpos) = $this->find_endtags($lpos, $epos, array('endfilter'))) === FALSE) { 
    798           return FALSE; 
    799         } 
     760        $spos += 2; 
    800761        $filter_expr = new GTFilterExpression('var|'. $in[1]); 
    801         $nodelist = $this->_parse($lpos, $bepos); 
     762        list($nodelist) = $this->_parse($spos, array('endfilter')); 
    802763        $node = new GTFilterNode($filter_expr, $nodelist); 
    803         $spos = $blpos; 
     764        break; 
     765      case 'endblock': 
     766      case 'else': 
     767      case 'endif': 
     768      case 'endfor': 
     769      case 'endfilter': 
     770        $node = $in[0]; // raw string 
     771        $spos = $lpos + 2; 
    804772        break; 
    805773      default: 
     
    811779  } 
    812780 
    813   private function parse_variable(&$spos, &$epos) { 
     781  private function parse_variable(&$spos) { 
    814782    $spos += 2; 
    815     if (($lpos = $this->find_closetag($spos, $epos, self::VARIABLE_TAG_END)) === FALSE) { 
     783    if (($lpos = $this->find_closetag($spos, self::VARIABLE_TAG_END)) === FALSE) { 
    816784      return FALSE; 
    817785    } 
     
    823791  } 
    824792 
    825   private function parse_comment(&$spos, &$epos) { 
     793  private function parse_comment(&$spos) { 
    826794    $spos += 2; 
    827     if (($lpos = $this->find_closetag($spos, $epos, self::COMMENT_TAG_END)) === FALSE) { 
     795    if (($lpos = $this->find_closetag($spos, self::COMMENT_TAG_END)) === FALSE) { 
    828796      return FALSE; 
    829797    } 
     
    837805    } 
    838806    $p = new GTParser($t); 
    839     $nl = $p->_parse(0, strlen($t)); 
     807    $spos = 0; 
     808    list($nl) = $p->_parse($spos, array()); 
    840809    return new GTFile($nl, $p->block_dict, $p->extends); 
    841810  } 
     
    843812  static public function parse($templateStr) { 
    844813    $p = new GTParser($templateStr); 
    845     $nl = $p->_parse(0, strlen($templateStr)); 
     814    $spos = 0; 
     815    list($nl) = $p->_parse($spos, array()); 
    846816    return new GTFile($nl, $p->block_dict); 
    847817  } 
    848818 
    849   private function _parse($spos, $epos) { 
     819  private function add_textnode(&$nodelist, &$tspos, &$epos) { 
     820    if ($tspos < $epos) { 
     821      $nodelist->push(new GTTextNode( 
     822        substr($this->template, $tspos, $epos - $tspos))); 
     823    } 
     824  } 
     825 
     826  private function _parse(&$spos, $parse_until) { 
    850827    $nl = new GTNodeList(); 
    851     while ($spos < $epos) { 
    852       $nspos = strpos($this->template, self::SINGLE_BRACE_START, $spos); 
    853       if ($nspos === FALSE) { 
    854         $nspos = $epos; 
    855       } 
    856       if ($spos < $nspos) { 
    857         // non-tag strings are stored to GTTextNode 
    858         $nl->push(new GTTextNode(substr($this->template, $spos, $nspos - $spos))); 
    859       } 
    860       if ($nspos < $epos) { 
    861         switch (substr($this->template, $nspos, 2)) { 
    862           case self::BLOCK_TAG_START: 
    863             if (($node = $this->parse_block($nspos, $epos)) === FALSE) { 
    864               unset($this->template); 
    865               return FALSE; 
     828    $tspos = $spos; 
     829    while (true) { 
     830      echo "*** spos:$spos tspos:$tspos\n"; 
     831      $spos = strpos($this->template, self::SINGLE_BRACE_START, $spos); 
     832      if ($spos === FALSE) { 
     833        $this->add_textnode($nl, $tspos, $this->template_len); 
     834        return array($nl, null); 
     835      } 
     836      switch (substr($this->template, $spos, 2)) { 
     837        case self::BLOCK_TAG_START: 
     838          $this->add_textnode($nl, $tspos, $spos); 
     839          if (($node = $this->parse_block($spos)) === FALSE) { 
     840            return FALSE; 
     841          } 
     842          $tspos = $spos; 
     843          if (is_string($node)) { 
     844            // close tag 
     845            if (in_array($node, $parse_until)) { 
     846              return array($nl, $node); 
     847            } else { 
     848              // invalid close tag 
    866849            } 
     850          } else { 
    867851            $nl->push($node); 
    868             break; 
    869           case self::VARIABLE_TAG_START: 
    870             if (($node = $this->parse_variable($nspos, $epos)) === FALSE) { 
    871               unset($this->template); 
    872               return FALSE; 
    873             } 
    874             $nl->push($node); 
    875             break; 
    876           case self::COMMENT_TAG_START: 
    877             if (($node = $this->parse_comment($nspos, $epos)) === FALSE) { 
    878               unset($this->template); 
    879               return FALSE; 
    880             } 
    881             $nl->push($node); 
    882             break; 
    883           default: 
    884             // { only 
    885             $nspos += 1; 
    886         } 
    887       } 
    888       $spos = $nspos; 
    889     } 
    890     return $nl; 
     852          } 
     853          break; 
     854        case self::VARIABLE_TAG_START: 
     855          $this->add_textnode($nl, $tspos, $spos); 
     856          if (($node = $this->parse_variable($spos)) === FALSE) { 
     857            return FALSE; 
     858          } 
     859          $nl->push($node); 
     860          $tspos = $spos; 
     861          break; 
     862        case self::COMMENT_TAG_START: 
     863          $this->add_textnode($nl, $tspos, $spos); 
     864          if (($node = $this->parse_comment($spos)) === FALSE) { 
     865            return FALSE; 
     866          } 
     867          $nl->push($node); 
     868          $tspos = $spos; 
     869          break; 
     870        default: 
     871          // { only 
     872          $spos += 1; 
     873      } 
     874    } 
    891875  } 
    892876}