摘要:之前寫過一個計算器,采用實現的,不過當時沒有想到的好的辦法,最終采用了的函數來實現字符串的解析和運算。
之前寫過一個計算器,采用JS實現的,不過當時沒有想到的好的辦法,最終采用了JS的eval函數來實現字符串的解析和運算。
這并不是的好的方法,如果實現的計算器比較復雜,最終會發現程序十分臃腫.
接下來部分,在重構https://github.com/rspivak/ls... 的同時,并實現一個完整計算器的解釋器
Part2代碼實現功能
加法運算
減法運算
去除空格
多位數運算
type=$type; $this->value=$value; } /** 通過該方法來獲取類的私有屬性 */ public function __get($name) { return $this->{$name}; } /** 用于調試 */ public function __toString() { return "type:".$this->type." value:".$this->value; } } //解釋器 class Interpreter{ private $current_char ; private $current_token ; private $text; private $pos=0; /*** $text 需要進行解釋的字符串 */ public function __construct($text){ //去除前后可能存在的空格 這些空格是無效的 $this->text=trim($text); //初始化 獲取第一個字符 $this->current_char = $this->text[$this->pos]; } public function error() { throw new Exception("Lexer eroor"); } /* 步進方法,每操作一個字符后前進一位 */ 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(); } } /* 如果要支持多位的整數,則需要將每位數字存儲起來 */ public function integers() { $result="";//用于存儲數字 while($this->current_char!=null&&is_numeric($this->current_char)){//只要當前字符是數字就一直循環并將數字存儲于$result $result.=$this->current_char; $this->advance();//步進方法,每操作一個字符后前進一位 } return intval($result);//將數字字符串轉成整數 } //獲取當前字符的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); } } //如果字符類型和判斷的類型一致,則繼續,否則輸入錯誤 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();//獲取字符串開頭部分的數字 $left=$this->current_token; $this->eat(ISINTEGER);//判斷取得的前半部分字符串是整數不是 $op=$this->current_token;//獲取前半部分后緊接的字符 并判斷是何種操作符 if ($op->type==PLUS) $this->eat(PLUS); else $this->eat(MINUS); $right=$this->current_token;//獲取最后部分 并判斷是否是整數 $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);
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/29001.html
摘要:單元測試上一節有討論過,單元測試就是以代碼單元為單位進行測試,代碼單元可以是一個函數,一個模塊,或者一個類。單元測試是最容易理解也最容易實現的測試方式。在寫單元測試的時候,盡量將你的單元測試獨立出來,不要幾個單元互相引用。 showImg(https://segmentfault.com/img/remote/1460000008823416?w=997&h=350); 本文作者:G...
摘要:單元測試上一節有討論過,單元測試就是以代碼單元為單位進行測試,代碼單元可以是一個函數,一個模塊,或者一個類。單元測試是最容易理解也最容易實現的測試方式。在寫單元測試的時候,盡量將你的單元測試獨立出來,不要幾個單元互相引用。 showImg(https://segmentfault.com/img/remote/1460000008823416?w=997&h=350); 本文作者:G...
摘要:它屬于類創建型模式。基于繼承,將復雜的放置在函數中,簡單的共同的放置到一個構造函數中。代碼與繼承類似,但是核心就是將簡單的共有的放置到構造函數中,與類的思想類似。單例模式實現代碼庫,產生命名空間,一次只能實例化一個。 JavaScript設計模式閱讀 更多文章查看本專欄 設計模式第一篇:創建型設計模式 1、簡單工廠模式 簡單工廠模式:又叫靜態工廠方法,有一個工廠對象決定創建某一種產品...
摘要:在默認情況下使用的公共注冊表。注意我們將在這里使用的公共注冊表,因為它是免費和預配置的,但是有許多公共注冊中心可供選擇,而且您甚至可以使用可信注冊表建立您自己的私有注冊表。標記鏡像將本地映像與注冊表中的存儲庫關聯的符號是。 要求 安裝了1.13或者更高版本的Docker 閱讀了Part1中的定位(我沒寫) 介紹 是時候用Docker構建一個app了。我們會從構建這樣一個app的最底...
摘要:另外一個道理,一部分是依賴另一部分的,比如依賴文件的載入。其實主要做的事情就是這兩點。這里只是我虛構一個假的例子,實際應用中要根據自己的實際需求去設計構思自己的項目,再次提醒,不要為了用而用。 前言 提到require.js大多數人會說提到模塊化開發,AMD等等,其實require.js并沒有這么多復雜的概念,這里我就希望排除這些概念,從實用的角度來簡單說一下require.js是干...
閱讀 2654·2021-11-23 09:51
閱讀 3246·2021-11-22 14:44
閱讀 4575·2021-11-22 09:34
閱讀 5102·2021-10-08 10:14
閱讀 2404·2021-09-22 15:47
閱讀 3502·2021-09-22 15:40
閱讀 1510·2019-08-30 15:44
閱讀 1619·2019-08-28 18:23