use elyze::errors::{ParseError, ParseResult};
use elyze::matcher::Match;
use elyze::peek::{
peek, DefaultPeekableImplementation, PeekResult, Peekable, PeekableImplementation,
};
use elyze::peeker::Peeker;
use elyze::recognizer::Recognizer;
use elyze::scanner::Scanner;
use elyze::visitor::Visitor;
fn match_char(data: &[u8], c: u8) -> (bool, usize) {
(data[0] == c, 1)
}
enum OperatorTokens {
Plus,
Times,
}
impl Match<u8> for OperatorTokens {
fn is_matching(&self, data: &[u8]) -> (bool, usize) {
match self {
OperatorTokens::Plus => match_char(data, b'+'),
OperatorTokens::Times => match_char(data, b'*'),
}
}
fn size(&self) -> usize {
match self {
OperatorTokens::Plus => 1,
OperatorTokens::Times => 1,
}
}
}
impl<'a> Visitor<'a, u8> for OperatorTokens {
fn accept(scanner: &mut Scanner<'a, u8>) -> ParseResult<Self> {
Ok(Recognizer::new(scanner)
.try_or(OperatorTokens::Times)?
.try_or(OperatorTokens::Plus)?
.finish()
.ok_or(ParseError::UnexpectedToken)?)
}
}
impl PeekableImplementation for OperatorTokens {
type Type = DefaultPeekableImplementation;
}
struct FirstOperator;
impl<'a> Peekable<'a, u8> for FirstOperator {
fn peek(&self, scanner: &Scanner<'a, u8>) -> ParseResult<PeekResult> {
Peeker::new(scanner)
.add_peekable(OperatorTokens::Plus)
.add_peekable(OperatorTokens::Times)
.peek()
.map(Into::into)
}
}
fn main() -> ParseResult<()> {
let data = b"7 * ( 1 + 2 )";
let scanner = Scanner::new(data);
let slice = peek(FirstOperator, &scanner)?;
if let Some(slice) = slice {
println!("{:?}", String::from_utf8_lossy(slice.peeked_slice())); }
let data = b"7 * ( 1 + 2 )";
let scanner = Scanner::new(data);
let slice = peek(FirstOperator, &scanner)?;
if let Some(slice) = slice {
println!("{:?}", String::from_utf8_lossy(slice.peeked_slice())); }
let data = b"1 + 2 * 7";
let scanner = Scanner::new(data);
let slice = peek(FirstOperator, &scanner)?;
if let Some(slice) = slice {
println!("{:?}", String::from_utf8_lossy(slice.peeked_slice())); }
Ok(())
}