1use crate::ast::*;
4use crate::lexer::Lexer;
5use crate::token::{Span, Token, TokenKind};
6use thiserror::Error;
7
8#[derive(Debug, Error)]
10pub enum ParseError {
11 #[error("unexpected token at {span}: expected {expected}, found {found}")]
12 UnexpectedToken {
13 expected: String,
14 found: String,
15 span: Span,
16 },
17 #[error("unexpected end of file at {span}")]
18 UnexpectedEof { span: Span },
19 #[error("invalid syntax at {span}: {message}")]
20 InvalidSyntax { message: String, span: Span },
21}
22
23impl ParseError {
24 pub fn span(&self) -> Span {
26 match self {
27 ParseError::UnexpectedToken { span, .. } => *span,
28 ParseError::UnexpectedEof { span } => *span,
29 ParseError::InvalidSyntax { span, .. } => *span,
30 }
31 }
32}
33
34pub type ParseResult<T> = Result<T, ParseError>;
35
36pub struct Parser {
38 tokens: Vec<Token>,
39 pos: usize,
40 in_bracket: usize,
42}
43
44impl Parser {
45 pub fn new(source: &str) -> Self {
47 let tokens: Vec<_> = Lexer::new(source)
48 .tokenize()
49 .into_iter()
50 .filter(|t| !t.kind.is_trivia())
51 .collect();
52 Self {
53 tokens,
54 pos: 0,
55 in_bracket: 0,
56 }
57 }
58
59 pub fn parse_module(&mut self) -> ParseResult<Module> {
61 let start = self.current_span();
62
63 self.expect(TokenKind::Module)?;
64 let name = self.parse_ident()?;
65
66 let mut decls = Vec::new();
67 while !self.is_at_end() {
68 decls.push(self.parse_decl()?);
69 }
70
71 let span = start.merge(self.prev_span());
72 Ok(Module { name, decls, span })
73 }
74
75 fn parse_decl(&mut self) -> ParseResult<Decl> {
77 match self.peek_kind() {
78 TokenKind::Use => self.parse_use_decl().map(Decl::Use),
79 TokenKind::Const => self.parse_const_decl().map(Decl::Const),
80 TokenKind::Var => self.parse_var_decl().map(Decl::Var),
81 TokenKind::Type => self.parse_type_decl().map(Decl::Type),
82 TokenKind::Func => self.parse_func_decl().map(Decl::Func),
83 TokenKind::Init => self.parse_init_decl().map(Decl::Init),
84 TokenKind::Action => self.parse_action_decl().map(Decl::Action),
85 TokenKind::Invariant => self.parse_invariant_decl().map(Decl::Invariant),
86 TokenKind::Property => self.parse_property_decl().map(Decl::Property),
87 TokenKind::Fairness => self.parse_fairness_decl().map(Decl::Fairness),
88 _ => Err(ParseError::UnexpectedToken {
89 expected: "declaration".to_string(),
90 found: self.peek_kind().to_string(),
91 span: self.current_span(),
92 }),
93 }
94 }
95
96 fn parse_use_decl(&mut self) -> ParseResult<UseDecl> {
97 let start = self.current_span();
98 self.expect(TokenKind::Use)?;
99 let module = self.parse_ident()?;
100 let span = start.merge(self.prev_span());
101 Ok(UseDecl { module, span })
102 }
103
104 fn parse_const_decl(&mut self) -> ParseResult<ConstDecl> {
105 let start = self.current_span();
106 self.expect(TokenKind::Const)?;
107 let name = self.parse_ident()?;
108 self.expect(TokenKind::Colon)?;
109
110 let value = if let TokenKind::Integer(n) = self.peek_kind() {
112 if self.peek_ahead_kind(1) != TokenKind::DotDot {
113 self.advance();
115 ConstValue::Scalar(n)
116 } else {
117 ConstValue::Type(self.parse_type_expr()?)
119 }
120 } else {
121 ConstValue::Type(self.parse_type_expr()?)
123 };
124
125 let span = start.merge(self.prev_span());
126 Ok(ConstDecl { name, value, span })
127 }
128
129 fn parse_var_decl(&mut self) -> ParseResult<VarDecl> {
130 let start = self.current_span();
131 self.expect(TokenKind::Var)?;
132 let name = self.parse_ident()?;
133 self.expect(TokenKind::Colon)?;
134 let ty = self.parse_type_expr()?;
135 let span = start.merge(self.prev_span());
136 Ok(VarDecl { name, ty, span })
137 }
138
139 fn parse_type_decl(&mut self) -> ParseResult<TypeDecl> {
140 let start = self.current_span();
141 self.expect(TokenKind::Type)?;
142 let name = self.parse_ident()?;
143 self.expect(TokenKind::Assign)?;
144 let ty = self.parse_type_expr()?;
145 let span = start.merge(self.prev_span());
146 Ok(TypeDecl { name, ty, span })
147 }
148
149 fn parse_func_decl(&mut self) -> ParseResult<FuncDecl> {
151 let start = self.current_span();
152 self.expect(TokenKind::Func)?;
153 let name = self.parse_ident()?;
154 self.expect(TokenKind::LParen)?;
155 let params = self.parse_func_params()?;
156 self.expect(TokenKind::RParen)?;
157 self.expect(TokenKind::LBrace)?;
158 let body = self.parse_expr()?;
159 self.expect(TokenKind::RBrace)?;
160 let span = start.merge(self.prev_span());
161 Ok(FuncDecl {
162 name,
163 params,
164 body,
165 span,
166 })
167 }
168
169 fn parse_func_params(&mut self) -> ParseResult<Vec<FuncParam>> {
171 let mut params = Vec::new();
172 if self.peek_kind() == TokenKind::RParen {
173 return Ok(params);
174 }
175 loop {
176 let start = self.current_span();
177 let name = self.parse_ident()?;
178 let span = start.merge(self.prev_span());
179 params.push(FuncParam { name, span });
180 if self.peek_kind() == TokenKind::Comma {
181 self.advance();
182 } else {
183 break;
184 }
185 }
186 Ok(params)
187 }
188
189 fn parse_init_decl(&mut self) -> ParseResult<InitDecl> {
190 let start = self.current_span();
191 self.expect(TokenKind::Init)?;
192 self.expect(TokenKind::LBrace)?;
193 let body = self.parse_expr()?;
194 self.expect(TokenKind::RBrace)?;
195 let span = start.merge(self.prev_span());
196 Ok(InitDecl { body, span })
197 }
198
199 fn parse_action_decl(&mut self) -> ParseResult<ActionDecl> {
200 let start = self.current_span();
201 self.expect(TokenKind::Action)?;
202 let name = self.parse_ident()?;
203 self.expect(TokenKind::LParen)?;
204 let params = self.parse_params()?;
205 self.expect(TokenKind::RParen)?;
206 self.expect(TokenKind::LBrace)?;
207 let body = self.parse_action_body()?;
208 self.expect(TokenKind::RBrace)?;
209 let span = start.merge(self.prev_span());
210 Ok(ActionDecl {
211 name,
212 params,
213 body,
214 span,
215 })
216 }
217
218 fn parse_params(&mut self) -> ParseResult<Vec<Param>> {
219 let mut params = Vec::new();
220 if !self.check(TokenKind::RParen) {
221 loop {
222 params.push(self.parse_param()?);
223 if !self.match_token(TokenKind::Comma) {
224 break;
225 }
226 }
227 }
228 Ok(params)
229 }
230
231 fn parse_param(&mut self) -> ParseResult<Param> {
232 let start = self.current_span();
233 let name = self.parse_ident()?;
234 self.expect(TokenKind::Colon)?;
235 let ty = self.parse_type_expr()?;
236 let span = start.merge(self.prev_span());
237 Ok(Param { name, ty, span })
238 }
239
240 fn parse_action_body(&mut self) -> ParseResult<ActionBody> {
241 let start = self.current_span();
242 let mut requires = Vec::new();
243
244 while self.check(TokenKind::Require) {
246 self.advance();
247 let expr = self.parse_expr()?;
248 requires.push(expr);
249 }
250
251 let effect = if !self.check(TokenKind::RBrace) {
253 Some(self.parse_expr()?)
254 } else {
255 None
256 };
257
258 let span = start.merge(self.prev_span());
259 Ok(ActionBody {
260 requires,
261 effect,
262 span,
263 })
264 }
265
266 fn parse_invariant_decl(&mut self) -> ParseResult<InvariantDecl> {
267 let start = self.current_span();
268 self.expect(TokenKind::Invariant)?;
269 let name = self.parse_ident()?;
270 self.expect(TokenKind::LBrace)?;
271 let body = self.parse_expr()?;
272 self.expect(TokenKind::RBrace)?;
273 let span = start.merge(self.prev_span());
274 Ok(InvariantDecl { name, body, span })
275 }
276
277 fn parse_property_decl(&mut self) -> ParseResult<PropertyDecl> {
278 let start = self.current_span();
279 self.expect(TokenKind::Property)?;
280 let name = self.parse_ident()?;
281 self.expect(TokenKind::LBrace)?;
282 let body = self.parse_expr()?;
283 self.expect(TokenKind::RBrace)?;
284 let span = start.merge(self.prev_span());
285 Ok(PropertyDecl { name, body, span })
286 }
287
288 fn parse_fairness_decl(&mut self) -> ParseResult<FairnessDecl> {
289 let start = self.current_span();
290 self.expect(TokenKind::Fairness)?;
291 self.expect(TokenKind::LBrace)?;
292
293 let mut constraints = Vec::new();
294 while !self.check(TokenKind::RBrace) {
295 constraints.push(self.parse_fairness_constraint()?);
296 }
297
298 self.expect(TokenKind::RBrace)?;
299 let span = start.merge(self.prev_span());
300 Ok(FairnessDecl { constraints, span })
301 }
302
303 fn parse_fairness_constraint(&mut self) -> ParseResult<FairnessConstraint> {
304 let start = self.current_span();
305 let kind = if self.match_token(TokenKind::WeakFair) {
306 FairnessKind::Weak
307 } else if self.match_token(TokenKind::StrongFair) {
308 FairnessKind::Strong
309 } else {
310 return Err(ParseError::UnexpectedToken {
311 expected: "weak_fair or strong_fair".to_string(),
312 found: self.peek_kind().to_string(),
313 span: self.current_span(),
314 });
315 };
316 self.expect(TokenKind::LParen)?;
317 let action = self.parse_ident()?;
318 self.expect(TokenKind::RParen)?;
319 let span = start.merge(self.prev_span());
320 Ok(FairnessConstraint { kind, action, span })
321 }
322
323 fn parse_type_expr(&mut self) -> ParseResult<TypeExpr> {
326 let start = self.current_span();
327
328 match self.peek_kind() {
330 TokenKind::Set => {
331 self.advance();
332 self.expect(TokenKind::LBracket)?;
333 let inner = self.parse_type_expr()?;
334 self.expect(TokenKind::RBracket)?;
335 let span = start.merge(self.prev_span());
336 Ok(TypeExpr::Set(Box::new(inner), span))
337 }
338 TokenKind::Seq => {
339 self.advance();
340 self.expect(TokenKind::LBracket)?;
341 let inner = self.parse_type_expr()?;
342 self.expect(TokenKind::RBracket)?;
343 let span = start.merge(self.prev_span());
344 Ok(TypeExpr::Seq(Box::new(inner), span))
345 }
346 TokenKind::Dict => {
347 self.advance();
348 self.expect(TokenKind::LBracket)?;
349 let key = self.parse_type_expr()?;
350 self.expect(TokenKind::Comma)?;
351 let value = self.parse_type_expr()?;
352 self.expect(TokenKind::RBracket)?;
353 let span = start.merge(self.prev_span());
354 Ok(TypeExpr::Dict(Box::new(key), Box::new(value), span))
355 }
356 TokenKind::Option_ => {
357 self.advance();
358 self.expect(TokenKind::LBracket)?;
359 let inner = self.parse_type_expr()?;
360 self.expect(TokenKind::RBracket)?;
361 let span = start.merge(self.prev_span());
362 Ok(TypeExpr::Option(Box::new(inner), span))
363 }
364 TokenKind::Integer(_) => {
365 let lo = self.parse_primary_expr()?;
367 self.expect(TokenKind::DotDot)?;
368 let hi = self.parse_primary_expr()?;
369 let span = start.merge(self.prev_span());
370 Ok(TypeExpr::Range(Box::new(lo), Box::new(hi), span))
371 }
372 TokenKind::LParen => {
373 self.advance();
375 let first = self.parse_type_expr()?;
376 if self.match_token(TokenKind::Comma) {
377 let mut elements = vec![first];
379 loop {
380 elements.push(self.parse_type_expr()?);
381 if !self.match_token(TokenKind::Comma) {
382 break;
383 }
384 }
385 self.expect(TokenKind::RParen)?;
386 let span = start.merge(self.prev_span());
387 Ok(TypeExpr::Tuple(elements, span))
388 } else {
389 self.expect(TokenKind::RParen)?;
391 Ok(first)
392 }
393 }
394 _ => {
395 let name = self.parse_ident()?;
397
398 if self.check(TokenKind::DotDot) {
400 self.advance();
401 let hi = self.parse_primary_expr()?;
402 let span = start.merge(self.prev_span());
403 let lo = Expr::new(ExprKind::Ident(name.name), name.span);
404 Ok(TypeExpr::Range(Box::new(lo), Box::new(hi), span))
405 } else {
406 Ok(TypeExpr::Named(name))
407 }
408 }
409 }
410 }
411
412 fn parse_expr(&mut self) -> ParseResult<Expr> {
415 self.parse_expr_impl(0, true)
416 }
417
418 fn parse_expr_no_in(&mut self) -> ParseResult<Expr> {
421 self.parse_expr_impl(0, false)
422 }
423
424 fn parse_expr_impl(&mut self, min_prec: u8, allow_in_op: bool) -> ParseResult<Expr> {
425 let mut left = self.parse_unary_expr()?;
426
427 if self.check(TokenKind::Assign) {
429 let assign_span = self.current_span();
430 self.advance(); let primed_left = match &left.kind {
434 ExprKind::Ident(name) => {
435 let span = left.span.merge(assign_span);
436 Expr::new(ExprKind::Primed(name.clone()), span)
437 }
438 _ => {
439 return Err(ParseError::InvalidSyntax {
440 message: "left side of assignment must be a variable".to_string(),
441 span: left.span,
442 });
443 }
444 };
445
446 let right = self.parse_expr_impl(5, allow_in_op)?;
449 let span = left.span.merge(right.span);
450 left = Expr::new(
451 ExprKind::Binary {
452 op: BinOp::Eq,
453 left: Box::new(primed_left),
454 right: Box::new(right),
455 },
456 span,
457 );
458 }
459
460 while let Some(op) = self.peek_binop(allow_in_op) {
461 let prec = op.precedence();
462 if prec < min_prec {
463 break;
464 }
465
466 self.advance(); let next_prec = if op.is_right_assoc() { prec } else { prec + 1 };
470 let right = self.parse_expr_impl(next_prec, allow_in_op)?;
471
472 let span = left.span.merge(right.span);
473 left = Expr::new(
474 ExprKind::Binary {
475 op,
476 left: Box::new(left),
477 right: Box::new(right),
478 },
479 span,
480 );
481 }
482
483 if self.check(TokenKind::LeadsTo) {
485 self.advance();
486 let right = self.parse_expr_impl(1, allow_in_op)?;
487 let span = left.span.merge(right.span);
488 left = Expr::new(
489 ExprKind::LeadsTo {
490 left: Box::new(left),
491 right: Box::new(right),
492 },
493 span,
494 );
495 }
496
497 Ok(left)
498 }
499
500 fn peek_binop(&self, allow_in_op: bool) -> Option<BinOp> {
501 match self.peek_kind() {
502 TokenKind::And => Some(BinOp::And),
503 TokenKind::Or => Some(BinOp::Or),
504 TokenKind::Implies => Some(BinOp::Implies),
505 TokenKind::Iff => Some(BinOp::Iff),
506 TokenKind::Eq => Some(BinOp::Eq),
507 TokenKind::Ne => Some(BinOp::Ne),
508 TokenKind::Lt => Some(BinOp::Lt),
509 TokenKind::Le => Some(BinOp::Le),
510 TokenKind::Gt => Some(BinOp::Gt),
511 TokenKind::Ge => Some(BinOp::Ge),
512 TokenKind::Plus => Some(BinOp::Add),
513 TokenKind::Minus => Some(BinOp::Sub),
514 TokenKind::Star => Some(BinOp::Mul),
515 TokenKind::Slash => Some(BinOp::Div),
516 TokenKind::Percent => Some(BinOp::Mod),
517 TokenKind::In if allow_in_op => Some(BinOp::In),
518 TokenKind::Union => Some(BinOp::Union),
519 TokenKind::Intersect => Some(BinOp::Intersect),
520 TokenKind::Diff => Some(BinOp::Diff),
521 TokenKind::SubsetOf => Some(BinOp::SubsetOf),
522 TokenKind::PlusPlus => Some(BinOp::Concat),
523 TokenKind::Ampersand => Some(BinOp::Intersect),
524 TokenKind::Pipe => Some(BinOp::Union),
525 _ => None,
526 }
527 }
528
529 fn parse_unary_expr(&mut self) -> ParseResult<Expr> {
530 self.parse_unary_expr_with_in(true)
531 }
532
533 fn parse_unary_expr_with_in(&mut self, allow_in_op: bool) -> ParseResult<Expr> {
534 let start = self.current_span();
535
536 if self.match_token(TokenKind::Not) {
537 let operand = self.parse_expr_impl(5, allow_in_op)?;
540 let span = start.merge(operand.span);
541 return Ok(Expr::new(
542 ExprKind::Unary {
543 op: UnaryOp::Not,
544 operand: Box::new(operand),
545 },
546 span,
547 ));
548 }
549
550 if self.match_token(TokenKind::Minus) {
551 let operand = self.parse_unary_expr_with_in(allow_in_op)?;
553 let span = start.merge(operand.span);
554 return Ok(Expr::new(
555 ExprKind::Unary {
556 op: UnaryOp::Neg,
557 operand: Box::new(operand),
558 },
559 span,
560 ));
561 }
562
563 if self.match_token(TokenKind::Always) {
565 let operand = self.parse_unary_expr_with_in(allow_in_op)?;
566 let span = start.merge(operand.span);
567 return Ok(Expr::new(ExprKind::Always(Box::new(operand)), span));
568 }
569
570 if self.match_token(TokenKind::Eventually) {
571 let operand = self.parse_unary_expr_with_in(allow_in_op)?;
572 let span = start.merge(operand.span);
573 return Ok(Expr::new(ExprKind::Eventually(Box::new(operand)), span));
574 }
575
576 self.parse_postfix_expr()
577 }
578
579 fn parse_postfix_expr(&mut self) -> ParseResult<Expr> {
580 let mut expr = self.parse_primary_expr()?;
581
582 loop {
583 if self.match_token(TokenKind::LBracket) {
584 self.in_bracket += 1;
586 let index = self.parse_expr()?;
587 self.in_bracket -= 1;
588 if self.match_token(TokenKind::DotDot) {
589 let hi = self.parse_expr()?;
590 self.expect(TokenKind::RBracket)?;
591 let span = expr.span.merge(self.prev_span());
592 expr = Expr::new(
593 ExprKind::Slice {
594 base: Box::new(expr),
595 lo: Box::new(index),
596 hi: Box::new(hi),
597 },
598 span,
599 );
600 } else {
601 self.expect(TokenKind::RBracket)?;
602 let span = expr.span.merge(self.prev_span());
603 expr = Expr::new(
604 ExprKind::Index {
605 base: Box::new(expr),
606 index: Box::new(index),
607 },
608 span,
609 );
610 }
611 } else if self.match_token(TokenKind::Dot) {
612 let field = self.parse_ident()?;
613 let span = expr.span.merge(field.span);
614 expr = Expr::new(
615 ExprKind::Field {
616 base: Box::new(expr),
617 field,
618 },
619 span,
620 );
621 } else if self.match_token(TokenKind::LParen) {
622 let args = self.parse_call_args()?;
624 self.expect(TokenKind::RParen)?;
625 let span = expr.span.merge(self.prev_span());
626 expr = Expr::new(
627 ExprKind::Call {
628 func: Box::new(expr),
629 args,
630 },
631 span,
632 );
633 } else if self.match_token(TokenKind::Prime) {
634 return Err(ParseError::InvalidSyntax {
636 message: "prime notation (x') is deprecated, use assignment syntax: x = value"
637 .to_string(),
638 span: self.prev_span(),
639 });
640 } else if self.in_bracket == 0 && self.match_token(TokenKind::DotDot) {
641 let hi = self.parse_postfix_expr()?;
644 let span = expr.span.merge(hi.span);
645 expr = Expr::new(
646 ExprKind::Range {
647 lo: Box::new(expr),
648 hi: Box::new(hi),
649 },
650 span,
651 );
652 break;
654 } else if self.match_token(TokenKind::With) {
655 self.expect(TokenKind::LBrace)?;
657 let updates = self.parse_record_updates()?;
658 self.expect(TokenKind::RBrace)?;
659 let span = expr.span.merge(self.prev_span());
660 expr = Expr::new(
661 ExprKind::RecordUpdate {
662 base: Box::new(expr),
663 updates,
664 },
665 span,
666 );
667 } else {
668 break;
669 }
670 }
671
672 Ok(expr)
673 }
674
675 fn parse_call_args(&mut self) -> ParseResult<Vec<Expr>> {
676 let mut args = Vec::new();
677 if !self.check(TokenKind::RParen) {
678 loop {
679 args.push(self.parse_expr()?);
680 if !self.match_token(TokenKind::Comma) {
681 break;
682 }
683 }
684 }
685 Ok(args)
686 }
687
688 fn parse_primary_expr(&mut self) -> ParseResult<Expr> {
689 let start = self.current_span();
690
691 match self.peek_kind() {
692 TokenKind::True => {
693 self.advance();
694 Ok(Expr::new(ExprKind::Bool(true), start))
695 }
696 TokenKind::False => {
697 self.advance();
698 Ok(Expr::new(ExprKind::Bool(false), start))
699 }
700 TokenKind::Integer(n) => {
701 self.advance();
702 Ok(Expr::new(ExprKind::Int(n), start))
703 }
704 TokenKind::StringLit(s) => {
705 let s = s.clone();
706 self.advance();
707 Ok(Expr::new(ExprKind::String(s), start))
708 }
709 TokenKind::Ident(name) => {
710 let name = name.clone();
711 self.advance();
712 if self.in_bracket == 0 && self.check(TokenKind::DotDot) {
714 self.advance();
715 let hi = self.parse_postfix_expr()?;
717 let span = start.merge(hi.span);
718 let lo = Expr::new(ExprKind::Ident(name), start);
719 return Ok(Expr::new(
720 ExprKind::Range {
721 lo: Box::new(lo),
722 hi: Box::new(hi),
723 },
724 span,
725 ));
726 }
727 Ok(Expr::new(ExprKind::Ident(name), start))
728 }
729 TokenKind::LParen => {
730 self.advance();
731 let first = self.parse_expr()?;
732 if self.match_token(TokenKind::Comma) {
733 let mut elements = vec![first];
735 loop {
736 elements.push(self.parse_expr()?);
737 if !self.match_token(TokenKind::Comma) {
738 break;
739 }
740 }
741 self.expect(TokenKind::RParen)?;
742 let span = start.merge(self.prev_span());
743 Ok(Expr::new(ExprKind::TupleLit(elements), span))
744 } else {
745 self.expect(TokenKind::RParen)?;
747 let span = start.merge(self.prev_span());
748 Ok(Expr::new(ExprKind::Paren(Box::new(first)), span))
749 }
750 }
751 TokenKind::LBrace => self.parse_set_or_record_lit(),
752 TokenKind::LBracket => self.parse_seq_lit(),
753 TokenKind::All => self.parse_quantifier(QuantifierKind::Forall),
754 TokenKind::Any => self.parse_quantifier(QuantifierKind::Exists),
755 TokenKind::Choose => self.parse_choose(),
756 TokenKind::Let => self.parse_let(),
757 TokenKind::If => self.parse_if(),
758 TokenKind::Require => {
759 self.advance();
760 let expr = self.parse_expr()?;
761 let span = start.merge(expr.span);
762 Ok(Expr::new(ExprKind::Require(Box::new(expr)), span))
763 }
764 TokenKind::Changes => {
765 self.advance();
766 self.expect(TokenKind::LParen)?;
767 let var = self.parse_ident()?;
768 self.expect(TokenKind::RParen)?;
769 let span = start.merge(self.prev_span());
770 Ok(Expr::new(ExprKind::Changes(var), span))
771 }
772 TokenKind::Enabled => {
773 self.advance();
774 self.expect(TokenKind::LParen)?;
775 let action = self.parse_ident()?;
776 self.expect(TokenKind::RParen)?;
777 let span = start.merge(self.prev_span());
778 Ok(Expr::new(ExprKind::Enabled(action), span))
779 }
780 TokenKind::Head => {
781 self.advance();
782 self.expect(TokenKind::LParen)?;
783 let seq = self.parse_expr()?;
784 self.expect(TokenKind::RParen)?;
785 let span = start.merge(self.prev_span());
786 Ok(Expr::new(ExprKind::SeqHead(Box::new(seq)), span))
787 }
788 TokenKind::Tail => {
789 self.advance();
790 self.expect(TokenKind::LParen)?;
791 let seq = self.parse_expr()?;
792 self.expect(TokenKind::RParen)?;
793 let span = start.merge(self.prev_span());
794 Ok(Expr::new(ExprKind::SeqTail(Box::new(seq)), span))
795 }
796 TokenKind::Len => {
797 self.advance();
798 self.expect(TokenKind::LParen)?;
799 let expr = self.parse_expr()?;
800 self.expect(TokenKind::RParen)?;
801 let span = start.merge(self.prev_span());
802 Ok(Expr::new(ExprKind::Len(Box::new(expr)), span))
803 }
804 TokenKind::Keys => {
805 self.advance();
806 self.expect(TokenKind::LParen)?;
807 let expr = self.parse_expr()?;
808 self.expect(TokenKind::RParen)?;
809 let span = start.merge(self.prev_span());
810 Ok(Expr::new(ExprKind::Keys(Box::new(expr)), span))
811 }
812 TokenKind::Values => {
813 self.advance();
814 self.expect(TokenKind::LParen)?;
815 let expr = self.parse_expr()?;
816 self.expect(TokenKind::RParen)?;
817 let span = start.merge(self.prev_span());
818 Ok(Expr::new(ExprKind::Values(Box::new(expr)), span))
819 }
820 TokenKind::Some_ => {
822 self.advance();
823 Ok(Expr::new(ExprKind::Ident("Some".to_string()), start))
824 }
825 TokenKind::None_ => {
826 self.advance();
827 Ok(Expr::new(ExprKind::Ident("None".to_string()), start))
828 }
829 TokenKind::Powerset => {
830 self.advance();
831 self.expect(TokenKind::LParen)?;
832 let expr = self.parse_expr()?;
833 self.expect(TokenKind::RParen)?;
834 let span = start.merge(self.prev_span());
835 Ok(Expr::new(ExprKind::Powerset(Box::new(expr)), span))
836 }
837 TokenKind::UnionAll => {
838 self.advance();
839 self.expect(TokenKind::LParen)?;
840 let expr = self.parse_expr()?;
841 self.expect(TokenKind::RParen)?;
842 let span = start.merge(self.prev_span());
843 Ok(Expr::new(ExprKind::BigUnion(Box::new(expr)), span))
844 }
845 _ => Err(ParseError::UnexpectedToken {
846 expected: "expression".to_string(),
847 found: self.peek_kind().to_string(),
848 span: start,
849 }),
850 }
851 }
852
853 fn parse_set_or_record_lit(&mut self) -> ParseResult<Expr> {
854 let start = self.current_span();
855 self.expect(TokenKind::LBrace)?;
856
857 if self.check(TokenKind::RBrace) {
859 self.advance();
860 let span = start.merge(self.prev_span());
861 return Ok(Expr::new(ExprKind::SetLit(vec![]), span));
862 }
863
864 if self.is_set_filter_comprehension() {
873 return self.parse_set_filter_comprehension(start);
874 }
875
876 let first = self.parse_expr()?;
878
879 if self.check(TokenKind::Colon) {
880 self.advance(); let value = self.parse_expr()?;
885
886 if self.check(TokenKind::For) {
888 self.advance(); let var = self.parse_ident()?;
890 self.expect(TokenKind::In)?;
891 let domain = self.parse_expr()?;
892 self.expect(TokenKind::RBrace)?;
893 let span = start.merge(self.prev_span());
894
895 let key_name = match &first.kind {
897 ExprKind::Ident(s) => s.clone(),
898 _ => {
899 return Err(ParseError::InvalidSyntax {
900 message: "dict comprehension key must be an identifier".to_string(),
901 span: first.span,
902 })
903 }
904 };
905 if key_name != var.name {
906 return Err(ParseError::InvalidSyntax {
907 message: format!(
908 "dict comprehension key '{}' must match iteration variable '{}'",
909 key_name, var.name
910 ),
911 span: first.span,
912 });
913 }
914
915 return Ok(Expr::new(
917 ExprKind::FnLit {
918 var,
919 domain: Box::new(domain),
920 body: Box::new(value),
921 },
922 span,
923 ));
924 }
925
926 let mut entries = vec![(first, value)];
928
929 while self.match_token(TokenKind::Comma) {
930 if self.check(TokenKind::RBrace) {
931 break; }
933 let key = self.parse_expr()?;
934 self.expect(TokenKind::Colon)?;
935 let val = self.parse_expr()?;
936 entries.push((key, val));
937 }
938
939 self.expect(TokenKind::RBrace)?;
940 let span = start.merge(self.prev_span());
941 Ok(Expr::new(ExprKind::DictLit(entries), span))
942 } else if self.check(TokenKind::For) {
943 self.advance(); let var = self.parse_ident()?;
946 self.expect(TokenKind::In)?;
947 let domain = self.parse_expr()?;
948 let filter = if self.match_token(TokenKind::If) {
949 Some(Box::new(self.parse_expr()?))
950 } else {
951 None
952 };
953 self.expect(TokenKind::RBrace)?;
954 let span = start.merge(self.prev_span());
955 Ok(Expr::new(
956 ExprKind::SetComprehension {
957 element: Box::new(first),
958 var,
959 domain: Box::new(domain),
960 filter,
961 },
962 span,
963 ))
964 } else {
965 let mut elements = vec![first];
967 while self.match_token(TokenKind::Comma) {
968 if self.check(TokenKind::RBrace) {
969 break; }
971 elements.push(self.parse_expr()?);
972 }
973 self.expect(TokenKind::RBrace)?;
974 let span = start.merge(self.prev_span());
975 Ok(Expr::new(ExprKind::SetLit(elements), span))
976 }
977 }
978
979 fn is_set_filter_comprehension(&self) -> bool {
981 matches!(self.peek_kind(), TokenKind::Ident(_)) && self.peek_ahead_kind(1) == TokenKind::In
983 }
984
985 fn parse_set_filter_comprehension(&mut self, start: Span) -> ParseResult<Expr> {
987 let var = self.parse_ident()?;
988 self.expect(TokenKind::In)?;
989 let domain = self.parse_expr()?;
992 self.expect(TokenKind::If)?;
993 let predicate = self.parse_expr()?;
994 self.expect(TokenKind::RBrace)?;
995 let span = start.merge(self.prev_span());
996 let element = Expr::new(ExprKind::Ident(var.name.clone()), var.span);
998 Ok(Expr::new(
999 ExprKind::SetComprehension {
1000 element: Box::new(element),
1001 var,
1002 domain: Box::new(domain),
1003 filter: Some(Box::new(predicate)),
1004 },
1005 span,
1006 ))
1007 }
1008
1009 fn parse_seq_lit(&mut self) -> ParseResult<Expr> {
1010 let start = self.current_span();
1011 self.expect(TokenKind::LBracket)?;
1012
1013 let mut elements = Vec::new();
1014 if !self.check(TokenKind::RBracket) {
1015 loop {
1016 elements.push(self.parse_expr()?);
1017 if !self.match_token(TokenKind::Comma) {
1018 break;
1019 }
1020 if self.check(TokenKind::RBracket) {
1021 break; }
1023 }
1024 }
1025
1026 self.expect(TokenKind::RBracket)?;
1027 let span = start.merge(self.prev_span());
1028 Ok(Expr::new(ExprKind::SeqLit(elements), span))
1029 }
1030
1031 fn parse_quantifier(&mut self, kind: QuantifierKind) -> ParseResult<Expr> {
1032 let start = self.current_span();
1033 self.advance(); let mut bindings = Vec::new();
1036 loop {
1037 let var = self.parse_ident()?;
1038 self.expect(TokenKind::In)?;
1039 let domain = self.parse_expr_no_in()?;
1041 let span = var.span.merge(domain.span);
1042 bindings.push(Binding { var, domain, span });
1043 if !self.match_token(TokenKind::Comma) {
1044 break;
1045 }
1046 }
1047
1048 self.expect(TokenKind::Colon)?;
1049 let body = self.parse_expr_no_in()?;
1052 let span = start.merge(body.span);
1053 Ok(Expr::new(
1054 ExprKind::Quantifier {
1055 kind,
1056 bindings,
1057 body: Box::new(body),
1058 },
1059 span,
1060 ))
1061 }
1062
1063 fn parse_choose(&mut self) -> ParseResult<Expr> {
1064 let start = self.current_span();
1065 self.expect(TokenKind::Choose)?;
1066 let var = self.parse_ident()?;
1067 self.expect(TokenKind::In)?;
1068 let domain = self.parse_expr_no_in()?;
1070 self.expect(TokenKind::Colon)?;
1071 let predicate = self.parse_expr_no_in()?;
1073 let span = start.merge(predicate.span);
1074 Ok(Expr::new(
1075 ExprKind::Choose {
1076 var,
1077 domain: Box::new(domain),
1078 predicate: Box::new(predicate),
1079 },
1080 span,
1081 ))
1082 }
1083
1084 fn parse_let(&mut self) -> ParseResult<Expr> {
1085 let start = self.current_span();
1086 self.expect(TokenKind::Let)?;
1087 let var = self.parse_ident()?;
1088 self.expect(TokenKind::Assign)?;
1089 let value = self.parse_expr_no_in()?;
1091 self.expect(TokenKind::In)?;
1092 let body = self.parse_expr()?;
1093 let span = start.merge(body.span);
1094 Ok(Expr::new(
1095 ExprKind::Let {
1096 var,
1097 value: Box::new(value),
1098 body: Box::new(body),
1099 },
1100 span,
1101 ))
1102 }
1103
1104 fn parse_if(&mut self) -> ParseResult<Expr> {
1105 let start = self.current_span();
1106 self.expect(TokenKind::If)?;
1107 let cond = self.parse_expr()?;
1108 self.expect(TokenKind::Then)?;
1109 let then_branch = self.parse_expr()?;
1110 self.expect(TokenKind::Else)?;
1111 let else_branch = self.parse_expr()?;
1112 let span = start.merge(else_branch.span);
1113 Ok(Expr::new(
1114 ExprKind::If {
1115 cond: Box::new(cond),
1116 then_branch: Box::new(then_branch),
1117 else_branch: Box::new(else_branch),
1118 },
1119 span,
1120 ))
1121 }
1122
1123 fn parse_record_updates(&mut self) -> ParseResult<Vec<RecordFieldUpdate>> {
1125 let mut updates = Vec::new();
1126
1127 if self.check(TokenKind::RBrace) {
1128 return Ok(updates);
1129 }
1130
1131 loop {
1132 let update = if self.match_token(TokenKind::LBracket) {
1133 let key = self.parse_expr()?;
1135 self.expect(TokenKind::RBracket)?;
1136 self.expect(TokenKind::Colon)?;
1137 let value = self.parse_expr()?;
1138 RecordFieldUpdate::Dynamic { key, value }
1139 } else {
1140 let name = self.parse_ident()?;
1142 self.expect(TokenKind::Colon)?;
1143 let value = self.parse_expr()?;
1144 RecordFieldUpdate::Field { name, value }
1145 };
1146 updates.push(update);
1147
1148 if !self.match_token(TokenKind::Comma) {
1149 break;
1150 }
1151 if self.check(TokenKind::RBrace) {
1152 break; }
1154 }
1155
1156 Ok(updates)
1157 }
1158
1159 fn parse_ident(&mut self) -> ParseResult<Ident> {
1162 let span = self.current_span();
1163 match self.peek_kind() {
1164 TokenKind::Ident(name) => {
1165 let name = name.clone();
1166 self.advance();
1167 Ok(Ident::new(name, span))
1168 }
1169 TokenKind::Nat => {
1171 self.advance();
1172 Ok(Ident::new("Nat", span))
1173 }
1174 TokenKind::Int => {
1175 self.advance();
1176 Ok(Ident::new("Int", span))
1177 }
1178 TokenKind::Bool => {
1179 self.advance();
1180 Ok(Ident::new("Bool", span))
1181 }
1182 TokenKind::String_ => {
1183 self.advance();
1184 Ok(Ident::new("String", span))
1185 }
1186 _ => Err(ParseError::UnexpectedToken {
1187 expected: "identifier".to_string(),
1188 found: self.peek_kind().to_string(),
1189 span,
1190 }),
1191 }
1192 }
1193
1194 fn peek(&self) -> &Token {
1195 self.tokens
1196 .get(self.pos)
1197 .unwrap_or_else(|| self.tokens.last().expect("tokens should have at least EOF"))
1198 }
1199
1200 fn peek_kind(&self) -> TokenKind {
1201 self.peek().kind.clone()
1202 }
1203
1204 fn peek_ahead_kind(&self, offset: usize) -> TokenKind {
1206 self.tokens
1207 .get(self.pos + offset)
1208 .map(|t| t.kind.clone())
1209 .unwrap_or(TokenKind::Eof)
1210 }
1211
1212 fn current_span(&self) -> Span {
1213 self.peek().span
1214 }
1215
1216 fn prev_span(&self) -> Span {
1217 if self.pos > 0 {
1218 self.tokens[self.pos - 1].span
1219 } else {
1220 Span::dummy()
1221 }
1222 }
1223
1224 fn is_at_end(&self) -> bool {
1225 matches!(self.peek_kind(), TokenKind::Eof)
1226 }
1227
1228 fn check(&self, kind: TokenKind) -> bool {
1229 std::mem::discriminant(&self.peek_kind()) == std::mem::discriminant(&kind)
1230 }
1231
1232 fn match_token(&mut self, kind: TokenKind) -> bool {
1233 if self.check(kind) {
1234 self.advance();
1235 true
1236 } else {
1237 false
1238 }
1239 }
1240
1241 fn advance(&mut self) {
1242 if !self.is_at_end() {
1243 self.pos += 1;
1244 }
1245 }
1246
1247 fn expect(&mut self, kind: TokenKind) -> ParseResult<()> {
1248 if self.check(kind.clone()) {
1249 self.advance();
1250 Ok(())
1251 } else {
1252 Err(ParseError::UnexpectedToken {
1253 expected: kind.to_string(),
1254 found: self.peek_kind().to_string(),
1255 span: self.current_span(),
1256 })
1257 }
1258 }
1259}
1260
1261pub fn parse(source: &str) -> ParseResult<Module> {
1263 Parser::new(source).parse_module()
1264}
1265
1266#[cfg(test)]
1267mod tests {
1268 use super::*;
1269
1270 fn parse_expr_str(source: &str) -> Expr {
1271 let full = format!("module Test\ninit {{ {} }}", source);
1273 let module = parse(&full).unwrap();
1274 match &module.decls[0] {
1275 Decl::Init(init) => init.body.clone(),
1276 _ => panic!("expected init decl"),
1277 }
1278 }
1279
1280 #[test]
1281 fn test_parse_empty_module() {
1282 let module = parse("module Empty").unwrap();
1283 assert_eq!(module.name.name, "Empty");
1284 assert!(module.decls.is_empty());
1285 }
1286
1287 #[test]
1288 fn test_parse_var_decl() {
1289 let module = parse("module Test\nvar count: Nat").unwrap();
1290 assert_eq!(module.decls.len(), 1);
1291 match &module.decls[0] {
1292 Decl::Var(v) => {
1293 assert_eq!(v.name.name, "count");
1294 }
1295 _ => panic!("expected var decl"),
1296 }
1297 }
1298
1299 #[test]
1300 fn test_parse_const_decl() {
1301 let module = parse("module Test\nconst MAX: Nat").unwrap();
1302 match &module.decls[0] {
1303 Decl::Const(c) => {
1304 assert_eq!(c.name.name, "MAX");
1305 }
1306 _ => panic!("expected const decl"),
1307 }
1308 }
1309
1310 #[test]
1311 fn test_parse_type_decl() {
1312 let module = parse("module Test\ntype Balance = 0..100").unwrap();
1313 match &module.decls[0] {
1314 Decl::Type(t) => {
1315 assert_eq!(t.name.name, "Balance");
1316 }
1317 _ => panic!("expected type decl"),
1318 }
1319 }
1320
1321 #[test]
1322 fn test_parse_init_block() {
1323 let module = parse("module Test\ninit { count == 0 }").unwrap();
1324 match &module.decls[0] {
1325 Decl::Init(i) => match &i.body.kind {
1326 ExprKind::Binary { op, .. } => {
1327 assert_eq!(*op, BinOp::Eq);
1328 }
1329 _ => panic!("expected binary expr"),
1330 },
1331 _ => panic!("expected init decl"),
1332 }
1333 }
1334
1335 #[test]
1336 fn test_parse_action() {
1337 let source = r#"
1338module Test
1339action Increment() {
1340 require count < MAX
1341 count = count + 1
1342}
1343"#;
1344 let module = parse(source).unwrap();
1345 match &module.decls[0] {
1346 Decl::Action(a) => {
1347 assert_eq!(a.name.name, "Increment");
1348 assert_eq!(a.body.requires.len(), 1);
1349 assert!(a.body.effect.is_some());
1350 }
1351 _ => panic!("expected action decl"),
1352 }
1353 }
1354
1355 #[test]
1356 fn test_parse_assignment() {
1357 let expr = parse_expr_str("x = x + 1");
1359 match &expr.kind {
1360 ExprKind::Binary { left, .. } => match &left.kind {
1361 ExprKind::Primed(name) => assert_eq!(name, "x"),
1362 _ => panic!("expected primed var"),
1363 },
1364 _ => panic!("expected binary"),
1365 }
1366 }
1367
1368 #[test]
1369 fn test_parse_quantifier() {
1370 let expr = parse_expr_str("all x in S: P(x)");
1371 match &expr.kind {
1372 ExprKind::Quantifier { kind, bindings, .. } => {
1373 assert_eq!(*kind, QuantifierKind::Forall);
1374 assert_eq!(bindings.len(), 1);
1375 assert_eq!(bindings[0].var.name, "x");
1376 }
1377 _ => panic!("expected quantifier"),
1378 }
1379 }
1380
1381 #[test]
1382 fn test_parse_set_comprehension() {
1383 let expr = parse_expr_str("{ x in S if P(x) }");
1384 match &expr.kind {
1385 ExprKind::SetComprehension {
1386 var,
1387 filter: Some(_),
1388 ..
1389 } => {
1390 assert_eq!(var.name, "x");
1391 }
1392 _ => panic!("expected set comprehension"),
1393 }
1394 }
1395
1396 #[test]
1397 fn test_parse_dict_merge() {
1398 let expr = parse_expr_str("r | {a: 1, k: v}");
1400 match &expr.kind {
1401 ExprKind::Binary { op, right, .. } => {
1402 assert_eq!(*op, BinOp::Union);
1403 match &right.kind {
1405 ExprKind::DictLit(entries) => {
1406 assert_eq!(entries.len(), 2);
1407 }
1408 _ => panic!("expected dict literal on right"),
1409 }
1410 }
1411 _ => panic!("expected binary union"),
1412 }
1413 }
1414
1415 #[test]
1416 fn test_parse_if_then_else() {
1417 let expr = parse_expr_str("if x > 0 then 1 else 0");
1418 match &expr.kind {
1419 ExprKind::If { .. } => {}
1420 _ => panic!("expected if"),
1421 }
1422 }
1423
1424 #[test]
1425 fn test_parse_let() {
1426 let expr = parse_expr_str("let x = 1 in x + 1");
1427 match &expr.kind {
1428 ExprKind::Let { var, .. } => {
1429 assert_eq!(var.name, "x");
1430 }
1431 _ => panic!("expected let"),
1432 }
1433 }
1434
1435 #[test]
1436 fn test_parse_dict_comprehension() {
1437 let expr = parse_expr_str("{ x: x + 1 for x in S }");
1439 match &expr.kind {
1440 ExprKind::FnLit { var, .. } => {
1441 assert_eq!(var.name, "x");
1442 }
1443 _ => panic!("expected fn lit from dict comprehension"),
1444 }
1445 }
1446
1447 #[test]
1448 fn test_parse_precedence() {
1449 let expr = parse_expr_str("a + b * c");
1451 match &expr.kind {
1452 ExprKind::Binary { op, right, .. } => {
1453 assert_eq!(*op, BinOp::Add);
1454 match &right.kind {
1455 ExprKind::Binary { op, .. } => {
1456 assert_eq!(*op, BinOp::Mul);
1457 }
1458 _ => panic!("expected binary"),
1459 }
1460 }
1461 _ => panic!("expected binary"),
1462 }
1463 }
1464
1465 #[test]
1466 fn test_parse_full_spec() {
1467 let source = r#"
1468module Counter
1469
1470const MAX: Nat
1471
1472var count: Nat
1473
1474init {
1475 count == 0
1476}
1477
1478action Increment() {
1479 require count < MAX
1480 count = count + 1
1481}
1482
1483invariant Bounded {
1484 count <= MAX
1485}
1486"#;
1487 let module = parse(source).unwrap();
1488 assert_eq!(module.name.name, "Counter");
1489 assert_eq!(module.decls.len(), 5);
1490 }
1491}