PhpDocumentor
[ class tree: PhpDocumentor ] [ index: PhpDocumentor ] [ all elements ]

Source for file Lexer.inc

Documentation is available at Lexer.inc

  1. <?php
  2. define('PHPDOC_LEXER_DESC'1);
  3. define('PHPDOC_LEXER_TAGS'2);
  4. define('PHPDOC_LEXER_ESCTAG'3);
  5. define('PHPDOC_LEXER_INLINETAG'4);
  6. define('PHPDOC_LEXER_INTERNAL'5);
  7. define('PHPDOC_LEXER_INTERNALTAG'6);
  8. define('PHPDOC_LEXER_SIMPLELIST'7);
  9. define('PHPDOC_DOCBLOCK_TOKEN_NEWLINE'1);
  10. define('PHPDOC_DOCBLOCK_TOKEN_DESC'2);
  11. define('PHPDOC_DOCBLOCK_TOKEN_ESCTAGOPEN'3);
  12. define('PHPDOC_DOCBLOCK_TOKEN_ESCTAGCLOSE'4);
  13. define('PHPDOC_DOCBLOCK_TOKEN_TAG'5);
  14. define('PHPDOC_DOCBLOCK_TOKEN_INLINETAG'6);
  15. define('PHPDOC_DOCBLOCK_TOKEN_INLINETAGCLOSE'7);
  16. define('PHPDOC_DOCBLOCK_TOKEN_INTERNAL'8);
  17. define('PHPDOC_DOCBLOCK_TOKEN_INTERNALCLOSE'9);
  18. define('PHPDOC_DOCBLOCK_TOKEN_HTMLTAG'10);
  19. define('PHPDOC_DOCBLOCK_TOKEN_HTMLTAGCLOSE'11);
  20. define('PHPDOC_DOCBLOCK_TOKEN_SIMPLELISTSTART'12);
  21. define('PHPDOC_DOCBLOCK_TOKEN_SIMPLELISTEND'13);
  22. define('PHPDOC_DOCBLOCK_TOKEN_UNORDEREDBULLET'14);
  23. define('PHPDOC_DOCBLOCK_TOKEN_ORDEREDBULLET'15);
  24. class PhpDocumentor_DocBlock_Lexer
  25. {
  26.     var $processedline;
  27.     var $tagStack = array();
  28.     var $tokens = array();
  29.     var $simplelist = array();
  30.     var $whitespace = array();
  31.     var $states = array(PHPDOC_LEXER_DESC);
  32.     function tokenName($token)
  33.     {
  34.         $this->tokens = array(
  35.             PHPDOC_DOCBLOCK_TOKEN_NEWLINE => 'PHPDOC_DOCBLOCK_TOKEN_NEWLINE',
  36.             PHPDOC_DOCBLOCK_TOKEN_DESC => 'PHPDOC_DOCBLOCK_TOKEN_DESC',
  37.             PHPDOC_DOCBLOCK_TOKEN_ESCTAGOPEN => 'PHPDOC_DOCBLOCK_TOKEN_ESCTAGOPEN',
  38.             PHPDOC_DOCBLOCK_TOKEN_ESCTAGCLOSE => 'PHPDOC_DOCBLOCK_TOKEN_ESCTAGCLOSE',
  39.             PHPDOC_DOCBLOCK_TOKEN_TAG => 'PHPDOC_DOCBLOCK_TOKEN_TAG',
  40.             PHPDOC_DOCBLOCK_TOKEN_INLINETAG => 'PHPDOC_DOCBLOCK_TOKEN_INLINETAG',
  41.             PHPDOC_DOCBLOCK_TOKEN_INLINETAGCLOSE => 'PHPDOC_DOCBLOCK_TOKEN_INLINETAGCLOSE',
  42.             PHPDOC_DOCBLOCK_TOKEN_INTERNAL => 'PHPDOC_DOCBLOCK_TOKEN_INTERNAL',
  43.             PHPDOC_DOCBLOCK_TOKEN_INTERNALCLOSE => 'PHPDOC_DOCBLOCK_TOKEN_INTERNALCLOSE',
  44.         );
  45.         if (in_array($tokenarray_keys($this->tokens))) {
  46.             return $this->tokens[$token];
  47.         }
  48.         return 'UNKNOWN';
  49.     }
  50.  
  51.     function lex($comment)
  52.     {
  53.         $comment str_replace(array("\r\n""\r")array("\n""\n")$comment);
  54.         $comment explode("\n"$comment);
  55.         $this->tokens = array();
  56.         $state PHPDOC_LEXER_DESC;
  57.         $this->states = array(PHPDOC_LEXER_DESC);
  58.         $tid = 0;
  59.         $token '';
  60.         $esctag = false;
  61.         $this->exception = false;
  62.         list($lastline,each(array_reverse($commenttrue));
  63.         foreach ($comment as $this->linenum => $line{
  64.             if ($this->exception{
  65.                 $this->tokens = array();
  66.                 return false;
  67.             }
  68.             $linestart = true;
  69.             $this->processedline trim($line);
  70.             if ($this->processedline == '*/'{
  71.                 break;
  72.             }
  73.             if (!$this->processedline{
  74.                 continue;
  75.             }
  76.             if (substr($this->processedline03== '/**'{
  77.                 $this->processedline substr($this->processedline3);
  78.                 if (!$this->processedline{
  79.                     continue;
  80.                 }
  81.                 if (trim($this->processedline== '*/'{
  82.                     $this->endSimpleList();
  83.                     break;
  84.                 }
  85.             else {
  86.                 $this->processedline substr($this->processedline1);
  87.             }
  88.             while (true{
  89.                 switch ($state{
  90.                     case PHPDOC_LEXER_INTERNALTAG :
  91.                         $internalendpos strpos($this->processedline'}}');
  92.                     case PHPDOC_LEXER_TAGS :
  93.                         $trimline trim($this->processedline);
  94.                         if (strlen($trimline&& $trimline{0== '@'{
  95.                             if (preg_match('/^(@[^\s]+)\s/'$trimline$matches||
  96.                                   preg_match('/^(@[^\s]+)$/'$trimline$matches)) {
  97.                                 $this->tokens[= array(PHPDOC_DOCBLOCK_TOKEN_TAG,
  98.                                     $matches[1]);
  99.                                 $this->processedline substr($trimlinestrpos($trimline$matches[1]+
  100.                                     strlen($matches[1]));
  101.                                 if (!$this->processedline{
  102.                                     break 2;
  103.                                 }
  104.                                 continue 2; // to while(true)
  105.                             }
  106.                         elseif (preg_match('/^@/'$trimline$matches)) {
  107.                             // throw exception for invalid tag
  108.                             return $this->throwException('Invalid tag encountered in line number ' .
  109.                                 $this->linenum ': "' $line '"''tag');
  110.                         else {
  111.                             $tagpos strpos($this->processedline'<');
  112.                             $inlinetagpos strpos($this->processedline'{@');
  113.                             if (isset($internalendpos&& $internalendpos !== false{
  114.                                 do {
  115.                                     if ($tagpos !== false && $internalendpos $tagpos{
  116.                                         break;
  117.                                     }
  118.                                     if ($inlinetagpos !== false && $internalendpos $inlinetagpos{
  119.                                         break;
  120.                                     }
  121.                                     // }} is the next important token
  122.                                     $this->appendDesc(substr($this->processedline0,
  123.                                         $internalendpos));
  124.                                     $this->tokens[= array(PHPDOC_DOCBLOCK_TOKEN_INTERNALCLOSE'}}');
  125.                                     $this->processedline substr($this->processedline$internalendpos
  126.                                         + 2);
  127.                                     array_shift($this->states);
  128.                                     $state PHPDOC_LEXER_TAGS;
  129.                                     continue 3; // to while(true);
  130.                                 while (false);
  131.                             }
  132.                             if ($tagpos !== false && $inlinetagpos !== false{
  133.                                 if ($tagpos $inlinetagpos{
  134.                                     $tagpos = false;
  135.                                 else {
  136.                                     $inlinetagpos = false;
  137.                                 }
  138.                             }
  139.                             if ($tagpos !== false{
  140.                                 continue $this->searchForHTMLTag($tagpos,
  141.                                     $state$esctag$linestart$trimline);
  142.                             }
  143.                             if ($inlinetagpos !== false{
  144.                                 $state $this->searchForInlineTag($inlinetagpos$comment);
  145.                                 $linestart = false;
  146.                                 continue 2; // to while (true)
  147.                             }
  148.                             if (strpos($this->processedline'*/')) {
  149.                                 $this->tokens[= array(PHPDOC_DOCBLOCK_TOKEN_DESC,
  150.                                     substr($this->processedline,
  151.                                     0strpos($this->processedline'*/')));
  152.                                 return $this->tokens;
  153.                             }
  154.                             $this->tokens[= array(PHPDOC_DOCBLOCK_TOKEN_DESC$this->processedline);
  155.                         }
  156.                     break;
  157.                     case PHPDOC_LEXER_INTERNAL :
  158.                         $internalendpos strpos($this->processedline'}}');
  159.                     case PHPDOC_LEXER_SIMPLELIST :
  160.                         if ($linestart && $state == PHPDOC_LEXER_SIMPLELIST{
  161.                             if (!$this->processSimpleList()) {
  162.                                 while (count($this->simplelist&& !$this->processSimpleList());
  163.                             }
  164.                             if (!count($this->simplelist)) {
  165.                                 array_shift($this->states);
  166.                                 $state array_shift($this->states);
  167.                                 array_unshift($this->states$state);
  168.                             }
  169.                         }
  170.                     case PHPDOC_LEXER_DESC :
  171.                         if (strpos($this->processedline'*/')) {
  172.                             $this->processedline substr($this->processedline,
  173.                                 0strpos($this->processedline'*/'));
  174.                         }
  175.                         if (!$this->processedline{
  176.                             if ($this->linenum != $lastline{
  177.                                 $this->tokens[= array(PHPDOC_DOCBLOCK_TOKEN_NEWLINE"\n");
  178.                             }
  179.                             continue 3; // to foreach
  180.                         }
  181.                         $trimline trim($this->processedline);
  182.                         if ($linestart && $state != PHPDOC_LEXER_TAGS && $trimline{0== '@'{
  183.                             if ($state == PHPDOC_LEXER_INTERNAL{
  184.                                 // throw exception
  185.                                 return $this->throwException('Cannot start tags in {@internal}} ' .
  186.                                     ' in line number ' .
  187.                                     $this->linenum ': "' $line '"''tag');
  188.                             }
  189.                             $this->states = array(PHPDOC_LEXER_TAGS);
  190.                             $state PHPDOC_LEXER_TAGS;
  191.                             continue 2; // to while(true)
  192.  
  193.                         }
  194.                         if ($state != PHPDOC_LEXER_SIMPLELIST && $linestart && strlen($trimline> 3 &&
  195.                              ($trimline{0== '-' || $trimline{0== '*' ||
  196.                               $trimline{0== '#' || $trimline{0== 'o' ||
  197.                               $trimline{0== '1')) {
  198.                             if ($this->searchForSimplelist($trimline)) {
  199.                                 $state PHPDOC_LEXER_SIMPLELIST;
  200.                                 $linestart = false;
  201.                                 continue 2; // to while(true)
  202.                             }
  203.                         }
  204.                         $tagpos strpos($this->processedline'<');
  205.                         $inlinetagpos strpos($this->processedline'{@');
  206.                         if (isset($internalendpos&& $internalendpos !== false{
  207.                             do {
  208.                                 if ($tagpos !== false && $internalendpos $tagpos{
  209.                                     break;
  210.                                 }
  211.                                 if ($inlinetagpos !== false && $internalendpos $inlinetagpos{
  212.                                     break;
  213.                                 }
  214.                                 // }} is the next important token
  215.                                 $this->appendDesc(substr($this->processedline0$internalendpos));
  216.                                 $this->tokens[= array(PHPDOC_DOCBLOCK_TOKEN_INTERNALCLOSE'}}');
  217.                                 $this->processedline substr($this->processedline$internalendpos
  218.                                     + 2);
  219.                                 array_shift($this->states);
  220.                                 $state PHPDOC_LEXER_DESC;
  221.                                 continue 3; // to while(true);
  222.                             while (false);
  223.                         }
  224.                         if ($tagpos !== false && $inlinetagpos !== false{
  225.                             if ($tagpos $inlinetagpos{
  226.                                 $tagpos = false;
  227.                             else {
  228.                                 $inlinetagpos = false;
  229.                             }
  230.                         }
  231.                         if ($tagpos !== false{
  232.                             continue $this->searchForHTMLTag($tagpos$state,
  233.                                 $esctag$linestart$trimline);
  234.                         }
  235.                         if ($inlinetagpos !== false{
  236.                             $state $this->searchForInlineTag($inlinetagpos$comment);
  237.                             $linestart = false;
  238.                             continue 2; // to while (true)
  239.                         }
  240.                         $this->appendDesc($this->processedline);
  241.                     break;
  242.                     case PHPDOC_LEXER_ESCTAG :
  243.                         if (!$this->processedline{
  244.                             if ($this->linenum != $lastline{
  245.                                 $this->tokens[= array(PHPDOC_DOCBLOCK_TOKEN_NEWLINE"\n");
  246.                             }
  247.                             continue 3; // to foreach
  248.                         }
  249.                         $endpos strpos($this->processedline$esctag);
  250.                         $inlinetagpos strpos($this->processedline'{@');
  251.                         if ($endpos !== false && $inlinetagpos !== false{
  252.                             if ($endpos $inlinetagpos{
  253.                                 $endpos = false;
  254.                             else {
  255.                                 $inlinetagpos = false;
  256.                             }
  257.                         }
  258.                         if ($endpos !== false{
  259.                             if (strlen(substr($this->processedline0$endpos))) {
  260.                                 $this->appendDesc(substr($this->processedline0$endpos));
  261.                             }
  262.                             $this->tokens[= array(PHPDOC_DOCBLOCK_TOKEN_ESCTAGCLOSE$esctag);
  263.                             $this->processedline substr($this->processedline$endpos +
  264.                                 strlen($esctag));
  265.                             $state $this->states[0];
  266.                             if (count($this->states> 1{
  267.                                 array_shift($this->states);
  268.                             }
  269.                             if (!$this->processedline{
  270.                                 break 2;
  271.                             }
  272.                         }
  273.                         if ($inlinetagpos !== false{
  274.                             array_unshift($this->statesPHPDOC_LEXER_ESCTAG);
  275.                             $state $this->searchForInlineTag($inlinetagpos$comment);
  276.                             $linestart = false;
  277.                             continue 2; // to while (true)
  278.                         }
  279.                         $this->appendDesc($this->processedline);
  280.                     break;
  281.                     case PHPDOC_LEXER_INLINETAG :
  282.                         if (!$this->processedline{
  283.                             if ($this->linenum != $lastline{
  284.                                 $this->tokens[= array(PHPDOC_DOCBLOCK_TOKEN_NEWLINE"\n");
  285.                             }
  286.                             continue 3; // to foreach
  287.                         }
  288.                         $endpos strpos($this->processedline'}');
  289.                         if ($endpos !== false{
  290.                             if (strlen(substr($this->processedline0$endpos))) {
  291.                                 $this->appendDesc(substr($this->processedline0$endpos));
  292.                             }
  293.                             $this->tokens[= array(PHPDOC_DOCBLOCK_TOKEN_INLINETAGCLOSE'}');
  294.                             $this->processedline substr($this->processedline$endpos + 1)// strlen('}')
  295.                             $state $this->states[0];
  296.                             if (count($this->states> 1{
  297.                                 array_shift($this->states);
  298.                             }
  299.                             if (!$this->processedline{
  300.                                 break 2;
  301.                             }
  302.                             if ($state != PHPDOC_LEXER_INLINETAG && strlen($this->processedline)) {
  303.                                 $linestart = false;
  304.                                 continue 2; // to while (true)
  305.                             }
  306.                         }
  307.                         $this->appendDesc($this->processedline);
  308.                     break;
  309.                 }
  310.                 break;
  311.             }
  312.             if ($this->linenum != $lastline{
  313.                 $this->tokens[= array(PHPDOC_DOCBLOCK_TOKEN_NEWLINE"\n");
  314.             }
  315.         }
  316.         return $this->tokens;
  317.     }
  318.  
  319.     function searchForSimplelist($trimline)
  320.     {
  321.         $whitespace strpos($this->processedline$trimline);
  322.         switch ($trimline{0}{
  323.             case '-' :
  324.             case '*' :
  325.             case '+' :
  326.             case 'o' :
  327.                 if (strlen($trimline< 3 || $trimline{1!= ' '{
  328.                     return false;
  329.                 }
  330.                 // unordered lists
  331.                 $this->simplelist['u' $trimline{0};
  332.                 $this->whitespace[$whitespace;
  333.                 $this->tokens[= array(PHPDOC_DOCBLOCK_TOKEN_SIMPLELISTSTART'');
  334.                 $this->tokens[= array(PHPDOC_DOCBLOCK_TOKEN_UNORDEREDBULLET$trimline{0});
  335.                 $this->processedline substr($this->processedlinestrpos($this->processedline,
  336.                     $trimline{0}+ 2);
  337.                 array_unshift($this->statesPHPDOC_LEXER_SIMPLELIST);
  338.                 return true;
  339.             break;
  340.             case '#' :
  341.                 if (strlen($trimline< 3{
  342.                     return false;
  343.                 }
  344.                 // ordered lists
  345.                 $this->simplelist['#1';
  346.                 $this->whitespace[$whitespace;
  347.                 $this->tokens[= array(PHPDOC_DOCBLOCK_TOKEN_SIMPLELISTSTART'');
  348.                 $this->tokens[= array(PHPDOC_DOCBLOCK_TOKEN_ORDEREDBULLET'#');
  349.                 $this->processedline substr($this->processedlinestrpos($this->processedline,
  350.                     '#'+ 2);
  351.                 array_unshift($this->statesPHPDOC_LEXER_SIMPLELIST);
  352.                 return true;
  353.             case '1' :
  354.                 if (strlen($trimline< 4{
  355.                     return false;
  356.                 }
  357.                 if ($trimline{1== ' '{
  358.                     $this->simplelist['O1';
  359.                 elseif ($trimline{1== '.' && $trimline{2== ' '{
  360.                     $this->simplelist['o1';
  361.                 else {
  362.                     return false;
  363.                 }
  364.                 $this->whitespace[$whitespace;
  365.                 $this->tokens[= array(PHPDOC_DOCBLOCK_TOKEN_SIMPLELISTSTART'');
  366.                 if ($trimline{1== '.'{
  367.                     $this->tokens[= array(PHPDOC_DOCBLOCK_TOKEN_ORDEREDBULLET'1.');
  368.                     $this->processedline substr($this->processedlinestrpos($this->processedline,
  369.                         '1.'+ 3);
  370.                 else {
  371.                     $this->tokens[= array(PHPDOC_DOCBLOCK_TOKEN_ORDEREDBULLET'1');
  372.                     $this->processedline substr($this->processedlinestrpos($this->processedline,
  373.                         '1'+ 2);
  374.                 }
  375.                 array_unshift($this->statesPHPDOC_LEXER_SIMPLELIST);
  376.                 return true;
  377.         }
  378.         return false;
  379.     }
  380.  
  381.     /**
  382.      * @todo process multi-line elements via whitespace
  383.      * @todo process nested simple lists
  384.      */
  385.     function processSimpleList()
  386.     {
  387.         $trimline trim($this->processedline);
  388.         $index count($this->simplelist- 1;
  389.         $whitespace strpos($this->processedline$trimline);
  390.         if ($whitespace $this->whitespace[$index]{
  391.             while (count($this->whitespace[$index]&& $whitespace $this->whitespace[$index]{
  392.                 // the end of the current simplelist
  393.                 $this->tokens = array(PHPDOC_DOCBLOCK_TOKEN_SIMPLELISTEND'');
  394.                 array_pop($this->simplelist);
  395.                 $index--;
  396.             }
  397.             if ($index == -1{
  398.                 return false; // all simple lists concluded
  399.             }
  400.         }
  401.         if ($whitespace $this->whitespace[$index]{
  402.             // could be a multi-line element or a new list
  403.             if (!$this->searchForSimplelist($trimline)) {
  404.                 // trim off the simple list whitespace if this is multi-line
  405.                 $this->processedline substr($this->processedline$this->whitespace[$index+ 2);
  406.             }
  407.             return true;
  408.         }
  409.         // implied: whitespace matches exactly so this is either another
  410.         // bullet point or the end of the simple list
  411.         switch ($this->simplelist[$index]{0}{
  412.             case 'u' :
  413.                 if (strlen($trimline< 3 || $trimline{0!= $this->simplelist[$index]{1||
  414.                       $trimline{1!= ' '{
  415.                     $this->tokens[= array(PHPDOC_DOCBLOCK_TOKEN_SIMPLELISTEND'');
  416.                     array_pop($this->simplelist);
  417.                     return false;
  418.                 }
  419.                 $this->tokens[= array(PHPDOC_DOCBLOCK_TOKEN_UNORDEREDBULLET$trimline{0});
  420.                 $this->processedline substr($this->processedlinestrpos($this->processedline,
  421.                     $trimline{0}+ 2);
  422.             break;
  423.             case 'o' :
  424.                 if (strlen($trimline< 4 || ($trimline{0!=
  425.                       ($this->simplelist[$index]{1+ 1''||
  426.                       $trimline{1!= '.' || $trimline{2!= ' '{
  427.                     $this->tokens[= array(PHPDOC_DOCBLOCK_TOKEN_SIMPLELISTEND'');
  428.                     array_pop($this->simplelist);
  429.                     return false;
  430.                 }
  431.                 $this->simplelist[$index$this->simplelist[$index]{0.
  432.                     ($this->simplelist[$index]{1+ 1);
  433.                 $this->tokens[= array(PHPDOC_DOCBLOCK_TOKEN_ORDEREDBULLET,
  434.                     $this->simplelist[$index]{1'.');
  435.                 $this->processedline substr($this->processedlinestrpos($this->processedline,
  436.                     $trimline{0'.'+ 3);
  437.             break;
  438.             case 'O' :
  439.                 if (strlen($trimline< 3 || $trimline{0!= ($this->simplelist[$index]{1+ 1'' ||
  440.                       $trimline{1!= ' '{
  441.                     $this->tokens[= array(PHPDOC_DOCBLOCK_TOKEN_SIMPLELISTEND'');
  442.                     array_pop($this->simplelist);
  443.                     return false;
  444.                 }
  445.                 $this->simplelist[$index$this->simplelist[$index]{0.
  446.                     ($this->simplelist[$index]{1+ 1);
  447.                 $this->tokens[= array(PHPDOC_DOCBLOCK_TOKEN_ORDEREDBULLET,
  448.                     $this->simplelist[$index]{1});
  449.                 $this->processedline substr($this->processedlinestrpos($this->processedline,
  450.                     $this->simplelist[$index]{1}+ 2);
  451.             break;
  452.             case '#' :
  453.                 if (strlen($trimline< 3 || $trimline{0!= '#' ||
  454.                       $trimline{1!= ' '{
  455.                     $this->tokens[= array(PHPDOC_DOCBLOCK_TOKEN_SIMPLELISTEND'');
  456.                     array_pop($this->simplelist);
  457.                     return false;
  458.                 }
  459.                 $this->simplelist[$index$this->simplelist[$index]{0.
  460.                     ($this->simplelist[$index]{1+ 1);
  461.                 $this->tokens[= array(PHPDOC_DOCBLOCK_TOKEN_ORDEREDBULLET,
  462.                     $this->simplelist[$index]{1});
  463.                 $this->processedline substr($this->processedlinestrpos($this->processedline,
  464.                     '#'+ 2);
  465.             break;
  466.         }
  467.         return true;
  468.     }
  469.  
  470.     function searchForHTMLTag($tagpos&$state&$esctag&$linestart,
  471.                               &$trimline)
  472.     {
  473.         if (preg_match('/^<(<\/?[a-zA-Z]+ ?\/?>)>/'substr($this->processedline$tagpos),
  474.               $matches)) {
  475.             if ($tagpos{
  476.                 $this->appendDesc(substr($this->processedline0$tagpos));
  477.             }
  478.             $this->appendDesc($matches[1]);
  479.             $this->processedline substr($this->processedline$tagpos
  480.                 + strlen($matches[1])
  481.                 + 2);
  482.             return 2;
  483.         elseif (!count($matches&&
  484.               preg_match('/^<(<\/?[a-zA-Z]+ ?\/?>)>/'substr($this->processedline$tagpos + 1),
  485.               $matches)) {
  486.             if ($tagpos{
  487.                 $this->appendDesc(substr($this->processedline0$tagpos));
  488.             }
  489.             $this->appendDesc('<' $matches[1]);
  490.             $this->processedline substr($this->processedline$tagpos
  491.                 + strlen($matches[1])
  492.                 + 3);
  493.             return 2;
  494.         elseif (preg_match('#^(br>|br/>|br />)#',
  495.               substr($this->processedline$tagpos + 1)$matches)) {
  496.             if ($tagpos{
  497.                 $this->appendDesc(substr($this->processedline0$tagpos));
  498.             }
  499.             $this->tokens[= array(PHPDOC_DOCBLOCK_TOKEN_HTMLTAG'br');
  500.             $this->tokens[= array(PHPDOC_DOCBLOCK_TOKEN_HTMLTAGCLOSE'br');
  501.             $this->processedline substr($this->processedline$tagpos
  502.                 + strlen($matches[1])
  503.                 + 1);
  504.             return 2;
  505.         elseif (preg_match('/^(b>|i>|li>|ol>|ul>|p>|pre>|var>)/',
  506.               substr($this->processedline$tagpos + 1)$matches)) {
  507.             if ($tagpos{
  508.                 $this->appendDesc(substr($this->processedline0$tagpos));
  509.             }
  510.             $matches substr($matches[1]0strlen($matches[1]- 1);
  511.             array_push($this->tagStack$matches);
  512.             $this->tokens[= array(PHPDOC_DOCBLOCK_TOKEN_HTMLTAG$matches);
  513.             $this->processedline substr($this->processedline$tagpos
  514.                 + strlen($matches)
  515.                 + 2);
  516.             return 2;
  517.         elseif (preg_match('#^(/b>|/i>|/li>|/ol>|/ul>|/p>|/pre>|/var>)#',
  518.               substr($this->processedline$tagpos + 1)$matches)) {
  519.             if ($tagpos{
  520.                 $this->appendDesc(substr($this->processedline0$tagpos));
  521.             }
  522.             $matches substr($matches[1]1strlen($matches[1]- 2);
  523.             $test array_pop($this->tagStack);
  524.             if ($matches != $test{
  525.                 // throw exception
  526.                 $this->throwException('Invalid closing html tag encountered in line number ' .
  527.                     $this->linenum ': "</' $matches '>", expecting "</' $test '>"''htmltag');
  528.                 return 3;
  529.             }
  530.             $this->tokens[= array(PHPDOC_DOCBLOCK_TOKEN_HTMLTAGCLOSE$matches);
  531.             $this->processedline substr($this->processedline$tagpos
  532.                 + strlen($matches)
  533.                 + 3);
  534.             return 2;
  535.         elseif (preg_match('/^(code>|pre>|kbd>|samp>)/',
  536.               substr($this->processedline$tagpos + 1)$matches)) {
  537.             $esctag '</' $matches[0];
  538.             if ($tagpos{
  539.                 $this->appendDesc(substr($this->processedline0$tagpos));
  540.             }
  541.             switch ($matches[0]{
  542.                 case 'code>' :
  543.                     $this->tokens[= array(PHPDOC_DOCBLOCK_TOKEN_ESCTAGOPEN,
  544.                         '<code>');
  545.                 break;
  546.                 case 'pre>' :
  547.                     $this->tokens[= array(PHPDOC_DOCBLOCK_TOKEN_ESCTAGOPEN,
  548.                         '<pre>');
  549.                 break;
  550.                 case 'kbd>' :
  551.                     $this->tokens[= array(PHPDOC_DOCBLOCK_TOKEN_ESCTAGOPEN,
  552.                         '<kbd>');
  553.                 break;
  554.                 case 'samp>' :
  555.                     $this->tokens[= array(PHPDOC_DOCBLOCK_TOKEN_ESCTAGOPEN,
  556.                         '<samp>');
  557.                 break;
  558.             }
  559.             $this->processedline $line substr($this->processedline$tagpos
  560.                 + strlen($matches[0])
  561.                 + 1);
  562.             $state PHPDOC_LEXER_ESCTAG;
  563.             if (!$this->processedline{
  564.                 return 3; // to foreach
  565.             }
  566.             if (strpos($this->processedline$esctag!== false{
  567.                 if (!strpos($this->processedline$esctag)) {
  568.                     $linestart = false;
  569.                     return 2; // to while (true)
  570.                 }
  571.                 if (strpos($this->processedline$esctag)) {
  572.                     $this->appendDesc(substr($this->processedline0,
  573.                         strpos($this->processedline$esctag)));
  574.                 }
  575.                 $this->processedline $trimline =
  576.                     substr($this->processedlinestrpos($this->processedline$esctag));
  577.                 $linestart = false;
  578.                 return 2; // to while(true)
  579.             }
  580.         }
  581.     }
  582.  
  583.     function searchForInlineTag($inlinetagpos$comment)
  584.     {
  585.         if ($inlinetagpos{
  586.             $this->appendDesc(substr($this->processedline0$inlinetagpos));
  587.         }
  588.         if ($inlinetagpos === strpos($this->processedline'{@internal')) {
  589.             $state array_shift($this->states);
  590.             array_unshift($this->states$state);
  591.             if ($state == PHPDOC_LEXER_INTERNAL || $state == PHPDOC_LEXER_INTERNALTAG{
  592.                 // throw exception
  593.                 return $this->throwException('cannot nest {@internal}} in line number ' .
  594.                     $this->linenum ': "' $line '"''internaltag');
  595.             }
  596.             $basestate array_pop($this->states);
  597.             array_push($this->states$basestate);
  598.             if ($basestate == PHPDOC_LEXER_DESC{
  599.                 $newstate PHPDOC_LEXER_INTERNAL;
  600.             else {
  601.                 $newstate PHPDOC_LEXER_INTERNALTAG;
  602.             }
  603.             array_unshift($this->states$newstate);
  604.             $this->tokens[= array(PHPDOC_DOCBLOCK_TOKEN_INTERNAL'{@internal');
  605.             $this->processedline substr($this->processedline$inlinetagpos strlen('{@internal'));
  606.             return $newstate;
  607.         }
  608.         if (!preg_match('/^({@[^}\s]+)\s/'substr($this->processedline$inlinetagpos)$matches)) {
  609.             if (!preg_match('/^({@[^}\s]+)}/'substr($this->processedline$inlinetagpos)$matches)) {
  610.                 if ($this->hasEndchar($comment'}')) {
  611.                     $matches = array(substr($this->processedline$inlinetagpos),
  612.                         substr($this->processedline$inlinetagpos));
  613.                 else {
  614.                     // throw exception if this does not match
  615.                     $this->throwException('Unclosed inline tag encountered on line number ' .
  616.                         $this->linenum ': "' $line '"''tag');
  617.                     return PHPDOC_LEXER_DESC;
  618.                 }
  619.             else {
  620.                 // throw exception if this does not match
  621.                 $this->throwException('Invalid inline tag encountered in line number ' .
  622.                     $this->linenum ': "' $line '"''tag');
  623.                 return PHPDOC_LEXER_DESC;
  624.             }
  625.         }
  626.         $this->tokens[= array(PHPDOC_DOCBLOCK_TOKEN_INLINETAG$matches[1]);
  627.         $this->processedline substr($this->processedline$inlinetagpos strlen($matches[1]));
  628.         return PHPDOC_LEXER_INLINETAG;
  629.     }
  630.  
  631.     function appendDesc($desc)
  632.     {
  633.         if (!strlen($desc)) {
  634.             return;
  635.         }
  636.         if (count($this->tokens)) {
  637.             $last array_pop($this->tokens);
  638.             if ($last[0== PHPDOC_DOCBLOCK_TOKEN_DESC{
  639.                 $last[1.= $desc;
  640.                 $this->tokens[$last;
  641.             else {
  642.                 $this->tokens[$last;
  643.                 $this->tokens[= array(PHPDOC_DOCBLOCK_TOKEN_DESC$desc);
  644.             }
  645.         else {
  646.             $this->tokens[= array(PHPDOC_DOCBLOCK_TOKEN_DESC$desc);
  647.         }
  648.     }
  649.  
  650.     function hasEndChar($comment$char)
  651.     {
  652.         $linenum $this->linenum;
  653.         foreach ($comment as $num => $line{
  654.             if ($linenum !== false && $num <= $linenum{
  655.                 continue;
  656.             }
  657.             $linenum = false;
  658.             $processedline trim($line);
  659.             if ($processedline == '*/'{
  660.                 break;
  661.             }
  662.             if (!$processedline{
  663.                 continue;
  664.             }
  665.             if (substr($processedline03== '/**'{
  666.                 $processedline substr($processedline3);
  667.                 if (!$processedline{
  668.                     continue;
  669.                 }
  670.                 if (trim($processedline== '*/'{
  671.                     break;
  672.                 }
  673.             else {
  674.                 $processedline substr($processedline1);
  675.             }
  676.             if (strpos($processedline$char!== false{
  677.                 return true;
  678.             }
  679.         }
  680.         return false;
  681.     }
  682.  
  683.     function endSimpleList()
  684.     {
  685.         if (count($this->tagStack)) {
  686.             $this->tokens = array();
  687.             return $this->throwException('Error: unclosed html tags: "' .
  688.                 implode(', '$this->tagStack'"''simplelist');
  689.         }
  690.         while (count($this->simplelist)) {
  691.             $this->tokens[= array(PHPDOC_DOCBLOCK_TOKEN_SIMPLELISTEND'');
  692.         }
  693.     }
  694.  
  695.     function throwException($message$type)
  696.     {
  697.         $this->error = array($message$this->linenum$type);
  698.         $this->exception = true;
  699.     }
  700. }
  701. ?>

Documentation generated on Mon, 11 Mar 2019 15:08:16 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.