Skip to content

Commit dc46ebb

Browse files
committed
parser: expression
1 parent 4d5fa95 commit dc46ebb

File tree

5 files changed

+376
-15
lines changed

5 files changed

+376
-15
lines changed

src/ast/expr.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ pub enum Expr {
55
CharLiteral(char),
66

77
// 단항연산자
8-
PrefixOp {
8+
UnaryPrefixOp {
99
op: PrefixOp,
1010
rhs: Box<Expr>,
1111
},
12-
PostfixOp {
12+
UnaryPostfixOp {
1313
lhs: Box<Expr>,
1414
op: PostfixOp,
1515
},
@@ -74,10 +74,13 @@ pub enum BinaryOp {
7474

7575
#[derive(Clone, Debug, PartialEq)]
7676
pub enum AssignOp {
77-
Assign, // =
78-
PlusAssign, // +=
79-
MinusAssign, // -=
80-
MulAssign, // *=
81-
DivAssign, // /=
82-
RemAssign, // &=
77+
Assign, // =
78+
PlusAssign, // +=
79+
MinusAssign, // -=
80+
MulAssign, // *=
81+
DivAssign, // /=
82+
RemAssign, // %=
83+
BitAndAssign, // &=
84+
BitOrAssign, // |=
85+
BitXorAssign, // ^=
8386
}

src/parser/expression.rs

Lines changed: 316 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,318 @@
1+
use crate::ast::Expr;
2+
use crate::ast::expr::{AssignOp, BinaryOp, PostfixOp, PrefixOp};
3+
use crate::lexer::Token;
14
use crate::parser::Parser;
5+
use crate::parser::parser::ParseResult;
26

3-
impl Parser {}
7+
impl Parser {
8+
pub fn parse_expr(&mut self) -> ParseResult<Expr> {
9+
self.parse_assignment()
10+
}
11+
12+
// assignment ::= logical_or ( ( "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "&=" | "|=" | "^=" ) assignment )?
13+
fn parse_assignment(&mut self) -> ParseResult<Expr> {
14+
let mut lhs = self.parse_logical_or()?;
15+
let op = match self.current_token() {
16+
Token::Assign => AssignOp::Assign,
17+
Token::PlusAssign => AssignOp::PlusAssign,
18+
Token::MinusAssign => AssignOp::MinusAssign,
19+
Token::AsteriskAssign => AssignOp::MulAssign,
20+
Token::SlashAssign => AssignOp::DivAssign,
21+
Token::ModuloAssign => AssignOp::RemAssign,
22+
Token::BitAndAssign => AssignOp::BitAndAssign,
23+
Token::BitOrAssign => AssignOp::BitOrAssign,
24+
Token::BitXorAssign => AssignOp::BitXorAssign,
25+
_ => {
26+
// 할당 연산자가 아니면 그대로 lhs 리턴
27+
return Ok(lhs);
28+
}
29+
};
30+
31+
// 할당 연산자 소비
32+
self.next_token();
33+
let rhs = self.parse_assignment()?;
34+
35+
lhs = Expr::Assignment {
36+
left: Box::new(lhs),
37+
op,
38+
right: Box::new(rhs),
39+
};
40+
Ok(lhs)
41+
}
42+
43+
// unary ::= ( "!" | "-" | "&" | "*" | "++" | "--" ) unary | postfix
44+
fn parse_unary(&mut self) -> ParseResult<Expr> {
45+
let op = match self.current_token() {
46+
Token::Not => PrefixOp::Not,
47+
Token::Minus => PrefixOp::Neg,
48+
Token::Ampersand => PrefixOp::Address,
49+
Token::Asterisk => PrefixOp::Deref,
50+
Token::Increment => PrefixOp::PreInc,
51+
Token::Decrement => PrefixOp::PreDec,
52+
_ => return self.parse_postfix(),
53+
};
54+
self.next_token();
55+
let rhs = self.parse_unary()?;
56+
Ok(Expr::UnaryPrefixOp {
57+
op,
58+
rhs: Box::new(rhs),
59+
})
60+
}
61+
62+
// multiplicative ::= unary ( ( "*" | "/" | "%" ) unary )*
63+
fn parse_multiplicative(&mut self) -> ParseResult<Expr> {
64+
let mut expr = self.parse_unary()?;
65+
66+
loop {
67+
let op = match self.current_token() {
68+
Token::Asterisk => BinaryOp::Mul,
69+
Token::Slash => BinaryOp::Div,
70+
Token::Percent => BinaryOp::Rem,
71+
_ => break,
72+
};
73+
self.next_token(); // 연산자소비
74+
let rhs = self.parse_unary()?;
75+
expr = Expr::BinaryOp {
76+
lhs: Box::new(expr),
77+
op,
78+
rhs: Box::new(rhs),
79+
};
80+
}
81+
82+
Ok(expr)
83+
}
84+
85+
// additive ::= multiplicative ( ( "+" | "-" ) multiplicative )*
86+
fn parse_additive(&mut self) -> ParseResult<Expr> {
87+
let mut expr = self.parse_multiplicative()?;
88+
89+
loop {
90+
let op = match self.current_token() {
91+
Token::Plus => BinaryOp::Add,
92+
Token::Minus => BinaryOp::Sub,
93+
_ => break,
94+
};
95+
self.next_token(); // 연산자소비
96+
let rhs = self.parse_multiplicative()?;
97+
expr = Expr::BinaryOp {
98+
lhs: Box::new(expr),
99+
op,
100+
rhs: Box::new(rhs),
101+
};
102+
}
103+
104+
Ok(expr)
105+
}
106+
107+
// relational ::= additive ( ( "<" | "<=" | ">" | ">=" ) additive )*
108+
fn parse_relational(&mut self) -> ParseResult<Expr> {
109+
let mut expr = self.parse_additive()?;
110+
111+
loop {
112+
let op = match self.current_token() {
113+
Token::Lt => BinaryOp::Lt,
114+
Token::Le => BinaryOp::Le,
115+
Token::Gt => BinaryOp::Gt,
116+
Token::Ge => BinaryOp::Ge,
117+
_ => break,
118+
};
119+
self.next_token(); // 연산자소비
120+
let rhs = self.parse_additive()?;
121+
expr = Expr::BinaryOp {
122+
lhs: Box::new(expr),
123+
op,
124+
rhs: Box::new(rhs),
125+
};
126+
}
127+
128+
Ok(expr)
129+
}
130+
131+
// equality ::= relational ( ( "==" | "!=" ) relational )*
132+
fn parse_equality(&mut self) -> ParseResult<Expr> {
133+
let mut expr = self.parse_relational()?;
134+
loop {
135+
let op = match self.current_token() {
136+
Token::Equal => BinaryOp::Eq,
137+
Token::NotEqual => BinaryOp::Ne,
138+
_ => break,
139+
};
140+
self.next_token(); // 연산자 소비
141+
let rhs = self.parse_relational()?;
142+
expr = Expr::BinaryOp {
143+
lhs: Box::new(expr),
144+
op,
145+
rhs: Box::new(rhs),
146+
};
147+
}
148+
149+
Ok(expr)
150+
}
151+
152+
// logical_and ::= equality ( "&&" equality )*
153+
fn parse_logical_and(&mut self) -> ParseResult<Expr> {
154+
let mut expr = self.parse_equality()?;
155+
156+
while self.current_token() == &Token::And {
157+
self.next_token(); // '&&' 소비
158+
let rhs = self.parse_equality()?;
159+
expr = Expr::BinaryOp {
160+
lhs: Box::new(expr),
161+
op: BinaryOp::And,
162+
rhs: Box::new(rhs),
163+
};
164+
}
165+
166+
Ok(expr)
167+
}
168+
169+
// logical_or ::= logical_and ( "||" logical_and )*
170+
fn parse_logical_or(&mut self) -> ParseResult<Expr> {
171+
let mut expr = self.parse_logical_and()?;
172+
173+
while self.current_token() == &Token::Or {
174+
self.next_token(); // '||' 소비
175+
let rhs = self.parse_logical_and()?;
176+
expr = Expr::BinaryOp {
177+
lhs: Box::new(expr),
178+
op: BinaryOp::Or,
179+
rhs: Box::new(rhs),
180+
};
181+
}
182+
183+
Ok(expr)
184+
}
185+
186+
/// primary + (postfix_op)*
187+
/// postfix_op ::= "(" argument_list? ")" (함수 호출)
188+
/// | "[" expression "]" (배열 인덱싱)
189+
/// | "++" (후위 증가)
190+
/// | "--" (후위 감소)
191+
fn parse_postfix(&mut self) -> ParseResult<Expr> {
192+
let mut expr = self.parse_primary()?;
193+
194+
loop {
195+
expr = match self.current_token() {
196+
Token::LParen => {
197+
self.next_token(); // '('
198+
let args = if self.current_token() != &Token::RParen {
199+
let mut v = Vec::new();
200+
loop {
201+
v.push(self.parse_expr()?);
202+
if self.current_token() == &Token::Comma {
203+
self.next_token();
204+
continue;
205+
}
206+
break;
207+
}
208+
v
209+
} else {
210+
Vec::new()
211+
};
212+
self.expect(Token::RParen)?;
213+
Expr::Call {
214+
func: Box::new(expr),
215+
args,
216+
}
217+
}
218+
219+
Token::LBracket => {
220+
self.next_token(); // '['
221+
let idx = self.parse_expr()?;
222+
self.expect(Token::RBracket)?; // ']'
223+
Expr::ArrayIndex {
224+
array: Box::new(expr),
225+
index: Box::new(idx),
226+
}
227+
}
228+
229+
Token::Increment => {
230+
self.next_token(); // 후위 ++
231+
Expr::UnaryPostfixOp {
232+
lhs: Box::new(expr),
233+
op: PostfixOp::PostInc,
234+
}
235+
}
236+
237+
Token::Decrement => {
238+
self.next_token(); // 후위 --
239+
Expr::UnaryPostfixOp {
240+
lhs: Box::new(expr),
241+
op: PostfixOp::PostDec,
242+
}
243+
}
244+
_ => break,
245+
};
246+
}
247+
248+
Ok(expr)
249+
}
250+
251+
// primary ::= identifier | int_literal | char_literal | "(" expression ")"
252+
fn parse_primary(&mut self) -> ParseResult<Expr> {
253+
let expr = match self.current_token() {
254+
Token::Ident(_) => Expr::Ident(self.expect_ident()?),
255+
Token::IntLiteral(_) => Expr::IntLiteral(self.expect_int_literal()?),
256+
Token::CharLiteral(_) => Expr::CharLiteral(self.expect_char_literal()?),
257+
Token::LParen => {
258+
self.next_token(); // '('
259+
let e = self.parse_expr()?;
260+
self.expect(Token::RParen)?;
261+
e
262+
}
263+
_ => return self.unsupported_token(),
264+
};
265+
Ok(expr)
266+
}
267+
268+
// initializer ::= expression | "{" initializer_list? "}"
269+
fn parse_initializer(&mut self) -> ParseResult<Expr> {
270+
if self.current_token() == &Token::LBrace {
271+
self.parse_initializer_list()
272+
} else {
273+
self.parse_assignment()
274+
}
275+
}
276+
277+
// initializer_list ::= initializer ( "," initializer )* ","?
278+
fn parse_initializer_list(&mut self) -> ParseResult<Expr> {
279+
self.expect(Token::LBrace)?; // '{' 소비
280+
let mut exprs = Vec::new();
281+
282+
if self.current_token() != &Token::RBrace {
283+
loop {
284+
exprs.push(self.parse_initializer()?);
285+
286+
// ',' 가 있다면 소비
287+
if self.current_token() == &Token::Comma {
288+
self.next_token();
289+
290+
// ',' 다음에 '}' 이면 종료
291+
if self.current_token() == &Token::RBrace {
292+
break;
293+
}
294+
continue;
295+
}
296+
// ',' 가 없다면 종료
297+
break;
298+
}
299+
}
300+
301+
self.expect(Token::RBrace)?; // '}' 소비
302+
Ok(Expr::InitializerList(exprs))
303+
}
304+
fn parse_char_literal(&mut self) -> ParseResult<Expr> {
305+
let value = self.expect_char_literal()?;
306+
Ok(Expr::CharLiteral(value))
307+
}
308+
309+
fn parse_int_literal(&mut self) -> ParseResult<Expr> {
310+
let value = self.expect_int_literal()?;
311+
Ok(Expr::IntLiteral(value))
312+
}
313+
314+
fn parse_identifier(&mut self) -> ParseResult<Expr> {
315+
let string = self.expect_ident()?;
316+
Ok(Expr::Ident(string))
317+
}
318+
}

src/parser/function.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ impl Parser {
5757
let name = self.expect_ident()?;
5858
params.push(Parameter { name, ty });
5959

60-
// 쉼표 혹은 ')'
60+
// ',' 혹은 ')'
6161
match self.current_token() {
6262
Token::Comma => {
6363
self.next_token();

0 commit comments

Comments
 (0)