PHP 中 EBNF 的递归下降解析器

发布于 2024-10-27 01:28:33 字数 2801 浏览 6 评论 0原文

我正在尝试用 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 函数时,我还从另一篇文章中找到了 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>

所以基本上我想知道导致该错误的原因以及原因以及我在创建此解析器方面是否走在正确的轨道上。

我感谢任何评论、建议、批评、水气球和西红柿。感谢您花时间阅读我的帖子。祝你度过愉快的一天/一夜。

I am attempting to write a recursive descent parser in PHP for the following EBNF:

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

I followed this guide which I saw recommended on a similar question. (I searched before I posted)

For the most part, I get how it works and I understand the grammar. I think the problem is within my syntax. I am new to PHP, so I have been referencing W3Schools. I currently am getting the following error with my code:

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

I have tried to look up this error and have not had much luck. I read some posts about people passing in the wrong parameter typed, but I do not have any parameters set for that function. Is there something about PHP I am missing here?

Below is my code, I think the logic is correct since I based it off of the parse tree for the grammar. The $input will be coming from a form box on an HTML page. I also picked up the str_split function from a different post when I discovered that PHP4 does not have it built in.

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

So basically I want to know what causes that error and why and am I on the right track in terms of creating this parser.

I appreciate any comments, suggestions, criticisms, water baloons, and tomatoes. Thank you for taking the time to read my post. Have a great day/night.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

甜`诱少女 2024-11-03 01:28:33

exp() 是一个内置的 PHP 函数。您不能用该名称来定义它。

应该没有理由在普通 PHP 应用程序中使用 if(!function_exists(') 习惯用法。(当包含脚本冲突或在不同位置声明相同的函数时,它通常更多地用作解决方法。)


您 我注意到的语法问题是您对按位 OR 的使用。逻辑 OR 应该是 || 或只是 or

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

exp() is a builtin PHP function. You cannot define it under that name.

You should have no reason to use the if(!function_exists(' idiom in normal PHP applications. (It's often used more as a workaround when include scripts clash or identical functions are declared at different places.)


Another syntax problem that I noticed is your use of the bitwise OR. The logical OR should be || or just or.

while($token == "*" | $token == "/"){
抚笙 2024-11-03 01:28:33

我会把我的疯狂猜测变成答案。那么也许这就是,问题出在哪里呢?

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

I'll turn my wild guess into an answer. So maybe this is, where the problem lies?

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

半透明的墙 2024-11-03 01:28:33

PHP 中已经有一个名为 exp() 的函数。您可以以某种方式为函数名称添加前缀,或者最好使用类来避免名称冲突。

There is also a function named exp() in PHP already. You may prefix your function names somehow, or it's better to use classes to avoid name collisions.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文