/** * Optimize regular expression * * Tries to optimize the given regular expression. Returns true if the AST * has been modified, and false otherwise. * * @param slRegularExpression $regularExpression * @return bool */ public function optimize(slRegularExpression &$regularExpression) { if ($regularExpression instanceof slRegularExpressionMultiple && count($children = $regularExpression->getChildren()) === 1) { $regularExpression = reset($children); return true; } return $this->recurse($regularExpression); }
/** * Optimize regular expression * * Tries to optimize the given regular expression. Returns true if the AST * has been modified, and false otherwise. * * @param slRegularExpression $regularExpression * @return bool */ public function optimize(slRegularExpression &$regularExpression) { if ((($op1 = $regularExpression instanceof slRegularExpressionOptional) || $regularExpression instanceof slRegularExpressionRepeated) && (($op2 = $regularExpression->getChild() instanceof slRegularExpressionOptional) || $regularExpression->getChild() instanceof slRegularExpressionRepeated)) { $class = $op1 && $op2 ? 'slRegularExpressionOptional' : 'slRegularExpressionRepeated'; $regularExpression = new $class($regularExpression->getChild()->getChild()); return true; } return $this->recurse($regularExpression); }
/** * Recurse through the container stack * * Recurse through the container stack and call the optimize method for * each child. * * Returns true, if something has been modified, and false otherwise. * * @param slRegularExpression $regularExpression * @return bool */ protected function recurse(slRegularExpression $regularExpression) { if (!$regularExpression instanceof slRegularExpressionContainer) { return false; } $modified = false; $children = $regularExpression->getChildren(); foreach ($children as &$child) { $modified |= $this->optimize($child); } if ($modified) { $regularExpression->setChildren($children); } return (bool) $modified; }
/** * Recursively filters out start and end markers * * Recursively filter out start and end markers from the regular expression * structure, since they do not have any real meaning, but were required to * create correct automatons. * * @param slRegularExpression $regularExpression * @return slRegularExpression */ protected function filterStartEndMarkers(slRegularExpression $regularExpression) { if ($regularExpression instanceof slRegularExpressionMultiple) { foreach ($regularExpression->getChildren() as $nr => $child) { if ($child instanceof slRegularExpressionElement && ($child->getContent() === 0 || $child->getContent() === 1)) { $regularExpression[$nr] = new slRegularExpressionEmpty(); } else { $this->filterStartEndMarkers($child); } } } if ($regularExpression instanceof slRegularExpressionSingular) { $child = $regularExpression->getChild(); if ($child instanceof slRegularExpressionElement && ($child->getContent() === 0 || $child->getContent() === 1)) { $regularExpression->setChild(new slRegularExpressionEmpty()); } else { $this->filterStartEndMarkers($child); } } return $regularExpression; }
/** * Get all elements occureing in a regular expression * * @param slRegularExpression $regExp * @return array */ protected function getChildElements(slRegularExpression $regExp) { if ($regExp instanceof slRegularExpressionElement) { return array($regExp->getContent()); } if (!$regExp instanceof slRegularExpressionContainer) { return array(); } $children = array(); foreach ($regExp->getChildren() as $child) { $children = array_merge($children, $this->getChildElements($child)); } return $children; }
/** * Extracts all types mentioned in a regular exression * * Returns an unique array with all types mentioned in the regular * expression, to create proper mixed types in the DTD schema output. * * @param slRegularExpression $regularExpression * @return array */ protected function extractTypes(slRegularExpression $regularExpression) { if ($regularExpression instanceof slRegularExpressionElement) { return array($regularExpression->getContent()); } if (!$regularExpression instanceof slRegularExpressionContainer) { return array(); } $types = array(); foreach ($regularExpression->getChildren() as $child) { $types = array_merge($types, $this->extractTypes($child)); } return array_unique($types); }