\'[^\\\\\']*+(?:\\\\.[^\\\\\']*+)*+\') (?"[^\\\\"]*+(?:\\\\.[^\\\\"]*+)*+") (?(?&singleQuotedString)|(?&doubleQuotedString)) (?/\*[^*]*+(?:\*(?!/)[^*]*+)*+\*/) (?\{[^\'"/{}]*+(?:(?:(?&string)|(?&comment)|(?&code)|/)[^\'"/{}]*+)*+}) )'; const PARAMS = '\[(?[^[\]]*+(?:\[(?¶ms)\][^[\]]*+)*+)\]'; const ARGS = '\((?[^()]*+(?:\((?&args)\)[^()]*+)*+)\)'; const RULE_BLOCK = '(?[a-z_]++):(?[^\'"/{};]*+(?:(?:(?&string)|(?&comment)|(?&code)|/|})[^\'"/{};]*+)*+);'; $tokensToExtract = array_flip(array( 'T_VARIABLE', 'T_STRING', 'T_INLINE_HTML', 'T_ENCAPSED_AND_WHITESPACE', 'T_LNUMBER', 'T_DNUMBER', 'T_CONSTANT_ENCAPSED_STRING', 'T_STRING_VARNAME', 'T_NUM_STRING' )); function regex($regex) { return '~' . LIB . '(?:' . str_replace('~', '\~', $regex) . ')~'; } function magicSplit($regex, $string) { $pieces = preg_split(regex('(?:(?&string)|(?&comment)|(?&code))(*SKIP)(*FAIL)|' . $regex), $string); foreach ($pieces as &$piece) { $piece = trim($piece); } return array_filter($pieces); } function generateNodeFilesFromSignatures($signatures, $dir) { foreach ($signatures as $nodeName => $signature) { $code = <<'; //////////////////// //////////////////// //////////////////// list($defs, $ruleBlocks) = magicSplit('%%', file_get_contents(IN)); if ('' !== trim(preg_replace(regex(RULE_BLOCK), '', $ruleBlocks))) { die('Not all rule blocks were properly recognized!'); } $nodeSignatures = array(); preg_match_all(regex(RULE_BLOCK), $ruleBlocks, $ruleBlocksMatches, PREG_SET_ORDER); foreach ($ruleBlocksMatches as $match) { $ruleBlockName = $match['name']; $rules = magicSplit('\|', $match['rules']); foreach ($rules as &$rule) { $parts = magicSplit('\s+', $rule); $usedParts = array(); foreach ($parts as $part) { if ('{' === $part[0]) { preg_match_all('~\$([0-9]+)~', $part, $backReferencesMatches, PREG_SET_ORDER); foreach ($backReferencesMatches as $match) { $usedParts[$match[1]] = true; } preg_match_all('~(?[A-Z][a-zA-Z]++)' . PARAMS . '~', $part, $nodeMatches, PREG_SET_ORDER); foreach ($nodeMatches as $match) { $signature =& $nodeSignatures[$match['name']]; $params = magicSplit('(?:' . PARAMS . '|' . ARGS . ')(*SKIP)(*FAIL)|,', $match['params']); if (!isset($signature)) { $signature = array(); foreach ($params as $i => $param) { list($name, ) = explode(': ', $param, 2); $signature[$i] = $name; } } else { foreach ($params as $i => $param) { list($name, ) = explode(': ', $param, 2); if ($signature[$i] != $name) { die('Signature mismatch for "' . $match['name'] . '"'); } } } } } } $i = 1; foreach ($parts as &$part) { if ('/' === $part[0]) { continue; } if (isset($usedParts[$i])) { if ('\'' === $part[0] || '{' === $part[0]) { $part = '' . $part . ''; } elseif ('T' === $part[0] && !isset($tokensToExtract[$part])) { $part = '' . $part . ''; } else { $part = '' . $part . ''; } } elseif (ctype_lower($part[0])) { $part = '' . $part . ''; } elseif ('T' === $part[0] && isset($tokensToExtract[$part])) { $part = '' . $part . ''; } ++$i; } $rule = implode(' ', $parts); } echo $ruleBlockName, ':', "\n", ' ', implode("\n" . ' | ', $rules), "\n", ';', "\n\n"; } var_dump($nodeSignatures); var_dump(array_keys($nodeSignatures)); $names = array(); foreach ($nodeSignatures as $params) { foreach ($params as $param) { $names[$param] = true; } } var_dump(array_keys($names)); generateNodeFilesFromSignatures($nodeSignatures, './lib/Node');