6

次の EBNF に対して、PHP で再帰降下パーサーを作成しようとしています。

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

同様の質問で推奨されているこのガイドに従いました。(投稿前に調べました)

ほとんどの場合、私はそれがどのように機能するかを理解し、文法を理解しています. 問題は私の構文にあると思います。私は PHP が初めてなので、W3Schoolsを参照しています。現在、コードで次のエラーが発生しています。

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

このエラーを調べてみましたが、うまくいきませんでした。間違ったパラメーターを入力した人に関する投稿を読みましたが、その関数にパラメーターが設定されていません。ここで欠けているPHPについて何かありますか?

以下は私のコードです。文法の解析ツリーに基づいているため、ロジックは正しいと思います。$input は、HTML ページのフォーム ボックスから取得されます。また、PHP4 には str_split 関数が組み込まれていないことを発見したときに、別の投稿から str_split 関数を取り上げました。

<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>

したがって、基本的に、そのエラーの原因とその理由を知りたいのですが、このパーサーを作成するという点で正しい軌道に乗っています。

コメント、提案、批判、水風船、トマトに感謝します。私の投稿を読んでくれてありがとう。素晴らしい昼/夜をお過ごしください。

4

3 に答える 3

6

exp()組み込みの PHP 関数です。その名前で定義することはできません。

if(!function_exists('通常の PHP アプリケーションでイディオムを使用する必要はありません。(これは、インクルード スクリプトが衝突したり、同一の関数が別の場所で宣言されたりした場合の回避策としてよく使用されます。)


私が気付いたもう 1 つの構文の問題は、ビットごとの OR の使用です。論理 OR は||または である必要がありますor

while($token == "*" | $token == "/"){
于 2011-03-28T00:03:43.860 に答える
1

私の勝手な推測を答えに変えます。問題はどこにあるのでしょうか?

http://php.net/manual/en/function.exp.php

于 2011-03-28T00:04:49.517 に答える
1

PHP にはすでに exp() という名前の関数もあります。関数名に何らかの接頭辞を付けるか、名前の衝突を避けるためにクラスを使用することをお勧めします。

于 2011-03-28T00:04:55.543 に答える