成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

用PHP寫(xiě)一個(gè)最簡(jiǎn)單的解釋器Part2

sixleaves / 1790人閱讀

摘要:之前寫(xiě)過(guò)一個(gè)計(jì)算器,采用實(shí)現(xiàn)的,不過(guò)當(dāng)時(shí)沒(méi)有想到的好的辦法,最終采用了的函數(shù)來(lái)實(shí)現(xiàn)字符串的解析和運(yùn)算。

之前寫(xiě)過(guò)一個(gè)計(jì)算器,采用JS實(shí)現(xiàn)的,不過(guò)當(dāng)時(shí)沒(méi)有想到的好的辦法,最終采用了JS的eval函數(shù)來(lái)實(shí)現(xiàn)字符串的解析和運(yùn)算。

這并不是的好的方法,如果實(shí)現(xiàn)的計(jì)算器比較復(fù)雜,最終會(huì)發(fā)現(xiàn)程序十分臃腫.

接下來(lái)部分,在重構(gòu)https://github.com/rspivak/ls... 的同時(shí),并實(shí)現(xiàn)一個(gè)完整計(jì)算器的解釋器

Part2代碼實(shí)現(xiàn)功能

加法運(yùn)算

減法運(yùn)算

去除空格

多位數(shù)運(yùn)算

type=$type;
        $this->value=$value;
    }
    
    /**
    通過(guò)該方法來(lái)獲取類的私有屬性
    */
    public function __get($name)
    {
        return $this->{$name};
    }
    /**
    用于調(diào)試
    */
    public function __toString()
    {
        return "type:".$this->type." value:".$this->value;
    }
}

//解釋器
class Interpreter{
    private $current_char ;
    private $current_token ;
    private $text;
    private $pos=0;
    /***
    $text 需要進(jìn)行解釋的字符串
    */
    public function __construct($text){
        //去除前后可能存在的空格 這些空格是無(wú)效的
        $this->text=trim($text);
        //初始化 獲取第一個(gè)字符
        $this->current_char = $this->text[$this->pos];
    }
    
    public function error()
    {
        throw new Exception("Lexer eroor");
    }
    
    /*
    步進(jìn)方法,每操作一個(gè)字符后前進(jìn)一位
    */
    public function advance()
    {
        $this->pos++;
        if ($this->pos>strlen($this->text)-1){
            $this->current_char=null;
        }else{
            $this->current_char=$this->text[$this->pos];
        }
    }
    
    /*
    去除空格
    */
    public function skip_whitespace()
    {
        if ($this->current_char!=null&&$this->current_char==WHITESPACE){
            $this->advance();
        }
    }
    
    /*
    如果要支持多位的整數(shù),則需要將每位數(shù)字存儲(chǔ)起來(lái)
    */
    public function integers()
    {
        $result="";//用于存儲(chǔ)數(shù)字
        while($this->current_char!=null&&is_numeric($this->current_char)){//只要當(dāng)前字符是數(shù)字就一直循環(huán)并將數(shù)字存儲(chǔ)于$result
            $result.=$this->current_char;
            $this->advance();//步進(jìn)方法,每操作一個(gè)字符后前進(jìn)一位
        }
        return intval($result);//將數(shù)字字符串轉(zhuǎn)成整數(shù)
    }
    
    //獲取當(dāng)前字符的Token  
    public function get_next_token()
    {
        while($this->current_char!=null){
            if ($this->current_char==WHITESPACE){
                $this->skip_whitespace();
                continue;
            }
            if (is_numeric($this->current_char)){
                return new Token(ISINTEGER,$this->integers());
            }
            
            if ($this->current_char=="+"){
                $this->advance();
                return new Token(PLUS,"+");
            }
            
            if ($this->current_char=="-"){
                $this->advance();
                return new Token(MINUS,"-");
            }
            return new Token("EOF", null);
        }
    }
    
    //如果字符類型和判斷的類型一致,則繼續(xù),否則輸入錯(cuò)誤
    public function eat($token_type)
    {
        if ($this->current_token->type==$token_type){
            $this->current_token=$this->get_next_token();
        }else{
            $this->error();
        }
    }
    
    //解釋方法
    public function expr()
    {
        $this->current_token=$this->get_next_token();//獲取字符串開(kāi)頭部分的數(shù)字
        $left=$this->current_token;
        $this->eat(ISINTEGER);//判斷取得的前半部分字符串是整數(shù)不是
        $op=$this->current_token;//獲取前半部分后緊接的字符 并判斷是何種操作符
        if ($op->type==PLUS)
            $this->eat(PLUS);
        else
            $this->eat(MINUS);
        $right=$this->current_token;//獲取最后部分 并判斷是否是整數(shù)
        $this->eat(ISINTEGER);
        
        if ($op->type==PLUS)
            $result=$left->value+$right->value;
        else
            $result=$left->value-$right->value;
        return $result;
    }
}

