Rust で 逆ポーランド記法の実装をしてみた.
こんにちは、 @kz_morita です。
以前,C++ で逆ポーランド記法を実装した のですが, 今回はそれの Rust 版を実装してみました.
また,今回は Crate として公開してみました.
Github: https://github.com/foresta/single-digit-rpn Crate: https://crates.io/crates/single-digit-rpn single-digit-rpn というパッケージで公開していて,その名の通り,ひと桁の 逆ポーランド記法を計算するものになります.
全体像 今回は,逆ポーランド記法を以下の手順を踏んで実装しました.
文字列をTokenに変換 Token を AST に変換 AST を評価して計算 また,src/ ディレクトリは以下のようになっています.
. ├── ast.rs ├── lib.rs ├── operator.rs ├── parser.rs └── tokenizer.rs Tokenize まずは,文字列をToken 列に変換します. コードは以下のような感じです.
tokenizer.rs pubfn tokenize(expr: &str)-> Result<Vec<Token>,TokenError>{expr.chars().filter(|c|!c.is_whitespace()).map(|e|matche{'+'=>Ok(Token::Operator(Operator::Add)),'-'=>Ok(Token::Operator(Operator::Sub)),'*'=>Ok(Token::Operator(Operator::Mul)),'/'=>Ok(Token::Operator(Operator::Div)),n=>matchn.to_string().parse::<f64>(){Ok(val)=>Ok(Token::Operand(val)),Err(_)=>Err(TokenError::InvalidChar(n)),},}).into_iter().collect()}入力文字列を,char の配列にして,ホワイトスペースを取り除いた後,文字をチェックしていきます.各文字をそれぞれのオペレータと,オペランド(数値)にマッピングし,マッピングできない文字列が現れたらエラーを還しています. 計算に使うオペレータは以下のように定義しました.
operator.rs #[derive(Debug, Clone, PartialEq, Eq, Hash)]pubenum Operator{Add,Sub,Mul,Div,}Parse 次に,Token列を AST にパースします.
parser.rs /// Parses a Token sequence nto an AST pubfn parse(tokens: Vec<Token>)-> Result<Ast,ParseError>{letmutstack: Vec<Ast>=Vec::new();fortokenintokens{matchtoken{Token::Operator(op)=>{ifstack.