1use super::ast::{BinOp, Expr, UnOp};
4use super::error::ParseError;
5use super::lexer::Lexer;
6use crate::span::Span;
7use crate::token::Token;
8
9pub type ParseResult = Result<Expr, ParseError>;
10
11pub struct Parser<'src> {
25 input: &'src str,
26}
27
28impl<'src> Parser<'src> {
29 pub fn new(input: &'src str) -> Self {
31 Self { input }
32 }
33
34 pub fn parse(&mut self) -> Result<Option<Expr>, ParseError> {
38 let mut lexer = Lexer::new(self.input);
39 let mut lookahead = lexer.next();
40 let mut span = lexer.span();
41
42 if lookahead == Token::Eof {
43 return Ok(None);
44 }
45
46 let expr = Self::expression(&mut lexer, &mut lookahead, &mut span)?;
47 Self::expect_token(&mut lexer, &mut lookahead, &mut span, &Token::Eof)?;
48 Ok(Some(expr))
49 }
50
51 fn expression<'lex>(
52 lexer: &mut Lexer<'lex>,
53 lookahead: &mut Token<'lex>,
54 span: &mut Span,
55 ) -> ParseResult {
56 let lhs = Self::primary(lexer, lookahead, span)?;
57 Self::climb(lexer, lookahead, span, lhs, 1)
58 }
59
60 fn primary<'lex>(
61 lexer: &mut Lexer<'lex>,
62 lookahead: &mut Token<'lex>,
63 span: &mut Span,
64 ) -> ParseResult {
65 let current_span = *span;
66 match *lookahead {
67 Token::Number(n) => {
68 Self::advance(lexer, lookahead, span);
69 Ok(Expr::literal(n, current_span))
70 }
71 Token::Ident(id) => {
72 let id_string = id.to_string();
73 Self::advance(lexer, lookahead, span);
74 if *lookahead == Token::ParenOpen {
75 return Self::call(lexer, lookahead, span, id_string, current_span);
76 }
77 Ok(Expr::ident(id_string, current_span))
78 }
79 Token::Minus => {
80 Self::advance(lexer, lookahead, span);
81 let expr = Self::primary(lexer, lookahead, span)?;
82 let expr = Self::climb(lexer, lookahead, span, expr, Token::Negate.precedence())?;
83 let full_span = current_span.merge(expr.span);
84 Ok(Expr::unary(UnOp::Neg, expr, full_span))
85 }
86 Token::ParenOpen => {
87 Self::advance(lexer, lookahead, span);
88 let expr = Self::expression(lexer, lookahead, span)?;
89 Self::expect_token(lexer, lookahead, span, &Token::ParenClose)?;
90 Ok(expr)
91 }
92 _ => Err(ParseError::UnexpectedToken {
93 message: format!(
94 "unexpected token '{}', expected an expression",
95 lookahead.lexeme()
96 ),
97 span: current_span,
98 }),
99 }
100 }
101
102 fn call<'lex>(
103 lexer: &mut Lexer<'lex>,
104 lookahead: &mut Token<'lex>,
105 span: &mut Span,
106 id: String,
107 start_span: Span,
108 ) -> ParseResult {
109 Self::advance(lexer, lookahead, span);
111
112 let mut args: Vec<Expr> = Vec::new();
113 while *lookahead != Token::ParenClose {
114 let arg = Self::expression(lexer, lookahead, span)?;
115 args.push(arg);
116 if *lookahead == Token::Comma {
117 Self::advance(lexer, lookahead, span);
118 } else {
119 break;
120 }
121 }
122 Self::expect_token(lexer, lookahead, span, &Token::ParenClose)?;
123
124 let full_span = start_span.merge(*span);
125 Ok(Expr::call(id, args, full_span))
126 }
127
128 fn climb<'lex>(
129 lexer: &mut Lexer<'lex>,
130 lookahead: &mut Token<'lex>,
131 span: &mut Span,
132 mut lhs: Expr,
133 min_prec: u8,
134 ) -> ParseResult {
135 let mut prec = lookahead.precedence();
136 while prec >= min_prec {
137 if lookahead.is_postfix_unary() {
139 let op = lookahead.clone();
140 let op_span = *span;
141 Self::advance(lexer, lookahead, span);
142 prec = lookahead.precedence();
143
144 let unary_op = UnOp::from_token(&op);
145 let full_span = lhs.span.merge(op_span);
146 lhs = Expr::unary(unary_op, lhs, full_span);
147 continue;
148 }
149
150 let op = lookahead.clone();
151
152 Self::advance(lexer, lookahead, span);
153 let mut rhs = Self::primary(lexer, lookahead, span)?;
154 prec = lookahead.precedence();
155
156 while prec > op.precedence()
157 || (lookahead.is_right_associative() && prec == op.precedence())
158 {
159 rhs = Self::climb(lexer, lookahead, span, rhs, prec)?;
160 prec = lookahead.precedence();
161 }
162
163 let binop = BinOp::from_token(&op);
164 let full_span = lhs.span.merge(rhs.span);
165 lhs = Expr::binary(binop, lhs, rhs, full_span);
166 }
167 Ok(lhs)
168 }
169
170 fn advance<'lex>(lexer: &mut Lexer<'lex>, lookahead: &mut Token<'lex>, span: &mut Span) {
171 *lookahead = lexer.next();
172 *span = lexer.span();
173 }
174
175 fn expect_token<'lex>(
176 lexer: &mut Lexer<'lex>,
177 lookahead: &mut Token<'lex>,
178 span: &mut Span,
179 expected: &Token<'lex>,
180 ) -> Result<(), ParseError> {
181 if lookahead == expected {
182 Self::advance(lexer, lookahead, span);
183 Ok(())
184 } else {
185 Err(ParseError::UnexpectedToken {
186 message: format!(
187 "unexpected token '{}', expected '{}'",
188 lookahead.lexeme(),
189 expected.lexeme()
190 ),
191 span: *span,
192 })
193 }
194 }
195}