Filter input chars
This commit is contained in:
parent
16ad2c2d3a
commit
4f2d50e9b8
35
src/input.rs
35
src/input.rs
|
@ -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]
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue