1
我正在嘗試創建一個公式解析器,並且我當前被困在如何遞歸地將代碼轉換爲表達式數組。以下面的公式,例如:遞歸解析預格式化數組
$formula = "
@VAR[a, 3];
@IF[ (a <= 3) & (a = 3) ]:
@VAR[a, a + 4];
@IF[ a > 5 ]:
@USE[a];
@ENDIF
@ELSEIF[ a > 4 ]:
@VAR[a, 2];
@ELSE:
@VAR[a, 5];
@ENDIF
@VAR[a,5];
@USE[a];
";
應該輸出:
{
"0": "VAR[a, 3];",
"IF[ (a <= 3) & (a = 3) ]:": {
"0": "VAR[a, a + 4];",
"1": "ENDIF",
"IF[ a > 5 ]:": [
"USE[a];"
]
},
"ELSEIF[ a > 4 ]:": [
"VAR[a, 2];"
],
"ELSE:": [
"VAR[a, 5];"
],
"1": "ENDIF",
"2": "VAR[a,5];",
"3": "USE[a];",
}
所以,我可以通過每個項目迭代並評估每個表達式。
我目前有以下代碼,它不輸出預期的格式。
<?php
$formula = "
@VAR[a, 3];
@IF[ (a <= 3) & (a = 3) ]:
@VAR[a, a + 4];
@IF[ a > 5 ]:
@USE[a];
@ENDIF
@ELSEIF[ a > 4 ]:
@VAR[a, 2];
@ELSE:
@VAR[a, 5];
@ENDIF
@VAR[a,5];
@USE[a];
";
$formulas = explode("@", $formula);
$result = parse($formulas);
echo json_encode($result);
function parse($lines ){
$exec_tree = array();
foreach($lines as $i => $block){
unset($lines[$i]);
$block = trim(str_replace(array(" ") , "" , preg_replace('/\s\s+/', ' ', $block)));
if(trim($block) != ""){
// MATCH Variable assignments
if(preg_match('/VAR\[(.*)\]\;?/', $block)){
$exec_tree[] = $block;
}
// MATCH USE Statements
if(preg_match('/USE\[(.*)\]\;?/', $block)){
$exec_tree[] = $block;
}
// MATCH IFs
if(preg_match('/^IF\[(.*)\]\:/', $block)){
$exec_tree[$block] = parse($lines);
}
// MATCH ELSEIFs
if(preg_match('/^ELSEIF\[(.*)\]\:/', $block)){
$exec_tree[$block] = parse($lines);
}
// MATCH ELSEs
if(preg_match('/^ELSE:/', $block)){
$exec_tree[$block] = parse($lines);
}
// MATCH ENDIFs
if(preg_match('/^ENDIF/', $block)){
break;
}
}
}
return $exec_tree;
}
代碼本質上是遞歸的,但我認爲我錯過了遞歸的終止。它應該以ENDIF關鍵字結束。任何人都可以指出我正確的方向將不勝感激。
現在這是它的輸出:(JSON格式)
[
"VAR[a,3];",
[
"IF[(a<=3)&(a=3)]:",
[
"VAR[a,a+4];",
[
"IF[a>5]:",
[
"USE[a];"
]
],
"USE[a];"
]
],
"VAR[a,a+4];",
[
"IF[a>5]:",
[
"USE[a];"
]
],
"USE[a];"
]
感謝,
月
我只想澄清一下,&$ rec有什麼用? –
哦。這是一個遞歸標誌,注意是否已達到最後一個案例。 –
工作,非常感謝! :) –