Changeset 2532 for lang/php

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

r260@dhcp158 (orig r3): tasuku | 2007-09-05 19:04:49 +0900
NowNode? ga ugoita !!!


Files:
1 modified

Legend:

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

    r2531 r2532  
    5252class GTNodeList { 
    5353  private $nodes; 
     54  function __construct() { 
     55    $this->nodes = array(); 
     56  } 
    5457  public function render($context) { 
    5558    $bits = array(); 
    56     foreach ($nodes as $node) { 
     59    foreach ($this->nodes as $node) { 
    5760      array_push($bits, $node->render($context)); 
    5861    } 
    5962    return implode('', $bits); 
    6063  } 
     64  public function push($node) { 
     65    array_push($this->nodes, $node); 
     66  } 
    6167} 
    6268 
    6369class GTTextNode extends GTNode { 
     70  private $text; 
     71  function __construct($text) { 
     72    $this->text = $text; 
     73  } 
     74  function render($context) { 
     75    return $text; 
     76  } 
    6477} 
    6578 
     
    89102 
    90103class GTIfNode extends GTNode { 
     104  private $bool_exprs; 
     105  private $nodelist_true; 
     106  private $nodelist_false; 
     107  private $link_type; 
     108 
     109  const LINKTYPE_AND = 0; 
     110  const LINKTYPE_OR  = 1; 
     111 
     112  function __construct($bool_exprs, $nodelist_true, $nodelist_false, $link_type) { 
     113    $this->bool_exprs = $bool_exprs; 
     114    $this->nodelist_true = $nodelist_true; 
     115    $this->nodelist_false = $nodelist_false; 
     116    $this->link_type = $link_type; 
     117  } 
     118  function render($context) { 
     119    if ($this->link_type == self::LINKTYPE_OR) { 
     120      // TODO: ����(resolve) 
     121      return $nodelist_false->render($context); 
     122    } else { // self::LINKTYPE_AND 
     123      // TODO: ����(resolve) 
     124      return $nodelist_true>render($context); 
     125    } 
     126  } 
    91127} 
    92128 
    93129class GTNowNode extends GTNode { 
    94 } 
    95  
    96 class GunyaTemplate { 
     130  private $format_string; 
     131  function __construct($format_string) { 
     132    $this->format_string = $format_string; 
     133  } 
     134  function render($context) { 
     135    return date($this->format_string); 
     136  } 
     137} 
     138 
     139class GTUnknownNode extends GTNode { 
     140  function render($context) { 
     141    return 'unknown...'; 
     142  } 
     143} 
     144 
     145class GTParser { 
    97146  private $template; // �ѡ�����Υƥ�졼����� private $errorStr; // ���顼ʸ�� private $ptemplate; // �ѡ������ƥ�졼��Node��rray) 
    98147 
     
    101150  private $outmode;   // 'a': ���'i': ̵��b': �֥�����ɲ� 
    102151  # template syntax constants 
    103   FILTER_SEPARATOR = '|' 
    104   FILTER_ARGUMENT_SEPARATOR = ':' 
    105   VARIABLE_ATTRIBUTE_SEPARATOR = '.' 
    106   BLOCK_TAG_START = '{%' 
    107   BLOCK_TAG_END = '%}' 
    108   VARIABLE_TAG_START = '{{' 
    109   VARIABLE_TAG_END = '}}' 
    110   COMMENT_TAG_START = '{#' 
    111   COMMENT_TAG_END = '#}' 
    112   SINGLE_BRACE_START = '{' 
    113   SINGLE_BRACE_END = '}' 
    114  
    115   function GunyaTemplate($templatePath) { 
     152  const FILTER_SEPARATOR = '|'; 
     153  const FILTER_ARGUMENT_SEPARATOR = ':'; 
     154  const VARIABLE_ATTRIBUTE_SEPARATOR = '.'; 
     155  const BLOCK_TAG_START = '{%'; 
     156  const BLOCK_TAG_END = '%}'; 
     157  const VARIABLE_TAG_START = '{{'; 
     158  const VARIABLE_TAG_END = '}}'; 
     159  const COMMENT_TAG_START = '{#'; 
     160  const COMMENT_TAG_END = '#}'; 
     161  const SINGLE_BRACE_START = '{'; 
     162  const SINGLE_BRACE_END = '}'; 
     163 
     164  // "��ǥ������Ȥ��줿������ƥ��ڡ�������� // "���"'������ˤϡ�\"\'�Ȥ��롣 
     165  // �ľ�����ɽ���ǽ񤱤Ф褫�ä������ޤ����ä��� 
     166  private function smart_split($text) { 
     167    $epos = strlen($text); 
     168    $ret = array(); 
     169    $mode = 'n';  // 'n': not quoted, 'd': in ", 'q': in ' 
     170    for ($spos = 0; $spos < $epos; $spos++) { 
     171      $a = $text[$spos]; 
     172      switch ($a) { 
     173        case '\\': 
     174          switch ($mode) { 
     175            case 'd': 
     176              if ($text[$spos + 1] == '"') { 
     177                $buf .= '"'; 
     178                $spos += 1; 
     179              } else if ($text[$spos + 1] == '\\') { 
     180                $buf .= '\\'; 
     181                $spos += 1; 
     182              } else { 
     183                $buf .= $a; 
     184              } 
     185              break; 
     186            case 'q': 
     187              if ($text[$spos + 1] == "'") { 
     188                $buf .= "'"; 
     189                $spos += 1; 
     190              } else if ($text[$spos + 1] == '\\') { 
     191                $buf .= '\\'; 
     192                $spos += 1; 
     193              } else { 
     194                $buf .= $a; 
     195              } 
     196              break; 
     197            default: 
     198              $buf .= '\\'; 
     199          } 
     200          break; 
     201        case "'": 
     202          switch ($mode) { 
     203            case 'd': 
     204              $buf .= "'"; 
     205              break; 
     206            case 'q': 
     207              array_push($ret, $buf); 
     208              $mode = 'n'; 
     209              $buf = ''; 
     210              break; 
     211            default: 
     212              if ($buf != '') { 
     213                array_push($ret, $buf); 
     214              } 
     215              $mode = 'q'; 
     216              $buf = ''; 
     217              break; 
     218          } 
     219          break; 
     220        case '"': 
     221          switch ($mode) { 
     222            case 'd': 
     223              array_push($ret, $buf); 
     224              $mode = 'n'; 
     225              $buf = ''; 
     226              break; 
     227            case 'q': 
     228              $buf .= '"'; 
     229              break; 
     230            default: 
     231              if ($buf != '') { 
     232                array_push($ret, $buf); 
     233              } 
     234              $mode = 'd'; 
     235              $buf = ''; 
     236              break; 
     237          } 
     238          break; 
     239        case ' ': 
     240          switch ($mode) { 
     241            case 'd': 
     242            case 'q': 
     243              $buf .= ' '; 
     244              break; 
     245            default: 
     246              if ($buf != '') { 
     247                array_push($ret, $buf); 
     248                $buf = ''; 
     249              } 
     250              break; 
     251          } 
     252          break; 
     253        default: 
     254          $buf .= $a; 
     255          break; 
     256      } 
     257    } 
     258    if ($mode == 'n' && $buf != '') { 
     259      array_push($ret, $buf); 
     260    } 
     261    return $ret; 
    116262  } 
    117263 
     
    119265  private function find_closetag($t, &$spos, $closetag) { 
    120266    if (($epos = strpos($t, $closetag, $spos)) === FALSE) { 
    121       $this->errorStr = "������������Ƥʤ��褦�Ǥ�($closetag�����Ĥ�������" 
     267      $this->errorStr = "������������Ƥʤ��褦�Ǥ�($closetag�����Ĥ�������"; 
    122268      return FALSE; 
    123269    } 
     
    128274  // extends����˽񤫤ʤ��Ȥ����ʤ� 
    129275  private function parse_block(&$spos) { 
    130     $spos += 2 
    131     if (($epos = find_closetag($this->template, $spos, self::BLOCK_TAG_END)) === FALSE) { 
     276    $spos += 2; 
     277    if (($epos = $this->find_closetag($this->template, $spos, self::BLOCK_TAG_END)) 
     278        === FALSE) { 
    132279      return FALSE; 
    133280    } 
    134     $in = trim(substr($this->template, $spos, $epos)); 
     281    $in = $this->smart_split(substr($this->template, $spos, $epos - 2)); 
     282    echo 'inblock: '. $in[0] .'\n'; 
    135283    switch ($in[0]) { 
    136284      case 'extends': 
    137285        // FIXME: �롼�ץ���å� 
    138286        $node = new GTExtendsNode(nodelist, parent_name, parent_name_expr); 
     287        break; 
    139288      case 'include': 
    140289        // FIXME: �롼�ץ���å� 
    141290        $node = new GTIncludeNode(template_name); 
     291        break; 
    142292      case 'block': // endblock 
    143         $node = new GTBlockNode(name, nodelist, parent=None); 
     293        $node = new GTBlockNode(name, nodelist, parent); 
     294        break; 
    144295      case 'for': // endfor 
    145296        $node = new GTForNode(loopvar, sequence, reversed, nodelist_loop); 
     297        break; 
    146298      case 'cycle': 
    147299        $node = new GTCycleNode(cyclevars); 
    148300        // TODO: implement 
     301        break; 
    149302      case 'if': // else, endif 
    150303        $node = new GTIfNode(bool_exprs, nodelist_true, nodelist_false, link_type); 
     304        break; 
    151305      case 'debug': 
    152306        $node = new GTDebugNode(); 
     307        break; 
    153308      case 'now': 
    154         $node = new GTNowNode(format_string); 
     309        var_dump($in); 
     310        if (count($in) != 2) { 
     311          $this->errorStr = 'now�Ͻ����ɬ��Ǥ�'; 
     312          return FALSE; 
     313        } 
     314        $node = new GTNowNode($in[1]); 
     315        break; 
     316      default: 
     317        $node = new GTUnknownNode(); 
     318        break; 
    155319    } 
    156320    $spos = $epos + 2; 
     
    165329  // {{ }}�������� 
    166330  private function parse_variable(&$spos) { 
    167     $spos += 2 
     331    $spos += 2; 
    168332    if (($epos = find_closetag($this->template, $spos, self::VARIABLE_TAG_END)) === FALSE) { 
    169333      return FALSE; 
     
    177341  // {# #}�������� 
    178342  private function parse_comment(&$spos) { 
    179     $spos += 2 
     343    $spos += 2; 
    180344    if (($epos = find_closetag($this->template, $spos, self::COMMENT_TAG_END)) === FALSE) { 
    181345      return FALSE; 
     
    183347    $spos = $epos + 2; // #}�Τ���  } 
    184348 
    185   public function parse($templatePath) { 
    186     if (($t = $file_get_contents($templatePath)) === FALSE) { 
     349  public function parse_from_file($templatePath) { 
     350    if (($t = file_get_contents($templatePath)) === FALSE) { 
    187351      $this->errorStr = '�ե����뤬�����ޤ���; 
    188352      return FALSE; 
    189353    } 
    190     $pos = 0; 
    191  
    192354    $this->template = $t; 
    193  
    194     // �����γ����򸫤Ĥ���   while (($pos = strpos($t, self::SINGLE_BRACE_START, $pos)) !== FALSE) { 
    195       switch (substr($t, pos, 2) { 
    196         case BLOCK_TAG_START: 
    197           if (parse_block($pos) === FALSE) { 
     355    return $this->_parse(0, strlen($t)); 
     356  } 
     357 
     358  public function parse($templateStr) { 
     359    $this->template = $templateStr; 
     360    return $this->_parse(0, strlen($templateStr)); 
     361  } 
     362 
     363  private function _parse($spos, $epos) { 
     364    $nl = new GTNodeList(); 
     365    while ($spos < $epos) { 
     366      // �����γ����򸫤Ĥ���     $nspos = strpos($this->template, self::SINGLE_BRACE_START, $spos); 
     367      if ($nspos === FALSE) { 
     368        $nspos = $epos; 
     369      } 
     370      if ($spos < $nspos) { 
     371        // �����ʳ�����extNode�Ȥ����� 
     372        $nl->push(new GTTextNode(substr($this->template, $spos, $nspos - $spos))); 
     373      } 
     374      switch (substr($this->template, $nspos, 2)) { 
     375        case self::BLOCK_TAG_START: 
     376          if (($node = $this->parse_block($nspos)) === FALSE) { 
    198377            unset($this->template); 
    199378            return FALSE; 
    200379          } 
    201           break; 
    202         case VARIABLE_TAG_START: 
    203           if (parse_variable($pos) === FALSE) { 
     380          $nl->push($node); 
     381          break; 
     382        case self::VARIABLE_TAG_START: 
     383          if (($node = $this->parse_variable($nspos)) === FALSE) { 
    204384            unset($this->template); 
    205385            return FALSE; 
    206386          } 
    207           break; 
    208         case COMMENT_TAG_START: 
    209           if (parse_comment($pos) === FALSE) { 
     387          $nl->push($node); 
     388          break; 
     389        case self::COMMENT_TAG_START: 
     390          if (($node = $this->parse_comment($nspos)) === FALSE) { 
    210391            unset($this->template); 
    211392            return FALSE; 
    212393          } 
     394          $nl->push($node); 
    213395          break; 
    214396        default: 
    215397          // ñ�ʤ��ɤߤȤФ� 
    216           $pos += 1; 
     398          $nspos += 1; 
    217399      } 
    218     } 
    219   } 
     400      $spos = $nspos; 
     401    } 
     402    return $nl; 
     403  } 
     404 
    220405} 
    221406?>