Filter input chars

This commit is contained in:
Alex Kotov 2023-04-02 15:02:15 +04:00
parent 16ad2c2d3a
commit 4f2d50e9b8
Signed by: kotovalexarian
GPG Key ID: 553C0EBBEB5D5F08
3 changed files with 50 additions and 15 deletions

View File

@ -1,10 +1,16 @@
use crate::models::{Char, Pos};
pub use std::io::{Error, Result};
use std::io::BufRead;
use std::vec::IntoIter;
pub type Result = std::result::Result<Char, Error>;
#[derive(Debug)]
pub enum Error {
IO(std::io::Error),
InvalidChar(char),
}
pub struct Input<'a> {
read: &'a mut dyn BufRead,
fin: bool,
@ -12,6 +18,18 @@ pub struct Input<'a> {
pos: Pos,
}
impl From<std::io::Error> for Error {
fn from(err: std::io::Error) -> Self {
Self::IO(err)
}
}
impl From<char> for Error {
fn from(chr: char) -> Self {
Self::InvalidChar(chr)
}
}
impl<'a> Input<'a> {
pub fn new(read: &'a mut dyn BufRead) -> Self {
Self {
@ -27,7 +45,7 @@ impl<'a> Input<'a> {
}
impl Iterator for Input<'_> {
type Item = Result<Char>;
type Item = Result;
fn next(&mut self) -> Option<Self::Item> {
if self.fin {
@ -35,10 +53,13 @@ impl Iterator for Input<'_> {
}
if let Some(chr) = self.iter.next() {
let result = Some(Ok(Char::new(chr, self.pos)));
let chr = Char::new(chr, self.pos);
self.pos.index += 1;
self.pos.col += 1;
return result;
return match chr {
Err(chr) => Some(Err(chr.into())),
Ok(chr) => Some(Ok(chr)),
};
}
let mut buffer = String::new();
@ -53,7 +74,7 @@ impl Iterator for Input<'_> {
}
Err(err) => {
self.fin = true;
Some(Err(err))
Some(Err(err.into()))
}
}
}
@ -64,7 +85,7 @@ mod tests {
use super::*;
fn chr(value: char, index: usize, line: usize, col: usize) -> Char {
Char::new(value, Pos::new(index, line, col))
Char::new(value, Pos::new(index, line, col)).unwrap()
}
#[test]

View File

@ -1,12 +1,12 @@
use crate::input::{self, Input};
use crate::models::{Char, Pos, Token};
use crate::models::{Pos, Token};
use crate::tokenizer::Tokenizer;
pub type Result = std::result::Result<Token, Error>;
pub struct Lexer<'a> {
input: Input<'a>,
cur: Option<input::Result<Char>>,
cur: Option<input::Result>,
pos: Pos,
tokenizer: Tokenizer,
}
@ -47,14 +47,14 @@ impl Iterator for Lexer<'_> {
Ok(chr) => {
let chr = *chr;
self.cur = self.input.next();
match self.tokenizer.iter(Some(chr.value)) {
match self.tokenizer.iter(Some(chr.value())) {
None => self.next(),
Some(value) => {
let token = Token {
value,
pos: self.pos,
};
self.pos = chr.pos;
self.pos = chr.pos();
Some(Ok(token))
}
}

View File

@ -1,7 +1,9 @@
const MIN_CHAR: char = ' '; // ASCII code: 32
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct Char {
pub value: char,
pub pos: Pos,
value: char,
pos: Pos,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
@ -18,8 +20,20 @@ pub struct Token {
}
impl Char {
pub fn new(value: char, pos: Pos) -> Self {
Self { value, pos }
pub fn new(value: char, pos: Pos) -> Result<Self, char> {
if value >= MIN_CHAR || value == ' ' || value == '\n' {
Ok(Self { value, pos })
} else {
Err(value)
}
}
pub fn value(&self) -> char {
self.value
}
pub fn pos(&self) -> Pos {
self.pos
}
}