120 lines
2.8 KiB
PHP
120 lines
2.8 KiB
PHP
|
<?php
|
||
|
namespace nur\ldap\schemas;
|
||
|
|
||
|
use nur\b\ValueException;
|
||
|
|
||
|
class LseParser {
|
||
|
/** supprimer le {size} à la fin d'un OID */
|
||
|
protected static function fix_oid(string $oid): string {
|
||
|
return preg_replace('/\{\d+}$/', "", $oid);
|
||
|
}
|
||
|
|
||
|
function __construct(?string $s=null) {
|
||
|
$this->s = $s;
|
||
|
}
|
||
|
|
||
|
protected function expected(string $expected): ValueException {
|
||
|
return new ValueException("expected $expected, got $this->s");
|
||
|
}
|
||
|
protected function unexpected(string $value): ValueException {
|
||
|
return new ValueException("unexpected $value");
|
||
|
}
|
||
|
|
||
|
protected $s;
|
||
|
|
||
|
#~~~~
|
||
|
|
||
|
const SPACES_PATTERN = '/^\s+/';
|
||
|
|
||
|
protected function skipSpaces(): void {
|
||
|
if (preg_match(self::SPACES_PATTERN, $this->s, $ms)) {
|
||
|
$this->s = substr($this->s, strlen($ms[0]));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#~~~~
|
||
|
protected function isLiteral(string $literal): bool {
|
||
|
return substr($this->s, 0, strlen($literal)) === $literal;
|
||
|
}
|
||
|
|
||
|
protected function skipLiteral(string $literal): void {
|
||
|
$pos = strlen($literal);
|
||
|
if (substr($this->s, 0, $pos) === $literal) {
|
||
|
$this->s = substr($this->s, $pos);
|
||
|
} else {
|
||
|
throw $this->expected($literal);
|
||
|
}
|
||
|
$this->skipSpaces();
|
||
|
}
|
||
|
|
||
|
#~~~~
|
||
|
|
||
|
const NAME_PATTERN = '/^\S+/';
|
||
|
|
||
|
protected function isName(): bool {
|
||
|
if (!preg_match(self::NAME_PATTERN, $this->s, $ms)) return false;
|
||
|
$name = $ms[0];
|
||
|
return !in_array($name, ['(', ')', '$']);
|
||
|
}
|
||
|
|
||
|
protected function parseName(): string {
|
||
|
if (!preg_match(self::NAME_PATTERN, $this->s, $ms)) {
|
||
|
throw $this->expected("<NAME>");
|
||
|
}
|
||
|
$name = $ms[0];
|
||
|
$this->s = substr($this->s, strlen($name));
|
||
|
$this->skipSpaces();
|
||
|
return $name;
|
||
|
}
|
||
|
|
||
|
#~~~~
|
||
|
|
||
|
const STRING_PATTERN = "/^'([^']*)'/";
|
||
|
|
||
|
protected function isString(): bool {
|
||
|
return preg_match(self::STRING_PATTERN, $this->s, $ms);
|
||
|
}
|
||
|
|
||
|
protected function parseString(): string {
|
||
|
if (!preg_match(self::STRING_PATTERN, $this->s, $ms)) {
|
||
|
throw $this->expected("<STRING>");
|
||
|
}
|
||
|
$this->s = substr($this->s, strlen($ms[0]));
|
||
|
$this->skipSpaces();
|
||
|
return $ms[1];
|
||
|
}
|
||
|
|
||
|
#~~~~
|
||
|
|
||
|
protected function parseNames(): array {
|
||
|
if ($this->isName()) return [$this->parseName()];
|
||
|
$names = [];
|
||
|
if ($this->isLiteral('(')) {
|
||
|
$this->skipLiteral('(');
|
||
|
while ($this->isName()) {
|
||
|
$names[] = $this->parseName();
|
||
|
if ($this->isLiteral('$')) $this->skipLiteral('$');
|
||
|
}
|
||
|
$this->skipLiteral(')');
|
||
|
} else {
|
||
|
$names[] = $this->parseName();
|
||
|
}
|
||
|
return $names;
|
||
|
}
|
||
|
|
||
|
protected function parseStrings(): array {
|
||
|
if ($this->isString()) return [$this->parseString()];
|
||
|
$strings = [];
|
||
|
if ($this->isLiteral('(')) {
|
||
|
$this->skipLiteral('(');
|
||
|
while ($this->isString()) {
|
||
|
$strings[] = $this->parseString();
|
||
|
}
|
||
|
$this->skipLiteral(')');
|
||
|
} else {
|
||
|
$strings[] = $this->parseString();
|
||
|
}
|
||
|
return $strings;
|
||
|
}
|
||
|
}
|