3v4l.org

run code in 300+ PHP versions simultaneously
<?php interface ILexer { /** * return associative array containing tokens for parser * @param string $input code to tokenize * @return array */ public function tokenize($input); } interface INameValidator { /** * Checks if name is valid. In a case of failure trigger syntax error. * @param string $name * @return void */ public function validate($name); } interface IParser { /** * Sets array of keywords. * @param array $keywords associative array where key is keyword and value respective php instruction. * @return void */ public function setKeywords(array $keywords); /** * Parses code. Checks for syntax errors. * If no error occurs returns data for compiler to assemble php class * otherwise trigger syntax error. * @param string $input code to parse. * @return array IParserResult */ public function parse($input); } interface IParseResult { public function getDefinition(); public function getName(); public function getConstants(); } //I know this lexer sucks. class Lexer extends CompilerElement implements ILexer { // Potential hidden dependency private $specialChars = array( '{' => 'start_body', '}' => 'end_body' ); public function tokenize($input) { if (!is_string($input)) { $this->getErrorManager()->ariseFatal(get_class($this).'::parse expects parameter 1 to be string. '.gettype($input).' given.'); } $tokens = array(); $token = $this->getEmptyToken(); $tokenMetadata = $this->getDefaultTokenMetadata(); $inputLength = strlen($input); for ($i = 0; $i < $inputLength; $i++) { $current = $input[$i]; //check if special character if (isset($this->specialChars[$current])) { $token[$this->specialChars[$current]] = $current; if ($i !== $inputLength - 1) continue; } if (isset($token['end_body'])) { $tokens[] = $token; $token = $this->getEmptyToken(); $tokenMetadata = $this->getDefaultTokenMetadata(); if ($i === $inputLength - 1) continue; } $isWhitespace = ctype_space($current); if (isset($token['start_body'])) { //skip if whitespace if ($isWhitespace) { continue; } if ($current === ',') { $tokenMetadata['newItem'] = true; $tokenMetadata['newItemNameResolved'] = false; continue; } if ($current === '=') { $tokenMetadata['newItemNameResolved'] = true; continue; } if ($tokenMetadata['newItem']) { $token['e_'.$current] = null; $tokenMetadata['newItem'] = false; } else { end($token); $lastKey = key($token); if (!$tokenMetadata['newItemNameResolved']) { unset($token[$lastKey]); $token[$lastKey.$current] = null; } else { $token[$lastKey] .= $current; } } continue; } if (!$tokenMetadata['typeResolved']) { if ($isWhitespace) { if (strlen($token['type']) === 0) { continue; } else { $tokenMetadata['typeResolved'] = true; } } else { $token['type'] .= $current; } } else if (!$tokenMetadata['nameResolved']) { if ($isWhitespace) { if (strlen($token['name']) === 0) { continue; } else { $tokenMetadata['nameResolved'] = true; } } else { $token['name'] .= $current; } } } return $tokens; } private function getEmptyToken() { return array( 'type' => '', 'name' => '' ); } private function getDefaultTokenMetadata() { return array( 'typeResolved' => false, 'nameResolved' => false, 'newItem' => true, 'newItemNameResolved' => false ); } public function __construct(IErrorManager $errorManager) { parent::__construct($errorManager); } }

preferences:
37.51 ms | 402 KiB | 5 Q