Skip to main content

peek_first_operator/
peek_first_operator.rs

1use elyze::errors::{ParseError, ParseResult};
2use elyze::matcher::Match;
3use elyze::peek::{
4    peek, DefaultPeekableImplementation, PeekResult, Peekable, PeekableImplementation,
5};
6use elyze::peeker::Peeker;
7use elyze::recognizer::Recognizer;
8use elyze::scanner::Scanner;
9use elyze::visitor::Visitor;
10
11fn match_char(data: &[u8], c: u8) -> (bool, usize) {
12    (data[0] == c, 1)
13}
14
15enum OperatorTokens {
16    Plus,
17    Times,
18}
19
20impl Match<u8> for OperatorTokens {
21    fn is_matching(&self, data: &[u8]) -> (bool, usize) {
22        match self {
23            OperatorTokens::Plus => match_char(data, b'+'),
24            OperatorTokens::Times => match_char(data, b'*'),
25        }
26    }
27
28    fn size(&self) -> usize {
29        match self {
30            OperatorTokens::Plus => 1,
31            OperatorTokens::Times => 1,
32        }
33    }
34}
35
36impl<'a> Visitor<'a, u8> for OperatorTokens {
37    fn accept(scanner: &mut Scanner<'a, u8>) -> ParseResult<Self> {
38        Ok(Recognizer::new(scanner)
39            .try_or(OperatorTokens::Times)?
40            .try_or(OperatorTokens::Plus)?
41            .finish()
42            .ok_or(ParseError::UnexpectedToken)?)
43    }
44}
45
46impl PeekableImplementation for OperatorTokens {
47    type Type = DefaultPeekableImplementation;
48}
49
50struct FirstOperator;
51
52impl<'a> Peekable<'a, u8> for FirstOperator {
53    fn peek(&self, scanner: &Scanner<'a, u8>) -> ParseResult<PeekResult> {
54        Peeker::new(scanner)
55            .add_peekable(OperatorTokens::Plus)
56            .add_peekable(OperatorTokens::Times)
57            .peek()
58            .map(Into::into)
59    }
60}
61
62fn main() -> ParseResult<()> {
63    let data = b"7 * ( 1 + 2 )";
64    let scanner = Scanner::new(data);
65    let slice = peek(FirstOperator, &scanner)?;
66    if let Some(slice) = slice {
67        println!("{:?}", String::from_utf8_lossy(slice.peeked_slice())); // "7 "
68    }
69
70    let data = b"7 * ( 1 + 2 )";
71    let scanner = Scanner::new(data);
72    let slice = peek(FirstOperator, &scanner)?;
73    if let Some(slice) = slice {
74        println!("{:?}", String::from_utf8_lossy(slice.peeked_slice())); // "7 "
75    }
76
77    let data = b"1 + 2 * 7";
78    let scanner = Scanner::new(data);
79    let slice = peek(FirstOperator, &scanner)?;
80    if let Some(slice) = slice {
81        println!("{:?}", String::from_utf8_lossy(slice.peeked_slice())); // "1 "
82    }
83
84    Ok(())
85}