Constructs the parse tree from a string of bbcode markup.

@param string $str the bbcode markup to parse

@return Parser
425922
public function parse($str)
    {
        /* Set the tree root back to a fresh DocumentElement. */
        $this->reset();

        $parent = $this->treeRoot;
        $tokenizer = new Tokenizer($str);

        while ($tokenizer->hasNext()) {
            $parent = $this->parseStartState($parent, $tokenizer);
            if ($parent->getCodeDefinition() && false ===
                $parent->getCodeDefinition()->parseContent()) {
                /* We're inside an element that does not allow its contents to be parseable. */
                $this->parseAsTextUntilClose($parent, $tokenizer);
                $parent = $parent->getParent();
            }
        }

        /* We parsed ignoring nest limits. Do an O(n) traversal to remove any elements that
         * are nested beyond their CodeDefinition's nest limit. */
        $this->removeOverNestedElements();

        return $this;
    }
82265
private function _strtoupper($str)
    {
        $str = html_entity_decode($str, ENT_COMPAT);

        if (function_exists('mb_strtoupper')) {
            $str = mb_strtoupper($str, 'UTF-8');
        } else {
            $str = strtoupper($str);
        }

        $str = htmlspecialchars($str, ENT_COMPAT);

        return $str;
    }
392941
public static function fromString($str)
    {
        $set = new Stringset();
        $data = str_split($str, 1);
        $pos = 0;

        list(,$magic) = unpack('L', self::mergechars($data, $pos, 4));

        if ($magic !== self::MAGIC_NUMBER) {
            throw new Exception("This is not a MO string.");
        }

        list(,$version) = unpack('L', self::mergechars($data, $pos, 4));

        if ($version !== self::REVISION) {
            throw new Exception("This file format revision is not supported.");
        }

        list(,$nstrings) = unpack('L', self::mergechars($data, $pos, 4));
        list(,$ostart) = unpack('L', self::mergechars($data, $pos, 4));
        list(,$tstart) = unpack('L', self::mergechars($data, $pos, 4));

        for ($i = 0; $i < $nstrings; $i += 1) {
            $original = $ostart + ($i * 8);
            $translated = $tstart + ($i * 8);
            $original = unpack('Llength/Loffset', self::mergechars($data, $original, 8));
            $translated = unpack('Llength/Loffset', self::mergechars($data, $translated, 8));

            $id = self::mergechars($data, $original['offset'], $original['length'] + 1, false);
            $value = self::mergechars($data, $translated['offset'], $translated['length'] + 1, false);

            if ($id[strlen($id) - 1] !== self::NUL || $value[strlen($value) - 1] !== self::NUL) {
                throw new Exception("String wasn't NUL-terminated");
            }

            $result = array();

            $id = explode(self::NUL, $id);
            if (count($id) === 3) {
                $result['msgid_plural'] = $id[1];
            }
            $id = explode(self::EOT, $id[0]);
            if (count($id) === 2) {
                $result['msgctxt'] = $id[0];
                $result['msgid'] = $id[1];
            } else {
                $result['msgid'] = $id[0];
            }

            $value = explode(self::NUL, $value);
            array_pop($value);
            $result['msgstr'] = $value;
            $set->add($result);
        }
        return $set;
    }
391867
protected function parseRoute($str) {
        $verbs=$path='';
        if (preg_match('/^\h*(\*|[\|\w]*)\h*(\H+)/',$str,$m)) {
            list(,$verbs,$path)=$m;
            if ($path[0]=='@')
                $path=\Base::instance()->get('ALIASES.'.substr($path,1));
        }
        if (!$verbs || $verbs=='*')
            $verbs=\Base::VERBS;
        return array(explode('|',$verbs),$path);
    }
