xref: /aosp_15_r20/external/cronet/third_party/rust/chromium_crates_io/vendor/fend-core-1.4.6/src/parser.rs (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 use crate::ast::{Bop, Expr};
2 use crate::lexer::{Symbol, Token};
3 use crate::value::Value;
4 use std::fmt;
5 
6 #[derive(Debug)]
7 pub(crate) enum ParseError {
8 	ExpectedAToken,
9 	ExpectedToken(Symbol, Symbol),
10 	FoundInvalidTokenWhileExpecting(Symbol),
11 	ExpectedANumber,
12 	ExpectedIdentifier,
13 	UnexpectedSymbol(Symbol),
14 	// TODO remove this
15 	InvalidApplyOperands,
16 	UnexpectedInput,
17 	ExpectedIdentifierAsArgument,
18 	ExpectedIdentifierInAssignment,
19 	ExpectedDotInLambda,
20 	InvalidMixedFraction,
21 }
22 
23 impl fmt::Display for ParseError {
fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error>24 	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
25 		match self {
26 			Self::ExpectedAToken => write!(f, "expected a token"),
27 			Self::ExpectedToken(fnd, ex) => write!(f, "found '{fnd}' while expecting '{ex}'"),
28 			Self::FoundInvalidTokenWhileExpecting(sym) => {
29 				write!(f, "found an invalid token while expecting '{sym}'")
30 			}
31 			Self::ExpectedANumber => write!(f, "expected a number"),
32 			Self::ExpectedIdentifier
33 			| Self::ExpectedIdentifierAsArgument
34 			| Self::ExpectedIdentifierInAssignment => {
35 				write!(f, "expected an identifier")
36 			}
37 			Self::UnexpectedSymbol(s) => {
38 				write!(f, "expected a value, instead found '{s}'")
39 			}
40 			// TODO improve this message or remove this error type
41 			Self::InvalidApplyOperands => write!(f, "error"),
42 			Self::UnexpectedInput => write!(f, "unexpected input found"),
43 			Self::ExpectedDotInLambda => {
44 				write!(f, "missing '.' in lambda (expected e.g. \\x.x)")
45 			}
46 			Self::InvalidMixedFraction => write!(f, "invalid mixed fraction"),
47 		}
48 	}
49 }
50 
51 type ParseResult<'a, T = Expr> = Result<(T, &'a [Token]), ParseError>;
52 
53 impl From<ParseError> for crate::error::FendError {
from(e: ParseError) -> Self54 	fn from(e: ParseError) -> Self {
55 		Self::ParseError(e)
56 	}
57 }
58 
parse_token(input: &[Token]) -> ParseResult<'_, Token>59 fn parse_token(input: &[Token]) -> ParseResult<'_, Token> {
60 	if input.is_empty() {
61 		return Err(ParseError::ExpectedAToken);
62 	}
63 	Ok((input[0].clone(), &input[1..]))
64 }
65 
parse_fixed_symbol(input: &[Token], symbol: Symbol) -> ParseResult<'_, ()>66 fn parse_fixed_symbol(input: &[Token], symbol: Symbol) -> ParseResult<'_, ()> {
67 	let (token, remaining) = parse_token(input)?;
68 	if let Token::Symbol(sym) = token {
69 		if sym == symbol {
70 			Ok(((), remaining))
71 		} else {
72 			Err(ParseError::ExpectedToken(sym, symbol))
73 		}
74 	} else {
75 		Err(ParseError::FoundInvalidTokenWhileExpecting(symbol))
76 	}
77 }
78 
parse_number(input: &[Token]) -> ParseResult<'_>79 fn parse_number(input: &[Token]) -> ParseResult<'_> {
80 	match parse_token(input)? {
81 		(Token::Num(num), remaining) => Ok((Expr::Literal(Value::Num(Box::new(num))), remaining)),
82 		_ => Err(ParseError::ExpectedANumber),
83 	}
84 }
85 
parse_ident(input: &[Token]) -> ParseResult<'_>86 fn parse_ident(input: &[Token]) -> ParseResult<'_> {
87 	match parse_token(input)? {
88 		(Token::Ident(ident), remaining) => {
89 			if ident.as_str() == "light" {
90 				if let Ok((ident2, remaining2)) = parse_ident(remaining) {
91 					return Ok((
92 						Expr::Apply(Box::new(Expr::Ident(ident)), Box::new(ident2)),
93 						remaining2,
94 					));
95 				}
96 			}
97 			if let Ok(((), remaining2)) = parse_fixed_symbol(remaining, Symbol::Of) {
98 				let (inner, remaining3) = parse_parens_or_literal(remaining2)?;
99 				Ok((Expr::Of(ident, Box::new(inner)), remaining3))
100 			} else {
101 				Ok((Expr::Ident(ident), remaining))
102 			}
103 		}
104 		_ => Err(ParseError::ExpectedIdentifier),
105 	}
106 }
107 
parse_parens(input: &[Token]) -> ParseResult<'_>108 fn parse_parens(input: &[Token]) -> ParseResult<'_> {
109 	let ((), input) = parse_fixed_symbol(input, Symbol::OpenParens)?;
110 	if let Ok(((), remaining)) = parse_fixed_symbol(input, Symbol::CloseParens) {
111 		return Ok((Expr::Literal(Value::Unit), remaining));
112 	}
113 	let (inner, mut input) = parse_expression(input)?;
114 	// allow omitting closing parentheses at end of input
115 	if !input.is_empty() {
116 		let ((), remaining) = parse_fixed_symbol(input, Symbol::CloseParens)?;
117 		input = remaining;
118 	}
119 	Ok((Expr::Parens(Box::new(inner)), input))
120 }
121 
parse_backslash_lambda(input: &[Token]) -> ParseResult<'_>122 fn parse_backslash_lambda(input: &[Token]) -> ParseResult<'_> {
123 	let ((), input) = parse_fixed_symbol(input, Symbol::Backslash)?;
124 	let (Expr::Ident(ident), input) = parse_ident(input)? else {
125 		return Err(ParseError::ExpectedIdentifier);
126 	};
127 	let ((), input) =
128 		parse_fixed_symbol(input, Symbol::Dot).map_err(|_| ParseError::ExpectedDotInLambda)?;
129 	let (rhs, input) = parse_function(input)?;
130 	Ok((Expr::Fn(ident, Box::new(rhs)), input))
131 }
132 
parse_parens_or_literal(input: &[Token]) -> ParseResult<'_>133 fn parse_parens_or_literal(input: &[Token]) -> ParseResult<'_> {
134 	let (token, remaining) = parse_token(input)?;
135 
136 	match token {
137 		Token::Num(_) => parse_number(input),
138 		Token::Ident(_) => parse_ident(input),
139 		Token::StringLiteral(s) => Ok((Expr::Literal(Value::String(s)), remaining)),
140 		Token::Symbol(Symbol::OpenParens) => parse_parens(input),
141 		Token::Symbol(Symbol::Backslash) => parse_backslash_lambda(input),
142 		Token::Symbol(s) => Err(ParseError::UnexpectedSymbol(s)),
143 		Token::Date(d) => Ok((Expr::Literal(Value::Date(d)), remaining)),
144 	}
145 }
146 
parse_factorial(input: &[Token]) -> ParseResult<'_>147 fn parse_factorial(input: &[Token]) -> ParseResult<'_> {
148 	let (mut res, mut input) = parse_parens_or_literal(input)?;
149 	while let Ok(((), remaining)) = parse_fixed_symbol(input, Symbol::Factorial) {
150 		res = Expr::Factorial(Box::new(res));
151 		input = remaining;
152 	}
153 	Ok((res, input))
154 }
155 
parse_power(input: &[Token], allow_unary: bool) -> ParseResult<'_>156 fn parse_power(input: &[Token], allow_unary: bool) -> ParseResult<'_> {
157 	if allow_unary {
158 		if let Ok(((), remaining)) = parse_fixed_symbol(input, Symbol::Sub) {
159 			let (result, remaining) = parse_power(remaining, true)?;
160 			return Ok((Expr::UnaryMinus(Box::new(result)), remaining));
161 		}
162 		if let Ok(((), remaining)) = parse_fixed_symbol(input, Symbol::Add) {
163 			let (result, remaining) = parse_power(remaining, true)?;
164 			return Ok((Expr::UnaryPlus(Box::new(result)), remaining));
165 		}
166 		// The precedence of unary division relative to exponentiation
167 		// is not important because /a^b -> (1/a)^b == 1/(a^b)
168 		if let Ok(((), remaining)) = parse_fixed_symbol(input, Symbol::Div) {
169 			let (result, remaining) = parse_power(remaining, true)?;
170 			return Ok((Expr::UnaryDiv(Box::new(result)), remaining));
171 		}
172 	}
173 	let (mut result, mut input) = parse_factorial(input)?;
174 	if let Ok(((), remaining)) = parse_fixed_symbol(input, Symbol::Pow) {
175 		let (rhs, remaining) = parse_power(remaining, true)?;
176 		result = Expr::Bop(Bop::Pow, Box::new(result), Box::new(rhs));
177 		input = remaining;
178 	}
179 	Ok((result, input))
180 }
181 
parse_apply_cont<'a>(input: &'a [Token], lhs: &Expr) -> ParseResult<'a>182 fn parse_apply_cont<'a>(input: &'a [Token], lhs: &Expr) -> ParseResult<'a> {
183 	let (rhs, input) = parse_power(input, false)?;
184 	Ok((
185 		match (lhs, &rhs) {
186 			(
187 				Expr::Literal(Value::Num(_)) | Expr::UnaryMinus(_) | Expr::ApplyMul(_, _),
188 				Expr::Literal(Value::Num(_)),
189 			) => {
190 				// this may later be parsed as a compound fraction, e.g. 1 2/3
191 				// or as an addition, e.g. 6 feet 1 inch
192 				return Err(ParseError::InvalidApplyOperands);
193 			}
194 			(
195 				Expr::Literal(Value::Num(_)) | Expr::UnaryMinus(_) | Expr::ApplyMul(_, _),
196 				Expr::Bop(Bop::Pow, a, _),
197 			) => {
198 				if let Expr::Literal(Value::Num(_)) = **a {
199 					return Err(ParseError::InvalidApplyOperands);
200 				}
201 				Expr::Apply(Box::new(lhs.clone()), Box::new(rhs))
202 			}
203 			// support e.g. '$5', '£3' or '¥10'
204 			(Expr::Ident(i), Expr::Literal(Value::Num(_))) if i.is_prefix_unit() => {
205 				Expr::Apply(Box::new(lhs.clone()), Box::new(rhs))
206 			}
207 			(_, Expr::Literal(Value::Num(_))) => {
208 				Expr::ApplyFunctionCall(Box::new(lhs.clone()), Box::new(rhs))
209 			}
210 			(Expr::Literal(Value::Num(_)) | Expr::ApplyMul(_, _), _) => {
211 				Expr::ApplyMul(Box::new(lhs.clone()), Box::new(rhs))
212 			}
213 			_ => Expr::Apply(Box::new(lhs.clone()), Box::new(rhs)),
214 		},
215 		input,
216 	))
217 }
218 
parse_mixed_fraction<'a>(input: &'a [Token], lhs: &Expr) -> ParseResult<'a>219 fn parse_mixed_fraction<'a>(input: &'a [Token], lhs: &Expr) -> ParseResult<'a> {
220 	let (positive, lhs, other_factor) = match lhs {
221 		Expr::Literal(Value::Num(_)) => (true, lhs, None),
222 		Expr::UnaryMinus(x) => {
223 			if let Expr::Literal(Value::Num(_)) = &**x {
224 				(false, lhs, None)
225 			} else {
226 				return Err(ParseError::InvalidMixedFraction);
227 			}
228 		}
229 		Expr::Bop(Bop::Mul, a, b) => match &**b {
230 			Expr::Literal(Value::Num(_)) => (true, &**b, Some(&**a)),
231 			Expr::UnaryMinus(x) => {
232 				if let Expr::Literal(Value::Num(_)) = &**x {
233 					(false, &**b, Some(&**a))
234 				} else {
235 					return Err(ParseError::InvalidMixedFraction);
236 				}
237 			}
238 			_ => return Err(ParseError::InvalidMixedFraction),
239 		},
240 		_ => return Err(ParseError::InvalidMixedFraction),
241 	};
242 	let (rhs_top, input) = parse_power(input, false)?;
243 	if let Expr::Literal(Value::Num(_)) = rhs_top {
244 	} else {
245 		return Err(ParseError::InvalidMixedFraction);
246 	}
247 	let ((), input) = parse_fixed_symbol(input, Symbol::Div)?;
248 	let (rhs_bottom, input) = parse_power(input, false)?;
249 	if let Expr::Literal(Value::Num(_)) = rhs_bottom {
250 	} else {
251 		return Err(ParseError::InvalidMixedFraction);
252 	}
253 	let rhs = Box::new(Expr::Bop(Bop::Div, Box::new(rhs_top), Box::new(rhs_bottom)));
254 	let mixed_fraction = if positive {
255 		Expr::Bop(Bop::Plus, Box::new(lhs.clone()), rhs)
256 	} else {
257 		Expr::Bop(Bop::Minus, Box::new(lhs.clone()), rhs)
258 	};
259 	let mixed_fraction = other_factor.map_or(mixed_fraction.clone(), |other_factor| {
260 		Expr::Bop(
261 			Bop::Mul,
262 			Box::new(other_factor.clone()),
263 			Box::new(mixed_fraction),
264 		)
265 	});
266 	Ok((mixed_fraction, input))
267 }
268 
parse_multiplication_cont(input: &[Token]) -> ParseResult<'_>269 fn parse_multiplication_cont(input: &[Token]) -> ParseResult<'_> {
270 	let ((), input) = parse_fixed_symbol(input, Symbol::Mul)?;
271 	let (b, input) = parse_power(input, true)?;
272 	Ok((b, input))
273 }
274 
parse_division_cont(input: &[Token]) -> ParseResult<'_>275 fn parse_division_cont(input: &[Token]) -> ParseResult<'_> {
276 	let ((), input) = parse_fixed_symbol(input, Symbol::Div)?;
277 	let (b, input) = parse_power(input, true)?;
278 	Ok((b, input))
279 }
280 
parse_modulo_cont(input: &[Token]) -> ParseResult<'_>281 fn parse_modulo_cont(input: &[Token]) -> ParseResult<'_> {
282 	let ((), input) = parse_fixed_symbol(input, Symbol::Mod)?;
283 	let (b, input) = parse_power(input, true)?;
284 	Ok((b, input))
285 }
286 
parse_multiplicative(input: &[Token]) -> ParseResult<'_>287 fn parse_multiplicative(input: &[Token]) -> ParseResult<'_> {
288 	let (mut res, mut input) = parse_power(input, true)?;
289 	loop {
290 		if let Ok((term, remaining)) = parse_multiplication_cont(input) {
291 			res = Expr::Bop(Bop::Mul, Box::new(res.clone()), Box::new(term));
292 			input = remaining;
293 		} else if let Ok((term, remaining)) = parse_division_cont(input) {
294 			res = Expr::Bop(Bop::Div, Box::new(res.clone()), Box::new(term));
295 			input = remaining;
296 		} else if let Ok((term, remaining)) = parse_modulo_cont(input) {
297 			res = Expr::Bop(Bop::Mod, Box::new(res.clone()), Box::new(term));
298 			input = remaining;
299 		} else if let Ok((new_res, remaining)) = parse_mixed_fraction(input, &res) {
300 			res = new_res;
301 			input = remaining;
302 		} else if let Ok((new_res, remaining)) = parse_apply_cont(input, &res) {
303 			res = new_res;
304 			input = remaining;
305 		} else {
306 			break;
307 		}
308 	}
309 	Ok((res, input))
310 }
311 
parse_implicit_addition(input: &[Token]) -> ParseResult<'_>312 fn parse_implicit_addition(input: &[Token]) -> ParseResult<'_> {
313 	let (res, input) = parse_multiplicative(input)?;
314 	if let Ok((rhs, remaining)) = parse_implicit_addition(input) {
315 		// n i n i, n i i n i i, etc. (n: number literal, i: identifier)
316 		if let (
317 			Expr::ApplyMul(_, _),
318 			Expr::ApplyMul(_, _) | Expr::Bop(Bop::ImplicitPlus, _, _) | Expr::Literal(_),
319 		) = (&res, &rhs)
320 		{
321 			return Ok((
322 				Expr::Bop(Bop::ImplicitPlus, Box::new(res), Box::new(rhs)),
323 				remaining,
324 			));
325 		};
326 	}
327 	Ok((res, input))
328 }
329 
parse_addition_cont(input: &[Token]) -> ParseResult<'_>330 fn parse_addition_cont(input: &[Token]) -> ParseResult<'_> {
331 	let ((), input) = parse_fixed_symbol(input, Symbol::Add)?;
332 	let (b, input) = parse_implicit_addition(input)?;
333 	Ok((b, input))
334 }
335 
parse_subtraction_cont(input: &[Token]) -> ParseResult<'_>336 fn parse_subtraction_cont(input: &[Token]) -> ParseResult<'_> {
337 	let ((), input) = parse_fixed_symbol(input, Symbol::Sub)?;
338 	let (b, input) = parse_implicit_addition(input)?;
339 	Ok((b, input))
340 }
341 
parse_to_cont(input: &[Token]) -> ParseResult<'_>342 fn parse_to_cont(input: &[Token]) -> ParseResult<'_> {
343 	let ((), input) = parse_fixed_symbol(input, Symbol::UnitConversion)?;
344 	let (b, input) = parse_implicit_addition(input)?;
345 	Ok((b, input))
346 }
347 
parse_additive(input: &[Token]) -> ParseResult<'_>348 fn parse_additive(input: &[Token]) -> ParseResult<'_> {
349 	let (mut res, mut input) = parse_implicit_addition(input)?;
350 	loop {
351 		if let Ok((term, remaining)) = parse_addition_cont(input) {
352 			res = Expr::Bop(Bop::Plus, Box::new(res), Box::new(term));
353 			input = remaining;
354 		} else if let Ok((term, remaining)) = parse_subtraction_cont(input) {
355 			res = Expr::Bop(Bop::Minus, Box::new(res), Box::new(term));
356 			input = remaining;
357 		} else if let Ok((term, remaining)) = parse_to_cont(input) {
358 			res = Expr::As(Box::new(res), Box::new(term));
359 			input = remaining;
360 		} else {
361 			break;
362 		}
363 	}
364 	Ok((res, input))
365 }
366 
parse_bitshifts(input: &[Token]) -> ParseResult<'_>367 fn parse_bitshifts(input: &[Token]) -> ParseResult<'_> {
368 	let (mut result, mut input) = parse_additive(input)?;
369 	loop {
370 		if let Ok(((), remaining)) = parse_fixed_symbol(input, Symbol::ShiftLeft) {
371 			let (rhs, remaining) = parse_additive(remaining)?;
372 			result = Expr::Bop(
373 				Bop::Bitwise(crate::ast::BitwiseBop::LeftShift),
374 				Box::new(result),
375 				Box::new(rhs),
376 			);
377 			input = remaining;
378 		} else if let Ok(((), remaining)) = parse_fixed_symbol(input, Symbol::ShiftRight) {
379 			let (rhs, remaining) = parse_additive(remaining)?;
380 			result = Expr::Bop(
381 				Bop::Bitwise(crate::ast::BitwiseBop::RightShift),
382 				Box::new(result),
383 				Box::new(rhs),
384 			);
385 			input = remaining;
386 		} else {
387 			break;
388 		}
389 	}
390 	Ok((result, input))
391 }
392 
parse_bitwise_and(input: &[Token]) -> ParseResult<'_>393 fn parse_bitwise_and(input: &[Token]) -> ParseResult<'_> {
394 	let (mut result, mut input) = parse_bitshifts(input)?;
395 	while let Ok(((), remaining)) = parse_fixed_symbol(input, Symbol::BitwiseAnd) {
396 		let (rhs, remaining) = parse_bitshifts(remaining)?;
397 		result = Expr::Bop(
398 			Bop::Bitwise(crate::ast::BitwiseBop::And),
399 			Box::new(result),
400 			Box::new(rhs),
401 		);
402 		input = remaining;
403 	}
404 	Ok((result, input))
405 }
406 
parse_bitwise_xor(input: &[Token]) -> ParseResult<'_>407 fn parse_bitwise_xor(input: &[Token]) -> ParseResult<'_> {
408 	let (mut result, mut input) = parse_bitwise_and(input)?;
409 	while let Ok(((), remaining)) = parse_fixed_symbol(input, Symbol::BitwiseXor) {
410 		let (rhs, remaining) = parse_bitwise_and(remaining)?;
411 		result = Expr::Bop(
412 			Bop::Bitwise(crate::ast::BitwiseBop::Xor),
413 			Box::new(result),
414 			Box::new(rhs),
415 		);
416 		input = remaining;
417 	}
418 	Ok((result, input))
419 }
420 
parse_bitwise_or(input: &[Token]) -> ParseResult<'_>421 fn parse_bitwise_or(input: &[Token]) -> ParseResult<'_> {
422 	let (mut result, mut input) = parse_bitwise_xor(input)?;
423 	while let Ok(((), remaining)) = parse_fixed_symbol(input, Symbol::BitwiseOr) {
424 		let (rhs, remaining) = parse_bitwise_xor(remaining)?;
425 		result = Expr::Bop(
426 			Bop::Bitwise(crate::ast::BitwiseBop::Or),
427 			Box::new(result),
428 			Box::new(rhs),
429 		);
430 		input = remaining;
431 	}
432 	Ok((result, input))
433 }
434 
parse_combination(input: &[Token]) -> ParseResult<'_>435 fn parse_combination(input: &[Token]) -> ParseResult<'_> {
436 	let (mut result, mut input) = parse_bitwise_or(input)?;
437 	while let Ok(((), remaining)) = parse_fixed_symbol(input, Symbol::Combination) {
438 		let (rhs, remaining) = parse_bitwise_or(remaining)?;
439 		result = Expr::Bop(Bop::Combination, Box::new(result), Box::new(rhs));
440 		input = remaining;
441 	}
442 	Ok((result, input))
443 }
444 
parse_permutation(input: &[Token]) -> ParseResult<'_>445 fn parse_permutation(input: &[Token]) -> ParseResult<'_> {
446 	let (mut result, mut input) = parse_combination(input)?;
447 	while let Ok(((), remaining)) = parse_fixed_symbol(input, Symbol::Permutation) {
448 		let (rhs, remaining) = parse_combination(remaining)?;
449 		result = Expr::Bop(Bop::Permutation, Box::new(result), Box::new(rhs));
450 		input = remaining;
451 	}
452 	Ok((result, input))
453 }
454 
parse_function(input: &[Token]) -> ParseResult<'_>455 fn parse_function(input: &[Token]) -> ParseResult<'_> {
456 	let (lhs, input) = parse_permutation(input)?;
457 	if let Ok(((), remaining)) = parse_fixed_symbol(input, Symbol::Fn) {
458 		if let Expr::Ident(s) = lhs {
459 			let (rhs, remaining) = parse_function(remaining)?;
460 			return Ok((Expr::Fn(s, Box::new(rhs)), remaining));
461 		}
462 		return Err(ParseError::ExpectedIdentifierAsArgument);
463 	}
464 	Ok((lhs, input))
465 }
466 
parse_equality(input: &[Token]) -> ParseResult<'_>467 fn parse_equality(input: &[Token]) -> ParseResult<'_> {
468 	let (lhs, input) = parse_function(input)?;
469 	if let Ok(((), remaining)) = parse_fixed_symbol(input, Symbol::DoubleEquals) {
470 		let (rhs, remaining) = parse_function(remaining)?;
471 		Ok((
472 			Expr::Equality(true, Box::new(lhs), Box::new(rhs)),
473 			remaining,
474 		))
475 	} else if let Ok(((), remaining)) = parse_fixed_symbol(input, Symbol::NotEquals) {
476 		let (rhs, remaining) = parse_function(remaining)?;
477 		Ok((
478 			Expr::Equality(false, Box::new(lhs), Box::new(rhs)),
479 			remaining,
480 		))
481 	} else {
482 		Ok((lhs, input))
483 	}
484 }
485 
parse_assignment(input: &[Token]) -> ParseResult<'_>486 fn parse_assignment(input: &[Token]) -> ParseResult<'_> {
487 	let (lhs, input) = parse_equality(input)?;
488 	if let Ok(((), remaining)) = parse_fixed_symbol(input, Symbol::Equals) {
489 		if let Expr::Ident(s) = lhs {
490 			let (rhs, remaining) = parse_assignment(remaining)?;
491 			return Ok((Expr::Assign(s, Box::new(rhs)), remaining));
492 		}
493 		return Err(ParseError::ExpectedIdentifierInAssignment);
494 	}
495 	Ok((lhs, input))
496 }
497 
parse_statements(mut input: &[Token]) -> ParseResult<'_>498 fn parse_statements(mut input: &[Token]) -> ParseResult<'_> {
499 	while let Ok(((), remaining)) = parse_fixed_symbol(input, Symbol::Semicolon) {
500 		input = remaining;
501 	}
502 	if input.is_empty() {
503 		return Ok((Expr::Literal(Value::Unit), &[]));
504 	}
505 	let (mut result, mut input) = parse_assignment(input)?;
506 	while let Ok(((), remaining)) = parse_fixed_symbol(input, Symbol::Semicolon) {
507 		if remaining.is_empty() || matches!(remaining[0], Token::Symbol(Symbol::Semicolon)) {
508 			input = remaining;
509 			continue;
510 		}
511 		let (rhs, remaining) = parse_assignment(remaining)?;
512 		result = Expr::Statements(Box::new(result), Box::new(rhs));
513 		input = remaining;
514 	}
515 	Ok((result, input))
516 }
517 
parse_expression(input: &[Token]) -> ParseResult<'_>518 pub(crate) fn parse_expression(input: &[Token]) -> ParseResult<'_> {
519 	parse_statements(input)
520 }
521 
parse_tokens(input: &[Token]) -> Result<Expr, ParseError>522 pub(crate) fn parse_tokens(input: &[Token]) -> Result<Expr, ParseError> {
523 	let (res, remaining) = parse_expression(input)?;
524 	if !remaining.is_empty() {
525 		return Err(ParseError::UnexpectedInput);
526 	}
527 	Ok(res)
528 }
529