Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- mod tokens {
- use std::{
- char,
- iter::{Filter, Peekable},
- };
- use thiserror::Error;
- #[derive(Debug, Clone, Copy, PartialEq, Eq)]
- pub enum TokenType {
- Number,
- Plus,
- Minus,
- Divide,
- Multiply,
- OpenParen,
- CloseParen,
- }
- #[derive(Debug, PartialEq, Eq, Clone)]
- pub struct Token {
- tok_type: TokenType,
- text: String,
- }
- impl Token {
- pub fn tok_type(&self) -> TokenType {
- self.tok_type
- }
- pub fn text(&self) -> &str {
- &self.text
- }
- }
- pub struct Lexer<I>
- where
- I: Iterator<Item = char>,
- {
- inner: Peekable<Filter<I, fn(&char) -> bool>>,
- }
- impl<I> Lexer<I>
- where
- I: Iterator<Item = char>,
- {
- pub fn new(inner: I) -> Self {
- Lexer {
- inner: inner.filter(Self::whitespace_filter).peekable(),
- }
- }
- fn whitespace_filter(c: &char) -> bool {
- !c.is_whitespace()
- }
- fn next_inner(&mut self) -> <Self as Iterator>::Item {
- match self.inner.peek().unwrap() {
- '(' => Ok(Token {
- tok_type: TokenType::OpenParen,
- text: self.inner.next().unwrap().to_string(),
- }),
- ')' => Ok(Token {
- tok_type: TokenType::CloseParen,
- text: self.inner.next().unwrap().to_string(),
- }),
- '+' => Ok(Token {
- tok_type: TokenType::Plus,
- text: self.inner.next().unwrap().to_string(),
- }),
- '-' => Ok(Token {
- tok_type: TokenType::Minus,
- text: self.inner.next().unwrap().to_string(),
- }),
- '*' => Ok(Token {
- tok_type: TokenType::Multiply,
- text: self.inner.next().unwrap().to_string(),
- }),
- '/' => Ok(Token {
- tok_type: TokenType::Divide,
- text: self.inner.next().unwrap().to_string(),
- }),
- c => Err(TokenizationError::UnexpectedCharacter(*c)),
- }
- }
- }
- #[derive(Debug, Error)]
- pub enum TokenizationError {
- #[error("unexpected character: '{0}'")]
- UnexpectedCharacter(char),
- }
- impl<I> Iterator for Lexer<I>
- where
- I: Iterator<Item = char>,
- {
- type Item = Result<Token, TokenizationError>;
- fn next(&mut self) -> Option<Self::Item> {
- match self.inner.peek() {
- Some(_) => Some(self.next_inner()),
- None => None,
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment