2011-03-27 124 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中了。你可能会以某种方式为你的函数名添加前缀,或者最好使用类来避免名称冲突。