diff --git a/crates/json-pawarser/src/grammar.rs b/crates/json-pawarser/src/grammar.rs index b7afe02..ce17972 100644 --- a/crates/json-pawarser/src/grammar.rs +++ b/crates/json-pawarser/src/grammar.rs @@ -1,3 +1,4 @@ +use array::array; use enumset::{enum_set, EnumSet}; use crate::{syntax_error::SyntaxError, syntax_kind::SyntaxKind}; @@ -15,7 +16,7 @@ pub fn value(p: &mut Parser) -> bool { p.do_bump(); return true; } else { - object(p).is_some() + object(p).or_else(|| array(p)).is_some() } } @@ -35,13 +36,13 @@ mod object { member(p); while p.at(SyntaxKind::COMMA) { // not always an error, later configurable - let potential_unexpected_comma = p.start("potential_unexpected_comma"); + let potential_trailing_comma = p.start("potential_trailing_comma"); p.eat(SyntaxKind::COMMA); if member(p).is_none() { - potential_unexpected_comma.complete(p, SyntaxKind::TRAILING_COMMA); + potential_trailing_comma.complete(p, SyntaxKind::TRAILING_COMMA); } else { - potential_unexpected_comma.abandon(p); + potential_trailing_comma.abandon(p); } } @@ -84,4 +85,41 @@ mod object { } } } -mod array {} +mod array { + use crate::{syntax_error::SyntaxError, syntax_kind::SyntaxKind}; + + use super::{value, CompletedMarker, Parser}; + + pub(super) fn array(p: &mut Parser) -> Option { + let array_start = p.start("array"); + + if !p.eat(SyntaxKind::BRACKET_OPEN) { + array_start.abandon(p); + return None; + } + + let el = p.start("arr_el"); + value(p); + el.complete(p, SyntaxKind::ELEMENT); + + while p.at(SyntaxKind::COMMA) { + let potential_trailing_comma = p.start("potential_trailing_comma"); + + p.eat(SyntaxKind::COMMA); + let maybe_el = p.start("arr_el"); + if !value(p) { + maybe_el.abandon(p); + potential_trailing_comma.complete(p, SyntaxKind::TRAILING_COMMA); + } else { + maybe_el.complete(p, SyntaxKind::ELEMENT); + potential_trailing_comma.abandon(p); + } + } + + Some(if !p.eat(SyntaxKind::BRACKET_CLOSE) { + array_start.error(p, SyntaxError::UnclosedArray) + } else { + array_start.complete(p, SyntaxKind::ARRAY) + }) + } +} diff --git a/crates/json-pawarser/src/syntax_error.rs b/crates/json-pawarser/src/syntax_error.rs index b607be1..8c76de2 100644 --- a/crates/json-pawarser/src/syntax_error.rs +++ b/crates/json-pawarser/src/syntax_error.rs @@ -3,6 +3,7 @@ use crate::syntax_kind::SyntaxKind; #[derive(Debug, Clone, PartialEq, Eq)] pub enum SyntaxError { UnclosedObject, + UnclosedArray, DisallowedKeyType(SyntaxKind), MemberMissingValue, UnexpectedTrailingComma,