301766
private function parse($str)
    {
        $str = trim($str);
        $this->expression = $str;
        $strlen = strlen($str);
        $main_array = [];
        $count = 0;

        for ($i=0; $i<$strlen; $i++) {

            $str_i = $str[$i];
            $str_ip1 = (isset($str[$i+1])) ? $str[$i+1] : null;
            $str_ip2 = (isset($str[$i+2])) ? $str[$i+2] : null;
            $str_ip3 = (isset($str[$i+3])) ? $str[$i+3] : null;
            $str_ip4 = (isset($str[$i+4])) ? $str[$i+4] : null;
            $str_im1 = (isset($str[$i-1])) ? $str[$i-1] : null;
            $str_im2 = (isset($str[$i-2])) ? $str[$i-2] : null;

            // NaN
            if (stristr($str, 'NaN'))
                return NAN;
            // Spaces will be skipped
            if ($str_i == ' ') {
                $count++;
            // Number
            } elseif (is_numeric($str_i)) {
                $main_array[$count] = (isset($main_array[$count])) ?
                        $main_array[$count].$str_i : $str_i;
            // Constant pi
            } elseif ($str_im1.$str_i == 'pi') {
            } elseif (($str_i.$str_ip1 == 'pi')
            && (!$str_ip2 || strstr('+-*/^ ', $str_ip2))) {
                $count++;
                $main_array[$count] = M_PI;
            // Constant e
            } elseif (($str_i == 'e') && ($str_ip1 != 'x') && (!is_numeric($str_im1))
            && (!$str_ip1 || strstr('+-*/^ ', $str_ip1))) {
                $count++;
                $main_array[$count] = M_E;
            // Number in E notation
            } elseif ((strtolower($str_i) == 'e') && ($str_ip1 != 'x')
            && (is_numeric($str_im1))) {
                $main_array[$count] = $main_array[$count].'E';
            } elseif ((strstr('+-', $str_i)) && (strtolower($str_im1) == 'e')
            && (is_numeric($str_ip1)) && (is_numeric($str_im2))) {
                $main_array[$count] = $main_array[$count].$str_i;
            // Decimal point
            } elseif (($str_i == '.') && ((isset($str_im1) && is_numeric($str_im1)) 
            || (isset($str_ip1)) && is_numeric($str_ip1))) {
                $main_array[$count] = (isset($main_array[$count])) ? 
                        $main_array[$count].'.' : '.';
            // Function
            } elseif ((in_array($str_i.$str_ip1.$str_ip2, $this->valid_functions))
            || ($str_i.$str_ip1.$str_ip2.$str_ip3 == 'sqrt')) {
                if ($str_i.$str_ip1.$str_ip2.$str_ip3 == 'sqrt') {
                    if ($str_ip4 == ' ')
                        $this->calculateFunction('sqrt', $str, $strlen, $i);
                } else {
                    if ($str_ip3 == ' ')
                        $this->calculateFunction($str_i.$str_ip1.$str_ip2, $str, $strlen, $i);
                }
            // Variable
            } elseif (in_array($str_i, $this->valid_variables) && count($this->variables)) {
                if (array_key_exists($str_i, $this->variables)
                && is_numeric($this->variables[$str_i])) {
                    $main_array[$count] = (float) $this->variables[$str_i];
                    $count++;
                } else {
                    $this->correct = 0;
                    $this->error_type = 4;
                    break;
                }
            } else {
                // Operator
                $count++;
                if (strstr('+-*/^', $str_i)) {
                    if (!count($main_array) && $str_i == '+')
                        continue;
                    $main_array[$count] = $str_i;
                    $count++;
                } else {
                    // Constant Inf
                    if ($str_im2.$str_im1.$str_i == 'INF') {
                    } elseif ($str_im1.$str_i.$str_ip1 == 'INF') {
                    } elseif ($str_i.$str_ip1.$str_ip2 == 'INF') {
                        if ($str_im1 == '-' && !count($main_array)) {
                            $main_array[$count] = '-';
                            $count++;
                        }
                        $main_array[$count] = INF;
                        $count++;
                    } else {
                        // Nothing matches
                        $this->correct = 0;
                        if (!$this->validate())
                            $this->error_type = 1;
                        break;
                    }
                }
            }
        }

        if (!$this->correct)
            return 0;

        $main_array = array_values($main_array);

        if (isset($main_array[1])) {

            $main_array = $this->combine($main_array);
            $main_array = $this->calculate1($main_array);
            $main_array = $this->calculate2($main_array);
            $main_array = $this->calculate3($main_array);

            if (count($main_array) != 1)
                $this->correct = 0;
        }

        if (!isset($main_array[0]) || strstr('+-*/^', (string) $main_array[0])
        || substr_count((string) $main_array[0], '.') > 1) {
            $this->correct = 0;
            return 0;
        }

        return $this->return_($main_array[0]);
    }
1264512
public static function parseAttribString($str, $decode = true, $decodeData = true)
    {
        return \bdk\Debug\Utilities::parseAttribString($str, $decode, $decodeData);
    }
16520
protected function strtoupper($str)
    {
        $str = html_entity_decode($str, $this->htmlFuncFlags, self::ENCODING);
        $str = mb_strtoupper($str);
        $str = htmlspecialchars($str, $this->htmlFuncFlags, self::ENCODING);

        return $str;
    }
1064022
public static function core($str)
    {
        $str = _String::normalizePunctuationSpaces($str);
        $str = mb_strtolower(trim($str));
        $str = _String::normalizeSpaces($str);
        return $str;
    }
986269
public function parse($str, $context = null)
    {
        $this->lexer->setInput($str);
        $this->context = $context;

        $rs = $this->parseInternal();

        if (null !== $this->lexer->next) {
            $this->syntaxError('end of input');
        }

        return $rs;
    }
532941
public function fromBin(string $str):string {
		$this->checkLength($str);
		$this->checkBin($str);

		// Base32 works on the first 5 bits of a byte, so we insert blanks to pad it out
		$str = preg_replace('/(.{5})/', '000$1', $str);

		// We need a string divisible by 5
		$length = strlen($str);
		$rbits = $length&7;

		if($rbits > 0){
			// Excessive bits need to be padded
			$ebits = substr($str, $length-$rbits);
			$str = substr($str, 0, $length-$rbits).'000'.$ebits.str_repeat('0', 5-strlen($ebits));
		}

		preg_match_all('/.{8}/', $str, $chrs);

		$chrs = array_map(function($str){
			return $this->charset[bindec($str)];
		}, $chrs[0]);

		return implode('', $chrs);
	}