do{
    fwrite(STDOUT,"xav>");;
    $input=fgets(STDIN);
    $Interpreter=new Interpreter($input);
    echo $Interpreter->expr();
    unset($Interpreter);
    
}while(true);


文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/29001.html

相關(guān)文章

  • 測(cè)試你前端代碼 - part2(單元測(cè)試)

    摘要:?jiǎn)卧獪y(cè)試上一節(jié)有討論過(guò),單元測(cè)試就是以代碼單元為單位進(jìn)行測(cè)試,代碼單元可以是一個(gè)函數(shù),一個(gè)模塊,或者一個(gè)類。單元測(cè)試是最容易理解也最容易實(shí)現(xiàn)的測(cè)試方式。在寫(xiě)單元測(cè)試的時(shí)候,盡量將你的單元測(cè)試獨(dú)立出來(lái),不要幾個(gè)單元互相引用。 showImg(https://segmentfault.com/img/remote/1460000008823416?w=997&h=350); 本文作者:G...

    daydream 評(píng)論0 收藏0
  • 測(cè)試你前端代碼 - part2(單元測(cè)試)

    摘要:?jiǎn)卧獪y(cè)試上一節(jié)有討論過(guò),單元測(cè)試就是以代碼單元為單位進(jìn)行測(cè)試,代碼單元可以是一個(gè)函數(shù),一個(gè)模塊,或者一個(gè)類。單元測(cè)試是最容易理解也最容易實(shí)現(xiàn)的測(cè)試方式。在寫(xiě)單元測(cè)試的時(shí)候,盡量將你的單元測(cè)試獨(dú)立出來(lái),不要幾個(gè)單元互相引用。 showImg(https://segmentfault.com/img/remote/1460000008823416?w=997&h=350); 本文作者:G...

    shadajin 評(píng)論0 收藏0
  • 《JavaScript設(shè)計(jì)模式》閱讀筆記_part2

    摘要:它屬于類創(chuàng)建型模式?;诶^承,將復(fù)雜的放置在函數(shù)中,簡(jiǎn)單的共同的放置到一個(gè)構(gòu)造函數(shù)中。代碼與繼承類似,但是核心就是將簡(jiǎn)單的共有的放置到構(gòu)造函數(shù)中,與類的思想類似。單例模式實(shí)現(xiàn)代碼庫(kù),產(chǎn)生命名空間,一次只能實(shí)例化一個(gè)。 JavaScript設(shè)計(jì)模式閱讀 更多文章查看本專欄 設(shè)計(jì)模式第一篇:創(chuàng)建型設(shè)計(jì)模式 1、簡(jiǎn)單工廠模式 簡(jiǎn)單工廠模式:又叫靜態(tài)工廠方法,有一個(gè)工廠對(duì)象決定創(chuàng)建某一種產(chǎn)品...

    RobinTang 評(píng)論0 收藏0
  • Part 2: Containers

    摘要:在默認(rèn)情況下使用的公共注冊(cè)表。注意我們將在這里使用的公共注冊(cè)表,因?yàn)樗敲赓M(fèi)和預(yù)配置的,但是有許多公共注冊(cè)中心可供選擇,而且您甚至可以使用可信注冊(cè)表建立您自己的私有注冊(cè)表。標(biāo)記鏡像將本地映像與注冊(cè)表中的存儲(chǔ)庫(kù)關(guān)聯(lián)的符號(hào)是。 要求 安裝了1.13或者更高版本的Docker 閱讀了Part1中的定位(我沒(méi)寫(xiě)) 介紹 是時(shí)候用Docker構(gòu)建一個(gè)app了。我們會(huì)從構(gòu)建這樣一個(gè)app的最底...

    Soarkey 評(píng)論0 收藏0
  • require.js 簡(jiǎn)潔入門(mén)

    摘要:另外一個(gè)道理,一部分是依賴另一部分的,比如依賴文件的載入。其實(shí)主要做的事情就是這兩點(diǎn)。這里只是我虛構(gòu)一個(gè)假的例子,實(shí)際應(yīng)用中要根據(jù)自己的實(shí)際需求去設(shè)計(jì)構(gòu)思自己的項(xiàng)目,再次提醒,不要為了用而用。 前言 提到require.js大多數(shù)人會(huì)說(shuō)提到模塊化開(kāi)發(fā),AMD等等,其實(shí)require.js并沒(méi)有這么多復(fù)雜的概念,這里我就希望排除這些概念,從實(shí)用的角度來(lái)簡(jiǎn)單說(shuō)一下require.js是干...

    andot 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<