一小時表達語言
這篇博文最好以其原始格式查看。
這篇文章回顧了題為一小時表達語言的演示,回顧了概念和程式碼。 1
表達式語言2,在此上下文中,計算表達式 - 位元組序列,很可能是 UTF-8 字元。 3 範例包括:
1 1
//article[@title="foobar"]//image
.items[].foo|select(.bar = "foo")
a.comments > 1 and a.category not in ["misc"]
表達式語言(或 DSL4)的範例是:
- JQ
- Kibana 查詢語言
- XPath 語言
- Symfony 表達語言
為什麼要建構自己的表達語言? 為什麼不呢? 太忙? 不用擔心!它不需要幾個月、幾週甚至幾天。 使用一小時表達語言在一小時內創建一個! 5
ProCalc2000
我們將建立 ProCalc2000 表達式語言 - 2000 年及以後的下一代非科學算術計算器。
它評估諸如 1 1
或 1 2
之類的表達式,並且可以處理諸如 1 3 2 / 2
.
哥吉拉
由於浮點數,哥吉拉不喜歡除法。語言包含數字(例如 1、2)和運算子(、-、)。 它不會*支援運算子優先級(參見附錄一)或除法。
儘管它很簡單,但它為添加功能提供了基礎:變數、函數、管道運算符、後綴、字串連接,甚至(違背哥吉拉的意願)除法。
請問,One 裡面有什麼?
評估位元組序列的方法有很多,但我們將使用分詞器、解析器和評估器:
<code> +-----------+ tokens +--------+ ast +-----------+ EXPRESSION ==>| Tokenizer |--------->| Parser |------>| Evaluator | => VALUE +-----------+ +--------+ +-----------+</code>
分詞器
也稱為詞法分析器或掃描器。此類別將字串拆分為稱為標記的分類區塊。
class Tokenizer { public function tokenize(string $expression): Tokens { // ... } }
例如,1 2 3
產生五個標記:
<code>Token(Integer, 1) Token(Plus) Token(Integer, 2) Token(Plus) Token(Integer, 3)</code>
分詞器從左到右掃描,辨識有趣的區塊:正整數以及 、 - 和 * 運算子。空白被忽略;其他字元會導致錯誤。 令牌類型有整數、加號、減號和乘號。
哥吉拉
哥吉拉建議使用分詞器和堆疊機,但我們將使用解析器和評估器,因為哥吉拉關心。分詞器不檢查表達式的有效性;它僅對區塊進行分類。 6 標記將傳遞給解析器。
解析器
解析器解釋標記,將它們轉換為抽象語法樹(AST)。
<code> +-----------+ tokens +--------+ ast +-----------+ EXPRESSION ==>| Tokenizer |--------->| Parser |------>| Evaluator | => VALUE +-----------+ +--------+ +-----------+</code>
給定一個標記列表,解析器傳回一個 AST-樹的根節點。 每個節點都是一個可評估的表達式;節點類型有 BinaryOp 和 Integer。
二元運算有兩個運算元(例如,
foo or bar
可以是BinaryOp(Variable('foo'), 'or', Variable('bar'))
)。一元運算有一個操作數(例如,
-1
)。三元運算有三個運算元(例如,
foo ? bar : baz
)。
表達式1 1 / 5
是一個以
為運算子的BinaryOp,一個操作數為1,另一個為另一個BinaryOp(1 / 5
)。
class Tokenizer { public function tokenize(string $expression): Tokens { // ... } }
評估者
求值器接受一個 Node 並回傳一個值(這裡有一個整數)。 這是一個樹行走翻譯器。
<code>Token(Integer, 1) Token(Plus) Token(Integer, 2) Token(Plus) Token(Integer, 3)</code>
請顯示您的程式碼?
此程式碼源自 PHPSW 聚會,由單元測試驅動(此處省略)。查看儲存庫。
哥吉拉
哥吉拉會對這段程式碼感到憤怒並建議重構。分詞器
首先,一個有 Token
枚舉和可選值的 TokenType
類別:
class Parser { public function parse(Tokens $tokens): Node { // ... } }
<code> +-------------+ | Binary Op + | <p>In PHP:</p> ```php $ast = new BinaryOp( left: new Integer(1), operator: '+', right: new BinaryOp( left: new Integer(1), operator: '/', right: new Integer(5), ) );</code>
令牌看起來像:
class Evaluator { public function evaluate(Node $node): int { // ... } }
Tokenizer
類別完成以下工作:7
class Token { public function __construct( public TokenType $type, public ?string $value = null ) {} }
Tokens
系列:
enum TokenType { case Plus; case Minus; case Multiply; case Integer; }
哥吉拉
Godzilla 喜歡使用陣列和 array_shift 或生成器來同時進行標記化和解析。解析器
[ new Token(TokenType::Integer, 50), new Token(TokenType::Plus), // ... ]
這是新增運算子優先權、後綴解析和管道運算子的地方。 例如,後綴解析可以處理「5 英哩」這樣的表達式。
評估者
class Tokenizer { public function tokenize(string $expression): Tokens { $offset = 0; $tokens = []; while (isset($expression[$offset])) { $char = $expression[$offset++]; if (is_numeric($char)) { while (is_numeric($expression[$offset] ?? null)) { $char .= $expression[$offset++]; } $tokens[] = new Token(TokenType::Integer, $char); continue; } $token = match ($char) { '+' => new Token(TokenType::Plus), '-' => new Token(TokenType::Minus), '*' => new Token(TokenType::Multiply), ' ' => null, default => throw new RuntimeException(sprintf( 'Invalid operator: "%s"', $char )), }; if ($token === null) { continue; } $tokens[] = $token; } return new Tokens($tokens); } }
就是這樣
此程式碼是即時編碼的,包括測試。 完整的程式碼可以在儲存庫中找到。
運算子優先權
表達式 1 * 3 4
應該是 (1 * 3) 4 = 7
,但由於解析方法,我們的語言將其計算為 1 * (3 4) = 7
。 8 Pratt 解析器修正了這一點:
<code> +-----------+ tokens +--------+ ast +-----------+ EXPRESSION ==>| Tokenizer |--------->| Parser |------>| Evaluator | => VALUE +-----------+ +--------+ +-----------+</code>
哥吉拉
哥吉拉了解遞歸。延伸閱讀
- 製作口譯員:羅伯特‧尼斯特羅姆 (Robert Nystrom) 所寫的書籍(免費網路版)
- 表達式解析變得簡單:Robert Nystrom 的部落格文章
- 堆疊機 RPN 計算器:2014 年 Igor Wiedler 發表
- 學說詞法分析器
- PHPStan Phpdoc 解析器9
- 程式碼隨著每次迭代而變化。
- 或更具體地說,是一個表達式語言解釋器。
- 在 PHP 中通常稱為字串。
- 領域特定語言。
- 不存在專利。
- 分詞器對於語法突出顯示很有用。
-
preg_
方法可能會更有效率。 - 只有在期望不同的答案時才是錯的。
- 樹遍歷是透過 Doctrine 的查詢建構器發現的。
以上是一小時表達語言的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

在PHP中,應使用password_hash和password_verify函數實現安全的密碼哈希處理,不應使用MD5或SHA1。1)password_hash生成包含鹽值的哈希,增強安全性。 2)password_verify驗證密碼,通過比較哈希值確保安全。 3)MD5和SHA1易受攻擊且缺乏鹽值,不適合現代密碼安全。

PHP和Python各有優勢,選擇依據項目需求。 1.PHP適合web開發,尤其快速開發和維護網站。 2.Python適用於數據科學、機器學習和人工智能,語法簡潔,適合初學者。

PHP在電子商務、內容管理系統和API開發中廣泛應用。 1)電子商務:用於購物車功能和支付處理。 2)內容管理系統:用於動態內容生成和用戶管理。 3)API開發:用於RESTfulAPI開發和API安全性。通過性能優化和最佳實踐,PHP應用的效率和可維護性得以提升。

PHP類型提示提升代碼質量和可讀性。 1)標量類型提示:自PHP7.0起,允許在函數參數中指定基本數據類型,如int、float等。 2)返回類型提示:確保函數返回值類型的一致性。 3)聯合類型提示:自PHP8.0起,允許在函數參數或返回值中指定多個類型。 4)可空類型提示:允許包含null值,處理可能返回空值的函數。

PHP仍然具有活力,其在現代編程領域中依然佔據重要地位。 1)PHP的簡單易學和強大社區支持使其在Web開發中廣泛應用;2)其靈活性和穩定性使其在處理Web表單、數據庫操作和文件處理等方面表現出色;3)PHP不斷進化和優化,適用於初學者和經驗豐富的開發者。

PHP主要是過程式編程,但也支持面向對象編程(OOP);Python支持多種範式,包括OOP、函數式和過程式編程。 PHP適合web開發,Python適用於多種應用,如數據分析和機器學習。

在PHP中使用預處理語句和PDO可以有效防範SQL注入攻擊。 1)使用PDO連接數據庫並設置錯誤模式。 2)通過prepare方法創建預處理語句,使用佔位符和execute方法傳遞數據。 3)處理查詢結果並確保代碼的安全性和性能。

PHP和Python各有優劣,選擇取決於項目需求和個人偏好。 1.PHP適合快速開發和維護大型Web應用。 2.Python在數據科學和機器學習領域佔據主導地位。
