Compare commits
No commits in common. "316432856808c238a57508810d05d4fec5231821" and "b8720b2df99e9019691a8e0e08d2dddf28c561e8" have entirely different histories.
3164328568
...
b8720b2df9
5 changed files with 28 additions and 36 deletions
|
@ -33,23 +33,9 @@ mod object {
|
||||||
}
|
}
|
||||||
|
|
||||||
member(p);
|
member(p);
|
||||||
while p.at(SyntaxKind::COMMA) {
|
|
||||||
// not always an error, later configurable
|
|
||||||
let potential_unexpected_comma = p.start("potential_unexpected_comma");
|
|
||||||
p.eat(SyntaxKind::COMMA);
|
|
||||||
|
|
||||||
if member(p).is_none() {
|
p.eat(SyntaxKind::BRACE_CLOSE);
|
||||||
potential_unexpected_comma.complete(p, SyntaxKind::TRAILING_COMMA);
|
Some(obj_start.complete(p, SyntaxKind::OBJECT))
|
||||||
} else {
|
|
||||||
potential_unexpected_comma.abandon(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Some(if !p.eat(SyntaxKind::BRACE_CLOSE) {
|
|
||||||
obj_start.error(p, SyntaxError::UnclosedObject)
|
|
||||||
} else {
|
|
||||||
obj_start.complete(p, SyntaxKind::OBJECT)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn member(p: &mut Parser) -> Option<CompletedMarker> {
|
fn member(p: &mut Parser) -> Option<CompletedMarker> {
|
||||||
|
@ -70,12 +56,9 @@ mod object {
|
||||||
todo!("handle wrong tokens")
|
todo!("handle wrong tokens")
|
||||||
}
|
}
|
||||||
|
|
||||||
let member_value_start = p.start("member_value_start");
|
|
||||||
if value(p) {
|
if value(p) {
|
||||||
member_value_start.complete(p, SyntaxKind::MEMBER_VALUE);
|
|
||||||
Some(member_start.complete(p, SyntaxKind::MEMBER))
|
Some(member_start.complete(p, SyntaxKind::MEMBER))
|
||||||
} else {
|
} else {
|
||||||
member_value_start.abandon(p);
|
|
||||||
let e = member_start.error(p, SyntaxError::MemberMissingValue);
|
let e = member_start.error(p, SyntaxError::MemberMissingValue);
|
||||||
Some(
|
Some(
|
||||||
e.precede(p, "member but failed already")
|
e.precede(p, "member but failed already")
|
||||||
|
|
|
@ -1,3 +1,29 @@
|
||||||
mod grammar;
|
mod grammar;
|
||||||
mod syntax_error;
|
mod syntax_error;
|
||||||
mod syntax_kind;
|
mod syntax_kind;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use pawarser::parser::ParserBuilder;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
grammar::{value, Parser},
|
||||||
|
syntax_kind::{lex, SyntaxKind},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test() {
|
||||||
|
const TEST_DATA: &str = r#"{"hello_world": "meow"}"#;
|
||||||
|
let toks = lex(TEST_DATA);
|
||||||
|
|
||||||
|
let mut p: Parser = ParserBuilder::new(toks)
|
||||||
|
.add_meaningless(SyntaxKind::WHITESPACE)
|
||||||
|
.add_meaningless(SyntaxKind::NEWLINE)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
value(&mut p);
|
||||||
|
|
||||||
|
let out = p.finish();
|
||||||
|
assert_eq!("", format!("{:#?}", out))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -2,9 +2,7 @@ use crate::syntax_kind::SyntaxKind;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum SyntaxError {
|
pub enum SyntaxError {
|
||||||
UnclosedObject,
|
|
||||||
DisallowedKeyType(SyntaxKind),
|
DisallowedKeyType(SyntaxKind),
|
||||||
MemberMissingValue,
|
MemberMissingValue,
|
||||||
UnexpectedTrailingComma,
|
|
||||||
}
|
}
|
||||||
impl pawarser::parser::SyntaxError for SyntaxError {}
|
impl pawarser::parser::SyntaxError for SyntaxError {}
|
||||||
|
|
|
@ -24,9 +24,6 @@ pub enum SyntaxKind {
|
||||||
ARRAY,
|
ARRAY,
|
||||||
ELEMENT,
|
ELEMENT,
|
||||||
|
|
||||||
// SyntaxKinds for future json5/etc support
|
|
||||||
TRAILING_COMMA,
|
|
||||||
|
|
||||||
// Tokens
|
// Tokens
|
||||||
// Regexes adapted from [the logos handbook](https://logos.maciej.codes/examples/json_borrowed.html)
|
// Regexes adapted from [the logos handbook](https://logos.maciej.codes/examples/json_borrowed.html)
|
||||||
#[token("true")]
|
#[token("true")]
|
||||||
|
|
|
@ -59,18 +59,6 @@ impl Marker {
|
||||||
mut self,
|
mut self,
|
||||||
p: &mut Parser<SyntaxKind, SyntaxErr>,
|
p: &mut Parser<SyntaxKind, SyntaxErr>,
|
||||||
) {
|
) {
|
||||||
self.bomb.defuse();
|
|
||||||
|
|
||||||
// clean up empty tombstone event from marker
|
|
||||||
if self.pos == p.events.len() - 1 {
|
|
||||||
match p.events.pop() {
|
|
||||||
Some(Event::Start {
|
|
||||||
kind: NodeKind::Tombstone,
|
|
||||||
forward_parent: None,
|
|
||||||
}) => (),
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue