DocblockGrammar.php
<?php
namespace Tlf\Lexer;
class DocblockGrammar extends Grammar {
//public $directives = [
//'/*'=>[
//'start'=>[
//'match'=>'/\\/\*/',
//'buffer.clear',
//],
//'stop'=>[
//'match'=>'*/',
//// 'directive.pop 1',
//'rewind 2',
//'this:processDocblock',
//'forward 2',
//'buffer.clear',
//]
//],
//];
public function __construct(){
$this->directives = require(__DIR__.'/directives.php');
}
public function getNamespace(){
return 'docblock';
}
public function onGrammarAdded($lexer){
//return; // @todo continue developing directive-driven grammar
//$lexer->addDirective($this->getDirectives(':php_open')['php_open']);
}
public function onLexerStart($lexer, $ast, $token){
}
public function onLexerEnd($lexer, $ast, $token){
$prev = $lexer->previous('docblock');
if ($prev!==null){
$ast->add('docblock', $prev);
}
}
public function processDocblock($lexer, $ast, $token, $directive){
// echo "\n\n\n-----------\n\n";
// echo 'are we here?';
// echo "\n\n\n-----------\n\n";
// exit;
// if ($lexer->loop_count==5483){
// var_dump($lexer->loop_count);
// var_dump("k");
// echo "\n\n\n";
// var_dump($token->buffer());
// exit;
// }
// if (false){
// var_dump($lexer->loop_count);
// var_dump("k");
// echo "\n\n\n";
// var_dump($token->buffer());
// // exit;
// }
$body = $token->buffer();
$lines = $this->cleanIndentation($body);
$ast = $this->buildAstWithAttributes($lines);
$lexer->setPrevious('docblock',$ast);
if ($lexer->getHead()->_type=='expression'){
$lexer->getHead()->set('docblock', $ast);
}
}
public function buildAstWithAttributes($lines){
// echo "\n\n\n++\n";
$docblock = new Ast('docblock');
$docblock->set('description', '');
$curAttr = false;
$head = $docblock;
$key = 'description';
$newLine = false;
foreach ($lines as $index=>$line){
if ($index>0)$newLine = true;
if (preg_match('/^\s*\@([a-zA-Z\_0-9]+)[^a-zA-Z\_0-9]/',$line, $match)){
if ($head->type=='attribute'){
$desc = $head->get('description');
$descLines = explode("\n", $desc);
// var_dump($descLines);
// exit;
while (count($descLines)>0&&trim($lastLine = array_pop($descLines)) == ''){
// var_dump($lastLine);
}
if (trim($lastLine)!=false){
$descLines[] = $lastLine;
}
$head->set('description', implode("\n", $descLines));
}
$line = substr($line, strlen($match[0])-1);
$line = trim($line);
$head = $match[1];
$isAttr = true;
$attr = new Ast('attribute');
$attr->set('name', $match[1]);
$attr->set('description', '');
$head = $attr;
$docblock->add('attribute', $attr);
$newLine = false;
}
if ($newLine)$line = "\n$line";
$head->append('description', $line);
}
// echo "\n\n\n++\n";
return $docblock;
}
/**
* Remove indentation and * from docblock body
*/
public function cleanIndentation($body){
if (substr($body,0)=='*')$body = substr($body,1);
// remove * from lines that only have whitespace and *
$body = preg_replace("/^(\s*)\*(\s*)$/m", '\1 \2', $body);
// remove * from all lines
$body = preg_replace("/^(\s*)\*(\s*)/m", '\1 \2', $body);
$body = \Tlf\Lexer\Utility::trim_indents($body);
return explode("\n", $body);
}
}