Skip to main content

expression/
expression.rs

1use elyze::acceptor::Acceptor;
2use elyze::bytes::components::groups::GroupKind;
3use elyze::bytes::matchers::match_pattern;
4use elyze::bytes::primitives::number::Number;
5use elyze::bytes::primitives::whitespace::OptionalWhitespaces;
6use elyze::errors::{ParseError, ParseResult};
7use elyze::matcher::Match;
8use elyze::peek::peek;
9use elyze::recognizer::Recognizer;
10use elyze::scanner::Scanner;
11use elyze::visitor::Visitor;
12
13// ------------------------------------------------------------
14// ExpressionInternal
15// ------------------------------------------------------------
16
17#[allow(dead_code)]
18#[derive(Debug)]
19enum ExpressionInternal {
20    Reducted(Reducted),
21    RightExpression(RightExpression),
22}
23
24// ------------------------------------------------------------
25
26#[derive(Debug)]
27struct Reducted {
28    lhs: usize,
29    op: BinaryOperator,
30    rhs: usize,
31}
32
33impl<'a> Visitor<'a, u8> for Reducted {
34    fn accept(scanner: &mut Scanner<'a, u8>) -> ParseResult<Self> {
35        OptionalWhitespaces::accept(scanner)?;
36        let lhs = Number::accept(scanner)?.0;
37        OptionalWhitespaces::accept(scanner)?;
38        let op = Recognizer::<u8, BinaryOperator>::new(scanner)
39            .try_or(BinaryOperator::Add)?
40            .try_or(BinaryOperator::Mul)?
41            .finish()
42            .ok_or(ParseError::UnexpectedToken)?;
43        OptionalWhitespaces::accept(scanner)?;
44        let rhs = Number::accept(scanner)?.0;
45        OptionalWhitespaces::accept(scanner)?;
46        Ok(Reducted { lhs, op, rhs })
47    }
48}
49
50// ------------------------------------------------------------
51//  +++ RightExpression
52// ------------------------------------------------------------
53
54#[derive(Debug)]
55struct RightExpression {
56    lhs: usize,
57    op: BinaryOperator,
58    rhs: Box<Expression>,
59}
60
61impl<'a> Visitor<'a, u8> for RightExpression {
62    fn accept(scanner: &mut Scanner<'a, u8>) -> ParseResult<Self> {
63        OptionalWhitespaces::accept(scanner)?;
64        let lhs = Number::accept(scanner)?.0;
65        OptionalWhitespaces::accept(scanner)?;
66        let op = Recognizer::<u8, BinaryOperator>::new(scanner)
67            .try_or(BinaryOperator::Add)?
68            .try_or(BinaryOperator::Mul)?
69            .finish()
70            .ok_or(ParseError::UnexpectedToken)?;
71        OptionalWhitespaces::accept(scanner)?;
72        let rhs = Expression::accept(scanner)?;
73        OptionalWhitespaces::accept(scanner)?;
74        Ok(RightExpression {
75            lhs,
76            op,
77            rhs: Box::new(rhs),
78        })
79    }
80}
81
82// ------------------------------------------------------------
83// BinaryOperator
84// ------------------------------------------------------------
85
86#[derive(Debug)]
87enum BinaryOperator {
88    Add,
89    Mul,
90}
91
92impl Match<u8> for BinaryOperator {
93    fn is_matching(&self, data: &[u8]) -> (bool, usize) {
94        match self {
95            BinaryOperator::Add => match_pattern(b"+", data),
96            BinaryOperator::Mul => match_pattern(b"*", data),
97        }
98    }
99
100    fn size(&self) -> usize {
101        match self {
102            BinaryOperator::Add => 1,
103            BinaryOperator::Mul => 1,
104        }
105    }
106}
107
108// impl<'a> Recognizable<'a, u8, BinaryOperator> for BinaryOperator {
109//     fn recognize(self, scanner: &mut Scanner<'a, u8>) -> ParseResult<Option<BinaryOperator>> {
110//         if scanner.is_empty() {
111//             return Ok(None);
112//         }
113//         let (matched, size) = self.matcher(scanner.remaining());
114//         if matched {
115//             scanner.bump_by(size);
116//             return Ok(Some(self));
117//         }
118//         Ok(None)
119//     }
120// }
121
122// ------------------------------------------------------------
123// Expression
124// ------------------------------------------------------------
125
126/// Final result of the expression.
127#[allow(dead_code)]
128#[derive(Debug)]
129enum Expression {
130    /// Both lhs and rhs are reduced.
131    Reduced {
132        lhs: usize,
133        op: BinaryOperator,
134        rhs: usize,
135    },
136    /// Only lhs is reduced.
137    RightExpression {
138        lhs: usize,
139        op: BinaryOperator,
140        rhs: Box<Expression>,
141    },
142}
143
144impl From<ExpressionInternal> for Expression {
145    fn from(value: ExpressionInternal) -> Self {
146        match value {
147            ExpressionInternal::Reducted(reduced) => Expression::Reduced {
148                lhs: reduced.lhs,
149                op: reduced.op,
150                rhs: reduced.rhs,
151            },
152            ExpressionInternal::RightExpression(right) => Expression::RightExpression {
153                lhs: right.lhs,
154                op: right.op,
155                rhs: right.rhs,
156            },
157        }
158    }
159}
160
161impl<'a> Visitor<'a, u8> for Expression {
162    fn accept(scanner: &mut Scanner<'a, u8>) -> ParseResult<Self> {
163        OptionalWhitespaces::accept(scanner)?;
164        // Check if there is a parenthesis
165        let result = peek(GroupKind::Parenthesis, scanner)?;
166
167        match result {
168            Some(peeked) => {
169                // Parse the inner expression
170                let mut inner_scanner = Scanner::new(peeked.peeked_slice());
171                let inner_result = Expression::accept(&mut inner_scanner)?;
172                scanner.bump_by(peeked.end_slice);
173                Ok(inner_result)
174            }
175            None => {
176                // Parse the reduced expression or the right expression
177                let accepted = Acceptor::new(scanner)
178                    .try_or(ExpressionInternal::RightExpression)?
179                    .try_or(ExpressionInternal::Reducted)?
180                    .finish()
181                    .ok_or(ParseError::UnexpectedToken)?;
182
183                Ok(accepted.into())
184            }
185        }
186    }
187}
188
189fn main() {
190    let data = b"1 + 2";
191    let mut scanner = Scanner::new(data);
192    let result = Expression::accept(&mut scanner);
193    println!("{:?}", result); // Ok(Reduced { lhs: 1, op: Add, rhs: 2 })
194
195    let data = b"1 + (2 * 3)";
196    let mut scanner = Scanner::new(data);
197    let result = Expression::accept(&mut scanner);
198    println!("{:?}", result); // Ok(RightExpression { lhs: 1, op: Add, rhs: Reduced { lhs: 2, op: Mul, rhs: 3 } })
199
200    let data = b"1 + (2 * 3 * ( 7 + 8))";
201    let mut scanner = Scanner::new(data);
202    let result = Expression::accept(&mut scanner);
203    println!("{:?}", result); //Ok(RightExpression { lhs: 1, op: Add, rhs: RightExpression { lhs: 2, op: Mul, rhs: RightExpression { lhs: 3, op: Mul, rhs: Reduced { lhs: 7, op: Add, rhs: 8 } } } })
204
205    let data = b"1 + 2 + 3";
206    let mut scanner = Scanner::new(data);
207    let result = Expression::accept(&mut scanner);
208    println!("{:?}", result); // Ok(RightExpression { lhs: 1, op: Add, rhs: Reduced { lhs: 2, op: Add, rhs: 3 } })
209}