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

用PHP写最简单的解释器Part5(最后一节计算器,如何写脚本语言在下一节)

时间:2023-03-29 22:45:36 PHP

经过几天的努力,已经用PHP实现了一个完整的基础计算器,如下代码type=$type;$this->value=$value;}/**通过这个方法获取类*/publicfunction__get($name){return$this->{$name};}/**用于调试*/publicfunction__toString(){return'type:'.$this->type.'值:'.$this->value;}}classLexer{private$current_char;私人$current_token;私人$文本;私人$pos=0;/***$要解释的文本字符串*/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){if($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();返回新令牌(负号,'-');}if($this->current_char=="*"){$this->advance();返回新令牌(MUL,'*');}if($this->current_char=="/"){$this->advance();返回新令牌(DIV,'/');}if($this->current_char=="("){$this->advance();返回新令牌(LPAREN,'(');}if($this->current_char==")"){$this->advance();returnnewToken(RPAREN,')');}returnnewToken('EOF',null);}}}//解释器类Interpreter{private$current_token;私人$词法分析器;publicfunction__construct($lexer){//去掉这些空格前后可能存在的空格$this->lexer=$lexer;//初始化获取第一个字符$this->current_token=$this->lexer->get_next_token();}//如果字符类型与判断的类型一致,则继续,否则输入错误publicfunctioneat($token_type){if($this->current_token->type==$token_type){$this->current_token=$this->词法分析器->get_next_token();}else{$this->error();}}publicfunctionerror(){thrownew\Exception('eroor');}publicfunctionfactor(){$token=$this->current_token;如果($token->type==ISINTEGER){$this->eat(ISINTEGER);返回$令牌->值;}elseif($token->type==LPAREN){$this->eat(LPAREN);$result=$this->expr();$这个->吃(RPAREN);返回$结果;}}publicfunctionterm(){$result=$this->factor();while(in_array($this->current_token->type,[MUL,DIV])){$token=$this->current_token;如果($token->type==MUL){$this->eat(MUL);$result=$result*$this->factor();}elseif($token->type==DIV){$这个->吃(DIV);$result=$result/$this->factor();}}返回$结果;}//解释方法publicfunctionexpr(){$result=$this->term();while(in_array($this->current_token->type,[PLUS,MINUS])){$token=$this->current_token;如果($token->type==PLUS){$this->eat(PLUS);$result=$result+$this->term();}elseif($token->type==MINUS){$this->eat(MINUS);$result=$result-$this->term();}}返回$结果;}}do{fwrite(STDOUT,'xav>');;$输入=fgets(标准输入);$Interpreter=newInterpreter(newLexer($input));echo$Interpreter->expr();取消设置($解释器);}而(真);有空我还要学习如何用图解来描述上面的逻辑。这是最后一篇文章。下一次,我真的应该写一个脚本语言!以上代码已全部上传到GITHUB,欢迎star传送门