/** * Parser. * @param string * @return array */ public function parse($input) { if (!self::$tokenizer) { // speed-up self::$tokenizer = new Tokenizer(self::$patterns, 'mi'); } $input = str_replace("\r", '', $input); $input = strtr($input, "\t", ' '); $input = "\n" . $input . "\n"; // first \n is required by "Indent" self::$tokenizer->tokenize($input); $this->n = 0; $res = $this->_parse(); while (isset(self::$tokenizer->tokens[$this->n])) { if (self::$tokenizer->tokens[$this->n][0] === "\n") { $this->n++; } else { $this->error(); } } return $res; }
/** * Lexical scanner. * @param string * @return void */ private function tokenize($s) { if (!self::$regexp) { self::$regexp = '~' . implode('|', self::$patterns) . '~mA'; } $s = str_replace("\r", '', $s); $s = strtr($s, "\t", ' '); $s = "\n" . $s . "\n"; // first is required by "Indent", last is required by parse-error check $this->input = $s; $this->tokens = String::split($s, self::$regexp, PREG_SPLIT_NO_EMPTY); if (end($this->tokens) !== "\n") { // unable to parse $this->n = key($this->tokens); $this->error(); } }