1 #[macro_use] 2 mod errors; 3 mod comment; 4 mod expression; 5 mod helper; 6 mod pattern; 7 mod slice; 8 9 use crate::ast; 10 use slice::Slice; 11 use std::result; 12 13 pub use errors::{ErrorKind, ParserError}; 14 15 pub type Result<T> = result::Result<T, ParserError>; 16 17 pub struct Parser<S> { 18 source: S, 19 ptr: usize, 20 length: usize, 21 } 22 23 impl<'s, S> Parser<S> 24 where 25 S: Slice<'s>, 26 { new(source: S) -> Self27 pub fn new(source: S) -> Self { 28 let length = source.as_ref().len(); 29 Self { 30 source, 31 ptr: 0, 32 length, 33 } 34 } 35 parse( &mut self, ) -> std::result::Result<ast::Resource<S>, (ast::Resource<S>, Vec<ParserError>)>36 pub fn parse( 37 &mut self, 38 ) -> std::result::Result<ast::Resource<S>, (ast::Resource<S>, Vec<ParserError>)> { 39 let mut errors = vec![]; 40 41 let mut body = vec![]; 42 43 self.skip_blank_block(); 44 let mut last_comment = None; 45 let mut last_blank_count = 0; 46 47 while self.ptr < self.length { 48 let entry_start = self.ptr; 49 let mut entry = self.get_entry(entry_start); 50 51 if let Some(comment) = last_comment.take() { 52 match entry { 53 Ok(ast::Entry::Message(ref mut msg)) if last_blank_count < 2 => { 54 msg.comment = Some(comment); 55 } 56 Ok(ast::Entry::Term(ref mut term)) if last_blank_count < 2 => { 57 term.comment = Some(comment); 58 } 59 _ => { 60 body.push(ast::Entry::Comment(comment)); 61 } 62 } 63 } 64 65 match entry { 66 Ok(ast::Entry::Comment(comment)) => { 67 last_comment = Some(comment); 68 } 69 Ok(entry) => { 70 body.push(entry); 71 } 72 Err(mut err) => { 73 self.skip_to_next_entry_start(); 74 err.slice = Some((entry_start, self.ptr)); 75 errors.push(err); 76 let content = self.source.slice(entry_start..self.ptr); 77 body.push(ast::Entry::Junk { content }); 78 } 79 } 80 last_blank_count = self.skip_blank_block(); 81 } 82 83 if let Some(last_comment) = last_comment.take() { 84 body.push(ast::Entry::Comment(last_comment)); 85 } 86 if errors.is_empty() { 87 Ok(ast::Resource { body }) 88 } else { 89 Err((ast::Resource { body }, errors)) 90 } 91 } 92 get_entry(&mut self, entry_start: usize) -> Result<ast::Entry<S>>93 fn get_entry(&mut self, entry_start: usize) -> Result<ast::Entry<S>> { 94 let entry = match self.source.as_ref().as_bytes().get(self.ptr) { 95 Some(b'#') => { 96 let (comment, level) = self.get_comment()?; 97 match level { 98 comment::Level::Regular => ast::Entry::Comment(comment), 99 comment::Level::Group => ast::Entry::GroupComment(comment), 100 comment::Level::Resource => ast::Entry::ResourceComment(comment), 101 comment::Level::None => unreachable!(), 102 } 103 } 104 Some(b'-') => ast::Entry::Term(self.get_term(entry_start)?), 105 _ => ast::Entry::Message(self.get_message(entry_start)?), 106 }; 107 Ok(entry) 108 } 109 get_message(&mut self, entry_start: usize) -> Result<ast::Message<S>>110 fn get_message(&mut self, entry_start: usize) -> Result<ast::Message<S>> { 111 let id = self.get_identifier()?; 112 self.skip_blank_inline(); 113 self.expect_byte(b'=')?; 114 let pattern = self.get_pattern()?; 115 116 self.skip_blank_block(); 117 118 let attributes = self.get_attributes(); 119 120 if pattern.is_none() && attributes.is_empty() { 121 let entry_id = id.name.as_ref().to_owned(); 122 return error!( 123 ErrorKind::ExpectedMessageField { entry_id }, 124 entry_start, self.ptr 125 ); 126 } 127 128 Ok(ast::Message { 129 id, 130 value: pattern, 131 attributes, 132 comment: None, 133 }) 134 } 135 get_term(&mut self, entry_start: usize) -> Result<ast::Term<S>>136 fn get_term(&mut self, entry_start: usize) -> Result<ast::Term<S>> { 137 self.expect_byte(b'-')?; 138 let id = self.get_identifier()?; 139 self.skip_blank_inline(); 140 self.expect_byte(b'=')?; 141 self.skip_blank_inline(); 142 143 let value = self.get_pattern()?; 144 145 self.skip_blank_block(); 146 147 let attributes = self.get_attributes(); 148 149 if let Some(value) = value { 150 Ok(ast::Term { 151 id, 152 value, 153 attributes, 154 comment: None, 155 }) 156 } else { 157 error!( 158 ErrorKind::ExpectedTermField { 159 entry_id: id.name.as_ref().to_owned() 160 }, 161 entry_start, self.ptr 162 ) 163 } 164 } 165 get_attributes(&mut self) -> Vec<ast::Attribute<S>>166 fn get_attributes(&mut self) -> Vec<ast::Attribute<S>> { 167 let mut attributes = vec![]; 168 169 loop { 170 let line_start = self.ptr; 171 self.skip_blank_inline(); 172 if !self.is_current_byte(b'.') { 173 self.ptr = line_start; 174 break; 175 } 176 177 if let Ok(attr) = self.get_attribute() { 178 attributes.push(attr); 179 } else { 180 self.ptr = line_start; 181 break; 182 } 183 } 184 attributes 185 } 186 get_attribute(&mut self) -> Result<ast::Attribute<S>>187 fn get_attribute(&mut self) -> Result<ast::Attribute<S>> { 188 self.expect_byte(b'.')?; 189 let id = self.get_identifier()?; 190 self.skip_blank_inline(); 191 self.expect_byte(b'=')?; 192 let pattern = self.get_pattern()?; 193 194 match pattern { 195 Some(pattern) => Ok(ast::Attribute { id, value: pattern }), 196 None => error!(ErrorKind::MissingValue, self.ptr), 197 } 198 } 199 get_identifier(&mut self) -> Result<ast::Identifier<S>>200 fn get_identifier(&mut self) -> Result<ast::Identifier<S>> { 201 let mut ptr = self.ptr; 202 203 match self.source.as_ref().as_bytes().get(ptr) { 204 Some(b) if b.is_ascii_alphabetic() => { 205 ptr += 1; 206 } 207 _ => { 208 return error!( 209 ErrorKind::ExpectedCharRange { 210 range: "a-zA-Z".to_string() 211 }, 212 ptr 213 ); 214 } 215 } 216 217 while let Some(b) = self.source.as_ref().as_bytes().get(ptr) { 218 if b.is_ascii_alphabetic() || b.is_ascii_digit() || [b'_', b'-'].contains(b) { 219 ptr += 1; 220 } else { 221 break; 222 } 223 } 224 225 let name = self.source.slice(self.ptr..ptr); 226 self.ptr = ptr; 227 228 Ok(ast::Identifier { name }) 229 } 230 get_attribute_accessor(&mut self) -> Result<Option<ast::Identifier<S>>>231 fn get_attribute_accessor(&mut self) -> Result<Option<ast::Identifier<S>>> { 232 if self.take_byte_if(b'.') { 233 let ident = self.get_identifier()?; 234 Ok(Some(ident)) 235 } else { 236 Ok(None) 237 } 238 } 239 get_variant_key(&mut self) -> Result<ast::VariantKey<S>>240 fn get_variant_key(&mut self) -> Result<ast::VariantKey<S>> { 241 if !self.take_byte_if(b'[') { 242 return error!(ErrorKind::ExpectedToken('['), self.ptr); 243 } 244 self.skip_blank(); 245 246 let key = if self.is_number_start() { 247 ast::VariantKey::NumberLiteral { 248 value: self.get_number_literal()?, 249 } 250 } else { 251 ast::VariantKey::Identifier { 252 name: self.get_identifier()?.name, 253 } 254 }; 255 256 self.skip_blank(); 257 258 self.expect_byte(b']')?; 259 260 Ok(key) 261 } 262 get_variants(&mut self) -> Result<Vec<ast::Variant<S>>>263 fn get_variants(&mut self) -> Result<Vec<ast::Variant<S>>> { 264 let mut variants = vec![]; 265 let mut has_default = false; 266 267 while self.is_current_byte(b'*') || self.is_current_byte(b'[') { 268 let default = self.take_byte_if(b'*'); 269 270 if default { 271 if has_default { 272 return error!(ErrorKind::MultipleDefaultVariants, self.ptr); 273 } else { 274 has_default = true; 275 } 276 } 277 278 let key = self.get_variant_key()?; 279 280 let value = self.get_pattern()?; 281 282 if let Some(value) = value { 283 variants.push(ast::Variant { 284 key, 285 value, 286 default, 287 }); 288 self.skip_blank(); 289 } else { 290 return error!(ErrorKind::MissingValue, self.ptr); 291 } 292 } 293 294 if has_default { 295 Ok(variants) 296 } else { 297 error!(ErrorKind::MissingDefaultVariant, self.ptr) 298 } 299 } 300 get_placeable(&mut self) -> Result<ast::Expression<S>>301 fn get_placeable(&mut self) -> Result<ast::Expression<S>> { 302 self.expect_byte(b'{')?; 303 self.skip_blank(); 304 let exp = self.get_expression()?; 305 self.skip_blank_inline(); 306 self.expect_byte(b'}')?; 307 308 let invalid_expression_found = match &exp { 309 ast::Expression::InlineExpression(ast::InlineExpression::TermReference { 310 ref attribute, 311 .. 312 }) => attribute.is_some(), 313 _ => false, 314 }; 315 if invalid_expression_found { 316 return error!(ErrorKind::TermAttributeAsPlaceable, self.ptr); 317 } 318 319 Ok(exp) 320 } 321 get_call_arguments(&mut self) -> Result<Option<ast::CallArguments<S>>>322 fn get_call_arguments(&mut self) -> Result<Option<ast::CallArguments<S>>> { 323 self.skip_blank(); 324 if !self.take_byte_if(b'(') { 325 return Ok(None); 326 } 327 328 let mut positional = vec![]; 329 let mut named = vec![]; 330 let mut argument_names = vec![]; 331 332 self.skip_blank(); 333 334 while self.ptr < self.length { 335 if self.is_current_byte(b')') { 336 break; 337 } 338 339 let expr = self.get_inline_expression()?; 340 341 if let ast::InlineExpression::MessageReference { 342 ref id, 343 attribute: None, 344 } = expr 345 { 346 self.skip_blank(); 347 if self.is_current_byte(b':') { 348 if argument_names.contains(&id.name) { 349 return error!( 350 ErrorKind::DuplicatedNamedArgument(id.name.as_ref().to_owned()), 351 self.ptr 352 ); 353 } 354 self.ptr += 1; 355 self.skip_blank(); 356 let val = self.get_inline_expression()?; 357 358 argument_names.push(id.name.clone()); 359 named.push(ast::NamedArgument { 360 name: ast::Identifier { 361 name: id.name.clone(), 362 }, 363 value: val, 364 }); 365 } else { 366 if !argument_names.is_empty() { 367 return error!(ErrorKind::PositionalArgumentFollowsNamed, self.ptr); 368 } 369 positional.push(expr); 370 } 371 } else { 372 if !argument_names.is_empty() { 373 return error!(ErrorKind::PositionalArgumentFollowsNamed, self.ptr); 374 } 375 positional.push(expr); 376 } 377 378 self.skip_blank(); 379 self.take_byte_if(b','); 380 self.skip_blank(); 381 } 382 383 self.expect_byte(b')')?; 384 385 Ok(Some(ast::CallArguments { positional, named })) 386 } 387 } 388