当前位置: 首页 > 后端技术 > PHP

用PHP编写最简单的解释器Part2

时间:2023-03-30 00:18:44 PHP

之前写过一个计算器,是用JS实现的,但是当时没想好办法,最后用JS的eval函数实现了对字符串的解析计算。这不是一个好方法。如果实现的计算器比较复杂,你最终会发现程序非常臃肿。下一部分在重构https://github.com/rspivak/ls...的同时,实现一个完整的计算器的解释器Part2代码实现函数加法运算减法运算去除空格多位运算type=$type;$this->value=$value;}/**使用这个方法获取类的私有属性*/publicfunction__get($name){return$this->{$name};}/**用于调试*/publicfunction__toString(){return'type:'.$this->type.'值:'.$this->value;}}//解释器类Interpreter{private$current_char;私人$current_token;私人$文本;私人$pos=0;/***$text需要输入该行解释的字符串*/publicfunction__construct($text){//去掉这些空格前后可能存在的空格$this->text=trim($text);//初始化获取第一个字符$this->current_char=$this->text[$this->pos];}publicfunctionerror(){thrownew\Exception('Lexereroor');}/*步进法,每次字符运算后前进一位*/publicfunctionadvance(){$this->pos++;如果($this->pos>strlen($this->text)-1){$this->current_char=null;}else{$this->current_char=$this->text[$this->pos];}}/*删除空格*/publicfunctionskip_whitespace(){if($this->current_char!=null&&$this->current_char==WHITESPACE){$this->advance();}}/*如果要支持多位整数,需要存储每一位数字*/publicfunctionintegers(){$result='';//用于存储数字while($this->current_char!=null&&is_numeric($this->current_char)){//循环,只要当前字符是数字,将数字存入$result$result.=$this->current_char;$this->advance();//步骤方法,每个字符操作后前进一位}returnintval($result);//将数字串转为整数}//获取当前字符的Tokenpublicfunctionget_next_token(){while($this->current_char!=null){如果($this->current_char==WHITESPACE){$this->skip_whitespace();继续;}if(is_numeric($this->current_char)){returnnewToken(ISINTEGER,$this->integers());}if($this->current_char=="+"){$this->advance();返回新令牌(加号,'+');}if($this->current_char=="-"){$this->advance();返回新令牌(负号,'-');}returnnewToken('EOF',null);}}//如果字符类型与判断的类型一致,则继续,否则输入错误publicfunctioneat($token_type){if($this->current_token->type==$token_type){$this->current_token=$this->get_next_token();}}else{$this->error();}}//解释方法publicfunctionexpr(){$this->current_token=$this->get_next_token();//获取字符串开头的数字$left=$this->current_token;$this->eat(ISINTEGER);//判断获取的字符串前半部分是否为整数$op=$this->current_token;//获取前半部分紧跟的字符并判断是哪种运算符它是if($op->type==PLUS)$this->eat(PLUS);否则$this->eat(MINUS);$right=$this->current_token;//获取最后一部分,判断是否为整数$this->eat(ISINTEGER);如果($op->type==PLUS)$result=$left->value+$right->value;否则$result=$left->value-$right->value;返回$结果;}}do{fwrite(STDOUT,'xav>');;$输入=fgets(标准输入);$Interpreter=新解释器($input);echo$Interpreter->expr();取消设置($解释器);}而(真);