protospec_build/parser/
mod.rs

1use crate::ast::*;
2use crate::tokenizer::*;
3
4mod error;
5pub use error::{ParseError, ParseResult};
6
7mod token_iter;
8use token_iter::TokenIter;
9
10mod declaration;
11use declaration::*;
12
13mod expression;
14use expression::*;
15
16mod types;
17use types::*;
18
19mod field;
20use field::*;
21
22mod program;
23use program::*;
24
25mod transform;
26use transform::*;
27
28pub fn parse(script: &str) -> ParseResult<Program> {
29    let mut tokens = TokenIter::new(crate::tokenize(script, true)?);
30
31    parse_program(&mut tokens)
32}
33
34fn parse_arguments(t: &mut TokenIter, span: &mut Span) -> ParseResult<Vec<Expression>> {
35    let mut arguments = vec![];
36    if t.eat(Token::LeftParen).is_some() {
37        loop {
38            if let Some(token) = t.eat(Token::RightParen) {
39                *span = *span + token.span;
40                break;
41            }
42            arguments.push(parse_expression(t)?);
43            if t.eat(Token::Comma).is_none() {
44                *span = *span + t.expect(Token::RightParen)?;
45                break;
46            }
47        }
48    }
49    Ok(arguments)
50}
51
52fn parse_conditional_clause(t: &mut TokenIter) -> ParseResult<Option<Box<Expression>>> {
53    Ok(if t.eat(Token::LeftCurly).is_some() {
54        let condition = parse_expression(t)?;
55        t.expect(Token::RightCurly)?;
56        Some(Box::new(condition))
57    } else {
58        None
59    })
60}
61
62fn parse_flags(t: &mut TokenIter) -> ParseResult<Vec<Ident>> {
63    let mut out = vec![];
64    while t.eat(Token::Plus).is_some() {
65        out.push(t.expect_ident()?);
66    }
67    Ok(out)
68}
69