add parser tests
This commit is contained in:
parent
ee0eba066a
commit
b4722b5016
@ -1,8 +1,9 @@
|
|||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use super::lexer::Token;
|
use super::lexer::Token;
|
||||||
use std::collections::HashMap;
|
use std::{collections::HashMap, hash::Hash};
|
||||||
|
|
||||||
|
#[derive(PartialEq, Debug)]
|
||||||
pub enum Node {
|
pub enum Node {
|
||||||
Element {
|
Element {
|
||||||
name: String,
|
name: String,
|
||||||
@ -77,7 +78,7 @@ impl Parser {
|
|||||||
fn parse_value(&mut self) -> Result<Node, ParserError> {
|
fn parse_value(&mut self) -> Result<Node, ParserError> {
|
||||||
match self.current() {
|
match self.current() {
|
||||||
Some(Token::LBrace(_)) => self.parse_object(),
|
Some(Token::LBrace(_)) => self.parse_object(),
|
||||||
Some(Token::LBracket(_)) => self.parse_object(),
|
Some(Token::LBracket(_)) => self.parse_array(),
|
||||||
Some(Token::Int(value)) => {
|
Some(Token::Int(value)) => {
|
||||||
let value = value.parse().map_err(|_| "malformed int".to_string())?;
|
let value = value.parse().map_err(|_| "malformed int".to_string())?;
|
||||||
self.step();
|
self.step();
|
||||||
@ -99,13 +100,13 @@ impl Parser {
|
|||||||
}
|
}
|
||||||
Some(Token::True(_)) => {
|
Some(Token::True(_)) => {
|
||||||
self.step();
|
self.step();
|
||||||
Ok(Node::Bool(false))
|
Ok(Node::Bool(true))
|
||||||
}
|
}
|
||||||
Some(Token::Null(_)) => {
|
Some(Token::Null(_)) => {
|
||||||
self.step();
|
self.step();
|
||||||
Ok(Node::Null)
|
Ok(Node::Null)
|
||||||
}
|
}
|
||||||
Some(_) => Err("unexpected token, expected value".to_owned()),
|
Some(t) => Err(format!("unexpected token {t:?}, expected value")),
|
||||||
None => Err("expected value".to_owned()),
|
None => Err("expected value".to_owned()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -216,7 +217,6 @@ impl Parser {
|
|||||||
break Ok(Node::Array(values));
|
break Ok(Node::Array(values));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
self.step();
|
|
||||||
self.parse_optional_whitespace()?;
|
self.parse_optional_whitespace()?;
|
||||||
values.push(self.parse_value()?)
|
values.push(self.parse_value()?)
|
||||||
}
|
}
|
||||||
@ -313,3 +313,99 @@ impl Parser {
|
|||||||
self.tokens.get(self.index)
|
self.tokens.get(self.index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_int() {
|
||||||
|
let parsed = Parser::new(vec![Token::Int("123".to_string())]).parse_top_level();
|
||||||
|
assert_eq!(parsed, Ok(Node::Int(123)))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_float() {
|
||||||
|
let parsed = Parser::new(vec![Token::Float("3.15".to_string())]).parse_top_level();
|
||||||
|
assert_eq!(parsed, Ok(Node::Float(3.15)))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_string() {
|
||||||
|
let parsed = Parser::new(vec![Token::String("\"hello\n\"".to_string())]).parse_top_level();
|
||||||
|
assert_eq!(parsed, Ok(Node::String("hello\n".to_string())))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_bool() {
|
||||||
|
let parsed = Parser::new(vec![Token::True("true".to_owned())]).parse_top_level();
|
||||||
|
assert_eq!(parsed, Ok(Node::Bool(true)))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_null() {
|
||||||
|
let parsed = Parser::new(vec![Token::Null("null".to_owned())]).parse_top_level();
|
||||||
|
assert_eq!(parsed, Ok(Node::Null))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_array0() {
|
||||||
|
let parsed = Parser::new(vec![
|
||||||
|
Token::LBracket("[".to_string()),
|
||||||
|
Token::RBracket("]".to_string()),
|
||||||
|
])
|
||||||
|
.parse_top_level();
|
||||||
|
assert_eq!(parsed, Ok(Node::Array(vec![])))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_array1() {
|
||||||
|
let parsed = Parser::new(vec![
|
||||||
|
Token::LBracket("[".to_string()),
|
||||||
|
Token::Int("123".to_string()),
|
||||||
|
Token::RBracket("]".to_string()),
|
||||||
|
])
|
||||||
|
.parse_top_level();
|
||||||
|
assert_eq!(parsed, Ok(Node::Array(vec![Node::Int(123)])))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_array2() {
|
||||||
|
let parsed = Parser::new(vec![
|
||||||
|
Token::LBracket("[".to_string()),
|
||||||
|
Token::Int("123".to_string()),
|
||||||
|
Token::Comma(",".to_string()),
|
||||||
|
Token::String("\"hello\n\"".to_string()),
|
||||||
|
Token::RBracket("]".to_string()),
|
||||||
|
])
|
||||||
|
.parse_top_level();
|
||||||
|
assert_eq!(
|
||||||
|
parsed,
|
||||||
|
Ok(Node::Array(vec![
|
||||||
|
Node::Int(123),
|
||||||
|
Node::String("hello\n".to_string()),
|
||||||
|
]))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_object0() {
|
||||||
|
let parsed = Parser::new(vec![
|
||||||
|
Token::LBrace("{".to_string()),
|
||||||
|
Token::RBrace("}".to_string()),
|
||||||
|
])
|
||||||
|
.parse_top_level();
|
||||||
|
assert_eq!(parsed, Ok(Node::Object(HashMap::new())))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_object1() {
|
||||||
|
let parsed = Parser::new(vec![
|
||||||
|
Token::LBrace("{".to_string()),
|
||||||
|
Token::RBrace("}".to_string()),
|
||||||
|
])
|
||||||
|
.parse_top_level();
|
||||||
|
assert_eq!(
|
||||||
|
parsed,
|
||||||
|
Ok(Node::Object({
|
||||||
|
let fields = HashMap::new();
|
||||||
|
fields
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user