about summary refs log tree commit diff stats
path: root/wiki/inc/parser/lexer.php
diff options
context:
space:
mode:
authorahriman <ahriman@falte.red>2019-01-02 04:57:35 +0000
committerahriman <ahriman@falte.red>2019-01-02 04:57:35 +0000
commit2bd7f83a6495011ada78ca8a9f2af417caf01760 (patch)
treef9acdb7f09e011c65330ab993d4db3620787dbfb /wiki/inc/parser/lexer.php
parentbcb215c3a7e914d05f166846a33860e48bba64fb (diff)
downloadsite-2bd7f83a6495011ada78ca8a9f2af417caf01760.tar.gz
removed dokuwiki
Diffstat (limited to 'wiki/inc/parser/lexer.php')
-rw-r--r--wiki/inc/parser/lexer.php614
1 files changed, 0 insertions, 614 deletions
diff --git a/wiki/inc/parser/lexer.php b/wiki/inc/parser/lexer.php
deleted file mode 100644
index ba6a653..0000000
--- a/wiki/inc/parser/lexer.php
+++ /dev/null
@@ -1,614 +0,0 @@
-<?php
-/**
- * Author Markus Baker: http://www.lastcraft.com
- * Version adapted from Simple Test: http://sourceforge.net/projects/simpletest/
- * For an intro to the Lexer see:
- * https://web.archive.org/web/20120125041816/http://www.phppatterns.com/docs/develop/simple_test_lexer_notes
- * @author Marcus Baker
- * @package Doku
- * @subpackage Lexer
- * @version $Id: lexer.php,v 1.1 2005/03/23 23:14:09 harryf Exp $
- */
-
-/**
- * Init path constant
- */
-if(!defined('DOKU_INC')) die('meh.');
-
-/**#@+
- * lexer mode constant
- */
-define("DOKU_LEXER_ENTER", 1);
-define("DOKU_LEXER_MATCHED", 2);
-define("DOKU_LEXER_UNMATCHED", 3);
-define("DOKU_LEXER_EXIT", 4);
-define("DOKU_LEXER_SPECIAL", 5);
-/**#@-*/
-
-/**
- * Compounded regular expression. Any of
- * the contained patterns could match and
- * when one does it's label is returned.
- *
- * @package Doku
- * @subpackage Lexer
- */
-class Doku_LexerParallelRegex {
-    var $_patterns;
-    var $_labels;
-    var $_regex;
-    var $_case;
-
-    /**
-     * Constructor. Starts with no patterns.
-     *
-     * @param boolean $case    True for case sensitive, false
-     *                         for insensitive.
-     * @access public
-     */
-    function __construct($case) {
-        $this->_case = $case;
-        $this->_patterns = array();
-        $this->_labels = array();
-        $this->_regex = null;
-    }
-
-    /**
-     * Adds a pattern with an optional label.
-     *
-     * @param mixed       $pattern Perl style regex. Must be UTF-8
-     *                             encoded. If its a string, the (, )
-     *                             lose their meaning unless they
-     *                             form part of a lookahead or
-     *                             lookbehind assertation.
-     * @param bool|string $label   Label of regex to be returned
-     *                             on a match. Label must be ASCII
-     * @access public
-     */
-    function addPattern($pattern, $label = true) {
-        $count = count($this->_patterns);
-        $this->_patterns[$count] = $pattern;
-        $this->_labels[$count] = $label;
-        $this->_regex = null;
-    }
-
-    /**
-     * Attempts to match all patterns at once against a string.
-     *
-     * @param string $subject      String to match against.
-     * @param string $match        First matched portion of
-     *                             subject.
-     * @return boolean             True on success.
-     * @access public
-     */
-    function match($subject, &$match) {
-        if (count($this->_patterns) == 0) {
-            return false;
-        }
-        if (! preg_match($this->_getCompoundedRegex(), $subject, $matches)) {
-            $match = "";
-            return false;
-        }
-
-        $match = $matches[0];
-        $size = count($matches);
-        for ($i = 1; $i < $size; $i++) {
-            if ($matches[$i] && isset($this->_labels[$i - 1])) {
-                return $this->_labels[$i - 1];
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Attempts to split the string against all patterns at once
-     *
-     * @param string $subject      String to match against.
-     * @param array $split         The split result: array containing, pre-match, match & post-match strings
-     * @return boolean             True on success.
-     * @access public
-     *
-     * @author Christopher Smith <chris@jalakai.co.uk>
-     */
-    function split($subject, &$split) {
-        if (count($this->_patterns) == 0) {
-            return false;
-        }
-
-        if (! preg_match($this->_getCompoundedRegex(), $subject, $matches)) {
-            if(function_exists('preg_last_error')){
-                $err = preg_last_error();
-                switch($err){
-                    case PREG_BACKTRACK_LIMIT_ERROR:
-                        msg('A PCRE backtrack error occured. Try to increase the pcre.backtrack_limit in php.ini',-1);
-                        break;
-                    case PREG_RECURSION_LIMIT_ERROR:
-                        msg('A PCRE recursion error occured. Try to increase the pcre.recursion_limit in php.ini',-1);
-                        break;
-                    case PREG_BAD_UTF8_ERROR:
-                        msg('A PCRE UTF-8 error occured. This might be caused by a faulty plugin',-1);
-                        break;
-                    case PREG_INTERNAL_ERROR:
-                        msg('A PCRE internal error occured. This might be caused by a faulty plugin',-1);
-                        break;
-                }
-            }
-
-            $split = array($subject, "", "");
-            return false;
-        }
-
-        $idx = count($matches)-2;
-        list($pre, $post) = preg_split($this->_patterns[$idx].$this->_getPerlMatchingFlags(), $subject, 2);
-        $split = array($pre, $matches[0], $post);
-
-        return isset($this->_labels[$idx]) ? $this->_labels[$idx] : true;
-    }
-
-    /**
-     * Compounds the patterns into a single
-     * regular expression separated with the
-     * "or" operator. Caches the regex.
-     * Will automatically escape (, ) and / tokens.
-     *
-     * @internal array $_patterns List of patterns in order.
-     * @return null|string
-     * @access private
-     */
-    function _getCompoundedRegex() {
-        if ($this->_regex == null) {
-            $cnt = count($this->_patterns);
-            for ($i = 0; $i < $cnt; $i++) {
-
-                /*
-                 * decompose the input pattern into "(", "(?", ")",
-                 * "[...]", "[]..]", "[^]..]", "[...[:...:]..]", "\x"...
-                 * elements.
-                 */
-                preg_match_all('/\\\\.|' .
-                               '\(\?|' .
-                               '[()]|' .
-                               '\[\^?\]?(?:\\\\.|\[:[^]]*:\]|[^]\\\\])*\]|' .
-                               '[^[()\\\\]+/', $this->_patterns[$i], $elts);
-
-                $pattern = "";
-                $level = 0;
-
-                foreach ($elts[0] as $elt) {
-                    /*
-                     * for "(", ")" remember the nesting level, add "\"
-                     * only to the non-"(?" ones.
-                     */
-
-                    switch($elt) {
-                        case '(':
-                            $pattern .= '\(';
-                            break;
-                        case ')':
-                            if ($level > 0)
-                                $level--; /* closing (? */
-                            else
-                                $pattern .= '\\';
-                            $pattern .= ')';
-                            break;
-                        case '(?':
-                            $level++;
-                            $pattern .= '(?';
-                            break;
-                        default:
-                            if (substr($elt, 0, 1) == '\\')
-                                $pattern .= $elt;
-                            else
-                                $pattern .= str_replace('/', '\/', $elt);
-                    }
-                }
-                $this->_patterns[$i] = "($pattern)";
-            }
-            $this->_regex = "/" . implode("|", $this->_patterns) . "/" . $this->_getPerlMatchingFlags();
-        }
-        return $this->_regex;
-    }
-
-    /**
-     * Accessor for perl regex mode flags to use.
-     * @return string       Perl regex flags.
-     * @access private
-     */
-    function _getPerlMatchingFlags() {
-        return ($this->_case ? "msS" : "msSi");
-    }
-}
-
-/**
- * States for a stack machine.
- * @package Lexer
- * @subpackage Lexer
- */
-class Doku_LexerStateStack {
-    var $_stack;
-
-    /**
-     * Constructor. Starts in named state.
-     * @param string $start        Starting state name.
-     * @access public
-     */
-    function __construct($start) {
-        $this->_stack = array($start);
-    }
-
-    /**
-     * Accessor for current state.
-     * @return string       State.
-     * @access public
-     */
-    function getCurrent() {
-        return $this->_stack[count($this->_stack) - 1];
-    }
-
-    /**
-     * Adds a state to the stack and sets it
-     * to be the current state.
-     * @param string $state        New state.
-     * @access public
-     */
-    function enter($state) {
-        array_push($this->_stack, $state);
-    }
-
-    /**
-     * Leaves the current state and reverts
-     * to the previous one.
-     * @return boolean    False if we drop off
-     *                    the bottom of the list.
-     * @access public
-     */
-    function leave() {
-        if (count($this->_stack) == 1) {
-            return false;
-        }
-        array_pop($this->_stack);
-        return true;
-    }
-}
-
-/**
- * Accepts text and breaks it into tokens.
- * Some optimisation to make the sure the
- * content is only scanned by the PHP regex
- * parser once. Lexer modes must not start
- * with leading underscores.
- * @package Doku
- * @subpackage Lexer
- */
-class Doku_Lexer {
-    var $_regexes;
-    var $_parser;
-    var $_mode;
-    var $_mode_handlers;
-    var $_case;
-
-    /**
-     * Sets up the lexer in case insensitive matching
-     * by default.
-     * @param Doku_Parser $parser  Handling strategy by
-     *                                 reference.
-     * @param string $start            Starting handler.
-     * @param boolean $case            True for case sensitive.
-     * @access public
-     */
-    function __construct($parser, $start = "accept", $case = false) {
-        $this->_case = $case;
-        /** @var Doku_LexerParallelRegex[] _regexes */
-        $this->_regexes = array();
-        $this->_parser = $parser;
-        $this->_mode = new Doku_LexerStateStack($start);
-        $this->_mode_handlers = array();
-    }
-
-    /**
-     * Adds a token search pattern for a particular
-     * parsing mode. The pattern does not change the
-     * current mode.
-     * @param string $pattern      Perl style regex, but ( and )
-     *                             lose the usual meaning.
-     * @param string $mode         Should only apply this
-     *                             pattern when dealing with
-     *                             this type of input.
-     * @access public
-     */
-    function addPattern($pattern, $mode = "accept") {
-        if (! isset($this->_regexes[$mode])) {
-            $this->_regexes[$mode] = new Doku_LexerParallelRegex($this->_case);
-        }
-        $this->_regexes[$mode]->addPattern($pattern);
-    }
-
-    /**
-     * Adds a pattern that will enter a new parsing
-     * mode. Useful for entering parenthesis, strings,
-     * tags, etc.
-     * @param string $pattern      Perl style regex, but ( and )
-     *                             lose the usual meaning.
-     * @param string $mode         Should only apply this
-     *                             pattern when dealing with
-     *                             this type of input.
-     * @param string $new_mode     Change parsing to this new
-     *                             nested mode.
-     * @access public
-     */
-    function addEntryPattern($pattern, $mode, $new_mode) {
-        if (! isset($this->_regexes[$mode])) {
-            $this->_regexes[$mode] = new Doku_LexerParallelRegex($this->_case);
-        }
-        $this->_regexes[$mode]->addPattern($pattern, $new_mode);
-    }
-
-    /**
-     * Adds a pattern that will exit the current mode
-     * and re-enter the previous one.
-     * @param string $pattern      Perl style regex, but ( and )
-     *                             lose the usual meaning.
-     * @param string $mode         Mode to leave.
-     * @access public
-     */
-    function addExitPattern($pattern, $mode) {
-        if (! isset($this->_regexes[$mode])) {
-            $this->_regexes[$mode] = new Doku_LexerParallelRegex($this->_case);
-        }
-        $this->_regexes[$mode]->addPattern($pattern, "__exit");
-    }
-
-    /**
-     * Adds a pattern that has a special mode. Acts as an entry
-     * and exit pattern in one go, effectively calling a special
-     * parser handler for this token only.
-     * @param string $pattern      Perl style regex, but ( and )
-     *                             lose the usual meaning.
-     * @param string $mode         Should only apply this
-     *                             pattern when dealing with
-     *                             this type of input.
-     * @param string $special      Use this mode for this one token.
-     * @access public
-     */
-    function addSpecialPattern($pattern, $mode, $special) {
-        if (! isset($this->_regexes[$mode])) {
-            $this->_regexes[$mode] = new Doku_LexerParallelRegex($this->_case);
-        }
-        $this->_regexes[$mode]->addPattern($pattern, "_$special");
-    }
-
-    /**
-     * Adds a mapping from a mode to another handler.
-     * @param string $mode        Mode to be remapped.
-     * @param string $handler     New target handler.
-     * @access public
-     */
-    function mapHandler($mode, $handler) {
-        $this->_mode_handlers[$mode] = $handler;
-    }
-
-    /**
-     * Splits the page text into tokens. Will fail
-     * if the handlers report an error or if no
-     * content is consumed. If successful then each
-     * unparsed and parsed token invokes a call to the
-     * held listener.
-     * @param string $raw        Raw HTML text.
-     * @return boolean           True on success, else false.
-     * @access public
-     */
-    function parse($raw) {
-        if (! isset($this->_parser)) {
-            return false;
-        }
-        $initialLength = strlen($raw);
-        $length = $initialLength;
-        $pos = 0;
-        while (is_array($parsed = $this->_reduce($raw))) {
-            list($unmatched, $matched, $mode) = $parsed;
-            $currentLength = strlen($raw);
-            $matchPos = $initialLength - $currentLength - strlen($matched);
-            if (! $this->_dispatchTokens($unmatched, $matched, $mode, $pos, $matchPos)) {
-                return false;
-            }
-            if ($currentLength == $length) {
-                return false;
-            }
-            $length = $currentLength;
-            $pos = $initialLength - $currentLength;
-        }
-        if (!$parsed) {
-            return false;
-        }
-        return $this->_invokeParser($raw, DOKU_LEXER_UNMATCHED, $pos);
-    }
-
-    /**
-     * Sends the matched token and any leading unmatched
-     * text to the parser changing the lexer to a new
-     * mode if one is listed.
-     * @param string $unmatched Unmatched leading portion.
-     * @param string $matched Actual token match.
-     * @param bool|string $mode Mode after match. A boolean
-     *                             false mode causes no change.
-     * @param int $initialPos
-     * @param int $matchPos
-     *                             Current byte index location in raw doc
-     *                             thats being parsed
-     * @return boolean             False if there was any error
-     *                             from the parser.
-     * @access private
-     */
-    function _dispatchTokens($unmatched, $matched, $mode = false, $initialPos, $matchPos) {
-        if (! $this->_invokeParser($unmatched, DOKU_LEXER_UNMATCHED, $initialPos) ){
-            return false;
-        }
-        if ($this->_isModeEnd($mode)) {
-            if (! $this->_invokeParser($matched, DOKU_LEXER_EXIT, $matchPos)) {
-                return false;
-            }
-            return $this->_mode->leave();
-        }
-        if ($this->_isSpecialMode($mode)) {
-            $this->_mode->enter($this->_decodeSpecial($mode));
-            if (! $this->_invokeParser($matched, DOKU_LEXER_SPECIAL, $matchPos)) {
-                return false;
-            }
-            return $this->_mode->leave();
-        }
-        if (is_string($mode)) {
-            $this->_mode->enter($mode);
-            return $this->_invokeParser($matched, DOKU_LEXER_ENTER, $matchPos);
-        }
-        return $this->_invokeParser($matched, DOKU_LEXER_MATCHED, $matchPos);
-    }
-
-    /**
-     * Tests to see if the new mode is actually to leave
-     * the current mode and pop an item from the matching
-     * mode stack.
-     * @param string $mode    Mode to test.
-     * @return boolean        True if this is the exit mode.
-     * @access private
-     */
-    function _isModeEnd($mode) {
-        return ($mode === "__exit");
-    }
-
-    /**
-     * Test to see if the mode is one where this mode
-     * is entered for this token only and automatically
-     * leaves immediately afterwoods.
-     * @param string $mode    Mode to test.
-     * @return boolean        True if this is the exit mode.
-     * @access private
-     */
-    function _isSpecialMode($mode) {
-        return (strncmp($mode, "_", 1) == 0);
-    }
-
-    /**
-     * Strips the magic underscore marking single token
-     * modes.
-     * @param string $mode    Mode to decode.
-     * @return string         Underlying mode name.
-     * @access private
-     */
-    function _decodeSpecial($mode) {
-        return substr($mode, 1);
-    }
-
-    /**
-     * Calls the parser method named after the current
-     * mode. Empty content will be ignored. The lexer
-     * has a parser handler for each mode in the lexer.
-     * @param string $content Text parsed.
-     * @param boolean $is_match Token is recognised rather
-     *                               than unparsed data.
-     * @param int $pos Current byte index location in raw doc
-     *                             thats being parsed
-     * @return bool
-     * @access private
-     */
-    function _invokeParser($content, $is_match, $pos) {
-        if (($content === "") || ($content === false)) {
-            return true;
-        }
-        $handler = $this->_mode->getCurrent();
-        if (isset($this->_mode_handlers[$handler])) {
-            $handler = $this->_mode_handlers[$handler];
-        }
-
-        // modes starting with plugin_ are all handled by the same
-        // handler but with an additional parameter
-        if(substr($handler,0,7)=='plugin_'){
-            list($handler,$plugin) = explode('_',$handler,2);
-            return $this->_parser->$handler($content, $is_match, $pos, $plugin);
-        }
-
-            return $this->_parser->$handler($content, $is_match, $pos);
-        }
-
-    /**
-     * Tries to match a chunk of text and if successful
-     * removes the recognised chunk and any leading
-     * unparsed data. Empty strings will not be matched.
-     * @param string $raw         The subject to parse. This is the
-     *                            content that will be eaten.
-     * @return array              Three item list of unparsed
-     *                            content followed by the
-     *                            recognised token and finally the
-     *                            action the parser is to take.
-     *                            True if no match, false if there
-     *                            is a parsing error.
-     * @access private
-     */
-    function _reduce(&$raw) {
-        if (! isset($this->_regexes[$this->_mode->getCurrent()])) {
-            return false;
-        }
-        if ($raw === "") {
-            return true;
-        }
-        if ($action = $this->_regexes[$this->_mode->getCurrent()]->split($raw, $split)) {
-            list($unparsed, $match, $raw) = $split;
-            return array($unparsed, $match, $action);
-        }
-        return true;
-    }
-}
-
-/**
- * Escapes regex characters other than (, ) and /
- *
- * @TODO
- *
- * @param string $str
- *
- * @return mixed
- */
-function Doku_Lexer_Escape($str) {
-    //$str = addslashes($str);
-    $chars = array(
-        '/\\\\/',
-        '/\./',
-        '/\+/',
-        '/\*/',
-        '/\?/',
-        '/\[/',
-        '/\^/',
-        '/\]/',
-        '/\$/',
-        '/\{/',
-        '/\}/',
-        '/\=/',
-        '/\!/',
-        '/\</',
-        '/\>/',
-        '/\|/',
-        '/\:/'
-        );
-
-    $escaped = array(
-        '\\\\\\\\',
-        '\.',
-        '\+',
-        '\*',
-        '\?',
-        '\[',
-        '\^',
-        '\]',
-        '\$',
-        '\{',
-        '\}',
-        '\=',
-        '\!',
-        '\<',
-        '\>',
-        '\|',
-        '\:'
-        );
-    return preg_replace($chars, $escaped, $str);
-}
-
-//Setup VIM: ex: et ts=4 sw=4 :