use elyze::acceptor::Acceptor;
use elyze::bytes::components::groups::GroupKind;
use elyze::bytes::matchers::match_pattern;
use elyze::bytes::primitives::number::Number;
use elyze::bytes::primitives::whitespace::OptionalWhitespaces;
use elyze::errors::{ParseError, ParseResult};
use elyze::matcher::Match;
use elyze::peek::peek;
use elyze::recognizer::Recognizer;
use elyze::scanner::Scanner;
use elyze::visitor::Visitor;
#[allow(dead_code)]
#[derive(Debug)]
enum ExpressionInternal {
Reducted(Reducted),
RightExpression(RightExpression),
}
#[derive(Debug)]
struct Reducted {
lhs: usize,
op: BinaryOperator,
rhs: usize,
}
impl<'a> Visitor<'a, u8> for Reducted {
fn accept(scanner: &mut Scanner<'a, u8>) -> ParseResult<Self> {
OptionalWhitespaces::accept(scanner)?;
let lhs = Number::accept(scanner)?.0;
OptionalWhitespaces::accept(scanner)?;
let op = Recognizer::<u8, BinaryOperator>::new(scanner)
.try_or(BinaryOperator::Add)?
.try_or(BinaryOperator::Mul)?
.finish()
.ok_or(ParseError::UnexpectedToken)?;
OptionalWhitespaces::accept(scanner)?;
let rhs = Number::accept(scanner)?.0;
OptionalWhitespaces::accept(scanner)?;
Ok(Reducted { lhs, op, rhs })
}
}
#[derive(Debug)]
struct RightExpression {
lhs: usize,
op: BinaryOperator,
rhs: Box<Expression>,
}
impl<'a> Visitor<'a, u8> for RightExpression {
fn accept(scanner: &mut Scanner<'a, u8>) -> ParseResult<Self> {
OptionalWhitespaces::accept(scanner)?;
let lhs = Number::accept(scanner)?.0;
OptionalWhitespaces::accept(scanner)?;
let op = Recognizer::<u8, BinaryOperator>::new(scanner)
.try_or(BinaryOperator::Add)?
.try_or(BinaryOperator::Mul)?
.finish()
.ok_or(ParseError::UnexpectedToken)?;
OptionalWhitespaces::accept(scanner)?;
let rhs = Expression::accept(scanner)?;
OptionalWhitespaces::accept(scanner)?;
Ok(RightExpression {
lhs,
op,
rhs: Box::new(rhs),
})
}
}
#[derive(Debug)]
enum BinaryOperator {
Add,
Mul,
}
impl Match<u8> for BinaryOperator {
fn is_matching(&self, data: &[u8]) -> (bool, usize) {
match self {
BinaryOperator::Add => match_pattern(b"+", data),
BinaryOperator::Mul => match_pattern(b"*", data),
}
}
fn size(&self) -> usize {
match self {
BinaryOperator::Add => 1,
BinaryOperator::Mul => 1,
}
}
}
#[allow(dead_code)]
#[derive(Debug)]
enum Expression {
Reduced {
lhs: usize,
op: BinaryOperator,
rhs: usize,
},
RightExpression {
lhs: usize,
op: BinaryOperator,
rhs: Box<Expression>,
},
}
impl From<ExpressionInternal> for Expression {
fn from(value: ExpressionInternal) -> Self {
match value {
ExpressionInternal::Reducted(reduced) => Expression::Reduced {
lhs: reduced.lhs,
op: reduced.op,
rhs: reduced.rhs,
},
ExpressionInternal::RightExpression(right) => Expression::RightExpression {
lhs: right.lhs,
op: right.op,
rhs: right.rhs,
},
}
}
}
impl<'a> Visitor<'a, u8> for Expression {
fn accept(scanner: &mut Scanner<'a, u8>) -> ParseResult<Self> {
OptionalWhitespaces::accept(scanner)?;
let result = peek(GroupKind::Parenthesis, scanner)?;
match result {
Some(peeked) => {
let mut inner_scanner = Scanner::new(peeked.peeked_slice());
let inner_result = Expression::accept(&mut inner_scanner)?;
scanner.bump_by(peeked.end_slice);
Ok(inner_result)
}
None => {
let accepted = Acceptor::new(scanner)
.try_or(ExpressionInternal::RightExpression)?
.try_or(ExpressionInternal::Reducted)?
.finish()
.ok_or(ParseError::UnexpectedToken)?;
Ok(accepted.into())
}
}
}
}
fn main() {
let data = b"1 + 2";
let mut scanner = Scanner::new(data);
let result = Expression::accept(&mut scanner);
println!("{:?}", result);
let data = b"1 + (2 * 3)";
let mut scanner = Scanner::new(data);
let result = Expression::accept(&mut scanner);
println!("{:?}", result);
let data = b"1 + (2 * 3 * ( 7 + 8))";
let mut scanner = Scanner::new(data);
let result = Expression::accept(&mut scanner);
println!("{:?}", result);
let data = b"1 + 2 + 3";
let mut scanner = Scanner::new(data);
let result = Expression::accept(&mut scanner);
println!("{:?}", result); }