Token.php
<?php
namespace ROF;
class Token {
// protected $start;
protected $name;
protected $text = '';
protected $remainder = [];
protected $next;
protected $children = [];
protected $parent;
protected $prev;
// protected $stack;
// protected $parent;
// protected $next;
// protected $previous;
public function asArray(){
$remainderInfo = implode($this->remainder);
$remainderInfo = 'string('.strlen($remainderInfo).'): '.substr($remainderInfo,0,10).'...';
$data = [
'name'=>$this->name,
'text'=>$this->text,
'remainder'=>$remainderInfo
];
if (count($this->children)>0){
$data['children'] = [];
foreach ($this->children as $child){
$data['children'][] = $child->asArray();
}
}
if ($this->parent===null){
$data['next'] = $this->next;
}
// foreach(['next'] as $param){
// if ($this->$param!=null){
// $data[$param] = $this->$param->asArray();
// }
// }
return $data;
}
public function __construct($name,$text=''){
$this->name = $name;
$this->append($text);
// $this->text = $text;
// $this->text = $fullText;
// $this->start = $index;
// // $this->stack = $stack;
// $this->name = $name;
// $lsit = [];
// foreach (str_split($stack) as $index=>$char){
// $list[] = $this->next($char);
// }
}
protected function pop($str,$offsetText=''){
if ($str=='')return;
$len = strlen($str);
$end = substr($this->text,-($len+strlen($offsetText)));
$popped = $end;
if (strlen($offsetText)>0){
$popped = substr($end,0,-strlen($offsetText));
}
// var_dump($str);
// var_dump($offsetText);
// var_dump($end);
// var_dump($popped);
// var_dump(-strlen($offsetText));
// var_dump($this->text);
if ($popped!==$str){
throw new \Exception("Attempted to pop '{$str}' from token '{$this->name}', but the end was '{$end}' and the end-offset string was '{$offsetText}',"
." and the strpos-based poppable text was '{$popped}'");
}
$this->text = substr($this->text,0,-strlen($end)).$offsetText;
}
public function append($text){
// if (strlen($text))
$this->remainder = str_split($text);
$this->remainderText = $text;
// var_dump($text);exit;
// if ($this->name=='chapter-name'){
// var_dump($text);
// }
while (count($this->remainder)>0){
// $char = $this->remainder[0];
$this->remainderText = substr($this->remainderText,1);
$char = array_shift($this->remainder);
// unset($this->remainder[0]);
if ($char==='')break;
$this->next($char);
}
// foreach ($remainder as $index => $char){
// $this->next($char);
// }
}
public function next($char){
if (strlen($char)==0){
throw new Exception("uh oh:".$char);
}
$this->text .= $char;
$typeParts = explode('-',$this->name);
$camelType = '';
foreach ($typeParts as $part){
$camelType .= ucfirst($part);
}
$willEnd = 'willEnd'.$camelType;
$end = 'end'.$camelType;
if (!method_exists($this,$willEnd)
||!method_exists($this,$end)){
throw new \Exception("both '{$willEnd}' and '{$end}' must exist for token type '{$this->name}'");
}
$matches = [];
if (!$this->$willEnd($matches)){
return;
}
$end = 'end'.$camelType;
$this->$end($matches);
}
public function __toString(){
return "\n<br><b>".$this->name.":</b>\n"
."<i>".$this->text."</i>";
}
protected function nextToken($name,$text,$offsetText=''){
$upcoming = $text.implode($this->remainder);
$this->remainder = [];
$this->pop($text,$offsetText);
$class = get_class($this);
$token = new $class($name,'');
if ($this->parent!=null)$this->parent->appendChild($token);
$token->prev = $this;
$this->next = $token;
// exit;
$token->append($upcoming);
return $token;
}
protected function childToken($name,$text){
$upcoming = $text.implode($this->remainder);
$this->remainder = [];
$this->pop($text);
$class = get_class($this);
$token = new $class($name,'');
$this->children[] = $token;
$token->parent = $this;
// exit;
$token->append($upcoming);
return $token;
}
protected function appendChild($token){
$this->children[] = $token;
$token->parent = $this;
}
protected function willEndInit(&$matches){
return true;
}
protected function endInit($matches){
$this->childToken('start',$this->text);
}
protected function willEndStart(&$matches){
// echo $this->text;
return preg_match('/[a-z]{100,}$/',$this->text,$matches);
}
protected function endStart($matches){
$this->nextToken('chapter-number','CHAPTER');
}
}