iowo/crates/json-pawarser/src/grammar.rs

71 lines
2 KiB
Rust
Raw Normal View History

2024-10-18 12:05:27 +00:00
use enumset::{enum_set, EnumSet};
use crate::{syntax_error::SyntaxError, syntax_kind::SyntaxKind};
use self::object::object;
pub(crate) type Parser<'src> = pawarser::Parser<'src, SyntaxKind, SyntaxError>;
pub(crate) type CompletedMarker = pawarser::CompletedMarker<SyntaxKind, SyntaxError>;
2024-10-18 12:05:27 +00:00
const BASIC_VALUE_TOKENS: EnumSet<SyntaxKind> =
enum_set!(SyntaxKind::BOOL | SyntaxKind::NULL | SyntaxKind::NUMBER | SyntaxKind::STRING);
pub fn value(p: &mut Parser) -> bool {
if BASIC_VALUE_TOKENS.contains(p.current()) {
p.do_bump();
return true;
} else {
object(p).is_some()
}
}
mod object {
use crate::{grammar::value, syntax_error::SyntaxError, syntax_kind::SyntaxKind};
use super::{CompletedMarker, Parser, BASIC_VALUE_TOKENS};
pub(super) fn object(p: &mut Parser) -> Option<CompletedMarker> {
let obj_start = p.start("object");
if !p.eat(SyntaxKind::BRACE_OPEN) {
2024-10-18 12:05:27 +00:00
obj_start.abandon(p);
return None;
}
member(p);
p.eat(SyntaxKind::BRACE_CLOSE);
Some(obj_start.complete(p, SyntaxKind::OBJECT))
2024-10-18 12:05:27 +00:00
}
fn member(p: &mut Parser) -> Option<CompletedMarker> {
let member_start = p.start("member");
if p.at(SyntaxKind::BRACE_CLOSE) {
member_start.abandon(p);
return None;
} else if p.at(SyntaxKind::STRING) {
let member_name_start = p.start("member_name");
p.eat(SyntaxKind::STRING);
member_name_start.complete(p, SyntaxKind::MEMBER_NAME);
} else {
return todo!("handle other tokens: {:?}", p.current());
2024-10-18 12:05:27 +00:00
}
if !p.eat(SyntaxKind::COLON) {
todo!("handle wrong tokens")
}
if value(p) {
Some(member_start.complete(p, SyntaxKind::MEMBER))
} else {
let e = member_start.error(p, SyntaxError::MemberMissingValue);
Some(
e.precede(p, "member but failed already")
.complete(p, SyntaxKind::MEMBER),
)
}
}
}
mod array {}