1

我需要在我的网络应用程序中实现以下内容。我知道我的解决方案是不正确的,但我把代码 jsut 来演示这个想法。

有一个类'弧'。我需要能够为这个弧分配任何表达式(例如a+b+c、ac、if-then)。一旦分配了表达式,我希望能够使用一些随机获取的变量来执行它。是否可以在 Web 应用程序中实现这样的功能?也许,我应该使用一些像 MathPL 这样的插件?或者也许有一种完全不同的方法来解决这类问题?

class arc {

    var $arcexpression;

    function setExpression($arcexpression) {
        $this->arcexpression = $arcexpression;
    }

    function getExpression() {
        return $this->arcexpression;
    }


}

$arc = new arc();

$arc->setExpression("if a>b then return a else return b");

$result = $arc->execute(a,b);  // the function 'execute' should be somehow described in 'arc'
4

1 回答 1

0

您不需要为此实现整个语言。我将从限制可以做的事情开始,例如,将表达式限制为算术运算符(+、-、*、/)、括号和 if-then 运算符。您需要为 if-then 强制执行某种语法以使其更容易,可能与 php 的 operator 相同?:。之后,您只需要为此语法构建解析器:将给定的表达式解析为树。例如,表达式 `a + b * c' 会解析成如下内容:

  +
 / \
a   *
   / \
  b   c

之后,您只需要评估这些表达式。例如,通过将一个数组传递给您evaluate的 type 函数{ a => 1, b => 2, c => 3 },您将得到 7 个。

解析的思路如下:

  1. 从字符串中的位置 1 开始 - 并调用递归函数来解析该位置的数据。在函数中,从指定位置开始读取。
  2. 如果您阅读左括号,请递归调用自身
  3. 如果遇到右括号或字符串结尾,则返回根节点
  4. 读取第一个标识符(或在括号内递归)
  5. 读算术符号
  6. 读取第二个标识符(或在括号内递归)
  7. 如果符号是 * 或 /,则创建其中包含符号的节点和两个操作数作为子节点,并将该节点附加为前一个运算符的相应(左或右)子节点。
  8. 如果符号是 + 或 -,则 find 创建带有符号的节点,其中一个子节点是操作数之一,第二个节点是子树的根节点,* 和 / 在根(或第二个操作数,如果它是一个简单的操作)。

得到纯算术,加上括号,工作很容易;if-then 有点棘手,但还算不错。大约 10 年前,我不得不在 Java 中实现类似的东西。我花了大约 3 天的时间来整理所有内容,并且在 1 个类中总共有大约 500 行代码,不包括 javadoc。我怀疑在 PHP 中代码会更少,因为 PHP 语法和类型转换非常简单。

这听起来可能很复杂,但实际上,一旦你开始这样做,它就会比看起来容易得多。我清楚地记得 17 到 18 年前的大学作业,作为算法课的一部分做类似的事情。

于 2012-07-19T14:18:34.240 回答