6

我正在尝试在 PHP 中为以下 EBNF 编写递归下降解析器:

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 函数时,我还从另一篇文章中选择了它。

<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 应用程序中使用该惯用语。(当包含脚本冲突或在不同位置声明相同的函数时,它通常更多地用作解决方法。)


我注意到的另一个语法问题是您使用按位或。逻辑 OR 应该是||or just 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 回答