简而言之,我需要一个函数来尝试通过添加括号/引号来修复基本代码,以用于解析目的。也就是说,生成的代码不应该是可运行的。
让我们看几个例子:
[1] class Aaa { $var a = "hi"; => class Aaa { $var a = "hi"; }
[2] $var a = "hi"; } => { $var a = "hi"; }
[3] class { a = "hi; function b( } => class { a = "hi; function b( }"}
[4] class { a = "hi"; function b( } => class { a = "hi"; function b() {}}
PS:上面的第4个例子看起来很复杂,其实很简单。如果引擎发现一个与堆栈不匹配的结束括号标记,它应该在那个之前的相反标记。如您所见,这非常有效。
作为函数签名,它看起来像:balanceTokens($code, $bracket_tokens, $quote_tokens)
我编写的函数使用堆栈工作。好吧,它并不完全有效,但它确实使用了堆栈。
function balanceTokens($code, $bracket_tokens, $quote_tokens){
$stack = array(); $last = null; $result = '';
foreach(str_split($code) as $c){
if($last==$c && in_array($c, $quote_tokens)){
// handle closing string
array_pop($stack);
}elseif(!in_array($last, $quote_tokens)){
// handle other tokens
if(isset($bracket_tokens[$c])){
// handle begining bracket
$stack[] = $c;
}elseif(($p = array_search($c, $bracket_tokens)) != false){
// handle ending bracket
$l = array_pop($stack);
if($l != $p)$result .= $p;
}elseif(isset($quote_tokens[$c])){
// handle begining quote
$stack[] = $c;
$last = $c;
}// else other token...
}
$result .= $c;
}
// perform fixes
foreach($stack as $token){
// fix ending brackets
if(isset($bracket_tokens[$token]))
$result .= $bracket_tokens[$token];
// fix begining brackets
if(in_array($token, $bracket_tokens))
$result = $token . $result;
}
return $result;
}
该函数是这样调用的:
$new_code = balanceTokens(
$old_code,
array(
'<' => '>',
'{' => '}',
'(' => ')',
'[' => ']',
),
array(
'"' => '"',
"'" => "'",
)
);
是的,它很通用,没有任何硬编码的标记。
我一点也不知道为什么它不起作用……事实上,我什至不知道它是否应该起作用。我承认我没有花太多心思去写它。也许有一些我没有看到的明显问题。