1
use std::iter;
2

            
3
use itertools::Itertools;
4
use pest::error::ErrorVariant;
5

            
6
use merc_pest_consume::Error;
7
use merc_pest_consume::match_nodes;
8

            
9
use crate::ActDecl;
10
use crate::ActFrm;
11
use crate::Action;
12
use crate::ActionRHS;
13
use crate::ActionRenameDecl;
14
use crate::ActionRenameRule;
15
use crate::Assignment;
16
use crate::BagElement;
17
use crate::CommExpr;
18
use crate::ComplexSort;
19
use crate::Condition;
20
use crate::ConstructorDecl;
21
use crate::DataExpr;
22
use crate::DataExprUnaryOp;
23
use crate::DataExprUpdate;
24
use crate::Eq;
25
use crate::EqnDecl;
26
use crate::EqnSpec;
27
use crate::FixedPointOperator;
28
use crate::IdDecl;
29
use crate::Mcrl2Parser;
30
use crate::MultiAction;
31
use crate::MultiActionLabel;
32
use crate::PbesEquation;
33
use crate::PbesExpr;
34
use crate::PresEquation;
35
use crate::PresExpr;
36
use crate::ProcDecl;
37
use crate::ProcessExpr;
38
use crate::PropVarDecl;
39
use crate::PropVarInst;
40
use crate::RegFrm;
41
use crate::Rename;
42
use crate::Rule;
43
use crate::SortDecl;
44
use crate::SortExpression;
45
use crate::StateFrm;
46
use crate::StateVarAssignment;
47
use crate::StateVarDecl;
48
use crate::UntypedActionRenameSpec;
49
use crate::UntypedDataSpecification;
50
use crate::UntypedPbes;
51
use crate::UntypedPres;
52
use crate::UntypedProcessSpecification;
53
use crate::UntypedStateFrmSpec;
54
use crate::parse_actfrm;
55
use crate::parse_dataexpr;
56
use crate::parse_pbesexpr;
57
use crate::parse_presexpr;
58
use crate::parse_process_expr;
59
use crate::parse_regfrm;
60
use crate::parse_sortexpr;
61
use crate::parse_sortexpr_primary;
62
use crate::parse_statefrm;
63

            
64
/// Type alias for Errors resulting parsing.
65
pub(crate) type ParseResult<T> = std::result::Result<T, Error<Rule>>;
66
pub(crate) type ParseNode<'i> = merc_pest_consume::Node<'i, Rule, ()>;
67

            
68
/// These functions are used to consume the parse tree generated by the `pest` parser into a syntax tree.
69
///
70
/// Functions that are private are only used by other functions within the module, especially within the `matches_nodes!` macro.
71
/// See `pest_consume` documentation for more details on how to use this macro. The main idea is to apply the consume functions to the children of a parse node whenver they matce the arm.
72
///
73
/// Functions that are `pub(crate)` are used by the pratt parser to consume the parse tree and build the syntax tree with priorities
74
/// and associativity. They are defined in `precedence.rs`.
75
#[merc_pest_consume::parser]
76
impl Mcrl2Parser {
77
    // Although these are not public, they are the main entry points for consuming the parse tree.
78
    pub(crate) fn MCRL2Spec(spec: ParseNode) -> ParseResult<UntypedProcessSpecification> {
79
        let mut action_declarations = Vec::new();
80
        let mut map_declarations = Vec::new();
81
        let mut constructor_declarations = Vec::new();
82
        let mut equation_declarations = Vec::new();
83
        let mut global_variables = Vec::new();
84
        let mut process_declarations = Vec::new();
85
        let mut sort_declarations = Vec::new();
86

            
87
        let mut init = None;
88

            
89
        for child in spec.into_children() {
90
            match child.as_rule() {
91
                Rule::ActSpec => {
92
                    action_declarations.extend(Mcrl2Parser::ActSpec(child)?);
93
                }
94
                Rule::ConsSpec => {
95
                    constructor_declarations.append(&mut Mcrl2Parser::ConsSpec(child)?);
96
                }
97
                Rule::MapSpec => {
98
                    map_declarations.append(&mut Mcrl2Parser::MapSpec(child)?);
99
                }
100
                Rule::GlobVarSpec => {
101
                    global_variables.append(&mut Mcrl2Parser::GlobVarSpec(child)?);
102
                }
103
                Rule::EqnSpec => {
104
                    equation_declarations.append(&mut Mcrl2Parser::EqnSpec(child)?);
105
                }
106
                Rule::ProcSpec => {
107
                    process_declarations.append(&mut Mcrl2Parser::ProcSpec(child)?);
108
                }
109
                Rule::SortSpec => {
110
                    sort_declarations.append(&mut Mcrl2Parser::SortSpec(child)?);
111
                }
112
                Rule::Init => {
113
                    if init.is_some() {
114
                        return Err(Error::new_from_span(
115
                            ErrorVariant::CustomError {
116
                                message: "Multiple init expressions are not allowed".to_string(),
117
                            },
118
                            child.as_span(),
119
                        ));
120
                    }
121

            
122
                    init = Some(Mcrl2Parser::Init(child)?);
123
                }
124
                Rule::EOI => {
125
                    // End of input
126
                    break;
127
                }
128
                _ => {
129
                    unimplemented!("Unexpected rule: {:?}", child.as_rule());
130
                }
131
            }
132
        }
133

            
134
        let data_specification = UntypedDataSpecification {
135
            map_declarations,
136
            constructor_declarations,
137
            equation_declarations,
138
            sort_declarations,
139
        };
140

            
141
        Ok(UntypedProcessSpecification {
142
            data_specification,
143
            global_variables,
144
            action_declarations,
145
            process_declarations,
146
            init,
147
        })
148
    }
149

            
150
    pub fn PbesSpec(spec: ParseNode) -> ParseResult<UntypedPbes> {
151
        let mut data_specification = None;
152
        let mut global_variables = None;
153
        let mut equations = None;
154
        let mut init = None;
155

            
156
        let span = spec.as_span();
157
        for child in spec.into_children() {
158
            match child.as_rule() {
159
                Rule::DataSpec => {
160
                    data_specification = Some(Mcrl2Parser::DataSpec(child)?);
161
                }
162
                Rule::GlobVarSpec => {
163
                    global_variables = Some(Mcrl2Parser::GlobVarSpec(child)?);
164
                }
165
                Rule::PbesEqnSpec => {
166
                    equations = Some(Mcrl2Parser::PbesEqnSpec(child)?);
167
                }
168
                Rule::PbesInit => {
169
                    init = Some(Mcrl2Parser::PbesInit(child)?);
170
                }
171
                Rule::EOI => {
172
                    // End of input
173
                    break;
174
                }
175
                _ => {
176
                    unimplemented!("Unexpected rule: {:?}", child.as_rule());
177
                }
178
            }
179
        }
180

            
181
        Ok(UntypedPbes {
182
            data_specification: data_specification.unwrap_or_default(),
183
            global_variables: global_variables.unwrap_or_default(),
184
            equations: equations.ok_or_else(|| {
185
                Error::new_from_span(
186
                    ErrorVariant::CustomError {
187
                        message: "A PBES requires a (possibly empty) pbes equation section".to_string(),
188
                    },
189
                    span,
190
                )
191
            })?,
192
            init: init.ok_or_else(|| {
193
                Error::new_from_span(
194
                    ErrorVariant::CustomError {
195
                        message: "A PBES requires an init declaration".to_string(),
196
                    },
197
                    span,
198
                )
199
            })?,
200
        })
201
    }
202

            
203
    fn PbesInit(init: ParseNode) -> ParseResult<PropVarInst> {
204
        match_nodes!(init.into_children();
205
            [PropVarInst(inst)] => {
206
                Ok(inst)
207
            }
208
        )
209
    }
210

            
211
    fn PbesEqnSpec(spec: ParseNode) -> ParseResult<Vec<PbesEquation>> {
212
        match_nodes!(spec.into_children();
213
            [PbesEqnDecl(equations)..] => {
214
                Ok(equations.collect())
215
            },
216
        )
217
    }
218

            
219
    fn PbesEqnDecl(decl: ParseNode) -> ParseResult<PbesEquation> {
220
        let span = decl.as_span();
221
        match_nodes!(decl.into_children();
222
            [FixedPointOperator(operator), PropVarDecl(variable), PbesExpr(formula)] => {
223
                Ok(PbesEquation {
224
                    operator,
225
                    variable,
226
                    formula,
227
                    span: span.into(),
228
                })
229
            },
230
        )
231
    }
232

            
233
    fn FixedPointOperator(op: ParseNode) -> ParseResult<FixedPointOperator> {
234
        match op.into_children().next().unwrap().as_rule() {
235
            Rule::FixedPointMu => Ok(FixedPointOperator::Least),
236
            Rule::FixedPointNu => Ok(FixedPointOperator::Greatest),
237
            x => unimplemented!("This is not a fixed point operator: {:?}", x),
238
        }
239
    }
240

            
241
    fn PropVarDecl(decl: ParseNode) -> ParseResult<PropVarDecl> {
242
        let span = decl.as_span();
243
        match_nodes!(decl.into_children();
244
            [Id(identifier), VarsDeclList(params)] => {
245
                Ok(PropVarDecl {
246
                    identifier,
247
                    parameters: params,
248
                    span: span.into(),
249
                })
250
            },
251
            [Id(identifier)] => {
252
                Ok(PropVarDecl {
253
                    identifier,
254
                    parameters: Vec::new(),
255
                    span: span.into(),
256
                })
257
            }
258
        )
259
    }
260

            
261
    pub(crate) fn PropVarInst(inst: ParseNode) -> ParseResult<PropVarInst> {
262
        match_nodes!(inst.into_children();
263
            [Id(identifier)] => {
264
                Ok(PropVarInst {
265
                    identifier,
266
                    arguments: Vec::new(),
267
                })
268
            },
269
            [Id(identifier), DataExprList(arguments)] => {
270
                Ok(PropVarInst {
271
                    identifier,
272
                    arguments,
273
                })
274
            }
275
        )
276
    }
277

            
278
    fn PbesExpr(expr: ParseNode) -> ParseResult<PbesExpr> {
279
        parse_pbesexpr(expr.children().as_pairs().clone())
280
    }
281

            
282
    pub fn PresSpec(spec: ParseNode) -> ParseResult<UntypedPres> {
283
        let mut data_specification = None;
284
        let mut global_variables = None;
285
        let mut equations = None;
286
        let mut init = None;
287

            
288
        let span = spec.as_span();
289
        for child in spec.into_children() {
290
            match child.as_rule() {
291
                Rule::DataSpec => {
292
                    data_specification = Some(Mcrl2Parser::DataSpec(child)?);
293
                }
294
                Rule::GlobVarSpec => {
295
                    global_variables = Some(Mcrl2Parser::GlobVarSpec(child)?);
296
                }
297
                Rule::PresEqnSpec => {
298
                    equations = Some(Mcrl2Parser::PresEqnSpec(child)?);
299
                }
300
                Rule::PbesInit => {
301
                    init = Some(Mcrl2Parser::PbesInit(child)?);
302
                }
303
                Rule::EOI => {
304
                    // End of input
305
                    break;
306
                }
307
                _ => {
308
                    unimplemented!("Unexpected rule: {:?}", child.as_rule());
309
                }
310
            }
311
        }
312

            
313
        Ok(UntypedPres {
314
            data_specification: data_specification.unwrap_or_default(),
315
            global_variables: global_variables.unwrap_or_default(),
316
            equations: equations.ok_or_else(|| {
317
                Error::new_from_span(
318
                    ErrorVariant::CustomError {
319
                        message: "A PRES requires a (possibly empty) pres equation section".to_string(),
320
                    },
321
                    span,
322
                )
323
            })?,
324
            init: init.ok_or_else(|| {
325
                Error::new_from_span(
326
                    ErrorVariant::CustomError {
327
                        message: "A PRES requires an init declaration".to_string(),
328
                    },
329
                    span,
330
                )
331
            })?,
332
        })
333
    }
334

            
335
    fn PresEqnSpec(spec: ParseNode) -> ParseResult<Vec<PresEquation>> {
336
        match_nodes!(spec.into_children();
337
            [PresEqnDecl(equations)..] => {
338
                Ok(equations.collect())
339
            },
340
        )
341
    }
342

            
343
    fn PresEqnDecl(decl: ParseNode) -> ParseResult<PresEquation> {
344
        let span = decl.as_span();
345
        match_nodes!(decl.into_children();
346
            [FixedPointOperator(operator), PropVarDecl(variable), PresExpr(formula)] => {
347
                Ok(PresEquation {
348
                    operator,
349
                    variable,
350
                    formula,
351
                    span: span.into(),
352
                })
353
            },
354
        )
355
    }
356

            
357
    fn PresExpr(expr: ParseNode) -> ParseResult<PresExpr> {
358
        parse_presexpr(expr.children().as_pairs().clone())
359
    }
360

            
361
    fn ActSpec(spec: ParseNode) -> ParseResult<Vec<ActDecl>> {
362
        match_nodes!(spec.into_children();
363
            [ActDecl(decls)..] => {
364
                Ok(decls.flatten().collect())
365
            },
366
        )
367
    }
368

            
369
    fn ActDecl(decl: ParseNode) -> ParseResult<Vec<ActDecl>> {
370
        let span = decl.as_span();
371
        match_nodes!(decl.into_children();
372
            [IdList(identifiers)] => {
373
12060
                Ok(identifiers.iter().map(|name| ActDecl { identifier: name.clone(), args: Vec::new(), span: span.into() }).collect())
374
            },
375
            [IdList(identifiers), SortProduct(args)] => {
376
34820
                Ok(identifiers.iter().map(|name| ActDecl { identifier: name.clone(), args: args.clone(), span: span.into() }).collect())
377
            },
378
        )
379
    }
380

            
381
    fn SortProduct(sort: ParseNode) -> ParseResult<Vec<SortExpression>> {
382
        let mut iter = sort.into_children();
383

            
384
        // An expression of the shape SortExprPrimary ~ (SortExprProduct ~ SortExprPrimary)*
385
        let mut result = vec![parse_sortexpr_primary(iter.next().unwrap().as_pair().clone())?];
386

            
387
        for mut chunk in &iter.chunks(2) {
388
            if chunk.next().unwrap().as_rule() == Rule::SortExprProduct {
389
                let sort = parse_sortexpr_primary(chunk.next().unwrap().as_pair().clone())?;
390
                result.push(sort);
391
            }
392
        }
393

            
394
        Ok(result)
395
    }
396

            
397
    fn GlobVarSpec(spec: ParseNode) -> ParseResult<Vec<IdDecl>> {
398
        match_nodes!(spec.into_children();
399
            [VarsDeclList(vars)] => {
400
                Ok(vars)
401
            }
402
        )
403
    }
404

            
405
    fn SortExprPrimary(sort: ParseNode) -> ParseResult<SortExpression> {
406
        parse_sortexpr(sort.children().as_pairs().clone())
407
    }
408

            
409
    pub(crate) fn DataSpec(spec: ParseNode) -> ParseResult<UntypedDataSpecification> {
410
        let mut map_declarations = Vec::new();
411
        let mut equation_declarations = Vec::new();
412
        let mut constructor_declarations = Vec::new();
413
        let mut sort_declarations = Vec::new();
414

            
415
        for child in spec.into_children() {
416
            match child.as_rule() {
417
                Rule::ConsSpec => {
418
                    constructor_declarations.append(&mut Mcrl2Parser::ConsSpec(child)?);
419
                }
420
                Rule::MapSpec => {
421
                    map_declarations.append(&mut Mcrl2Parser::MapSpec(child)?);
422
                }
423
                Rule::EqnSpec => {
424
                    equation_declarations.append(&mut Mcrl2Parser::EqnSpec(child)?);
425
                }
426
                Rule::SortSpec => {
427
                    sort_declarations.append(&mut Mcrl2Parser::SortSpec(child)?);
428
                }
429
                Rule::EOI => {
430
                    // End of input
431
                    break;
432
                }
433
                _ => {
434
                    unimplemented!("Unexpected rule: {:?}", child.as_rule());
435
                }
436
            }
437
        }
438

            
439
        Ok(UntypedDataSpecification {
440
            map_declarations,
441
            equation_declarations,
442
            constructor_declarations,
443
            sort_declarations,
444
        })
445
    }
446

            
447
    pub fn ActionRenameSpec(spec: ParseNode) -> ParseResult<UntypedActionRenameSpec> {
448
        let mut map_declarations = Vec::new();
449
        let mut equation_declarations = Vec::new();
450
        let mut constructor_declarations = Vec::new();
451
        let mut sort_declarations = Vec::new();
452
        let mut action_declarations = Vec::new();
453
        let mut rename_declarations = Vec::new();
454

            
455
        for child in spec.into_children() {
456
            match child.as_rule() {
457
                Rule::ConsSpec => {
458
                    constructor_declarations.append(&mut Mcrl2Parser::ConsSpec(child)?);
459
                }
460
                Rule::MapSpec => {
461
                    map_declarations.append(&mut Mcrl2Parser::MapSpec(child)?);
462
                }
463
                Rule::EqnSpec => {
464
                    equation_declarations.append(&mut Mcrl2Parser::EqnSpec(child)?);
465
                }
466
                Rule::SortSpec => {
467
                    sort_declarations.append(&mut Mcrl2Parser::SortSpec(child)?);
468
                }
469
                Rule::ActSpec => {
470
                    action_declarations.append(&mut Mcrl2Parser::ActSpec(child)?);
471
                }
472
                Rule::ActionRenameRuleSpec => {
473
                    rename_declarations.append(&mut Mcrl2Parser::ActionRenameRuleSpec(child)?)
474
                }
475
                Rule::EOI => {
476
                    // End of input
477
                    break;
478
                }
479
                _ => {
480
                    unimplemented!("Unexpected rule: {:?}", child.as_rule());
481
                }
482
            }
483
        }
484

            
485
        let data_specification = UntypedDataSpecification {
486
            map_declarations,
487
            equation_declarations,
488
            constructor_declarations,
489
            sort_declarations,
490
        };
491

            
492
        Ok(UntypedActionRenameSpec {
493
            data_specification,
494
            action_declarations,
495
            rename_declarations,
496
        })
497
    }
498

            
499
    pub(crate) fn StateFrmId(id: ParseNode) -> ParseResult<StateFrm> {
500
        match_nodes!(id.into_children();
501
            [Id(identifier)] => {
502
                Ok(StateFrm::Id(identifier, Vec::new()))
503
            },
504
            [Id(identifier), DataExprList(expressions)] => {
505
                Ok(StateFrm::Id(identifier, expressions))
506
            },
507
        )
508
    }
509

            
510
    fn MapSpec(spec: ParseNode) -> ParseResult<Vec<IdDecl>> {
511
        match_nodes!(spec.into_children();
512
            [IdsDecl(decls)..] => {
513
                Ok(decls.flatten().collect())
514
            }
515
        )
516
    }
517

            
518
    fn SortSpec(spec: ParseNode) -> ParseResult<Vec<SortDecl>> {
519
        match_nodes!(spec.into_children();
520
            [SortDecl(decls)..] => {
521
                Ok(decls.flatten().collect())
522
            }
523
        )
524
    }
525

            
526
    fn SortDecl(decl: ParseNode) -> ParseResult<Vec<SortDecl>> {
527
        let span = decl.as_span();
528

            
529
        match_nodes!(decl.into_children();
530
            [IdAt(identifier), SortExpr(expr)] => {
531
                Ok(vec![SortDecl::new(identifier, Some(expr), span.into())])
532
            },
533
            [IdList(ids)] => {
534
160
                Ok(ids.iter().map(|identifier| SortDecl::new(identifier.clone(), None, span.into())).collect())
535
            },
536
            [IdsDecl(decl)] => {
537
                Ok(decl.iter().map(|element| SortDecl::new(element.identifier.clone(), Some(element.sort.clone()), span.into())).collect())
538
            }
539
        )
540
    }
541

            
542
    fn ConsSpec(spec: ParseNode) -> ParseResult<Vec<IdDecl>> {
543
        match_nodes!(spec.into_children();
544
            [IdsDecl(decls)..] => {
545
                Ok(decls.flatten().collect())
546
            }
547
        )
548
    }
549

            
550
    fn Init(init: ParseNode) -> ParseResult<ProcessExpr> {
551
        match_nodes!(init.into_children();
552
            [ProcExpr(expr)] => {
553
                Ok(expr)
554
            }
555
        )
556
    }
557

            
558
    fn ProcSpec(spec: ParseNode) -> ParseResult<Vec<ProcDecl>> {
559
        match_nodes!(spec.into_children();
560
            [ProcDecl(decls)..] => {
561
                Ok(decls.collect())
562
            },
563
        )
564
    }
565

            
566
    fn ProcDecl(decl: ParseNode) -> ParseResult<ProcDecl> {
567
        let span = decl.as_span();
568
        match_nodes!(decl.into_children();
569
            [Id(identifier), VarsDeclList(params), ProcExpr(body)] => {
570
                Ok(ProcDecl {
571
                    identifier,
572
                    params,
573
                    body,
574
                    span: span.into(),
575
                })
576
            },
577
            [Id(identifier), ProcExpr(body)] => {
578
                Ok(ProcDecl {
579
                    identifier,
580
                    params: Vec::new(),
581
                    body,
582
                    span: span.into(),
583
                })
584
            }
585
        )
586
    }
587

            
588
    pub(crate) fn ProcExprAt(input: ParseNode) -> ParseResult<DataExpr> {
589
        match_nodes!(input.into_children();
590
            [DataExprUnit(expr)] => {
591
                Ok(expr)
592
            },
593
        )
594
    }
595

            
596
    pub(crate) fn StateFrmExists(input: ParseNode) -> ParseResult<Vec<IdDecl>> {
597
        match_nodes!(input.into_children();
598
            [VarsDeclList(variables)] => {
599
                Ok(variables)
600
            },
601
        )
602
    }
603

            
604
    pub(crate) fn StateFrmForall(input: ParseNode) -> ParseResult<Vec<IdDecl>> {
605
        match_nodes!(input.into_children();
606
            [VarsDeclList(variables)] => {
607
                Ok(variables)
608
            },
609
        )
610
    }
611

            
612
    pub(crate) fn StateFrmMu(input: ParseNode) -> ParseResult<StateVarDecl> {
613
        match_nodes!(input.into_children();
614
            [StateVarDecl(variable)] => {
615
                Ok(variable)
616
            },
617
        )
618
    }
619

            
620
    pub(crate) fn StateFrmNu(input: ParseNode) -> ParseResult<StateVarDecl> {
621
        match_nodes!(input.into_children();
622
            [StateVarDecl(variable)] => {
623
                Ok(variable)
624
            },
625
        )
626
    }
627

            
628
    pub(crate) fn ActFrmExists(input: ParseNode) -> ParseResult<Vec<IdDecl>> {
629
        match_nodes!(input.into_children();
630
            [VarsDeclList(variables)] => {
631
                Ok(variables)
632
            },
633
        )
634
    }
635

            
636
    pub(crate) fn ActFrmForall(input: ParseNode) -> ParseResult<Vec<IdDecl>> {
637
        match_nodes!(input.into_children();
638
            [VarsDeclList(variables)] => {
639
                Ok(variables)
640
            },
641
        )
642
    }
643

            
644
    pub(crate) fn DataExpr(expr: ParseNode) -> ParseResult<DataExpr> {
645
        parse_dataexpr(expr.children().as_pairs().clone())
646
    }
647

            
648
    pub(crate) fn DataExprUnit(expr: ParseNode) -> ParseResult<DataExpr> {
649
        parse_dataexpr(expr.children().as_pairs().clone())
650
    }
651

            
652
    pub(crate) fn DataValExpr(expr: ParseNode) -> ParseResult<DataExpr> {
653
        match_nodes!(expr.into_children();
654
            [DataExpr(expr)] => {
655
                Ok(expr)
656
            },
657
        )
658
    }
659

            
660
    pub(crate) fn DataExprUpdate(expr: ParseNode) -> ParseResult<DataExprUpdate> {
661
        match_nodes!(expr.into_children();
662
            [DataExpr(expr), DataExpr(update)] => {
663
                Ok(DataExprUpdate { expr, update })
664
            },
665
        )
666
    }
667

            
668
    pub(crate) fn DataExprApplication(expr: ParseNode) -> ParseResult<Vec<DataExpr>> {
669
        match_nodes!(expr.into_children();
670
            [DataExprList(expressions)] => {
671
                Ok(expressions)
672
            },
673
        )
674
    }
675

            
676
    pub(crate) fn DataExprWhr(expr: ParseNode) -> ParseResult<Vec<Assignment>> {
677
        match_nodes!(expr.into_children();
678
            [AssignmentList(assignments)] => {
679
                Ok(assignments)
680
            },
681
        )
682
    }
683

            
684
    pub(crate) fn AssignmentList(assignments: ParseNode) -> ParseResult<Vec<Assignment>> {
685
        match_nodes!(assignments.into_children();
686
            [Assignment(assignment)] => {
687
                Ok(vec![assignment])
688
            },
689
            [Assignment(assignment)..] => {
690
                Ok(assignment.collect())
691
            },
692
        )
693
    }
694

            
695
    pub(crate) fn Assignment(assignment: ParseNode) -> ParseResult<Assignment> {
696
        match_nodes!(assignment.into_children();
697
            [IdAt(identifier), DataExpr(expr)] => {
698
                Ok(Assignment { identifier, expr })
699
            },
700
        )
701
    }
702

            
703
    pub(crate) fn DataExprSize(expr: ParseNode) -> ParseResult<DataExpr> {
704
        match_nodes!(expr.into_children();
705
            [DataExpr(expr)] => {
706
                Ok(DataExpr::Unary { op: DataExprUnaryOp::Size, expr: Box::new(expr) })
707
            },
708
        )
709
    }
710

            
711
    fn DataExprList(expr: ParseNode) -> ParseResult<Vec<DataExpr>> {
712
        match_nodes!(expr.into_children();
713
            [DataExpr(expr)] => {
714
                Ok(vec![expr])
715
            },
716
            [DataExpr(expr)..] => {
717
                Ok(expr.collect())
718
            },
719
        )
720
    }
721

            
722
    fn VarSpec(vars: ParseNode) -> ParseResult<Vec<IdDecl>> {
723
        match_nodes!(vars.into_children();
724
            [VarsDeclList(ids)..] => {
725
                Ok(ids.flatten().collect())
726
            },
727
        )
728
    }
729

            
730
    pub(crate) fn VarsDeclList(vars: ParseNode) -> ParseResult<Vec<IdDecl>> {
731
        match_nodes!(vars.into_children();
732
            [VarsDecl(decl)..] => {
733
                Ok(decl.flatten().collect())
734
            },
735
        )
736
    }
737

            
738
    fn VarsDecl(decl: ParseNode) -> ParseResult<Vec<IdDecl>> {
739
        let mut vars = Vec::new();
740

            
741
        let span = decl.as_span();
742
        match_nodes!(decl.into_children();
743
            [IdList(identifier), SortExpr(sort)] => {
744
                for id in identifier {
745
                    vars.push(IdDecl::new(id, sort.clone(), span.into()));
746
                }
747
            },
748
        );
749

            
750
        Ok(vars)
751
    }
752

            
753
    pub(crate) fn SortExpr(expr: ParseNode) -> ParseResult<SortExpression> {
754
        parse_sortexpr(expr.children().as_pairs().clone())
755
    }
756

            
757
    pub(crate) fn Id(identifier: ParseNode) -> ParseResult<String> {
758
        Ok(identifier.as_str().to_string())
759
    }
760

            
761
    pub(crate) fn IdAt(identifier: ParseNode) -> ParseResult<String> {
762
        Ok(identifier.as_str().to_string())
763
    }
764

            
765
    pub(crate) fn IdList(identifiers: ParseNode) -> ParseResult<Vec<String>> {
766
        match_nodes!(identifiers.into_children();
767
            [IdAt(ids)..] => {
768
                Ok(ids.collect())
769
            },
770
        )
771
    }
772

            
773
    fn IdInfix(identifier: ParseNode) -> ParseResult<String> {
774
        Ok(identifier.as_str().to_string())
775
    }
776

            
777
    fn IdInfixList(identifiers: ParseNode) -> ParseResult<Vec<String>> {
778
        match_nodes!(identifiers.into_children();
779
            [IdInfix(ids)..] => {
780
                Ok(ids.collect())
781
            },
782
        )
783
    }
784

            
785
    // Complex sorts
786
    pub(crate) fn SortExprList(inner: ParseNode) -> ParseResult<SortExpression> {
787
        Ok(SortExpression::Complex(
788
            ComplexSort::List,
789
            Box::new(parse_sortexpr(inner.children().as_pairs().clone())?),
790
        ))
791
    }
792

            
793
    pub(crate) fn SortExprSet(inner: ParseNode) -> ParseResult<SortExpression> {
794
        Ok(SortExpression::Complex(
795
            ComplexSort::Set,
796
            Box::new(parse_sortexpr(inner.children().as_pairs().clone())?),
797
        ))
798
    }
799

            
800
    pub(crate) fn SortExprBag(inner: ParseNode) -> ParseResult<SortExpression> {
801
        Ok(SortExpression::Complex(
802
            ComplexSort::Bag,
803
            Box::new(parse_sortexpr(inner.children().as_pairs().clone())?),
804
        ))
805
    }
806

            
807
    pub(crate) fn SortExprFSet(inner: ParseNode) -> ParseResult<SortExpression> {
808
        Ok(SortExpression::Complex(
809
            ComplexSort::FSet,
810
            Box::new(parse_sortexpr(inner.children().as_pairs().clone())?),
811
        ))
812
    }
813

            
814
    pub(crate) fn SortExprFBag(inner: ParseNode) -> ParseResult<SortExpression> {
815
        Ok(SortExpression::Complex(
816
            ComplexSort::FBag,
817
            Box::new(parse_sortexpr(inner.children().as_pairs().clone())?),
818
        ))
819
    }
820

            
821
    pub(crate) fn SortExprStruct(inner: ParseNode) -> ParseResult<SortExpression> {
822
        match_nodes!(inner.into_children();
823
            [ConstrDeclList(inner)] => {
824
                Ok(SortExpression::Struct { inner })
825
            },
826
        )
827
    }
828

            
829
    pub(crate) fn ConstrDeclList(input: ParseNode) -> ParseResult<Vec<ConstructorDecl>> {
830
        match_nodes!(input.into_children();
831
            [ConstrDecl(decl)..] => {
832
                Ok(decl.collect())
833
            },
834
        )
835
    }
836

            
837
    pub(crate) fn ProjDeclList(input: ParseNode) -> ParseResult<Vec<(Option<String>, SortExpression)>> {
838
        match_nodes!(input.into_children();
839
            [ProjDecl(decl)..] => {
840
                Ok(decl.collect())
841
            },
842
        )
843
    }
844

            
845
    pub(crate) fn ConstrDecl(input: ParseNode) -> ParseResult<ConstructorDecl> {
846
        match_nodes!(input.into_children();
847
            [IdAt(name)] => {
848
                Ok(ConstructorDecl { name, args: Vec::new(), projection: None })
849
            },
850
            [IdAt(name), IdAt(projection)] => {
851
                Ok(ConstructorDecl { name, args: Vec::new(), projection: Some(projection)  })
852
            },
853
            [IdAt(name), ProjDeclList(args)] => {
854
                Ok(ConstructorDecl { name, args, projection: None })
855
            },
856
            [IdAt(name), ProjDeclList(args), IdAt(projection)] => {
857
                Ok(ConstructorDecl { name, args, projection: Some(projection) })
858
            },
859
        )
860
    }
861

            
862
    pub(crate) fn ProjDecl(input: ParseNode) -> ParseResult<(Option<String>, SortExpression)> {
863
        match_nodes!(input.into_children();
864
            [SortExpr(sort)] => {
865
                Ok((None, sort))
866
            },
867
            [Id(name), SortExpr(sort)] => {
868
                Ok((Some(name), sort))
869
            },
870
        )
871
    }
872

            
873
    pub(crate) fn DataExprListEnum(input: ParseNode) -> ParseResult<DataExpr> {
874
        match_nodes!(input.into_children();
875
            [DataExprList(expressions)] => {
876
                Ok(DataExpr::List(expressions))
877
            },
878
        )
879
    }
880

            
881
    pub(crate) fn DataExprBagEnum(input: ParseNode) -> ParseResult<DataExpr> {
882
        match_nodes!(input.into_children();
883
            [BagEnumEltList(elements)] => {
884
                Ok(DataExpr::Bag(elements))
885
            },
886
        )
887
    }
888

            
889
    fn BagEnumEltList(input: ParseNode) -> ParseResult<Vec<BagElement>> {
890
        match_nodes!(input.into_children();
891
            [BagEnumElt(elements)..] => {
892
                Ok(elements.collect())
893
            },
894
        )
895
    }
896

            
897
    fn BagEnumElt(input: ParseNode) -> ParseResult<BagElement> {
898
        match_nodes!(input.into_children();
899
            [DataExpr(expr), DataExpr(multiplicity)] => {
900
                Ok(BagElement { expr, multiplicity })
901
            },
902
        )
903
    }
904

            
905
    pub(crate) fn DataExprSetEnum(input: ParseNode) -> ParseResult<DataExpr> {
906
        match_nodes!(input.into_children();
907
            [DataExprList(expressions)] => {
908
                Ok(DataExpr::Set(expressions))
909
            },
910
        )
911
    }
912

            
913
    pub(crate) fn DataExprSetBagComp(input: ParseNode) -> ParseResult<DataExpr> {
914
        match_nodes!(input.into_children();
915
            [VarDecl(variable), DataExpr(predicate)] => {
916
                Ok(DataExpr::SetBagComp { variable, predicate: Box::new(predicate) })
917
            },
918
        )
919
    }
920

            
921
    pub(crate) fn Number(input: ParseNode) -> ParseResult<DataExpr> {
922
        Ok(DataExpr::Number(input.as_str().into()))
923
    }
924

            
925
    fn VarDecl(decl: ParseNode) -> ParseResult<IdDecl> {
926
        let span = decl.as_span();
927
        match_nodes!(decl.into_children();
928
            [IdAt(identifier), SortExpr(sort)] => {
929
                Ok(IdDecl::new(identifier, sort, span.into()))
930
            },
931
        )
932
    }
933

            
934
    pub(crate) fn DataExprLambda(input: ParseNode) -> ParseResult<Vec<IdDecl>> {
935
        match_nodes!(input.into_children();
936
            [VarsDeclList(vars)] => {
937
                Ok(vars)
938
            },
939
        )
940
    }
941

            
942
    pub(crate) fn DataExprForall(input: ParseNode) -> ParseResult<Vec<IdDecl>> {
943
        match_nodes!(input.into_children();
944
            [VarsDeclList(vars)] => {
945
                Ok(vars)
946
            },
947
        )
948
    }
949

            
950
    pub(crate) fn DataExprExists(input: ParseNode) -> ParseResult<Vec<IdDecl>> {
951
        match_nodes!(input.into_children();
952
            [VarsDeclList(vars)] => {
953
                Ok(vars)
954
            },
955
        )
956
    }
957

            
958
    pub(crate) fn ActFrm(input: ParseNode) -> ParseResult<ActFrm> {
959
        parse_actfrm(input.children().as_pairs().clone())
960
    }
961

            
962
    pub(crate) fn ActIdSet(actions: ParseNode) -> ParseResult<Vec<String>> {
963
        match_nodes!(actions.into_children();
964
            [IdList(list)] => {
965
                Ok(list)
966
            },
967
        )
968
    }
969

            
970
    fn MultActId(actions: ParseNode) -> ParseResult<MultiActionLabel> {
971
        match_nodes!(actions.into_children();
972
            [Id(action), Id(actions)..] => {
973
                Ok(MultiActionLabel { actions: iter::once(action).chain(actions).collect() })
974
            },
975
        )
976
    }
977

            
978
    fn MultActIdList(actions: ParseNode) -> ParseResult<Vec<MultiActionLabel>> {
979
        match_nodes!(actions.into_children();
980
            [MultActId(action), MultActId(actions)..] => {
981
                Ok(iter::once(action).chain(actions).collect())
982
            },
983
        )
984
    }
985

            
986
    pub(crate) fn MultActIdSet(actions: ParseNode) -> ParseResult<Vec<MultiActionLabel>> {
987
        match_nodes!(actions.into_children();
988
            [MultActIdList(list)] => {
989
                Ok(list)
990
            },
991
        )
992
    }
993

            
994
    fn ProcExpr(input: ParseNode) -> ParseResult<ProcessExpr> {
995
        parse_process_expr(input.children().as_pairs().clone())
996
    }
997

            
998
    fn ProcExprNoIf(input: ParseNode) -> ParseResult<ProcessExpr> {
999
        parse_process_expr(input.children().as_pairs().clone())
    }
    pub(crate) fn ProcExprId(input: ParseNode) -> ParseResult<ProcessExpr> {
        match_nodes!(input.into_children();
            [Id(identifier)] => {
                Ok(ProcessExpr::Id(identifier, Vec::new()))
            },
            [Id(identifier), AssignmentList(assignments)] => {
                Ok(ProcessExpr::Id(identifier, assignments))
            },
        )
    }
    pub(crate) fn ProcExprBlock(input: ParseNode) -> ParseResult<ProcessExpr> {
        match_nodes!(input.into_children();
            [ActIdSet(actions), ProcExpr(expr)] => {
                Ok(ProcessExpr::Block {
                    actions,
                    operand: Box::new(expr),
                })
            },
        )
    }
    pub(crate) fn ProcExprIf(input: ParseNode) -> ParseResult<DataExpr> {
        match_nodes!(input.into_children();
            [DataExpr(condition)] => {
                Ok(condition)
            },
        )
    }
    pub(crate) fn ProcExprIfThen(input: ParseNode) -> ParseResult<(DataExpr, ProcessExpr)> {
        match_nodes!(input.into_children();
            [DataExpr(condition), ProcExprNoIf(expr)] => {
                Ok((condition, expr))
            },
        )
    }
    pub(crate) fn ProcExprAllow(input: ParseNode) -> ParseResult<ProcessExpr> {
        match_nodes!(input.into_children();
            [MultActIdSet(actions), ProcExpr(expr)] => {
                Ok(ProcessExpr::Allow {
                    actions,
                    operand: Box::new(expr),
                })
            },
        )
    }
    pub(crate) fn ProcExprHide(input: ParseNode) -> ParseResult<ProcessExpr> {
        match_nodes!(input.into_children();
            [ActIdSet(actions), ProcExpr(expr)] => {
                Ok(ProcessExpr::Hide {
                    actions,
                    operand: Box::new(expr),
                })
            },
        )
    }
    fn ActionList(actions: ParseNode) -> ParseResult<Vec<Action>> {
        match_nodes!(actions.into_children();
            [Action(action), Action(actions)..] => {
                Ok(iter::once(action).chain(actions).collect())
            },
        )
    }
    fn MultiActTau(_input: ParseNode) -> ParseResult<()> {
        Ok(())
    }
    fn ProcExprDelta(_input: ParseNode) -> ParseResult<()> {
        Ok(())
    }
    pub(crate) fn MultAct(input: ParseNode) -> ParseResult<MultiAction> {
        match_nodes!(input.into_children();
            [MultiActTau(_)] => {
                Ok(MultiAction { actions: Vec::new() })
            },
            [ActionList(actions)] => {
                Ok(MultiAction { actions })
            },
        )
    }
    fn CommExpr(action: ParseNode) -> ParseResult<CommExpr> {
        match_nodes!(action.into_children();
            [Id(id), MultActId(multiact), Id(to)] => {
                let mut actions = vec![id];
                actions.extend(multiact.actions);
                Ok(CommExpr {
                    from: MultiActionLabel { actions },
                    to
                })
            },
        )
    }
    fn CommExprList(actions: ParseNode) -> ParseResult<Vec<CommExpr>> {
        match_nodes!(actions.into_children();
            [CommExpr(action), CommExpr(actions)..] => {
                Ok(iter::once(action).chain(actions).collect())
            },
        )
    }
    pub(crate) fn CommExprSet(actions: ParseNode) -> ParseResult<Vec<CommExpr>> {
        match_nodes!(actions.into_children();
            [CommExprList(list)] => {
                Ok(list)
            },
        )
    }
    pub(crate) fn ProcExprRename(input: ParseNode) -> ParseResult<ProcessExpr> {
        match_nodes!(input.into_children();
            [RenExprSet(renames), ProcExpr(expr)] => {
                Ok(ProcessExpr::Rename {
                    renames,
                    operand: Box::new(expr),
                })
            },
        )
    }
    pub(crate) fn ProcExprComm(input: ParseNode) -> ParseResult<ProcessExpr> {
        match_nodes!(input.into_children();
            [CommExprSet(comm), ProcExpr(expr)] => {
                Ok(ProcessExpr::Comm {
                    comm,
                    operand: Box::new(expr),
                })
            },
        )
    }
    pub(crate) fn Action(input: ParseNode) -> ParseResult<Action> {
        match_nodes!(input.into_children();
            [Id(id), DataExprList(args)] => {
                Ok(Action { id, args })
            },
            [Id(id)] => {
                Ok(Action { id, args: Vec::new() })
            },
        )
    }
    fn RenExprSet(renames: ParseNode) -> ParseResult<Vec<Rename>> {
        match_nodes!(renames.into_children();
            [RenExprList(renames)] => {
                Ok(renames)
            },
        )
    }
    fn RenExprList(renames: ParseNode) -> ParseResult<Vec<Rename>> {
        match_nodes!(renames.into_children();
            [RenExpr(renames)..] => {
                Ok(renames.collect())
            },
        )
    }
    fn RenExpr(renames: ParseNode) -> ParseResult<Rename> {
        match_nodes!(renames.into_children();
            [Id(from), Id(to)] => {
                Ok(Rename { from, to })
            },
        )
    }
    pub(crate) fn ProcExprSum(input: ParseNode) -> ParseResult<Vec<IdDecl>> {
        match_nodes!(input.into_children();
            [VarsDeclList(variables)] => {
                Ok(variables)
            },
        )
    }
    pub(crate) fn ProcExprDist(input: ParseNode) -> ParseResult<(Vec<IdDecl>, DataExpr)> {
        match_nodes!(input.into_children();
            [VarsDeclList(variables), DataExpr(expr)] => {
                Ok((variables, expr))
            },
        )
    }
    pub(crate) fn StateFrmDelay(input: ParseNode) -> ParseResult<StateFrm> {
        // The `@`-time argument is optional, so there may be zero or one child.
        match input.into_children().next() {
            Some(child) => Ok(StateFrm::Delay(Some(Mcrl2Parser::DataExpr(child)?))),
            None => Ok(StateFrm::Delay(None)),
        }
    }
    pub(crate) fn StateFrmYaled(input: ParseNode) -> ParseResult<StateFrm> {
        // The `@`-time argument is optional, so there may be zero or one child.
        match input.into_children().next() {
            Some(child) => Ok(StateFrm::Yaled(Some(Mcrl2Parser::DataExpr(child)?))),
            None => Ok(StateFrm::Yaled(None)),
        }
    }
    pub(crate) fn StateFrmNegation(input: ParseNode) -> ParseResult<StateFrm> {
        match_nodes!(input.into_children();
            [StateFrm(state)] => {
                Ok(StateFrm::Unary { op: crate::StateFrmUnaryOp::Negation, expr: Box::new(state) })
            },
        )
    }
    pub(crate) fn StateFrmLeftConstantMultiply(input: ParseNode) -> ParseResult<DataExpr> {
        match_nodes!(input.into_children();
            [DataValExpr(expr)] => {
                Ok(expr)
            },
        )
    }
    pub(crate) fn StateFrmRightConstantMultiply(input: ParseNode) -> ParseResult<DataExpr> {
        match_nodes!(input.into_children();
            [DataValExpr(expr)] => {
                Ok(expr)
            },
        )
    }
    pub(crate) fn StateFrmDiamond(input: ParseNode) -> ParseResult<RegFrm> {
        match_nodes!(input.into_children();
            [RegFrm(formula)] => {
                Ok(formula)
            },
        )
    }
    pub(crate) fn StateFrmBox(input: ParseNode) -> ParseResult<RegFrm> {
        match_nodes!(input.into_children();
            [RegFrm(formula)] => {
                Ok(formula)
            },
        )
    }
    pub(crate) fn StateFrmSpec(spec: ParseNode) -> ParseResult<UntypedStateFrmSpec> {
        let mut map_declarations = Vec::new();
        let mut equation_declarations = Vec::new();
        let mut constructor_declarations = Vec::new();
        let mut sort_declarations = Vec::new();
        let mut action_declarations = Vec::new();
        let mut form_spec = None;
        let span = spec.as_span();
        for child in spec.into_children() {
            match child.as_rule() {
                Rule::StateFrmSpecElt => {
                    let element = child
                        .into_children()
                        .next()
                        .expect("StateFrmSpecElt has exactly one child");
                    match element.as_rule() {
                        Rule::ConsSpec => {
                            constructor_declarations.append(&mut Mcrl2Parser::ConsSpec(element)?);
                        }
                        Rule::MapSpec => {
                            map_declarations.append(&mut Mcrl2Parser::MapSpec(element)?);
                        }
                        Rule::EqnSpec => {
                            equation_declarations.append(&mut Mcrl2Parser::EqnSpec(element)?);
                        }
                        Rule::SortSpec => {
                            sort_declarations.append(&mut Mcrl2Parser::SortSpec(element)?);
                        }
                        Rule::ActSpec => {
                            action_declarations.append(&mut Mcrl2Parser::ActSpec(element)?);
                        }
                        _ => {
                            unimplemented!("Unexpected rule in StateFrmSpecElt: {:?}", element.as_rule());
                        }
                    }
                }
                Rule::StateFrm => {
                    if form_spec.is_some() {
                        return Err(Error::new_from_span(
                            ErrorVariant::CustomError {
                                message: "Multiple state formula specifications are not allowed".to_string(),
                            },
                            child.as_span(),
                        ));
                    }
                    form_spec = Some(Mcrl2Parser::StateFrm(child)?);
                }
                Rule::FormSpec => {
                    if form_spec.is_some() {
                        return Err(Error::new_from_span(
                            ErrorVariant::CustomError {
                                message: "Multiple state formula specifications are not allowed".to_string(),
                            },
                            child.as_span(),
                        ));
                    }
                    form_spec = Some(Mcrl2Parser::FormSpec(child)?);
                }
                Rule::EOI => {
                    // End of input
                    break;
                }
                _ => {
                    unimplemented!("Unexpected rule: {:?}", child.as_rule());
                }
            }
        }
        let data_specification = UntypedDataSpecification {
            map_declarations,
            equation_declarations,
            constructor_declarations,
            sort_declarations,
        };
        Ok(UntypedStateFrmSpec {
            data_specification,
            action_declarations,
            formula: form_spec.ok_or(Error::new_from_span(
                ErrorVariant::CustomError {
                    message: "No state formula found in the state formula specification".to_string(),
                },
                span,
            ))?,
        })
    }
    pub(crate) fn PbesExprForall(input: ParseNode) -> ParseResult<Vec<IdDecl>> {
        match_nodes!(input.into_children();
            [VarsDeclList(vars)] => {
                Ok(vars)
            },
        )
    }
    pub(crate) fn PbesExprExists(input: ParseNode) -> ParseResult<Vec<IdDecl>> {
        match_nodes!(input.into_children();
            [VarsDeclList(vars)] => {
                Ok(vars)
            },
        )
    }
    pub(crate) fn PresExprEqinf(input: ParseNode) -> ParseResult<PresExpr> {
        match_nodes!(input.into_children();
            [PresExpr(body)] => {
                Ok(PresExpr::Equal {
                    eq: Eq::EqInf,
                    body: Box::new(body),
                })
            },
        )
    }
    pub(crate) fn PresExprEqninf(input: ParseNode) -> ParseResult<PresExpr> {
        match_nodes!(input.into_children();
            [PresExpr(body)] => {
                Ok(PresExpr::Equal {
                    eq: Eq::EqnInf,
                    body: Box::new(body),
                })
            },
        )
    }
    pub(crate) fn PresExprCondsm(input: ParseNode) -> ParseResult<PresExpr> {
        match_nodes!(input.into_children();
            [PresExpr(expr), PresExpr(then), PresExpr(else_)] => {
                Ok(PresExpr::Condition{
                    condition: Condition::Condsm,
                    lhs: Box::new(expr),
                    then: Box::new(then),
                    else_: Box::new(else_),
                })
            },
        )
    }
    pub(crate) fn PresExprCondeq(input: ParseNode) -> ParseResult<PresExpr> {
        match_nodes!(input.into_children();
            [PresExpr(expr), PresExpr(then), PresExpr(else_)] => {
                Ok(PresExpr::Condition{
                    condition: Condition::Condeq,
                    lhs: Box::new(expr),
                    then: Box::new(then),
                    else_: Box::new(else_),
                })
            },
        )
    }
    fn IdsDecl(decl: ParseNode) -> ParseResult<Vec<IdDecl>> {
        let span = decl.as_span();
        match_nodes!(decl.into_children();
            [IdInfixList(identifiers), SortExpr(sort)] => {
139500
                let id_decls = identifiers.into_iter().map(|identifier| {
139500
                    IdDecl::new(identifier, sort.clone(), span.into())
139500
                }).collect();
                Ok(id_decls)
            },
        )
    }
    fn EqnSpec(spec: ParseNode) -> ParseResult<Vec<EqnSpec>> {
        let mut ids = Vec::new();
        match_nodes!(spec.into_children();
            [VarSpec(variables), EqnDecl(decls)..] => {
                ids.push(EqnSpec { variables, equations: decls.collect() });
            },
            [EqnDecl(decls)..] => {
                ids.push(EqnSpec { variables: Vec::new(), equations: decls.collect() });
            },
        );
        Ok(ids)
    }
    fn EqnDecl(decl: ParseNode) -> ParseResult<EqnDecl> {
        let span = decl.as_span();
        match_nodes!(decl.into_children();
            [DataExpr(condition), DataExpr(lhs), DataExpr(rhs)] => {
                Ok(EqnDecl { condition: Some(condition), lhs, rhs, span: span.into() })
            },
            [DataExpr(lhs), DataExpr(rhs)] => {
                Ok(EqnDecl { condition: None, lhs, rhs, span: span.into() })
            },
        )
    }
    fn StateFrm(input: ParseNode) -> ParseResult<StateFrm> {
        parse_statefrm(input.children().as_pairs().clone())
    }
    fn RegFrm(input: ParseNode) -> ParseResult<RegFrm> {
        parse_regfrm(input.children().as_pairs().clone())
    }
    fn StateVarDecl(input: ParseNode) -> ParseResult<StateVarDecl> {
        let span = input.as_span();
        match_nodes!(input.into_children();
            [Id(identifier), StateVarAssignmentList(arguments)] => {
                Ok(StateVarDecl {
                    identifier,
                    arguments,
                    span: span.into(),
                })
            },
            [Id(identifier)] => {
                Ok(StateVarDecl {
                    identifier,
                    arguments: Vec::new(),
                    span: span.into(),
                })
            }
        )
    }
    fn StateVarAssignmentList(input: ParseNode) -> ParseResult<Vec<StateVarAssignment>> {
        match_nodes!(input.into_children();
            [StateVarAssignment(assignments)..] => {
                Ok(assignments.collect())
            }
        )
    }
    fn StateVarAssignment(input: ParseNode) -> ParseResult<StateVarAssignment> {
        match_nodes!(input.into_children();
            [Id(identifier), SortExpr(sort), DataExpr(expr)] => {
                Ok(StateVarAssignment {
                    identifier,
                    sort,
                    expr,
                })
            }
        )
    }
    fn ActionRenameRuleSpec(spec: ParseNode) -> ParseResult<Vec<ActionRenameDecl>> {
        match_nodes!(spec.into_children();
            [VarSpec(variables_specification), ActionRenameRule(renames)..] => {
                Ok(renames.map(|rename_rule| {
                    ActionRenameDecl { variables_specification: variables_specification.clone(), rename_rule }
                }).collect())
            },
            [ActionRenameRule(renames)..] => {
                Ok(renames.map(|rename_rule| {
                    ActionRenameDecl { variables_specification: Vec::new(), rename_rule }
                }).collect())
            },
        )
    }
    fn ActionRenameRule(input: ParseNode) -> ParseResult<ActionRenameRule> {
        match_nodes!(input.into_children();
            [DataExpr(condition), Action(action), ActionRenameRuleRHS(rhs)] => {
                Ok(ActionRenameRule { condition: Some(condition), action, rhs })
            },
            [Action(action), ActionRenameRuleRHS(rhs)] => {
                Ok(ActionRenameRule { condition: None, action, rhs })
            },
        )
    }
    fn ActionRenameRuleRHS(input: ParseNode) -> ParseResult<ActionRHS> {
        match_nodes!(input.into_children();
            [Action(action)] => {
                Ok(ActionRHS::Action(action))
            },
            [MultiActTau(_)] => {
                Ok(ActionRHS::Tau)
            },
            [ProcExprDelta(_)] => {
                Ok(ActionRHS::Delta)
            },
        )
    }
    fn FormSpec(input: ParseNode) -> ParseResult<StateFrm> {
        match_nodes!(input.into_children();
            [StateFrm(formula)] => {
                Ok(formula)
            },
        )
    }
    pub(crate) fn StateFrmSup(input: ParseNode) -> ParseResult<Vec<IdDecl>> {
        match_nodes!(input.into_children();
            [VarsDeclList(variables)] => {
                Ok(variables)
            },
        )
    }
    pub(crate) fn StateFrmInf(input: ParseNode) -> ParseResult<Vec<IdDecl>> {
        match_nodes!(input.into_children();
            [VarsDeclList(variables)] => {
                Ok(variables)
            },
        )
    }
    pub(crate) fn StateFrmSum(input: ParseNode) -> ParseResult<Vec<IdDecl>> {
        match_nodes!(input.into_children();
            [VarsDeclList(variables)] => {
                Ok(variables)
            },
        )
    }
    pub(crate) fn PresExprInf(input: ParseNode) -> ParseResult<Vec<IdDecl>> {
        match_nodes!(input.into_children();
            [VarsDeclList(variables)] => {
                Ok(variables)
            },
        )
    }
    pub(crate) fn PresExprSup(input: ParseNode) -> ParseResult<Vec<IdDecl>> {
        match_nodes!(input.into_children();
            [VarsDeclList(variables)] => {
                Ok(variables)
            },
        )
    }
    pub(crate) fn PresExprSum(input: ParseNode) -> ParseResult<Vec<IdDecl>> {
        match_nodes!(input.into_children();
            [VarsDeclList(variables)] => {
                Ok(variables)
            },
        )
    }
    pub(crate) fn PresExprLeftConstantMultiply(input: ParseNode) -> ParseResult<DataExpr> {
        match_nodes!(input.into_children();
            [DataValExpr(constant)] => {
                Ok(constant)
            },
        )
    }
    pub(crate) fn PresExprRightConstMultiply(input: ParseNode) -> ParseResult<DataExpr> {
        match_nodes!(input.into_children();
            [DataValExpr(constant)] => {
                Ok(constant)
            },
        )
    }
    fn EOI(_input: ParseNode) -> ParseResult<()> {
        Ok(())
    }
}