Changeset 2564

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

r292@dhcp158 (orig r35): tasuku | 2007-09-11 15:43:49 +0900
spos pass


Files:
1 modified

Legend:

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

    r2563 r2564  
    6363// block.super         : �ƥƥ�졼�Ȥ�lock��������������ä��������� 
    6464 
    65 // ����/ find_endtags�ϸ��Ĥ����parse�⤷�ơ�$sposư�����Ƥ⤤���󤸤����� 
    66 // FIXME�����褦�ˡ� 
     65// ����/ FIXME�����褦�ˡ� 
    6766// �������嵡���Ȥ�������͡��ѡ����Ѥߤι�¤�򥷥ꥢ�饤�����롩 
    6867 
     
    149148class MuErrorNode extends MuNode { 
    150149  private $errorCode; 
     150  private $filename; 
     151  private $linenumber; 
    151152  // TODO: php5 don't support array as const 
    152153  private static $errorMsg = array( 
     
    177178    'unknown' => 'Unknown error. Maybe bugs in MuMu' 
    178179  ); 
    179   function __construct($errorCode) { 
     180  function __construct($errorCode, $filename, $linenumber) { 
    180181    if (array_key_exists($errorCode, self::$errorMsg)) { 
    181182      $this->errorCode = $errorCode; 
     
    183184      $this->errorCode = 'unknown'; 
    184185    } 
     186    $this->filename = $filename; 
     187    $this->linenumber = $linenumber; 
    185188  } 
    186189  public function _render($context) { 
    187     return self::$errorMsg[$this->errorCode]; 
     190    return 'file: '. $this->filename .' line: '. $this->linenumber .' '. 
     191           self::$errorMsg[$this->errorCode]; 
    188192  } 
    189193} 
     
    198202    if ($parentPath) { 
    199203      if (($this->parent_tfile = MuParser::parse_from_file($parentPath)) === FALSE) { 
    200         // TODO: ���顼���������ƥ�졼�������˶����Ƥ�����       return new MuErrorNode('invalidfilename_extends'); 
     204        // TODO: ���顼���������ƥ�졼�������˶����Ƥ�����       return $this->make_errornode('invalidfilename_extends'); 
    201205      } 
    202206    } 
     
    267271    // FIXME: �������ƥ�����å���̵�¥롼�ץ���å� 
    268272    if (($this->tplfile = MuParser::parse_from_file($includePath)) === FALSE) { 
    269       // TODO: ���顼���������ƥ�졼�������˶����Ƥ�����     $this->tplfile = new MuErrorNode('invalidfilename_include'); 
     273      // TODO: ���顼���������ƥ�졼�������˶����Ƥ�����     $this->tplfile = $this->make_errornode('invalidfilename_include'); 
    270274    } 
    271275  } 
     
    536540class MuParser { 
    537541  private $template;             // �ѡ�����Υƥ�졼����� private $template_len;         // �ƥ�졼�����Ĺ�� 
     542  public $templatePath;         // �ƥ�졼�ȤΥѥ�(����) 
    538543  private $block_dict = array(); // block���� => block�ؤλ���  private $extends = false;      // extends�ξ��Υե����� 
    539  
     544  private $spos = 0;             // ���ߥѡ�����ΰ�� 
    540545  # template syntax constants 
    541546  const FILTER_SEPARATOR = '|'; 
     
    656661 
    657662  // ��λ����(#}�Ȥ�)����ơ����ΰ�֤�� 
    658   private function find_closetag($spos, $closetag) { 
    659     if (($fpos = strpos($this->template, $closetag, $spos)) === FALSE) { 
     663  private function find_closetag($closetag) { 
     664    if (($fpos = strpos($this->template, $closetag, $this->spos)) === FALSE) { 
    660665      return FALSE; 
    661666    } 
    662667    return $fpos; 
     668  } 
     669 
     670  private function make_errornode($errorCode) { 
     671    // from $spos to linenumber 
     672    // TODO: count on parsing 
     673    $c = substr($this->template, 0, $this->spos); 
     674    $ln = 0; 
     675    for ($i = 0; $i < $this->spos; $i++) { 
     676      switch ($c[$i]) { 
     677        case "\r": 
     678          if ($c[$i + 1] == "\n") { 
     679            $i++; 
     680          } 
     681          $ln++; 
     682          break; 
     683        case "\n": 
     684          $ln++; 
     685          break; 
     686      } 
     687    } 
     688    return new MuErrorNode($errorCode, $this->templatePath, $ln); 
    663689  } 
    664690 
    665691  // {% %}�����������ơ�MuNode����� 
    666692  // extends����˽񤫤ʤ��Ȥ����ʤ� 
    667   private function parse_block(&$spos) { 
    668     $spos += 2; 
    669     if (($lpos = $this->find_closetag($spos, self::BLOCK_TAG_END)) === FALSE) { 
    670       return new MuErrorNode('without_closetag_tag'); 
    671     } 
    672     $in = $this->smart_split(substr($this->template, $spos, $lpos - $spos)); 
     693  private function parse_block() { 
     694    $this->spos += 2; 
     695    if (($lpos = $this->find_closetag(self::BLOCK_TAG_END)) === FALSE) { 
     696      return $this->make_errornode('without_closetag_tag'); 
     697    } 
     698    $in = $this->smart_split(substr($this->template, $this->spos, $lpos - $this->spos)); 
    673699    switch ($in[0]) { 
    674700      // TODO: ������å����      case 'extends': 
    675701        if ($this->extends !== FALSE) { 
    676           return new MuErrorNode('multiple_extends_tag'); 
     702          return $this->make_errornode('multiple_extends_tag'); 
    677703        } 
    678704        if (count($in) != 2) { 
    679           return new MuErrorNode('numofparam_extends_tag'); 
     705          return $this->make_errornode('numofparam_extends_tag'); 
    680706        } 
    681707        $param = explode('"', $in[1]); 
    682708        if (count($param) != 3) { 
    683           // Django��ѿ�K����ɤ�          return new MuErrorNode('invalidparam_extends_tag'); 
     709          // Django��ѿ�K����ɤ�          return $this->make_errornode('invalidparam_extends_tag'); 
    684710        } 
    685711        $this->extends = $param[1]; 
    686         $spos = $lpos + 2; 
     712        $this->spos = $lpos + 2; 
    687713        break; 
    688714      case 'include': 
    689715        if (count($in) != 2) { 
    690           return new MuErrorNode('numofparam_include_tag'); 
     716          return $this->make_errornode('numofparam_include_tag'); 
    691717        } 
    692718        $param = explode('"', $in[1]); 
    693719        if (count($param) != 3) { 
    694           // Django��ѿ�K����ɤ�          return new MuErrorNode('invalidparam_include_tag'); 
     720          // Django��ѿ�K����ɤ�          return $this->make_errornode('invalidparam_include_tag'); 
    695721        } 
    696722        $node = new MuIncludeNode($param[1]); 
    697         $spos = $lpos + 2; 
     723        $this->spos = $lpos + 2; 
    698724        break; 
    699725      case 'block': // endblock 
     
    702728        $blockname = $in[1]; 
    703729        if (array_key_exists($blockname, $this->block_dict)) { 
    704           return new MuErrorNode('multiple_block_tag'); 
    705         } 
    706         $spos = $lpos + 2; 
    707         list($nodelist) = $this->_parse($spos, array('endblock')); 
     730          return $this->make_errornode('multiple_block_tag'); 
     731        } 
     732        $this->spos = $lpos + 2; 
     733        list($nodelist) = $this->_parse(array('endblock')); 
    708734        $node = new MuBlockNode($blockname, $nodelist); 
    709735        $this->block_dict[$blockname] = $node; 
     
    712738        // $in[1] = $loopvar, $in[2] = 'in', $in[3] = $sequence, $in[4] = 'reversed' 
    713739        if ((count($in) != 4 && count($in) != 5) || $in[2] != 'in') { 
    714           return new MuErrorNode('numofparam_for_tag'); 
     740          return $this->make_errornode('numofparam_for_tag'); 
    715741        } 
    716742        if (count($in) == 5) { 
     
    718744            $reversed = True; 
    719745          } else { 
    720             return new MuErrorNode('invalidparam_for_tag'); 
     746            return $this->make_errornode('invalidparam_for_tag'); 
    721747          } 
    722748        } else { 
    723749          $reversed = False; 
    724750        } 
    725         $spos = $lpos + 2; 
    726         list($nodelist) = $this->_parse($spos, array('endfor')); 
     751        $this->spos = $lpos + 2; 
     752        list($nodelist) = $this->_parse(array('endfor')); 
    727753        $node = new MuForNode($in[1], $in[3], $reversed, $nodelist); 
    728754        break; 
     
    730756        // TODO: implement namedCycleNodes 
    731757        if (count($in) != 2) { 
    732           return new MuErrorNode('numofparam_cycle_tag'); 
     758          return $this->make_errornode('numofparam_cycle_tag'); 
    733759        } 
    734760        $cyclevars = explode(',', $in[1]); 
    735761        if (count($cyclevars) == 0) { 
    736           return new MuErrorNode('invalidparam_cycle_tag'); 
     762          return $this->make_errornode('invalidparam_cycle_tag'); 
    737763        } 
    738764        $node = new MuCycleNode($cyclevars); 
    739         $spos = $lpos + 2; 
     765        $this->spos = $lpos + 2; 
    740766        break; 
    741767      case 'if': // else, endif 
    742768        array_shift($in); 
    743769        if (count($in) < 1) { 
    744           return new MuErrorNode('numofparam_if_tag'); 
     770          return $this->make_errornode('numofparam_if_tag'); 
    745771        } 
    746772        $bitstr = implode(' ', $in); 
     
    753779          $link_type = MuIfNode::LINKTYPE_AND; 
    754780          if (in_array(' or ', $bitstr)) { 
    755             return new MuErrorNode('andormixed_if_tag'); 
     781            return $this->make_errornode('andormixed_if_tag'); 
    756782          } 
    757783        } 
     
    762788            list($not, $boolvar) = explode(' ', $boolpair); 
    763789            if ($not != 'not') { 
    764               return new MuErrorNode('invalidparam_if_tag'); 
     790              return $this->make_errornode('invalidparam_if_tag'); 
    765791            } 
    766792            array_push($boolvars, array(True, $boolvar)); 
     
    769795          } 
    770796        } 
    771         $spos = $lpos + 2; 
     797        $this->spos = $lpos + 2; 
    772798        list($nodelist_true, $nexttag) = 
    773           $this->_parse($spos, array('else', 'endif')); 
     799          $this->_parse(array('else', 'endif')); 
    774800        if ($nexttag == 'else') { 
    775           list($nodelist_false) = $this->_parse($spos, array('endif')); 
     801          list($nodelist_false) = $this->_parse(array('endif')); 
    776802        } else { 
    777803          $nodelist_false = new MuNodeList(); 
     
    781807      case 'debug': 
    782808        $node = new MuDebugNode(); 
    783         $spos = $lpos + 2; 
     809        $this->spos = $lpos + 2; 
    784810        break; 
    785811      case 'now': 
    786812        if (count($in) != 2) { 
    787           return new MuErrorNode('numofparam_now_tag'); 
     813          return $this->make_errornode('numofparam_now_tag'); 
    788814        } 
    789815        $param = explode('"', $in[1]); 
    790816        if (count($param) != 3) { 
    791           return new MuErrorNode('invalidparam_now_tag'); 
     817          return $this->make_errornode('invalidparam_now_tag'); 
    792818        } 
    793819        $node = new MuNowNode($param[1]); 
    794         $spos = $lpos + 2; 
     820        $this->spos = $lpos + 2; 
    795821        break; 
    796822      case 'filter': // endfilter 
    797823        if (count($in) != 2) { 
    798           return new MuErrorNode('numofparam_filter_tag'); 
    799         } 
    800         $spos = $lpos + 2; 
     824          return $this->make_errornode('numofparam_filter_tag'); 
     825        } 
     826        $this->spos = $lpos + 2; 
    801827        if (($filter_expr = new MuFilterExpression('var|'. $in[1])) === FALSE) { 
    802           return new MuErrorNode('invalidparam_filter_tag'); 
    803         } 
    804         list($nodelist) = $this->_parse($spos, array('endfilter')); 
     828          return $this->make_errornode('invalidparam_filter_tag'); 
     829        } 
     830        list($nodelist) = $this->_parse(array('endfilter')); 
    805831        $node = new MuFilterNode($filter_expr, $nodelist); 
    806832        break; 
     
    811837      case 'endfilter': 
    812838        $node = $in[0]; // raw string 
    813         $spos = $lpos + 2; 
     839        $this->spos = $lpos + 2; 
    814840        break; 
    815841      default: 
    816         $node = new MuErrorNode('unknown_tag'); 
    817         echo $in[0]; 
    818         $spos = $lpos + 2; 
     842        $node = $this->make_errornode('unknown_tag'); 
     843        $this->spos = $lpos + 2; 
    819844        break; 
    820845    } 
     
    822847  } 
    823848 
    824   private function parse_variable(&$spos) { 
    825     $spos += 2; 
    826     if (($lpos = $this->find_closetag($spos, self::VARIABLE_TAG_END)) === FALSE) { 
     849  private function parse_variable() { 
     850    $this->spos += 2; 
     851    if (($lpos = $this->find_closetag(self::VARIABLE_TAG_END)) === FALSE) { 
     852      echo "uhyohyo\n"; 
    827853      return FALSE; 
    828854    } 
    829855    // TODO: handle empty {{ }} 
    830856    if (($fil = new MuFilterExpression( 
    831                   substr($this->template, $spos, $lpos - $spos))) === FALSE) { 
    832       return new MuErrorNode('invalidparam_filter_variable'); 
     857                  substr($this->template, $this->spos, $lpos - $this->spos))) === FALSE) { 
     858      return $this->make_errornode('invalidparam_filter_variable'); 
    833859    } 
    834860    $node = new MuVariableNode($fil); 
    835     $spos = $lpos + 2; 
     861    $this->spos = $lpos + 2; 
    836862    return $node; 
    837863  } 
    838864 
    839   private function parse_comment(&$spos) { 
    840     $spos += 2; 
    841     if (($lpos = $this->find_closetag($spos, self::COMMENT_TAG_END)) === FALSE) { 
     865  private function parse_comment() { 
     866    $this->spos += 2; 
     867    if (($lpos = $this->find_closetag(self::COMMENT_TAG_END)) === FALSE) { 
    842868      return FALSE; 
    843869    } 
    844     $spos = $lpos + 2; 
     870    $this->spos = $lpos + 2; 
    845871  } 
    846872 
     
    850876    } 
    851877    $p = new MuParser($t); 
    852     $spos = 0; 
    853     list($nl) = $p->_parse($spos, array()); 
     878    $p->templatePath = $templatePath; 
     879    list($nl) = $p->_parse(array()); 
    854880    return new MuFile($nl, $p->block_dict, $p->extends); 
    855881  } 
     
    857883  static public function parse($templateStr) { 
    858884    $p = new MuParser($templateStr); 
    859     $spos = 0; 
    860     list($nl) = $p->_parse($spos, array()); 
     885    list($nl) = $p->_parse(array()); 
    861886    return new MuFile($nl, $p->block_dict); 
    862887  } 
     
    869894  } 
    870895 
    871   private function _parse(&$spos, $parse_until) { 
     896  private function _parse($parse_until) { 
    872897    $nl = new MuNodeList(); 
    873     $tspos = $spos; 
     898    $tspos = $this->spos; 
    874899    while (true) { 
    875       $spos = strpos($this->template, self::SINGLE_BRACE_START, $spos); 
    876       if ($spos === FALSE) { 
     900      $this->spos = strpos($this->template, self::SINGLE_BRACE_START, $this->spos); 
     901      if ($this->spos === FALSE) { 
     902        $this->spos = $this->template_len; 
    877903        $this->add_textnode($nl, $tspos, $this->template_len); 
    878904        return array($nl, null); 
    879905      } 
    880       switch (substr($this->template, $spos, 2)) { 
     906      switch (substr($this->template, $this->spos, 2)) { 
    881907        case self::BLOCK_TAG_START: 
    882           $this->add_textnode($nl, $tspos, $spos); 
    883           if (($node = $this->parse_block($spos)) === FALSE) { 
     908          $this->add_textnode($nl, $tspos, $this->spos); 
     909          if (($node = $this->parse_block()) === FALSE) { 
    884910            return FALSE; 
    885911          } 
    886           $tspos = $spos; 
     912          $tspos = $this->spos; 
    887913          if (is_string($node)) { 
    888914            // close tag 
     
    897923          break; 
    898924        case self::VARIABLE_TAG_START: 
    899           $this->add_textnode($nl, $tspos, $spos); 
    900           if (($node = $this->parse_variable($spos)) === FALSE) { 
     925          $this->add_textnode($nl, $tspos, $this->spos); 
     926          if (($node = $this->parse_variable()) === FALSE) { 
    901927            return FALSE; 
    902928          } 
    903929          $nl->push($node); 
    904           $tspos = $spos; 
     930          $tspos = $this->spos; 
    905931          break; 
    906932        case self::COMMENT_TAG_START: 
    907           $this->add_textnode($nl, $tspos, $spos); 
    908           if (($node = $this->parse_comment($spos)) === FALSE) { 
     933          $this->add_textnode($nl, $tspos, $this->spos); 
     934          if (($node = $this->parse_comment()) === FALSE) { 
    909935            return FALSE; 
    910936          } 
    911937          $nl->push($node); 
    912           $tspos = $spos; 
     938          $tspos = $this->spos; 
    913939          break; 
    914940        default: 
    915941          // { only 
    916           $spos += 1; 
     942          $this->spos += 1; 
    917943      } 
    918944    }