1
use pest::Parser;
2
use pest_derive::Parser;
3

            
4
use merc_pest_consume::Error;
5
use merc_utilities::MercError;
6

            
7
use crate::DataExpr;
8
use crate::DataExprBinaryOp;
9
use crate::MultiAction;
10
use crate::ParseNode;
11
use crate::StateFrmOp;
12
use crate::UntypedActionRenameSpec;
13
use crate::UntypedDataSpecification;
14
use crate::UntypedPbes;
15
use crate::UntypedPres;
16
use crate::UntypedProcessSpecification;
17
use crate::UntypedStateFrmSpec;
18

            
19
#[derive(Parser)]
20
#[grammar = "mcrl2_grammar.pest"]
21
pub struct Mcrl2Parser;
22

            
23
/// Parses the given mCRL2 specification into an AST.
24
impl UntypedProcessSpecification {
25
1026
    pub fn parse(spec: &str) -> Result<UntypedProcessSpecification, MercError> {
26
1026
        let mut result = Mcrl2Parser::parse(Rule::MCRL2Spec, spec).map_err(extend_parser_error)?;
27
1026
        let root = result.next().expect("Could not parse mCRL2 specification");
28

            
29
1026
        Ok(Mcrl2Parser::MCRL2Spec(ParseNode::new(root))?)
30
1026
    }
31
}
32

            
33
/// Parses the given mCRL2 specification into an AST.
34
impl UntypedDataSpecification {
35
570
    pub fn parse(spec: &str) -> Result<UntypedDataSpecification, MercError> {
36
570
        let mut result = Mcrl2Parser::parse(Rule::DataSpec, spec).map_err(extend_parser_error)?;
37
570
        let root = result.next().expect("Could not parse mCRL2 data specification");
38

            
39
570
        Ok(Mcrl2Parser::DataSpec(ParseNode::new(root))?)
40
570
    }
41
}
42

            
43
impl DataExpr {
44
12
    pub fn parse(spec: &str) -> Result<DataExpr, MercError> {
45
12
        let mut result = Mcrl2Parser::parse(Rule::DataExpr, spec).map_err(extend_parser_error)?;
46
12
        let root = result.next().expect("Could not parse mCRL2 data expression");
47

            
48
12
        Ok(Mcrl2Parser::DataExpr(ParseNode::new(root))?)
49
12
    }
50
}
51

            
52
impl MultiAction {
53
12804
    pub fn parse(spec: &str) -> Result<MultiAction, MercError> {
54
12804
        let mut result = Mcrl2Parser::parse(Rule::MultAct, spec).map_err(extend_parser_error)?;
55
12804
        let root = result.next().expect("Could not parse mCRL2 multi-action");
56

            
57
12804
        Ok(Mcrl2Parser::MultAct(ParseNode::new(root))?)
58
12804
    }
59
}
60

            
61
impl UntypedStateFrmSpec {
62
901
    pub fn parse(spec: &str) -> Result<UntypedStateFrmSpec, MercError> {
63
901
        let mut result = Mcrl2Parser::parse(Rule::StateFrmSpec, spec).map_err(extend_parser_error)?;
64
901
        let root = result
65
901
            .next()
66
901
            .expect("Could not parse mCRL2 state formula specification");
67

            
68
901
        Ok(Mcrl2Parser::StateFrmSpec(ParseNode::new(root))?)
69
901
    }
70
}
71

            
72
impl UntypedActionRenameSpec {
73
    pub fn parse(spec: &str) -> Result<UntypedActionRenameSpec, MercError> {
74
        let mut result = Mcrl2Parser::parse(Rule::ActionRenameSpec, spec).map_err(extend_parser_error)?;
75
        let root = result
76
            .next()
77
            .expect("Could not parse mCRL2 action rename specification");
78

            
79
        Ok(Mcrl2Parser::ActionRenameSpec(ParseNode::new(root))?)
80
    }
81
}
82

            
83
impl UntypedPbes {
84
18
    pub fn parse(spec: &str) -> Result<UntypedPbes, MercError> {
85
18
        let mut result = Mcrl2Parser::parse(Rule::PbesSpec, spec).map_err(extend_parser_error)?;
86
18
        let root = result
87
18
            .next()
88
18
            .expect("Could not parse parameterised boolean equation system");
89

            
90
18
        Ok(Mcrl2Parser::PbesSpec(ParseNode::new(root))?)
91
18
    }
92
}
93

            
94
impl UntypedPres {
95
    pub fn parse(spec: &str) -> Result<UntypedPres, MercError> {
96
        let mut result = Mcrl2Parser::parse(Rule::PresSpec, spec).map_err(extend_parser_error)?;
97
        let root = result
98
            .next()
99
            .expect("Could not parse parameterised real equation system");
100

            
101
        Ok(Mcrl2Parser::PresSpec(ParseNode::new(root))?)
102
    }
103
}
104

            
105
fn extend_parser_error(error: Error<Rule>) -> Error<Rule> {
106
    error.renamed_rules(|rule| match rule {
107
        Rule::DataExprWhr => "DataExpr whr AssignmentList end".to_string(),
108
        Rule::DataExprUpdate => "DataExpr[(DataExpr -> DataExpr)*]".to_string(),
109
        Rule::DataExprApplication => "DataExpr(DataExpr*)".to_string(),
110

            
111
        // DataExpr Binary Operators
112
        Rule::DataExprConj => format!("{}", DataExprBinaryOp::Conj),
113
        Rule::DataExprDisj => format!("{}", DataExprBinaryOp::Disj),
114
        Rule::DataExprImpl => format!("{}", DataExprBinaryOp::Implies),
115
        Rule::DataExprEq => format!("{}", DataExprBinaryOp::Equal),
116
        Rule::DataExprNeq => format!("{}", DataExprBinaryOp::NotEqual),
117
        Rule::DataExprLess => format!("{}", DataExprBinaryOp::LessThan),
118
        Rule::DataExprLeq => format!("{}", DataExprBinaryOp::LessEqual),
119
        Rule::DataExprGreater => format!("{}", DataExprBinaryOp::GreaterThan),
120
        Rule::DataExprGeq => format!("{}", DataExprBinaryOp::GreaterEqual),
121
        Rule::DataExprIn => format!("{}", DataExprBinaryOp::In),
122
        Rule::DataExprDiv => format!("{}", DataExprBinaryOp::Div),
123
        Rule::DataExprIntDiv => format!("{}", DataExprBinaryOp::IntDiv),
124
        Rule::DataExprMod => format!("{}", DataExprBinaryOp::Mod),
125
        Rule::DataExprMult => format!("{}", DataExprBinaryOp::Multiply),
126
        Rule::DataExprAdd => format!("{}", DataExprBinaryOp::Add),
127
        Rule::DataExprSubtract => format!("{}", DataExprBinaryOp::Subtract),
128
        Rule::DataExprAt => format!("{}", DataExprBinaryOp::At),
129
        Rule::DataExprCons => format!("{}", DataExprBinaryOp::Cons),
130
        Rule::DataExprSnoc => format!("{}", DataExprBinaryOp::Snoc),
131
        Rule::DataExprConcat => format!("{}", DataExprBinaryOp::Concat),
132

            
133
        // Regular Formulas
134
        Rule::RegFrmAlternative => "RegFrm + RegFrm".to_string(),
135
        Rule::RegFrmComposition => "RegFrm . RegFrm".to_string(),
136
        Rule::RegFrmIteration => "RegFrm*".to_string(),
137
        Rule::RegFrmPlus => "RegFrm+".to_string(),
138

            
139
        // State formulas
140
        Rule::StateFrmAddition => format!("{}", StateFrmOp::Addition),
141
        Rule::StateFrmLeftConstantMultiply => "Number * StateFrm".to_string(),
142
        Rule::StateFrmImplication => format!("{}", StateFrmOp::Implies),
143
        Rule::StateFrmDisjunction => format!("{}", StateFrmOp::Disjunction),
144
        Rule::StateFrmConjunction => format!("{}", StateFrmOp::Conjunction),
145
        Rule::StateFrmRightConstantMultiply => "StateFrm * Number".to_string(),
146
        _ => format!("{rule:?}"),
147
    })
148
}