1use crate::ast::*;
14use crate::error::ParseError;
15use crate::lexer::{Token, TokenKind};
16
17pub struct Parser {
19 tokens: Vec<Token>,
20 pos: usize,
21}
22
23impl Parser {
24 pub fn new(tokens: Vec<Token>) -> Self {
26 Self { tokens, pos: 0 }
27 }
28
29 pub fn from_tokens_at(tokens: Vec<Token>, pos: usize) -> Self {
35 Self { tokens, pos }
36 }
37
38 pub fn pos(&self) -> usize {
40 self.pos
41 }
42
43 pub fn into_inner(self) -> (Vec<Token>, usize) {
48 (self.tokens, self.pos)
49 }
50
51 pub fn parse_document(&mut self) -> Result<Document, ParseError> {
55 let mut items = Vec::new();
56
57 while !self.at_eof() {
58 match &self.peek().kind {
59 TokenKind::Ident(ref s) if s == "private" => {
60 self.advance(); if !self.check(TokenKind::Pattern) {
63 return Err(self.error("expected 'pattern' after 'private'"));
64 }
65 let mut pat = self.parse_pattern()?;
66 pat.private = true;
67 items.push(DocumentItem::Pattern(pat));
68 }
69 TokenKind::Pattern => items.push(DocumentItem::Pattern(self.parse_pattern()?)),
70 TokenKind::Graph => items.push(DocumentItem::Graph(self.parse_graph()?)),
71 TokenKind::Compose => items.push(DocumentItem::Compose(self.parse_compose()?)),
72 _ => return Err(self.error("expected 'pattern', 'graph', or 'compose'")),
73 }
74 }
75
76 Ok(Document { items })
77 }
78
79 pub fn parse_pattern_only(&mut self) -> Result<PatternAst, ParseError> {
81 let pat = self.parse_pattern()?;
82 if !self.at_eof() {
83 return Err(self.error("unexpected content after pattern"));
84 }
85 Ok(pat)
86 }
87
88 pub fn parse_graph_only(&mut self) -> Result<GraphAst, ParseError> {
90 let g = self.parse_graph()?;
91 if !self.at_eof() {
92 return Err(self.error("unexpected content after graph"));
93 }
94 Ok(g)
95 }
96
97 pub fn parse_pattern(&mut self) -> Result<PatternAst, ParseError> {
101 self.expect(TokenKind::Pattern)?;
102 let name = self.expect_ident()?;
103 self.expect(TokenKind::LBrace)?;
104 let body = self.parse_pattern_body()?;
105 self.expect(TokenKind::RBrace)?;
106 Ok(PatternAst {
107 name,
108 stages: body.stages,
109 negations: body.negations,
110 temporals: body.temporals,
111 metadata: body.metadata,
112 deadline: body.deadline,
113 unordered_groups: body.unordered_groups,
114 private: false,
115 })
116 }
117
118 pub fn parse_pattern_body(&mut self) -> Result<PatternBody, ParseError> {
137 let mut stages = Vec::new();
138 let mut negations = Vec::new();
139 let mut temporals = Vec::new();
140 let mut metadata = Vec::new();
141 let mut deadline = None;
142 let mut unordered_groups = Vec::new();
143
144 while !self.check(TokenKind::RBrace) && !self.at_eof() {
145 match &self.peek().kind {
146 TokenKind::Stage => stages.push(self.parse_stage()?),
147 TokenKind::Unless => negations.push(self.parse_negation()?),
148 TokenKind::Temporal => temporals.push(self.parse_temporal()?),
149 TokenKind::Concurrent => {
150 self.advance();
151 self.expect(TokenKind::LBrace)?;
152 let group_start = stages.len();
153 while !self.check(TokenKind::RBrace) && !self.at_eof() {
154 if !self.check(TokenKind::Stage) {
155 return Err(
156 self.error("only 'stage' blocks are allowed inside 'concurrent'")
157 );
158 }
159 stages.push(self.parse_stage()?);
160 }
161 self.expect(TokenKind::RBrace)?;
162 let group_end = stages.len();
163 if group_end > group_start {
164 let indices: Vec<usize> = (group_start..group_end).collect();
165 unordered_groups.push(indices);
166 }
167 }
168 TokenKind::Ident(s) if s == "meta" => {
169 metadata.push(self.parse_meta()?);
170 }
171 TokenKind::Ident(s) if s == "deadline" => {
172 self.advance();
173 deadline = Some(self.expect_number()?);
174 }
175 _ => return Err(self.error(
176 "expected 'stage', 'unless', 'temporal', 'concurrent', 'meta', or 'deadline'",
177 )),
178 }
179 }
180
181 Ok(PatternBody {
182 stages,
183 negations,
184 temporals,
185 metadata,
186 deadline,
187 unordered_groups,
188 private: false,
189 })
190 }
191
192 fn parse_meta(&mut self) -> Result<(String, String), ParseError> {
194 self.advance();
196 self.expect(TokenKind::LParen)?;
197 let key = match &self.peek().kind {
198 TokenKind::String(_) => {
199 if let TokenKind::String(s) = &self.advance().kind {
200 s.clone()
201 } else {
202 unreachable!()
203 }
204 }
205 _ => return Err(self.error("expected string literal for meta key")),
206 };
207 self.expect(TokenKind::Comma)?;
208 let value = match &self.peek().kind {
209 TokenKind::String(_) => {
210 if let TokenKind::String(s) = &self.advance().kind {
211 s.clone()
212 } else {
213 unreachable!()
214 }
215 }
216 _ => return Err(self.error("expected string literal for meta value")),
217 };
218 self.expect(TokenKind::RParen)?;
219 Ok((key, value))
220 }
221
222 pub fn parse_stage(&mut self) -> Result<StageAst, ParseError> {
224 self.expect(TokenKind::Stage)?;
225 let anchor = self.expect_ident()?;
226 self.expect(TokenKind::LBrace)?;
227
228 let mut clauses = Vec::new();
229 while !self.check(TokenKind::RBrace) {
230 clauses.push(self.parse_clause()?);
231 }
232
233 self.expect(TokenKind::RBrace)?;
234 Ok(StageAst { anchor, clauses })
235 }
236
237 pub fn parse_negation(&mut self) -> Result<NegationAst, ParseError> {
239 self.expect(TokenKind::Unless)?;
240
241 let kind = if self.check(TokenKind::Between) {
242 self.advance();
243 let start = self.expect_ident()?;
244 let end = self.expect_ident()?;
245 NegationKind::Between(start, end)
246 } else if self.check(TokenKind::After) {
247 self.advance();
248 let start = self.expect_ident()?;
249 NegationKind::After(start)
250 } else {
251 NegationKind::Global
253 };
254
255 self.expect(TokenKind::LBrace)?;
256 let mut clauses = Vec::new();
257 while !self.check(TokenKind::RBrace) {
258 clauses.push(self.parse_clause()?);
259 }
260 self.expect(TokenKind::RBrace)?;
261
262 Ok(NegationAst { kind, clauses })
263 }
264
265 pub fn parse_temporal(&mut self) -> Result<TemporalAst, ParseError> {
267 self.expect(TokenKind::Temporal)?;
268 let left = self.expect_ident()?;
269 let relation = self.expect_ident()?;
270 let right = self.expect_ident()?;
271
272 let (gap_min, gap_max) = if matches!(self.peek().kind, TokenKind::Ident(ref s) if s == "gap")
274 {
275 self.advance();
276 self.parse_gap_range()?
277 } else {
278 (None, None)
279 };
280
281 Ok(TemporalAst {
282 left,
283 relation,
284 right,
285 gap_min,
286 gap_max,
287 })
288 }
289
290 fn parse_gap_range(&mut self) -> Result<(Option<f64>, Option<f64>), ParseError> {
291 if self.check(TokenKind::DotDot) {
293 self.advance();
295 let max = self.expect_number()?;
296 Ok((None, Some(max)))
297 } else if matches!(self.peek().kind, TokenKind::Number(_) | TokenKind::Minus) {
298 let first = self.expect_number()?;
299 if self.check(TokenKind::DotDot) {
300 self.advance();
301 if matches!(self.peek().kind, TokenKind::Number(_) | TokenKind::Minus) {
303 let second = self.expect_number()?;
304 Ok((Some(first), Some(second)))
305 } else {
306 Ok((Some(first), None))
308 }
309 } else {
310 Ok((Some(first), Some(first)))
312 }
313 } else {
314 Err(self.error("expected gap range (e.g., '3..10', '..10', '3..')"))
315 }
316 }
317
318 pub fn parse_compose(&mut self) -> Result<ComposeAst, ParseError> {
322 self.expect(TokenKind::Compose)?;
323 let name = self.expect_ident()?;
324 self.expect(TokenKind::Eq)?;
325
326 let first = self.expect_ident()?;
328
329 let body = if self.check(TokenKind::GtGt) {
331 self.advance();
333 let second = self.expect_ident()?;
334 let shared = self.parse_sharing_clause()?;
335 ComposeBody::Sequence {
336 left: first,
337 right: second,
338 shared,
339 }
340 } else if self.check(TokenKind::Pipe) {
341 let mut alternatives = vec![first];
343 while self.check(TokenKind::Pipe) {
344 self.advance();
345 alternatives.push(self.expect_ident()?);
346 }
347 let exclusive = match &self.peek().kind {
348 TokenKind::Ident(s) if s == "nonexclusive" => {
349 self.advance();
350 false
351 }
352 _ => true,
353 };
354 ComposeBody::Choice {
355 alternatives,
356 exclusive,
357 }
358 } else if self.check(TokenKind::Star) {
359 self.advance();
361 let min = self.expect_number()? as usize;
362 let max = if self.check(TokenKind::DotDot) {
363 self.advance();
364 if matches!(self.peek().kind, TokenKind::Number(_) | TokenKind::Minus) {
366 Some(Some(self.expect_number()? as usize))
367 } else {
368 Some(None) }
370 } else {
371 None };
373 let shared = self.parse_sharing_clause()?;
374 match max {
375 None => {
376 ComposeBody::Repeat {
378 pattern: first,
379 min,
380 max: Some(min),
381 shared,
382 }
383 }
384 Some(max_val) => {
385 ComposeBody::Repeat {
387 pattern: first,
388 min,
389 max: max_val,
390 shared,
391 }
392 }
393 }
394 } else {
395 return Err(self.error("expected '>>' (sequence), '|' (choice), or '*' (repeat)"));
396 };
397
398 Ok(ComposeAst { name, body })
399 }
400
401 fn parse_sharing_clause(&mut self) -> Result<Vec<String>, ParseError> {
402 if !self.check(TokenKind::Sharing) {
403 return Ok(Vec::new());
404 }
405 self.advance(); self.expect(TokenKind::LParen)?;
407
408 let mut vars = vec![self.expect_ident()?];
409 while self.check(TokenKind::Comma) {
410 self.advance();
411 vars.push(self.expect_ident()?);
412 }
413
414 self.expect(TokenKind::RParen)?;
415 Ok(vars)
416 }
417
418 pub fn parse_clause(&mut self) -> Result<ClauseAst, ParseError> {
420 let negated = if self.check(TokenKind::Bang) {
422 self.advance();
423 true
424 } else {
425 false
426 };
427
428 let source_kind = if self.check(TokenKind::Question) {
430 self.advance();
431 if !matches!(self.peek().kind, TokenKind::Ident(_)) {
433 return Err(self.error("expected variable name after '?'"));
434 }
435 SourceKind::Var
436 } else {
437 SourceKind::Literal
438 };
439
440 let source = self.expect_ident()?;
441 self.expect(TokenKind::Dot)?;
442 let label = self.expect_ident_or_string()?;
443
444 let target = if self.check(TokenKind::Eq) {
446 self.advance();
447 if self.check(TokenKind::Question) {
448 self.advance();
449 let var = self.expect_ident()?;
450 ClauseTarget::ConstraintVar(ConstraintOp::Eq, var)
451 } else {
452 self.parse_literal_target()?
453 }
454 } else if self.check(TokenKind::Arrow) {
455 self.advance();
456 if self.check(TokenKind::Question) {
457 self.advance();
458 let var = self.expect_ident()?;
459 ClauseTarget::Bind(var)
460 } else {
461 let node = self.expect_ident()?;
462 ClauseTarget::NodeRef(node)
463 }
464 } else if self.check(TokenKind::Lt) {
465 self.advance();
466 self.parse_constraint_target(ConstraintOp::Lt)?
467 } else if self.check(TokenKind::Gt) {
468 self.advance();
469 self.parse_constraint_target(ConstraintOp::Gt)?
470 } else if self.check(TokenKind::Lte) {
471 self.advance();
472 self.parse_constraint_target(ConstraintOp::Lte)?
473 } else if self.check(TokenKind::Gte) {
474 self.advance();
475 self.parse_constraint_target(ConstraintOp::Gte)?
476 } else {
477 return Err(self.error("expected '=', '->', '<', '>', '<=', or '>='"));
478 };
479
480 Ok(ClauseAst {
481 source,
482 source_kind,
483 label,
484 target,
485 negated,
486 })
487 }
488
489 fn parse_literal_target(&mut self) -> Result<ClauseTarget, ParseError> {
490 if self.check(TokenKind::Minus) {
492 self.advance();
493 if let TokenKind::Number(n) = &self.advance().kind {
494 return Ok(ClauseTarget::LiteralNum(-n));
495 }
496 return Err(self.error("expected number after '-'"));
497 }
498 match &self.peek().kind {
499 TokenKind::String(_) => {
500 if let TokenKind::String(s) = &self.advance().kind {
501 Ok(ClauseTarget::LiteralStr(s.clone()))
502 } else {
503 unreachable!()
504 }
505 }
506 TokenKind::Number(_) => {
507 if let TokenKind::Number(n) = &self.advance().kind {
508 Ok(ClauseTarget::LiteralNum(*n))
509 } else {
510 unreachable!()
511 }
512 }
513 TokenKind::True => {
514 self.advance();
515 Ok(ClauseTarget::LiteralBool(true))
516 }
517 TokenKind::False => {
518 self.advance();
519 Ok(ClauseTarget::LiteralBool(false))
520 }
521 _ => Err(self.error("expected a string, number, or boolean value")),
522 }
523 }
524
525 fn parse_constraint_target(&mut self, op: ConstraintOp) -> Result<ClauseTarget, ParseError> {
526 if self.check(TokenKind::Question) {
527 self.advance();
528 let var = self.expect_ident()?;
529 Ok(ClauseTarget::ConstraintVar(op, var))
530 } else {
531 let val = self.parse_constraint_value()?;
532 Ok(ClauseTarget::Constraint(op, val))
533 }
534 }
535
536 fn parse_constraint_value(&mut self) -> Result<ConstraintValue, ParseError> {
537 let negative = if self.check(TokenKind::Minus) {
538 self.advance();
539 true
540 } else {
541 false
542 };
543 match &self.peek().kind {
544 TokenKind::Number(_) => {
545 if let TokenKind::Number(n) = &self.advance().kind {
546 Ok(ConstraintValue::Num(if negative { -*n } else { *n }))
547 } else {
548 unreachable!()
549 }
550 }
551 TokenKind::String(_) if !negative => {
552 if let TokenKind::String(s) = &self.advance().kind {
553 Ok(ConstraintValue::Str(s.clone()))
554 } else {
555 unreachable!()
556 }
557 }
558 _ => Err(self.error("expected a number or string value")),
559 }
560 }
561
562 pub fn parse_graph(&mut self) -> Result<GraphAst, ParseError> {
566 self.expect(TokenKind::Graph)?;
567 self.expect(TokenKind::LBrace)?;
568
569 let mut edges = Vec::new();
570 let mut now = None;
571
572 while !self.check(TokenKind::RBrace) {
573 if self.check(TokenKind::Now) {
574 self.advance();
575 self.expect(TokenKind::Eq)?;
576 let n = self.expect_number()?;
577 now = Some(n as i64);
578 } else if self.check(TokenKind::At) {
579 edges.push(self.parse_graph_edge()?);
580 } else {
581 return Err(self.error("expected '@' (edge) or 'now' in graph block"));
582 }
583 }
584
585 self.expect(TokenKind::RBrace)?;
586 Ok(GraphAst { edges, now })
587 }
588
589 fn parse_graph_edge(&mut self) -> Result<EdgeAst, ParseError> {
590 self.expect(TokenKind::At)?;
591 let time_start = self.expect_number()? as i64;
592
593 let time_end = if self.check(TokenKind::DotDot) {
595 self.advance();
596 Some(self.expect_number()? as i64)
597 } else {
598 None
599 };
600
601 let source = self.expect_ident()?;
602 self.expect(TokenKind::Dot)?;
603 let label = self.expect_ident_or_string()?;
604
605 let target = if self.check(TokenKind::Eq) {
606 self.advance();
607 self.parse_edge_target_literal()?
608 } else if self.check(TokenKind::Arrow) {
609 self.advance();
610 let node = self.expect_ident()?;
611 EdgeTarget::NodeRef(node)
612 } else {
613 return Err(self.error("expected '=' or '->' in graph edge"));
614 };
615
616 Ok(EdgeAst {
617 time_start,
618 time_end,
619 source,
620 label,
621 target,
622 })
623 }
624
625 fn parse_edge_target_literal(&mut self) -> Result<EdgeTarget, ParseError> {
626 if self.check(TokenKind::Minus) {
627 self.advance();
628 if let TokenKind::Number(n) = &self.advance().kind {
629 return Ok(EdgeTarget::Num(-n));
630 }
631 return Err(self.error("expected number after '-'"));
632 }
633 match &self.peek().kind {
634 TokenKind::String(_) => {
635 if let TokenKind::String(s) = &self.advance().kind {
636 Ok(EdgeTarget::Str(s.clone()))
637 } else {
638 unreachable!()
639 }
640 }
641 TokenKind::Number(_) => {
642 if let TokenKind::Number(n) = &self.advance().kind {
643 Ok(EdgeTarget::Num(*n))
644 } else {
645 unreachable!()
646 }
647 }
648 TokenKind::True => {
649 self.advance();
650 Ok(EdgeTarget::Bool(true))
651 }
652 TokenKind::False => {
653 self.advance();
654 Ok(EdgeTarget::Bool(false))
655 }
656 _ => Err(self.error("expected a string, number, or boolean value")),
657 }
658 }
659
660 pub fn peek(&self) -> &Token {
664 &self.tokens[self.pos]
665 }
666
667 pub fn advance(&mut self) -> &Token {
669 let tok = &self.tokens[self.pos];
670 if self.pos + 1 < self.tokens.len() {
671 self.pos += 1;
672 }
673 tok
674 }
675
676 pub fn at_eof(&self) -> bool {
678 matches!(self.tokens[self.pos].kind, TokenKind::Eof)
679 }
680
681 pub fn check(&self, kind: TokenKind) -> bool {
683 std::mem::discriminant(&self.tokens[self.pos].kind) == std::mem::discriminant(&kind)
684 }
685
686 pub fn expect(&mut self, expected: TokenKind) -> Result<&Token, ParseError> {
688 if self.check(expected.clone()) {
689 Ok(self.advance())
690 } else {
691 Err(self.error(&format!("expected {:?}", expected)))
692 }
693 }
694
695 pub fn expect_ident(&mut self) -> Result<String, ParseError> {
698 match &self.peek().kind {
699 TokenKind::Ident(_) => {
700 if let TokenKind::Ident(s) = &self.advance().kind {
701 Ok(s.clone())
702 } else {
703 unreachable!()
704 }
705 }
706 TokenKind::Between => {
708 self.advance();
709 Ok("between".to_string())
710 }
711 TokenKind::After => {
712 self.advance();
713 Ok("after".to_string())
714 }
715 TokenKind::Compose => {
716 self.advance();
717 Ok("compose".to_string())
718 }
719 TokenKind::Sharing => {
720 self.advance();
721 Ok("sharing".to_string())
722 }
723 TokenKind::Concurrent => {
724 self.advance();
725 Ok("concurrent".to_string())
726 }
727 _ => Err(self.error("expected identifier")),
728 }
729 }
730
731 pub fn expect_ident_or_string(&mut self) -> Result<String, ParseError> {
733 match &self.peek().kind {
734 TokenKind::Ident(_) => {
735 if let TokenKind::Ident(s) = &self.advance().kind {
736 Ok(s.clone())
737 } else {
738 unreachable!()
739 }
740 }
741 TokenKind::String(_) => {
742 if let TokenKind::String(s) = &self.advance().kind {
743 Ok(s.clone())
744 } else {
745 unreachable!()
746 }
747 }
748 _ => Err(self.error("expected identifier or string")),
749 }
750 }
751
752 pub fn expect_number(&mut self) -> Result<f64, ParseError> {
754 let negative = if self.check(TokenKind::Minus) {
755 self.advance();
756 true
757 } else {
758 false
759 };
760 match &self.peek().kind {
761 TokenKind::Number(_) => {
762 if let TokenKind::Number(n) = &self.advance().kind {
763 Ok(if negative { -*n } else { *n })
764 } else {
765 unreachable!()
766 }
767 }
768 _ => Err(self.error("expected number")),
769 }
770 }
771
772 pub fn error(&self, msg: &str) -> ParseError {
774 let tok = &self.tokens[self.pos];
775 ParseError {
776 line: tok.line,
777 column: tok.column,
778 span: tok.span(),
779 message: msg.to_string(),
780 }
781 }
782}