1use core::{error::Error, fmt::Display};
4
5use alloc::{
6 boxed::Box,
7 collections::{BTreeMap, btree_set::BTreeSet},
8 format,
9 string::{String, ToString},
10 vec::Vec,
11};
12
13use crate::{
14 WasmValue,
15 ast::{Node, NodeType},
16 lex::{FuncNameLexer, FuncNameToken, Keyword, Lexer, Span, Token},
17 untyped::{UntypedFuncCall, UntypedValue},
18};
19
20const MAX_DEPTH: usize = 100;
21
22pub struct Parser<'source> {
24 lex: Lexer<'source>,
25 curr: Option<Token>,
26 depth: usize,
27}
28
29impl<'source> Parser<'source> {
30 pub fn new(source: &'source str) -> Self {
32 Self::with_lexer(Lexer::new(source))
33 }
34
35 pub fn with_lexer(lexer: Lexer<'source>) -> Self {
37 Self {
38 lex: lexer,
39 curr: None,
40 depth: 0,
41 }
42 }
43
44 pub fn parse_value<V: WasmValue>(&mut self, ty: &V::Type) -> Result<V, ParserError> {
47 let node = self.parse_node()?;
48 node.to_wasm_value(ty, self.lex.source())
49 }
50
51 pub fn parse_raw_value(&mut self) -> Result<UntypedValue<'source>, ParserError> {
53 let node = self.parse_node()?;
54 Ok(UntypedValue::new(self.lex.source(), node))
55 }
56
57 pub fn finish(&mut self) -> Result<(), ParserError> {
59 match self.lex.clone().spanned().next() {
60 None => Ok(()),
61 Some((_, span)) => Err(ParserError::new(
62 ParserErrorKind::TrailingCharacters,
63 span.clone(),
64 )),
65 }
66 }
67
68 fn parse_node(&mut self) -> Result<Node, ParserError> {
69 if self.depth >= MAX_DEPTH {
70 return Err(ParserError::new(
71 ParserErrorKind::NestingTooDeep,
72 self.lex.span(),
73 ));
74 }
75 self.depth += 1;
76 let result = self.parse_node_inner();
77 self.depth -= 1;
78 result
79 }
80
81 fn parse_node_inner(&mut self) -> Result<Node, ParserError> {
82 Ok(match self.advance()? {
83 Token::Number => self.leaf_node(NodeType::Number),
84 Token::Char => self.leaf_node(NodeType::Char),
85 Token::String => self.leaf_node(NodeType::String),
86 Token::MultilineString => self.leaf_node(NodeType::MultilineString),
87 Token::ParenOpen => self.parse_tuple()?,
88 Token::BracketOpen => self.parse_list()?,
89 Token::BraceOpen => self.parse_record_or_flags()?,
90 Token::LabelOrKeyword => match Keyword::decode(self.slice()) {
91 Some(Keyword::True) => self.leaf_node(NodeType::BoolTrue),
92 Some(Keyword::False) => self.leaf_node(NodeType::BoolFalse),
93 Some(Keyword::Some) => self.parse_option(NodeType::OptionSome)?,
94 Some(Keyword::None) => self.parse_option(NodeType::OptionNone)?,
95 Some(Keyword::Ok) => self.parse_result(NodeType::ResultOk)?,
96 Some(Keyword::Err) => self.parse_result(NodeType::ResultErr)?,
97 Some(Keyword::Inf | Keyword::Nan) => self.leaf_node(NodeType::Number),
98 None => self.parse_label_maybe_payload()?,
99 },
100 Token::BraceClose
101 | Token::ParenClose
102 | Token::BracketClose
103 | Token::Colon
104 | Token::Comma => return Err(self.unexpected_token()),
105 })
106 }
107
108 fn parse_tuple(&mut self) -> Result<Node, ParserError> {
109 let start = self.span().start;
110 let children = self.parse_comma_separated_nodes(Token::ParenClose)?;
111 let span = start..self.span().end;
112 if children.is_empty() {
113 return Err(ParserError::new(ParserErrorKind::EmptyTuple, span));
114 }
115 Ok(Node::new(NodeType::Tuple, span, children))
116 }
117
118 fn parse_list(&mut self) -> Result<Node, ParserError> {
119 let start = self.span().start;
120 let children = self.parse_comma_separated_nodes(Token::BracketClose)?;
121 Ok(Node::new(NodeType::List, start..self.span().end, children))
122 }
123
124 fn parse_record_or_flags(&mut self) -> Result<Node, ParserError> {
125 let start = self.span().start;
126 self.advance()?;
127
128 match self.token() {
129 Token::Colon => {
131 self.advance()?; self.expect_token(Token::BraceClose)?;
133 return Ok(Node::new(NodeType::Record, start..self.span().end, []));
134 }
135 Token::BraceClose => return Ok(Node::new(NodeType::Flags, start..self.span().end, [])),
137 _ => (),
138 }
139
140 if self.next_is(Token::Colon) {
142 self.finish_record(start)
143 } else {
144 self.finish_flags(start)
145 }
146 }
147
148 fn finish_record(&mut self, start: usize) -> Result<Node, ParserError> {
149 let mut seen = BTreeSet::new();
150 let mut children = Vec::with_capacity(2);
151 loop {
152 let label = self.parse_label()?;
154 let field = self.slice().trim_start_matches('%');
156 if !seen.insert(field) {
157 return Err(ParserError::with_detail(
158 ParserErrorKind::DuplicateField,
159 label.span(),
160 format!("{field:?}"),
161 ));
162 }
163 self.advance()?;
165 self.expect_token(Token::Colon)?;
166 let value = self.parse_node()?;
168 children.extend([label, value]);
169 if self.advance()? == Token::Comma {
171 self.advance()?;
172 }
173 if self.token() == Token::BraceClose {
174 break;
175 }
176 }
177 Ok(Node::new(
178 NodeType::Record,
179 start..self.span().end,
180 children,
181 ))
182 }
183
184 fn finish_flags(&mut self, start: usize) -> Result<Node, ParserError> {
185 let mut flags = BTreeMap::new();
186 loop {
187 let label = self.parse_label()?;
189 let span = label.span();
191 let flag = self.slice().trim_start_matches('%');
192 if flags.insert(flag, label).is_some() {
193 return Err(ParserError::with_detail(
194 ParserErrorKind::DuplicateFlag,
195 span,
196 format!("{flag:?}"),
197 ));
198 }
199 if self.advance()? == Token::Comma {
201 self.advance()?;
202 }
203 if self.token() == Token::BraceClose {
204 break;
205 }
206 }
207 Ok(Node::new(
208 NodeType::Flags,
209 start..self.span().end,
210 flags.into_values(),
211 ))
212 }
213
214 fn parse_label_maybe_payload(&mut self) -> Result<Node, ParserError> {
215 let start = self.span().start;
216 let label = self.parse_label()?;
217 if self.next_is(Token::ParenOpen) {
218 self.advance()?;
219 let payload = self.parse_node()?;
220 self.advance()?;
221 self.expect_token(Token::ParenClose)?;
222 Ok(Node::new(
223 NodeType::VariantWithPayload,
224 start..self.span().end,
225 [label, payload],
226 ))
227 } else {
228 Ok(label)
229 }
230 }
231
232 fn parse_option(&mut self, ty: NodeType) -> Result<Node, ParserError> {
233 let start = self.span().start;
234 let payload = match ty {
235 NodeType::OptionSome => {
236 self.advance()?;
237 self.expect_token(Token::ParenOpen)?;
238 let payload = self.parse_node()?;
239 self.advance()?;
240 self.expect_token(Token::ParenClose)?;
241 Some(payload)
242 }
243 NodeType::OptionNone => None,
244 _ => unreachable!(),
245 };
246 Ok(Node::new(ty, start..self.span().end, payload))
247 }
248
249 fn parse_result(&mut self, ty: NodeType) -> Result<Node, ParserError> {
250 let start = self.span().start;
251 let mut payload = None;
252 if self.next_is(Token::ParenOpen) {
253 self.advance()?;
254 self.expect_token(Token::ParenOpen)?;
255 payload = Some(self.parse_node()?);
256 self.advance()?;
257 self.expect_token(Token::ParenClose)?;
258 }
259 Ok(Node::new(ty, start..self.span().end, payload))
260 }
261
262 fn parse_label(&mut self) -> Result<Node, ParserError> {
263 self.expect_token(Token::LabelOrKeyword)?;
264 Ok(self.leaf_node(NodeType::Label))
265 }
266
267 fn advance(&mut self) -> Result<Token, ParserError> {
268 let token = match self.lex.next() {
269 Some(Ok(token)) => token,
270 Some(Err(span)) => {
271 let span = span.unwrap_or_else(|| self.lex.span());
272 return Err(ParserError::new(ParserErrorKind::InvalidToken, span));
273 }
274 None => {
275 return Err(ParserError::new(
276 ParserErrorKind::UnexpectedEnd,
277 self.lex.span(),
278 ));
279 }
280 };
281 self.curr = Some(token);
282 Ok(token)
283 }
284
285 fn token(&self) -> Token {
286 self.curr.unwrap()
287 }
288
289 fn span(&self) -> Span {
290 self.lex.span()
291 }
292
293 fn slice(&self) -> &'source str {
294 &self.lex.source()[self.span()]
295 }
296
297 fn next_is(&mut self, token: Token) -> bool {
298 self.lex.clone().next().and_then(|res| res.ok()) == Some(token)
299 }
300
301 fn expect_token(&self, token: Token) -> Result<(), ParserError> {
302 if self.token() == token {
303 Ok(())
304 } else {
305 Err(self.unexpected_token())
306 }
307 }
308
309 fn unexpected_token(&self) -> ParserError {
310 ParserError::with_detail(ParserErrorKind::UnexpectedToken, self.span(), self.token())
311 }
312
313 fn parse_comma_separated_nodes(&mut self, end_token: Token) -> Result<Vec<Node>, ParserError> {
314 let mut nodes = Vec::new();
315 if self.next_is(end_token) {
316 self.advance()?;
317 return Ok(nodes);
318 }
319 loop {
320 nodes.push(self.parse_node()?);
321
322 match self.advance()? {
323 Token::Comma => {
324 if self.next_is(end_token) {
325 self.advance()?;
326 break;
327 }
328 }
329 _ => {
330 self.expect_token(end_token)?;
331 break;
332 }
333 }
334 }
335 Ok(nodes)
336 }
337
338 fn leaf_node(&self, ty: NodeType) -> Node {
339 Node::new(ty, self.span(), [])
340 }
341}
342
343#[derive(Debug)]
345pub struct ParserError {
346 kind: ParserErrorKind,
347 span: Span,
348 detail: Option<String>,
349 source: Option<Box<dyn Error + Send + Sync + 'static>>,
350}
351
352impl ParserError {
353 pub(crate) fn new(kind: ParserErrorKind, span: Span) -> Self {
354 Self {
355 kind,
356 span,
357 detail: None,
358 source: None,
359 }
360 }
361
362 pub(crate) fn with_detail(kind: ParserErrorKind, span: Span, detail: impl Display) -> Self {
363 Self {
364 kind,
365 span,
366 detail: Some(detail.to_string()),
367 source: None,
368 }
369 }
370
371 pub(crate) fn with_source(
372 kind: ParserErrorKind,
373 span: Span,
374 source: impl Into<Box<dyn Error + Send + Sync>>,
375 ) -> Self {
376 Self {
377 kind,
378 span,
379 detail: None,
380 source: Some(source.into()),
381 }
382 }
383
384 pub fn kind(&self) -> ParserErrorKind {
386 self.kind
387 }
388
389 pub fn span(&self) -> Span {
391 self.span.clone()
392 }
393
394 pub fn detail(&self) -> Option<&str> {
396 self.detail.as_deref()
397 }
398}
399
400impl Display for ParserError {
401 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
402 if let Some(source) = &self.source {
403 write!(f, "{}: {} at {:?}", self.kind, source, self.span)
404 } else if let Some(detail) = &self.detail {
405 write!(f, "{}: {} at {:?}", self.kind, detail, self.span)
406 } else {
407 write!(f, "{} at {:?}", self.kind, self.span)
408 }
409 }
410}
411
412impl Error for ParserError {
413 fn source(&self) -> Option<&(dyn Error + 'static)> {
414 Some(self.source.as_deref()? as _)
415 }
416}
417
418pub fn parse_raw_func_call<'source>(
421 source: &'source str,
422) -> Result<UntypedFuncCall<'source>, ParserError> {
423 let mut name_parser = FuncNameParser::with_lexer(FuncNameLexer::new(source));
424 let _func_name = name_parser.advance()?;
425 let name = name_parser.lex.span();
426
427 let mut params_parser = Parser::with_lexer(name_parser.lex.morph());
428 params_parser.advance()?;
429 params_parser.expect_token(Token::ParenOpen)?;
430
431 let params = if params_parser.next_is(Token::ParenClose) {
432 params_parser.advance()?;
433 None
434 } else {
435 Some(params_parser.parse_tuple()?)
436 };
437 params_parser.finish()?;
438 Ok(UntypedFuncCall::new(source, name, params))
439}
440
441struct FuncNameParser<'source> {
442 lex: FuncNameLexer<'source>,
443 curr: Option<FuncNameToken>,
444}
445impl<'source> FuncNameParser<'source> {
446 fn with_lexer(lex: FuncNameLexer<'source>) -> Self {
447 Self { lex, curr: None }
448 }
449 fn advance(&mut self) -> Result<FuncNameToken, ParserError> {
450 let token = match self.lex.next() {
451 Some(Ok(token)) => token,
452 Some(Err(span)) => {
453 let span = span.unwrap_or_else(|| self.lex.span());
454 return Err(ParserError::new(ParserErrorKind::InvalidToken, span));
455 }
456 None => {
457 return Err(ParserError::new(
458 ParserErrorKind::UnexpectedEnd,
459 self.lex.span(),
460 ));
461 }
462 };
463 self.curr = Some(token);
464 Ok(token)
465 }
466}
467#[derive(Clone, Copy, Debug, PartialEq)]
469#[non_exhaustive]
470#[allow(missing_docs)]
471pub enum ParserErrorKind {
472 EmptyTuple,
473 MultipleChars,
474 InvalidEscape,
475 InvalidMultilineString,
476 InvalidParams,
477 InvalidToken,
478 InvalidType,
479 InvalidValue,
480 TrailingCharacters,
481 UnexpectedEnd,
482 UnexpectedToken,
483 DuplicateField,
484 DuplicateFlag,
485 WasmValueError,
486 NestingTooDeep,
487}
488
489impl Display for ParserErrorKind {
490 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
491 let msg = match self {
492 ParserErrorKind::EmptyTuple => "empty tuple",
493 ParserErrorKind::MultipleChars => "multiple characters in char value",
494 ParserErrorKind::InvalidEscape => "invalid character escape",
495 ParserErrorKind::InvalidMultilineString => "invalid multiline string",
496 ParserErrorKind::InvalidParams => "invalid params",
497 ParserErrorKind::InvalidToken => "invalid token",
498 ParserErrorKind::InvalidType => "invalid value type",
499 ParserErrorKind::InvalidValue => "invalid value",
500 ParserErrorKind::TrailingCharacters => "trailing characters after value",
501 ParserErrorKind::UnexpectedEnd => "unexpected end of input",
502 ParserErrorKind::UnexpectedToken => "unexpected token",
503 ParserErrorKind::DuplicateField => "duplicate field",
504 ParserErrorKind::DuplicateFlag => "duplicate flag",
505 ParserErrorKind::WasmValueError => "error converting Wasm value",
506 ParserErrorKind::NestingTooDeep => "value nesting too deep",
507 };
508 write!(f, "{msg}")
509 }
510}
511
512#[cfg(test)]
513mod tests {
514 use super::*;
515 use crate::value::{Type, Value};
516
517 #[test]
518 fn parse_option_or_result() {
519 let ty = Type::option(Type::BOOL);
520 assert_eq!(
521 parse_value("some(true)", &ty),
522 Value::make_option(&ty, Some(Value::make_bool(true))).unwrap()
523 );
524 let ty = Type::result(Some(Type::BOOL), None);
525 assert_eq!(
526 parse_value("ok(false)", &ty),
527 Value::make_result(&ty, Ok(Some(Value::make_bool(false)))).unwrap()
528 );
529 }
530
531 #[test]
532 fn parse_flat_option_or_result() {
533 let ty = Type::option(Type::BOOL);
534 assert_eq!(
535 parse_value("true", &ty),
536 Value::make_option(&ty, Some(Value::make_bool(true))).unwrap()
537 );
538 let ty = Type::result(Some(Type::BOOL), None);
539 assert_eq!(
540 parse_value("false", &ty),
541 Value::make_result(&ty, Ok(Some(Value::make_bool(false)))).unwrap()
542 );
543 }
544
545 #[test]
546 fn parse_record_reordering() {
547 let ty = Type::record([("red", Type::S32), ("green", Type::CHAR)]).unwrap();
548 assert_eq!(
550 parse_value("{red: 0, green: 'a'}", &ty),
551 Value::make_record(
552 &ty,
553 [
554 ("red", Value::make_s32(0)),
555 ("green", Value::make_char('a'))
556 ]
557 )
558 .unwrap()
559 );
560 assert_eq!(
562 parse_value("{green: 'a', red: 0}", &ty),
563 Value::make_record(
564 &ty,
565 [
566 ("red", Value::make_s32(0)),
567 ("green", Value::make_char('a'))
568 ]
569 )
570 .unwrap()
571 );
572 }
573
574 #[test]
575 fn parse_record_with_optional_fields() {
576 let field_ty = Type::option(Type::CHAR);
577 let ty = Type::record([("red", Type::S32), ("green", field_ty.clone())]).unwrap();
578 assert_eq!(
580 parse_value("{red: 0, green: some('a')}", &ty),
581 Value::make_record(
582 &ty,
583 [
584 ("red", Value::make_s32(0)),
585 (
586 "green",
587 Value::make_option(&field_ty, Some(Value::make_char('a'))).unwrap()
588 )
589 ]
590 )
591 .unwrap()
592 );
593 assert_eq!(
595 parse_value("{red: 0, green: 'a'}", &ty),
596 Value::make_record(
597 &ty,
598 [
599 ("red", Value::make_s32(0)),
600 (
601 "green",
602 Value::make_option(&field_ty, Some(Value::make_char('a'))).unwrap()
603 )
604 ]
605 )
606 .unwrap()
607 );
608 assert_eq!(
610 parse_value("{red: 0, green: none}", &ty),
611 Value::make_record(
612 &ty,
613 [
614 ("red", Value::make_s32(0)),
615 ("green", Value::make_option(&field_ty, None).unwrap())
616 ]
617 )
618 .unwrap()
619 );
620 assert_eq!(
622 parse_value("{red: 0}", &ty),
623 Value::make_record(
624 &ty,
625 [
626 ("red", Value::make_s32(0)),
627 ("green", Value::make_option(&field_ty, None).unwrap())
628 ]
629 )
630 .unwrap()
631 );
632 }
633
634 #[test]
635 fn parse_flag_reordering() {
636 let ty = Type::flags(["hot", "cold"]).unwrap();
637 assert_eq!(
639 parse_value("{hot, cold}", &ty),
640 Value::make_flags(&ty, ["hot", "cold"]).unwrap()
641 );
642 assert_eq!(
644 parse_value("{cold, hot}", &ty),
645 Value::make_flags(&ty, ["hot", "cold"]).unwrap()
646 );
647 }
648
649 #[test]
650 fn parse_percent_identifiers() {
651 let ty = Type::record([
652 ("red", Type::S32),
653 ("green", Type::CHAR),
654 ("color-42-2A-5d", Type::BOOL),
655 ])
656 .unwrap();
657 assert_eq!(
659 parse_value("{ %red: 0, %green: 'a', %color-42-2A-5d: true }", &ty),
660 Value::make_record(
661 &ty,
662 [
663 ("red", Value::make_s32(0)),
664 ("green", Value::make_char('a')),
665 ("color-42-2A-5d", Value::make_bool(true))
666 ]
667 )
668 .unwrap()
669 );
670 }
671
672 #[test]
673 fn parse_prefixed_keyword_variant_cases() {
674 let ty = Type::list(
675 Type::variant([
676 ("true", Some(Type::U8)),
677 ("false", None),
678 ("inf", Some(Type::U8)),
679 ("nan", None),
680 ("some", Some(Type::U8)),
681 ("none", None),
682 ("ok", Some(Type::U8)),
683 ("err", None),
684 ])
685 .unwrap(),
686 );
687 parse_value(
688 "[%true(1), %false, %inf(1), %nan, %some(1), %none, %ok(1), %err]",
689 &ty,
690 );
691 }
692
693 #[test]
694 fn reject_unprefixed_keyword_enum_cases() {
695 let cases = ["true", "false", "inf", "nan", "none", "ok", "err"];
696 let ty = Type::enum_ty(cases).unwrap();
697 for case in cases {
698 let err = Parser::new(case).parse_value::<Value>(&ty).unwrap_err();
699 assert_eq!(err.kind(), ParserErrorKind::InvalidType);
700 }
701 }
702
703 #[test]
704 fn parse_unprefixed_keyword_fields() {
705 let ty = Type::record([
706 ("true", Type::U8),
707 ("false", Type::U8),
708 ("inf", Type::U8),
709 ("nan", Type::U8),
710 ("some", Type::U8),
711 ("none", Type::U8),
712 ("ok", Type::U8),
713 ("err", Type::U8),
714 ])
715 .unwrap();
716 parse_value(
717 "{true: 1, false: 1, inf: 1, nan: 1, some: 1, none: 1, ok: 1, err: 1}",
718 &ty,
719 );
720 }
721
722 #[test]
723 fn parse_unprefixed_keyword_flags() {
724 let ty = Type::flags(["true", "false", "inf", "nan", "some", "none", "ok", "err"]).unwrap();
725 parse_value("{true, false, inf, nan, some, none, ok, err}", &ty);
726 }
727
728 #[test]
729 fn reject_unprefixed_some_variant_case() {
730 let ty = Type::variant([("some", Some(Type::U8))]).unwrap();
731 let err = Parser::new("some(1)")
732 .parse_value::<Value>(&ty)
733 .unwrap_err();
734 assert_eq!(err.kind(), ParserErrorKind::InvalidType);
735 }
736
737 #[test]
738 fn reject_deeply_nested_values() {
739 let deep = MAX_DEPTH + 1;
740 let cases = [
741 ("[".repeat(deep) + &"]".repeat(deep), "nested lists"),
742 ("(".repeat(deep) + "0" + &")".repeat(deep), "nested tuples"),
743 (
744 "some(".repeat(deep) + "0" + &")".repeat(deep),
745 "nested some()",
746 ),
747 ("ok(".repeat(deep) + "0" + &")".repeat(deep), "nested ok()"),
748 (
749 "{a:".repeat(deep) + "0" + &"}".repeat(deep),
750 "nested records",
751 ),
752 (
753 "v(".repeat(deep) + "0" + &")".repeat(deep),
754 "nested variant payloads",
755 ),
756 ];
757 for (input, desc) in cases {
758 let err = UntypedValue::parse(&input)
759 .expect_err(&alloc::format!("{desc} should be rejected"));
760 assert_eq!(
761 err.kind(),
762 ParserErrorKind::NestingTooDeep,
763 "wrong error kind for {desc}"
764 );
765 }
766 }
767
768 #[test]
769 fn reject_deeply_nested_func_call_params() {
770 let deep = MAX_DEPTH + 1;
771 let input = alloc::format!("f({}0{})", "some(".repeat(deep), ")".repeat(deep));
772 let err = match UntypedFuncCall::parse(&input) {
773 Ok(_) => panic!("deeply nested func call params should be rejected"),
774 Err(err) => err,
775 };
776 assert_eq!(err.kind(), ParserErrorKind::NestingTooDeep);
777 }
778
779 fn parse_value(input: &str, ty: &Type) -> Value {
780 Parser::new(input)
781 .parse_value(ty)
782 .unwrap_or_else(|err| panic!("error decoding {input:?}: {err}"))
783 }
784}