1use noa_parser::acceptor::Acceptor;
2use noa_parser::bytes::components::groups::GroupKind;
3use noa_parser::bytes::matchers::match_pattern;
4use noa_parser::bytes::primitives::number::Number;
5use noa_parser::bytes::primitives::whitespace::OptionalWhitespaces;
6use noa_parser::errors::{ParseError, ParseResult};
7use noa_parser::matcher::{Match, MatchSize};
8use noa_parser::peek::peek;
9use noa_parser::recognizer::{Recognizable, Recognizer};
10use noa_parser::scanner::Scanner;
11use noa_parser::visitor::Visitor;
12
13#[allow(dead_code)]
18#[derive(Debug)]
19enum ExpressionInternal {
20 Reducted(Reducted),
21 RightExpression(RightExpression),
22}
23
24#[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#[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#[derive(Debug)]
87enum BinaryOperator {
88 Add,
89 Mul,
90}
91
92impl Match<u8> for BinaryOperator {
93 fn matcher(&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
101impl MatchSize for BinaryOperator {
102 fn size(&self) -> usize {
103 match self {
104 BinaryOperator::Add => 1,
105 BinaryOperator::Mul => 1,
106 }
107 }
108}
109
110impl<'a> Recognizable<'a, u8, BinaryOperator> for BinaryOperator {
111 fn recognize(self, scanner: &mut Scanner<'a, u8>) -> ParseResult<Option<BinaryOperator>> {
112 if scanner.is_empty() {
113 return Ok(None);
114 }
115 let (matched, size) = self.matcher(scanner.remaining());
116 if matched {
117 scanner.bump_by(size);
118 return Ok(Some(self));
119 }
120 Ok(None)
121 }
122}
123
124#[allow(dead_code)]
130#[derive(Debug)]
131enum Expression {
132 Reduced {
134 lhs: usize,
135 op: BinaryOperator,
136 rhs: usize,
137 },
138 RightExpression {
140 lhs: usize,
141 op: BinaryOperator,
142 rhs: Box<Expression>,
143 },
144}
145
146impl From<ExpressionInternal> for Expression {
147 fn from(value: ExpressionInternal) -> Self {
148 match value {
149 ExpressionInternal::Reducted(reduced) => Expression::Reduced {
150 lhs: reduced.lhs,
151 op: reduced.op,
152 rhs: reduced.rhs,
153 },
154 ExpressionInternal::RightExpression(right) => Expression::RightExpression {
155 lhs: right.lhs,
156 op: right.op,
157 rhs: right.rhs,
158 },
159 }
160 }
161}
162
163impl<'a> Visitor<'a, u8> for Expression {
164 fn accept(scanner: &mut Scanner<'a, u8>) -> ParseResult<Self> {
165 OptionalWhitespaces::accept(scanner)?;
166 let result = peek(GroupKind::Parenthesis, scanner)?;
168
169 match result {
170 Some(peeked) => {
171 let mut inner_scanner = Scanner::new(peeked.peeked_slice());
173 let inner_result = Expression::accept(&mut inner_scanner)?;
174 scanner.bump_by(peeked.end_slice);
175 Ok(inner_result)
176 }
177 None => {
178 let accepted = Acceptor::new(scanner)
180 .try_or(ExpressionInternal::RightExpression)?
181 .try_or(ExpressionInternal::Reducted)?
182 .finish()
183 .ok_or(ParseError::UnexpectedToken)?;
184
185 Ok(accepted.into())
186 }
187 }
188 }
189}
190
191fn main() {
192 let data = b"1 + 2";
193 let mut scanner = Scanner::new(data);
194 let result = Expression::accept(&mut scanner);
195 println!("{:?}", result); let data = b"1 + (2 * 3)";
198 let mut scanner = Scanner::new(data);
199 let result = Expression::accept(&mut scanner);
200 println!("{:?}", result); let data = b"1 + (2 * 3 * ( 7 + 8))";
203 let mut scanner = Scanner::new(data);
204 let result = Expression::accept(&mut scanner);
205 println!("{:?}", result); let data = b"1 + 2 + 3";
208 let mut scanner = Scanner::new(data);
209 let result = Expression::accept(&mut scanner);
210 println!("{:?}", result); }