2011-03-27 116 views
6

我試圖用PHP編寫的遞歸下降解析器以下EBNF:
遞歸下降解析器EBNF在PHP

EXP ::= <TERM> { (+ | -) <TERM> } 
TERM ::= <FACTOR> { (* | /) <FACTOR> } 
FACTOR ::= (<EXP>) | <DIGIT> 
DIGIT ::= 0 | 1 | 2 | 3 

我跟着這個guide我所看見的推薦上了類似的問題。 (在我發佈之前我搜索過)

大多數情況下,我知道它是如何工作的,並且我理解語法。我認爲這個問題在我的語法中。我是PHP新手,所以我一直在參考W3Schools。我目前正在以下錯誤我的代碼:

Warning: Wrong parameter count for exp() .... on line 101 

我試圖查找此錯誤,並沒有多少運氣。我閱讀了一些關於傳入錯誤參數類型的人的帖子,但是我沒有爲該函數設置任何參數。有什麼關於我在這裏失蹤的PHP?

下面是我的代碼,我認爲邏輯是正確的,因爲我基於它的語法分析樹。 $輸入將來自HTML頁面上的表單框。我也從一個不同的崗位拿起str_split功能時,我發現,PHP4沒有它內置的。

<html> 
<body> 
<?php 
if(!function_exists("exp")){ 
    function exp(){ 
    term(); 
    while($token == "+" | $token == "-"){ 
     if($token == "+"){ 
      match("+"); 
      term(); 
     } 
     if($token == "-"){ 
      match("-"); 
      term(); 
     } 
    } 
    }//end exp 
} 

if(!function_exists("term")){ 
    function term(){ 
    factor(); 
    while($token == "*" | $token == "/"){ 
     if($token == "*"){ 
      match("*"); 
      factor(); 
     } 
     if($token == "/"){ 
      match("/"); 
      factor(); 
     } 
    } 
    }//end term 
} 

if(!function_exists("factor")){ 
    function factor(){ 
    if($token == "("){ 
     match("("); 
     exp(); 
     if($token == ")") 
      match(")"); 
    } 
    else if($token == 0|1|2|3){ 
     if($token == 0) 
      match(0); 
     if($token == 1) 
      match(1); 
     if($token == 2) 
      match(2); 
     if($token == 3) 
      match(3); 
    } 
    else 
     error(); 
    }//end factor 
} 

if(!function_exists("match")){ 
    function match($expected){ 
    if($token == $expected) 
     nextToken(); 
    else 
     error(); 
    }//end match 
} 

if(!function_exists("next_Token")){ 
    function nextToken(){ 
    $next++; 
    $token = $tokenStr[$next]; 
    if($token == "$"); 
     legal(); 
    } 
} 

if(!function_exists("error")){ 
    function error(){ 
    echo "Illegal token stream, try again"; 
    } 
} 

if(!function_exists("legal")){ 
    function legal(){ 
    echo "Legal token stream, congrats!"; 
    } 
} 

if(!function_exists('str_split')) { 
    function str_split($string, $split_length = 1) { 
    $array = explode("\r\n", chunk_split($string, $split_length)); 
    array_pop($array); 
    return $array; 
    } 
} 

$tokenStr = str_split($input); 
$next = 0; 
$token = $tokenStr[0]; 
exp(); 
?> 
</body> 
</html> 

所以基本上我想知道是什麼原因導致的錯誤,爲什麼和我是在正確的軌道上創建此解析器的條款。

我很欣賞任何意見,建議,批評,水上巴士和西紅柿。感謝您花時間閱讀我的文章。祝您有美好的一天/晚上。

+1

對不起,瘋狂的猜測,但不是某種與數學中的'exp()'函數衝突:http://php.net/manual/en/function.exp.php? – julkiewicz 2011-03-28 00:00:56

+0

謝謝,這正是它,但現在一切正常編譯沒有輸出。我的猜測是它沒有得到傳入的輸入。我的函數如何訪問全局變量有問題嗎? – Seephor 2011-03-28 02:15:37

回答

6

exp()是PHP內置函數。你不能用這個名字來定義它。

在正常的PHP應用程序中,您應該沒有理由使用if(!function_exists('慣用法。 (它通常使用較多包括腳本衝突或相同的功能在不同的地方聲明時解決此問題。)


,我注意到另外一個語法問題是你的位OR的使用。邏輯OR應該是||或者只是or

while($token == "*" | $token == "/"){ 
+0

因爲沒有考慮到這一點,我感到有點無聊。非常感謝你。我清理了代碼,使用了邏輯OR並刪除了函數存在的調用,並且現在正在檢查以確保它們全部正常工作。 – Seephor 2011-03-28 00:13:55

+0

清理完成後它是否工作? – 2013-05-14 06:47:26

1

還有一個功能名爲EXP()在PHP中了。你可能會以某種方式爲你的函數名添加前綴,或者最好使用類來避免名稱衝突。