dongwei8729 2012-04-10 18:22
浏览 18
已采纳

在php中填充前缀[关闭]

I'm trying to implement prefix to infix in PHP. The input should be for example something like this:

prefix  * + 3 2 4
infix   ((3+2)*4)

I want to convert prefix expression like (* + 3 2 4) into infix expression using PHP or JavaScript (((3+2)*4)).

  • 写回答

2条回答 默认 最新

  • doubu1964 2012-04-10 19:10
    关注

    An exemplary object oriented AST and parser:

    $prefix = '* + 3 2 4';
    $parser = new InfixPrefixParser($prefix);
    $node = $parser->parse();
    echo $node, "
    "; # ((3 + 2) * 4)
    echo ' = ', $node->evaluate(), "
    "; # 20
    

    The parser:

    class InfixPrefixParser extends IteratorIterator
    {
        public function __construct($prefix)
        {
            $tokens = new ArrayIterator(preg_split('/\s/', $prefix, 0, PREG_SPLIT_NO_EMPTY));
            parent::__construct($tokens);
        }
    
        /**
         * @return InfixNode
         */
        public function current()
        {
            $string = parent::current();
            parent::next();
            $operators = array('*' => 'Mult', '+' => 'Plus');
            $class = 'InfixNode' . (isset($operators[$string]) ? 'Operator' . $operators[$string] : 'Value');
            $node = new $class($string);
            if ($node instanceof InfixNodeOperator) {
                $node->setLeft($this->current());
                $node->setRight($this->current());
            }
            return $node;
        }
    
        public function __toString()
        {
            return (string)$this->parse();
        }
    
        public function parse()
        {
            $this->rewind();
            return $this->current();
        }
    }
    

    The object model for the AST

    abstract class InfixNode
    {
        abstract function evaluate();
    }
    
    abstract class InfixNodeOperator extends InfixNode
    {
        private $operator;
        protected $left;
        protected $right;
    
        public function __construct($operator)
        {
            $this->operator = $operator;
        }
    
        public function setLeft(InfixNode $node)
        {
            $this->left = $node;
        }
    
        public function getLeft()
        {
            return $this->left;
        }
    
        public function setRight(InfixNode $node)
        {
            $this->right = $node;
        }
    
        public function getRight()
        {
            return $this->right;
        }
    
        public function __toString()
        {
            return sprintf('(%s %s %s)', $this->left, $this->operator, $this->right);
        }
    }
    
    class InfixNodeOperatorMult extends InfixNodeOperator
    {
        public function evaluate()
        {
            return $this->left->evaluate() * $this->right->evaluate();
        }
    }
    
    class InfixNodeOperatorPlus extends InfixNodeOperator
    {
        public function evaluate()
        {
            return $this->left->evaluate() + $this->right->evaluate();
        }
    }
    
    class InfixNodeValue extends InfixNode
    {
        private $value;
    
        public function __construct($value)
        {
            $this->value = $value;
        }
    
        public function __toString()
        {
            return (string)$this->value;
        }
    
        public function evaluate()
        {
            return $this->value;
        }
    }
    

    I'm not very confident with the wording, because the nodes aren't exactly fully related to infix, large parts of them could be used for prefix or postfix as well, only the __toString() functions are infix related actually.


    (old version) Some PHP code, using some recursive parse function and an object model for the nodes. Usage:

    $prefix = '* + 3 2 4';
    
    $tokens = new ArrayIterator(preg_split('/\s/', $prefix, 0, PREG_SPLIT_NO_EMPTY));
    
    $parse = function() use ($tokens, &$parse) {
        $string = $tokens->current(); $tokens->next();
        $isOperator = in_array($string, array('*', '+'));
        $class = 'InfixNode' . ($isOperator ? 'Operator' : 'Value');
        $node = new $class($string);
        if ($node instanceof InfixNodeOperator) {
            $node->setLeft($parse());
            $node->setRight($parse());
        }
        return $node;
    };
    
    echo $parse(); # ((3 + 2) * 4)
    

    The node classes:

    class InfixNode {}
    
    class InfixNodeOperator extends InfixNode
    {
        private $operator;
        private $left;
        private $right;
        public function __construct($operator) {
            $this->operator = $operator;
        }
        public function setLeft(InfixNode $node) {
            $this->left = $node;
        }
        public function getLeft() {
            return $this->left;
        }
        public function setRight(InfixNode $node) {
            $this->right = $node;
        }
        public function getRight() {
            return $this->right;
        }
        public function __toString() {
            return sprintf('(%s %s %s)', $this->left, $this->operator, $this->right);
        }
    }
    
    class InfixNodeValue extends InfixNode
    {
        private $value;
        public function __construct($value) {
            $this->value = $value;
        }
        public function __toString() {
            return (string) $this->value;
        }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 乌班图ip地址配置及远程SSH
  • ¥15 怎么让点阵屏显示静态爱心,用keiluVision5写出让点阵屏显示静态爱心的代码,越快越好
  • ¥15 PSPICE制作一个加法器
  • ¥15 javaweb项目无法正常跳转
  • ¥15 VMBox虚拟机无法访问
  • ¥15 skd显示找不到头文件
  • ¥15 机器视觉中图片中长度与真实长度的关系
  • ¥15 fastreport table 怎么只让每页的最下面和最顶部有横线
  • ¥15 java 的protected权限 ,问题在注释里
  • ¥15 这个是哪里有问题啊?