Skip to content

Instantly share code, notes, and snippets.

@morrisonlevi
Created March 20, 2012 08:14
Show Gist options
  • Save morrisonlevi/2132707 to your computer and use it in GitHub Desktop.
Save morrisonlevi/2132707 to your computer and use it in GitHub Desktop.
Http Routes Tokenizer
<?php
namespace Http;
require './Token.php';
use Iterator;
use RuntimeException;
class Tokenizer implements Iterator {
protected $file;
protected $line = null;
protected $position = 0;
protected $token = null;
protected $httpMethods = ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'HEAD', 'PATCH'];
public function __construct($path) {
$this->file = fopen($path, 'r');
if (!$this->file)
throw new RuntimeException('Tokenizer must be provided a readable file.');
}
public function current() {
if ($this->token === NULL) {
if ($this->position === strlen($this->line)) {
$this->line = $this->getLine();
if ($this->line === FALSE) {
return new Token('EOF');
}
$this->token = new Token('EOL');
$this->position = 0;
} else {
$this->token = $this->getToken();
}
}
return $this->token;
}
public function valid() {
if ($this->line === null) {
$this->line = $this->getLine();
}
if ($this->position <= strlen($this->line)) {
return TRUE;
}
$this->line = $this->getLine();
$this->position = 0;
return $this->line !== FALSE;
}
public function next() {
$this->token = null;
}
public function rewind() {
return rewind($this->file);
}
public function key() {
return 'unknown';
}
protected function getLine() {
$line = fgets($this->file);
if ($line === FALSE) {
return FALSE;
}
return trim($line);
}
protected function getToken() {
$char = $this->line[$this->position];
$token;
while ($char !== '\n' && ctype_space($char)) {
$this->position++;
$char = $this->line[$this->position];
}
if ($char === ';') {
$token = $this->comment();
} else if ($char === '/' || ctype_alpha($char)) {
$token = $this->identifier();
} else {
echo "char:$char {$this->position}\n";
throw new RuntimeException($this->line);
}
return $token;
}
protected function identifier() {
$value = '';
for (
$i =& $this->position, $strlen = strlen($this->line);
$i < $strlen && $this->line[$i] !== ';' && !ctype_space($this->line[$i]);
$i++
) {
$value .= $this->line[$i];
}
$token = 'string';
if (in_array($value, $this->httpMethods)) {
$token = 'httpMethod';
}
if ($value[0] === '/') {
$token = 'pattern';
}
return new Token($token, $value);
}
protected function comment() {
$value = '';
$strlen = strlen($this->line);
if ($this->position < $strlen) {
$value = substr($this->line, $this->position);
}
$token = new Token('comment', $value);
$this->position = $strlen;
return $token;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment