Source for file Lexer.inc
Documentation is available at Lexer.inc
define('PHPDOC_LEXER_DESC', 1 );
define('PHPDOC_LEXER_TAGS', 2 );
define('PHPDOC_LEXER_ESCTAG', 3 );
define('PHPDOC_LEXER_INLINETAG', 4 );
define('PHPDOC_LEXER_INTERNAL', 5 );
define('PHPDOC_LEXER_INTERNALTAG', 6 );
define('PHPDOC_LEXER_SIMPLELIST', 7 );
define('PHPDOC_DOCBLOCK_TOKEN_NEWLINE', 1 );
define('PHPDOC_DOCBLOCK_TOKEN_DESC', 2 );
define('PHPDOC_DOCBLOCK_TOKEN_ESCTAGOPEN', 3 );
define('PHPDOC_DOCBLOCK_TOKEN_ESCTAGCLOSE', 4 );
define('PHPDOC_DOCBLOCK_TOKEN_TAG', 5 );
define('PHPDOC_DOCBLOCK_TOKEN_INLINETAG', 6 );
define('PHPDOC_DOCBLOCK_TOKEN_INLINETAGCLOSE', 7 );
define('PHPDOC_DOCBLOCK_TOKEN_INTERNAL', 8 );
define('PHPDOC_DOCBLOCK_TOKEN_INTERNALCLOSE', 9 );
define('PHPDOC_DOCBLOCK_TOKEN_HTMLTAG', 10 );
define('PHPDOC_DOCBLOCK_TOKEN_HTMLTAGCLOSE', 11 );
define('PHPDOC_DOCBLOCK_TOKEN_SIMPLELISTSTART', 12 );
define('PHPDOC_DOCBLOCK_TOKEN_SIMPLELISTEND', 13 );
define('PHPDOC_DOCBLOCK_TOKEN_UNORDEREDBULLET', 14 );
define('PHPDOC_DOCBLOCK_TOKEN_ORDEREDBULLET', 15 );
class PhpDocumentor_DocBlock_Lexer
var $simplelist = array ();
var $whitespace = array ();
var $states = array (PHPDOC_LEXER_DESC );
function tokenName ($token)
return $this->tokens[$token];
$comment = str_replace(array ("\r\n", "\r"), array ("\n", "\n"), $comment);
$comment = explode("\n", $comment);
$this->exception = false;
foreach ($comment as $this->linenum => $line) {
$this->processedline = trim($line);
if ($this->processedline == '*/') {
if (!$this->processedline) {
if (substr($this->processedline, 0 , 3 ) == '/**') {
$this->processedline = substr($this->processedline, 3 );
if (!$this->processedline) {
if (trim($this->processedline) == '*/') {
$this->processedline = substr($this->processedline, 1 );
$internalendpos = strpos($this->processedline, '}}');
$trimline = trim($this->processedline);
if (strlen($trimline) && $trimline{0 } == '@') {
if (preg_match('/^(@[^\s]+)\s/', $trimline, $matches) ||
preg_match('/^(@[^\s]+)$/', $trimline, $matches)) {
$this->processedline = substr($trimline, strpos($trimline, $matches[1 ]) +
if (!$this->processedline) {
continue 2; // to while(true)
} elseif (preg_match('/^@/', $trimline, $matches)) {
// throw exception for invalid tag
return $this->throwException ('Invalid tag encountered in line number ' .
$this->linenum . ': "' . $line . '"', 'tag');
$tagpos = strpos($this->processedline, '<');
$inlinetagpos = strpos($this->processedline, '{@');
if (isset ($internalendpos) && $internalendpos !== false ) {
if ($tagpos !== false && $internalendpos > $tagpos) {
if ($inlinetagpos !== false && $internalendpos > $inlinetagpos) {
// }} is the next important token
$this->appendDesc (substr($this->processedline, 0 ,
$this->processedline = substr($this->processedline, $internalendpos
continue 3; // to while(true);
if ($tagpos !== false && $inlinetagpos !== false ) {
if ($tagpos > $inlinetagpos) {
continue $this->searchForHTMLTag ($tagpos,
$state, $esctag, $linestart, $trimline);
if ($inlinetagpos !== false ) {
$state = $this->searchForInlineTag ($inlinetagpos, $comment);
continue 2; // to while (true)
if (strpos($this->processedline, '*/')) {
0 , strpos($this->processedline, '*/')));
$internalendpos = strpos($this->processedline, '}}');
if (!$this->processSimpleList ()) {
while (count($this->simplelist) && !$this->processSimpleList ());
if (!count($this->simplelist)) {
if (strpos($this->processedline, '*/')) {
$this->processedline = substr($this->processedline,
0 , strpos($this->processedline, '*/'));
if (!$this->processedline) {
if ($this->linenum != $lastline) {
continue 3; // to foreach
$trimline = trim($this->processedline);
return $this->throwException ('Cannot start tags in {@internal}} ' .
$this->linenum . ': "' . $line . '"', 'tag');
continue 2; // to while(true)
($trimline{0 } == '-' || $trimline{0 } == '*' ||
$trimline{0 } == '#' || $trimline{0 } == 'o' ||
if ($this->searchForSimplelist ($trimline)) {
continue 2; // to while(true)
$tagpos = strpos($this->processedline, '<');
$inlinetagpos = strpos($this->processedline, '{@');
if (isset ($internalendpos) && $internalendpos !== false ) {
if ($tagpos !== false && $internalendpos > $tagpos) {
if ($inlinetagpos !== false && $internalendpos > $inlinetagpos) {
// }} is the next important token
$this->appendDesc (substr($this->processedline, 0 , $internalendpos));
$this->processedline = substr($this->processedline, $internalendpos
continue 3; // to while(true);
if ($tagpos !== false && $inlinetagpos !== false ) {
if ($tagpos > $inlinetagpos) {
continue $this->searchForHTMLTag ($tagpos, $state,
$esctag, $linestart, $trimline);
if ($inlinetagpos !== false ) {
$state = $this->searchForInlineTag ($inlinetagpos, $comment);
continue 2; // to while (true)
$this->appendDesc ($this->processedline);
if (!$this->processedline) {
if ($this->linenum != $lastline) {
continue 3; // to foreach
$endpos = strpos($this->processedline, $esctag);
$inlinetagpos = strpos($this->processedline, '{@');
if ($endpos !== false && $inlinetagpos !== false ) {
if ($endpos > $inlinetagpos) {
$this->appendDesc (substr($this->processedline, 0 , $endpos));
$this->processedline = substr($this->processedline, $endpos +
$state = $this->states[0 ];
if (count($this->states) > 1 ) {
if (!$this->processedline) {
if ($inlinetagpos !== false ) {
$state = $this->searchForInlineTag ($inlinetagpos, $comment);
continue 2; // to while (true)
$this->appendDesc ($this->processedline);
if (!$this->processedline) {
if ($this->linenum != $lastline) {
continue 3; // to foreach
$endpos = strpos($this->processedline, '}');
$this->appendDesc (substr($this->processedline, 0 , $endpos));
$this->processedline = substr($this->processedline, $endpos + 1 ); // strlen('}')
$state = $this->states[0 ];
if (count($this->states) > 1 ) {
if (!$this->processedline) {
continue 2; // to while (true)
$this->appendDesc ($this->processedline);
if ($this->linenum != $lastline) {
function searchForSimplelist ($trimline)
$whitespace = strpos($this->processedline, $trimline);
if (strlen($trimline) < 3 || $trimline{1 } != ' ') {
$this->simplelist[] = 'u' . $trimline{0 };
$this->whitespace[] = $whitespace;
$this->processedline = substr($this->processedline, strpos($this->processedline,
$this->simplelist[] = '#1';
$this->whitespace[] = $whitespace;
$this->processedline = substr($this->processedline, strpos($this->processedline,
if ($trimline{1 } == ' ') {
$this->simplelist[] = 'O1';
} elseif ($trimline{1 } == '.' && $trimline{2 } == ' ') {
$this->simplelist[] = 'o1';
$this->whitespace[] = $whitespace;
if ($trimline{1 } == '.') {
$this->processedline = substr($this->processedline, strpos($this->processedline,
$this->processedline = substr($this->processedline, strpos($this->processedline,
* @todo process multi-line elements via whitespace
* @todo process nested simple lists
function processSimpleList ()
$trimline = trim($this->processedline);
$index = count($this->simplelist) - 1;
$whitespace = strpos($this->processedline, $trimline);
if ($whitespace < $this->whitespace[$index]) {
while (count($this->whitespace[$index]) && $whitespace < $this->whitespace[$index]) {
// the end of the current simplelist
return false; // all simple lists concluded
if ($whitespace > $this->whitespace[$index]) {
// could be a multi-line element or a new list
if (!$this->searchForSimplelist ($trimline)) {
// trim off the simple list whitespace if this is multi-line
$this->processedline = substr($this->processedline, $this->whitespace[$index] + 2 );
// implied: whitespace matches exactly so this is either another
// bullet point or the end of the simple list
switch ($this->simplelist[$index]{0 }) {
if (strlen($trimline) < 3 || $trimline{0 } != $this->simplelist[$index]{1 } ||
$this->processedline = substr($this->processedline, strpos($this->processedline,
if (strlen($trimline) < 4 || ($trimline{0 } !=
($this->simplelist[$index]{1 } + 1 ) . '') ||
$trimline{1 } != '.' || $trimline{2 } != ' ') {
$this->simplelist[$index] = $this->simplelist[$index]{0 } .
($this->simplelist[$index]{1 } + 1 );
$this->simplelist[$index]{1 } . '.');
$this->processedline = substr($this->processedline, strpos($this->processedline,
$trimline{0 } . '.') + 3 );
if (strlen($trimline) < 3 || $trimline{0 } != ($this->simplelist[$index]{1 } + 1 ) . '' ||
$this->simplelist[$index] = $this->simplelist[$index]{0 } .
($this->simplelist[$index]{1 } + 1 );
$this->simplelist[$index]{1 });
$this->processedline = substr($this->processedline, strpos($this->processedline,
$this->simplelist[$index]{1 }) + 2 );
if (strlen($trimline) < 3 || $trimline{0 } != '#' ||
$this->simplelist[$index] = $this->simplelist[$index]{0 } .
($this->simplelist[$index]{1 } + 1 );
$this->simplelist[$index]{1 });
$this->processedline = substr($this->processedline, strpos($this->processedline,
function searchForHTMLTag ($tagpos, &$state, &$esctag, &$linestart,
if (preg_match('/^<(<\/?[a-zA-Z]+ ?\/?>)>/', substr($this->processedline, $tagpos),
$this->appendDesc (substr($this->processedline, 0 , $tagpos));
$this->appendDesc ($matches[1 ]);
$this->processedline = substr($this->processedline, $tagpos
} elseif (!count($matches) &&
preg_match('/^<(<\/?[a-zA-Z]+ ?\/?>)>/', substr($this->processedline, $tagpos + 1 ),
$this->appendDesc (substr($this->processedline, 0 , $tagpos));
$this->appendDesc ('<' . $matches[1 ]);
$this->processedline = substr($this->processedline, $tagpos
substr($this->processedline, $tagpos + 1 ), $matches)) {
$this->appendDesc (substr($this->processedline, 0 , $tagpos));
$this->processedline = substr($this->processedline, $tagpos
} elseif (preg_match('/^(b>|i>|li>|ol>|ul>|p>|pre>|var>)/',
substr($this->processedline, $tagpos + 1 ), $matches)) {
$this->appendDesc (substr($this->processedline, 0 , $tagpos));
$this->processedline = substr($this->processedline, $tagpos
} elseif (preg_match('#^(/b>|/i>|/li>|/ol>|/ul>|/p>|/pre>|/var>)#',
substr($this->processedline, $tagpos + 1 ), $matches)) {
$this->appendDesc (substr($this->processedline, 0 , $tagpos));
$this->throwException ('Invalid closing html tag encountered in line number ' .
$this->linenum . ': "</' . $matches . '>", expecting "</' . $test . '>"', 'htmltag');
$this->processedline = substr($this->processedline, $tagpos
} elseif (preg_match('/^(code>|pre>|kbd>|samp>)/',
substr($this->processedline, $tagpos + 1 ), $matches)) {
$esctag = '</' . $matches[0 ];
$this->appendDesc (substr($this->processedline, 0 , $tagpos));
$this->processedline = $line = substr($this->processedline, $tagpos
if (!$this->processedline) {
if (strpos($this->processedline, $esctag) !== false ) {
if (!strpos($this->processedline, $esctag)) {
return 2; // to while (true)
if (strpos($this->processedline, $esctag)) {
$this->appendDesc (substr($this->processedline, 0 ,
strpos($this->processedline, $esctag)));
$this->processedline = $trimline =
substr($this->processedline, strpos($this->processedline, $esctag));
return 2; // to while(true)
function searchForInlineTag ($inlinetagpos, $comment)
$this->appendDesc (substr($this->processedline, 0 , $inlinetagpos));
if ($inlinetagpos === strpos($this->processedline, '{@internal')) {
return $this->throwException ('cannot nest {@internal}} in line number ' .
$this->linenum . ': "' . $line . '"', 'internaltag');
$this->processedline = substr($this->processedline, $inlinetagpos + strlen('{@internal'));
if (!preg_match('/^({@[^}\s]+)\s/', substr($this->processedline, $inlinetagpos), $matches)) {
if (!preg_match('/^({@[^}\s]+)}/', substr($this->processedline, $inlinetagpos), $matches)) {
if ($this->hasEndchar ($comment, '}')) {
$matches = array (substr($this->processedline, $inlinetagpos),
substr($this->processedline, $inlinetagpos));
// throw exception if this does not match
$this->throwException ('Unclosed inline tag encountered on line number ' .
$this->linenum . ': "' . $line . '"', 'tag');
// throw exception if this does not match
$this->throwException ('Invalid inline tag encountered in line number ' .
$this->linenum . ': "' . $line . '"', 'tag');
$this->processedline = substr($this->processedline, $inlinetagpos + strlen($matches[1 ]));
function appendDesc ($desc)
if (count($this->tokens)) {
function hasEndChar ($comment, $char)
$linenum = $this->linenum;
foreach ($comment as $num => $line) {
if ($linenum !== false && $num <= $linenum) {
$processedline = trim($line);
if ($processedline == '*/') {
if (substr($processedline, 0 , 3 ) == '/**') {
$processedline = substr($processedline, 3 );
if (trim($processedline) == '*/') {
$processedline = substr($processedline, 1 );
if (strpos($processedline, $char) !== false ) {
if (count($this->tagStack)) {
return $this->throwException ('Error: unclosed html tags: "' .
implode(', ', $this->tagStack) . '"', 'simplelist');
while (count($this->simplelist)) {
function throwException ($message, $type)
$this->error = array ($message, $this->linenum, $type);
Documentation generated on Mon, 11 Mar 2019 15:08:16 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.
|