Rust實現(xiàn)一個表達(dá)式Parser小結(jié)
正文
在 src/lib.rs
補(bǔ)上一個函數(shù)和一個 smoke test, 如下
pub use traversal::{eval, format}; pub fn build_ast(expr: &str) -> Result<Node, String> { let root = syntax(lex(expr)?)?; Ok(root) } #[cfg(test)] mod tests { use super::*; #[test] fn smoke() { let expr = "1*2+(3/(4+(-5)))"; let ast = build_ast(expr).unwrap(); assert_eq!(-1, eval(&ast)); assert_eq!("1 * 2 + 3 / (4 + (-5))", format(&ast)); } } 復(fù)制代碼
lexer
Lexer
模塊主要圍繞 DFA 展開講了很多, 具體實現(xiàn)的時候其實并沒有那么復(fù)雜, 主要是需要設(shè)計好存儲結(jié)構(gòu), 并理解清楚狀態(tài)轉(zhuǎn)移表的含義
parser
Parser
模塊大部分篇幅都在講文法和 Parser Combinator
, 最后真正實現(xiàn)的時候反而非常簡單, 這里有兩點需要注意
- 文法的處理
- 處理優(yōu)先級
- 消除左遞歸
Parser Combinator
的封裝和設(shè)計理念
Parser Combinator
只是一種工具而已, 同類型的還有 Parser Generator
, 由于筆者接觸不多, 就不好展開講了
不過這里個人認(rèn)為, 比起 Parser Combinator
本身, 他的設(shè)計理念更值得關(guān)注, 尤其是這種相對比較小眾的函數(shù)式編程思維, 個人覺得很有意思
traversal
Traversal
模塊最主要的就是訪問者模式了, 根據(jù)我查到的資料來看, 普通的 AST 基本只有這一種遍歷方式
借助訪問者模式, 將所有的 visitor 單獨抽離進(jìn)行實現(xiàn), 代碼可讀性和耦合度得到了很大的優(yōu)化, 筆者最開始其實是希望實現(xiàn)一個最最最簡化的表達(dá)式解析器, 因此第一版并沒有引入訪問者模式, 而在實現(xiàn)最后的兩個需求時發(fā)現(xiàn)代碼完全耦合在一起實在很惡心, 就干脆加進(jìn)來了, 反正遍歷 AST 基本逃不掉這個訪問者模式
說在最后
個人感覺很多內(nèi)容其實都講的有遺漏或者有不規(guī)范的地方, 但是整個編譯領(lǐng)域, 光入門的理論知識就太多太多了, 況且筆者只是自己寫了個玩具, 而且?guī)缀跏莻€純編譯前端的項目, 也不敢說入門了, 因此就權(quán)當(dāng)是學(xué)習(xí)筆記的分享了
源碼中有大量注釋, 個人感覺結(jié)合著看會更加清晰, 可以看一下, 在這里可以看
以上就是Rust實現(xiàn)一個表達(dá)式Parser小結(jié)的詳細(xì)內(nèi)容,更多關(guān)于Rust Parser表達(dá)式小結(jié)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Rust初體驗:手把手教你構(gòu)建‘Hello,?World!’
"準(zhǔn)備好了嗎?一起踏上Rust編程語言的精彩旅程!在這篇「Rust初體驗」中,我們將手把手教你構(gòu)建經(jīng)典程序“Hello,?World!”,感受Rust的強(qiáng)大與安全,短短幾行代碼,就能讓你對這個系統(tǒng)級語言的魅力一探究竟!快加入吧,驚喜等你發(fā)現(xiàn)!"2024-01-01