1use std::collections::HashMap;
2
3use crate::lexer::{Token, TokenPos};
4use crate::json::{*, self};
5
6pub struct Parser {
7 tokens: Vec<TokenPos>,
9 pos: usize,
11}
12
13impl From<Vec<TokenPos>> for Parser {
14 fn from(tokens: Vec<TokenPos>) -> Self {
15 Self {
16 tokens,
17 pos: 0,
18 }
19 }
20}
21
22impl Parser {
23 #[inline]
24 fn curr(&self) -> Token {
25 self.tokens[self.pos].0.clone()
26 }
27 #[inline]
28 fn advance(&mut self, len: usize) {
29 self.pos += len;
30 }
31
32 fn expect(&mut self, expected: Token) -> json::Result<()> {
33 if self.curr() == expected {
34 self.pos += 1;
35 Ok(())
36 } else {
37 Err(JSONError::ParseError(format!("expected {:?}, found {:?}", expected, self.curr())))
38 }
39 }
40
41 pub fn parse(&mut self) -> json::Result<JSONValue> {
43 let (line, column) = (self.tokens[self.pos].1, self.tokens[self.pos].2);
44 match self.curr().clone() {
45 Token::OpenBrace => {
46 let mut ret: HashMap<String, JSONValue> = HashMap::new();
48
49 self.advance(1);
50
51 if self.curr() == Token::CloseBrace {
53 return Ok(JSONValue::Object(ret))
54 }
55
56 loop {
58 let key = match self.curr().clone() {
60 Token::StringLiteral(val) => val[1..val.len() - 1].to_owned(),
62 _ => return Err(JSONError::ParseError(format!("expected string literal at line {line}, column {column}"))),
63 };
64 self.advance(1);
65
66 self.expect(Token::Colon)?;
68 let val = self.parse()?;
70 self.advance(1);
71
72 ret.insert(key, val);
73
74 if self.curr() == Token::CloseBrace {
75 break;
76 }
77 self.expect(Token::Comma)?;
78 }
79
80 Ok(JSONValue::Object(ret))
81 },
82 Token::CloseBrace => {
83 Err(JSONError::ParseError(format!("unexpected token `CloseBrace` at line {line}, column {column}")))
84 },
85 Token::OpenBracket => {
86 let mut ret: Vec<JSONValue> = vec![];
88
89 self.pos += 1;
91
92 if self.curr() == Token::CloseBracket {
94 return Ok(JSONValue::Array(ret));
95 }
96
97 loop {
98 ret.push(self.parse()?);
99 self.pos += 1;
101
102 if self.curr() == Token::CloseBracket {
104 break;
105 }
106
107 self.expect(Token::Comma)?;
108 }
109
110 Ok(JSONValue::Array(ret))
111 },
112 Token::CloseBracket => {
113 Err(JSONError::ParseError(format!("unexpected token `CloseBracket` at line {line}, column {column}")))
114 },
115 Token::Colon => {
116 Err(JSONError::ParseError(format!("unexpected token `Colon` at line {line}, column {column}")))
117 },
118 Token::Comma => {
119 Err(JSONError::ParseError(format!("unexpected token `Comma` at line {line}, column {column}")))
120 },
121 Token::StringLiteral(val) => {
122 let trimmed = val[1..val.len() - 1].to_owned();
126 let t_iter: Vec<char> = trimmed.chars().collect();
127 let mut formatted: Vec<char> = vec![];
128 let mut i = 0;
129 while i < t_iter.len() {
130 if t_iter[i] == '\\' {
131 formatted.push(match t_iter[i+1] {
132 '"' => '"',
133 '\\' => '\\',
134 '/' => '/',
135 'b' => '\u{0008}',
136 'f' => '\u{000c}',
137 'n' => '\u{000a}',
138 'r' => '\u{000d}',
139 't' => '\u{0009}',
140 'u' => {
141 let chars: String = t_iter[i+2..i+6].iter().collect();
142
143 let num = u16::from_str_radix(&chars, 16)
144 .or(Err(JSONError::ValueError(format!("invalid hexadecimal code: {}", chars))))? as u32;
145
146 i += 4;
147 match char::from_u32(num) {
148 Some(v) => v,
149 None => return Err(JSONError::ValueError(format!("invalid utf16 hexadecimal code: {}", &chars)))
150 }
151 }
152 _ => return Err(JSONError::ValueError(format!("invalid escape char: {}", t_iter[i+1])))
153 });
154 i += 1;
155 } else {
156 formatted.push(t_iter[i]);
157 }
158 i += 1;
159 }
160
161 Ok(JSONValue::String(String::from_utf8(formatted.iter().map(|c| *c as u8).collect()).unwrap()))
162 },
163 Token::NumericLiteral(val) => {
164 Ok(JSONValue::Number(val.parse().unwrap()))
166 },
167 Token::True => {
168 Ok(JSONValue::Bool(true))
169 },
170 Token::False => {
171 Ok(JSONValue::Bool(false))
172 },
173 Token::Null => {
174 Ok(JSONValue::Null)
175 }
176 Token::Unknown(text) => {
177 Err(JSONError::ParseError(format!("unexpected token `{text}` at line {line}, column {column}")))
178 }
179 }
180 }
181}