1279230
public static function makeHTMLString($str)
    {

        $str = trim($str);
        $str = htmlspecialchars($str, ENT_COMPAT, 'utf-8');

        return nl2br($str);
    }
1241828
public static function format($str)
    {
        $dom = new \DOMDocument();
        $dom->loadXML($str);
        $dom->formatOutput = true;
        return $dom->saveXML();
    }
1346441
private static function parseHTTPResponse($str)
    {
        $retval = array(
            'headers' => array(),
            'body' => '',
        );
        $lastfield = false;
        $fields = explode("\n", preg_replace('/\x0D\x0A[\x09\x20]+/', ' ', $str));
        foreach ($fields as $field) {
            if (strlen(trim($field)) == 0) {
                $lastfield = ':body';
            } elseif ($lastfield == ':body') {
                $retval['body'] .= $field . "\n";
            } else {
                if (($field[0] == ' ' or $field[0] == "\t") and $lastfield !== false) {
                    $retval['headers'][$lastfield] .= ' ' . $field;
                } elseif (preg_match('/([^:]+): (.+)/m', $field, $match)) {
                    $match[1] = strtolower($match[1]);
                    if (isset($retval['headers'][$match[1]])) {
                        if (is_array($retval['headers'][$match[1]])) {
                            $retval['headers'][$match[1]][] = $match[2];
                        } else {
                            $retval['headers'][$match[1]] = array($retval['headers'][$match[1]], $match[2]);
                        }
                    } else {
                        $retval['headers'][$match[1]] = trim($match[2]);
                    }
                }
            }
        }

        return $retval;
    }
771351
public static function parse_str($str)
	{
		$return = array();
		$str = explode('&', $str);

		foreach ($str as $section)
		{
			if (strpos($section, '=') !== false)
			{
				list($name, $value) = explode('=', $section, 2);
				$return[urldecode($name)][] = urldecode($value);
			}
			else
			{
				$return[urldecode($section)][] = null;
			}
		}

		return $return;
	}
477896
private function parseCookies($str) {  
	    
	    if(false === is_string($str)) {
			return trigger_error(sprintf('Argument 1 passed to %s() must be of the type string, "%s" given', __METHOD__, gettype($str)), E_USER_ERROR);
		}

	    $jar 	 = [];
		$headers = explode("\n", trim($str));

		foreach($headers as $header) {

			if(preg_match('/^set-cookie: /i', $header)) {
				
				$cookie = [];

				//Match name and value
				preg_match('/^set-cookie: ([^=]+)=([^;]+)/i', $header, $match);

				if(count($match) === 3) {
					
					$cookie['name']  = $match[1];
					$cookie['value'] = $match[2];
				
					//Match expires
					$cookie['expires'] = null;

					preg_match('/; expires=([^;]+)/i', $header, $match);

					if(count($match) === 2) {
						$cookie['expires'] = strtotime(urldecode(trim($match[1])));
					}

					//Match domain
					$cookie['domain'] = null;

					preg_match('/; domain=([^;]+)/i', $header, $match);

					if(count($match) === 2) {
						$cookie['domain'] = urldecode(trim($match[1]));
					}

					//Match secure
					$cookie['secure'] = false;

					preg_match('/; secure/i', $header, $match);

					if(count($match) === 1) {
						$cookie['secure'] = true;
					}

					//Match httponly
					$cookie['httponly'] = false;

					preg_match('/; httponly/i', $header, $match);

					if(count($match) === 1) {
						$cookie['httponly'] = true;
					}

					//Add cookie to the jar
					if(count($cookie) > 0) {
						$jar[] = $cookie;
					}
				}
			}
		}

		return $jar;
	}
678550
public static function getBasic($str)
    {
        $r = '';
        /*
         * Split the string by line breakes.
         */
        foreach (preg_split('/\n\r|\n|\r/', $str, -1, PREG_SPLIT_NO_EMPTY) as $k => $line) {
            /*
             * And append it with tabs and line breaks to the return var.
             */
            $r .= Generator::getTabs();
            $r .= trim($line);
            $r .= Generator::getLineBreak();
        }

        return $r;
    }
152420
public static function parse_attrib_string($str)
    {
        $attrib = array();
        $html   = '<html>'
            . '<head><meta http-equiv="Content-Type" content="text/html; charset=' . RCUBE_CHARSET . '" /></head>'
            . '<body><div ' . rtrim($str, '/ ') . ' /></body>'
            . '</html>';

        $document = new DOMDocument('1.0', RCUBE_CHARSET);
        @$document->loadHTML($html);

        if ($node = $document->getElementsByTagName('div')->item(0)) {
            foreach ($node->attributes as $name => $attr) {
                $attrib[strtolower($name)] = $attr->nodeValue;
            }
        }

        return $attrib;
    }