<?php
interface IErrorManager {
public function ariseFatal($message);
public function ariseWarning($message);
public function ariseNotice($message);
}
interface ILexer {
public function getTokens();
public function tokenize($input);
}
interface IParser {
public function parse($input);
}
interface IParseResult {
public function getDefinition();
public function getName();
public function getConstants();
}
interface ICompiler {
public function compile($input);
}
class ErrorManager implements IErrorManager {
public function ariseFatal($message) {
$this->triggerError($message, E_USER_FATAL);
}
public function ariseWarning($message) {
$this->triggerError($message, E_USER_WARNING);
}
public function ariseNotice($message) {
$this->triggerError($message, E_USER_NOTICE);
}
private function triggerError($message, $type) {
trigger_error((string)$message, (int)$type);
}
}
abstract class CompilerElement {
private $errorManager;
protected function getErrorManager() {
return $this->errorManager;
}
protected function __construct(IErrorManager $errorManager) {
$this->errorManager = $errorManager;
}
}
class Lexer extends CompilerElement implements ILexer {
private $tokens = array();
public function getTokens() {
return $this->tokens;
}
public function tokenize($input) {
if (!is_string($input)) {
$this->getErrorManager()->ariseFatal(get_class($this).'::parse expects parameter 1 to be string. '.gettype($input).' given.');
}
}
public function __construct(IErrorManager $errorManager) {
parent::__construct($errorManager);
}
}
class Parser extends CompilerElement implements IParser {
private $lexer;
public function parse($input) {
if (!is_string($input)) {
$this->getErrorManager()->ariseFatal(get_class($this).'::parse expects parameter 1 to be string. '.gettype($input).' given.');
}
}
public function __construct(ILexer $lexer, IErrorManager $errorManager) {
parent::__construct($errorManager);
$this->lexer = $lexer;
}
}
class ParseResult extends CompilerElement implements IParseResult {
private $definition;
private $name;
private $constants;
public function getDefinition() {
return $this->definition;
}
public function getName() {
return $this->name;
}
public function getConstants() {
return $this->constants;
}
public function __construct($definition, $name, array $constants, IErrorManager $errorManager) {
parent::__construct($errorManager);
if (!is_string($definition)) {
$this->getErrorManager()->ariseFatal(get_class($this).'::__construct expects parameter 1 to be string. '.gettype($definition).' given.');
}
if (!is_string($name)) {
$this->getErrorManager()->ariseFatal(get_class($this).'::__construct expects parameter 2 to be string. '.gettype($name).' given.');
}
$this->definition = $definition;
$this->name = $name;
$this->constants = $constants;
}
}
class Compiler implements ICompiler {
private $parser;
const INTENDATION_CHAR = "\t";
public function compile($input) {
$parseResult = $this->parser->parse($input);
$return = $parseResult->getDefinition().' '.$parseResult->getName().' {'.PHP_EOL;
foreach ($parseResult->getConstants() as $name => $value) {
$return .= Compiler::INTENDATION_CHAR.'const '.$name.' = '.$value.PHP_EOL;
}
$return .= Compiler::INTENDATION_CHAR.'private function __construct() {}'.PHP_EOL;
$return .= '}';
return $return;
}
public function __construct(IParser $parser) {
$this->parser = $parser;
}
}
/*$enumCode =<<< PHP
enum MyEnum {
Item1, Item2, Item3
}
PHP;*/