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::UntypedProcessSpecification;
16
use crate::UntypedStateFrmSpec;
17

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

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

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

            
37
255
        Ok(Mcrl2Parser::DataSpec(ParseNode::new(root))?)
38
255
    }
39
}
40

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

            
46
6
        Ok(Mcrl2Parser::DataExpr(ParseNode::new(root))?)
47
6
    }
48
}
49

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

            
55
180
        Ok(Mcrl2Parser::MultAct(ParseNode::new(root))?)
56
180
    }
57
}
58

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

            
66
448
        Ok(Mcrl2Parser::StateFrmSpec(ParseNode::new(root))?)
67
448
    }
68
}
69

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

            
77
        Ok(Mcrl2Parser::ActionRenameSpec(ParseNode::new(root))?)
78
    }
79
}
80

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

            
88
9
        Ok(Mcrl2Parser::PbesSpec(ParseNode::new(root))?)
89
9
    }
90
}
91

            
92
fn extend_parser_error(error: Error<Rule>) -> Error<Rule> {
93
    error.renamed_rules(|rule| match rule {
94
        Rule::DataExprWhr => "DataExpr whr AssignmentList end".to_string(),
95
        Rule::DataExprUpdate => "DataExpr[(DataExpr -> DataExpr)*]".to_string(),
96
        Rule::DataExprApplication => "DataExpr(DataExpr*)".to_string(),
97

            
98
        // DataExpr Binary Operators
99
        Rule::DataExprConj => format!("{}", DataExprBinaryOp::Conj),
100
        Rule::DataExprDisj => format!("{}", DataExprBinaryOp::Disj),
101
        Rule::DataExprImpl => format!("{}", DataExprBinaryOp::Implies),
102
        Rule::DataExprEq => format!("{}", DataExprBinaryOp::Equal),
103
        Rule::DataExprNeq => format!("{}", DataExprBinaryOp::NotEqual),
104
        Rule::DataExprLess => format!("{}", DataExprBinaryOp::LessThan),
105
        Rule::DataExprLeq => format!("{}", DataExprBinaryOp::LessEqual),
106
        Rule::DataExprGreater => format!("{}", DataExprBinaryOp::GreaterThan),
107
        Rule::DataExprGeq => format!("{}", DataExprBinaryOp::GreaterEqual),
108
        Rule::DataExprIn => format!("{}", DataExprBinaryOp::In),
109
        Rule::DataExprDiv => format!("{}", DataExprBinaryOp::Div),
110
        Rule::DataExprIntDiv => format!("{}", DataExprBinaryOp::IntDiv),
111
        Rule::DataExprMod => format!("{}", DataExprBinaryOp::Mod),
112
        Rule::DataExprMult => format!("{}", DataExprBinaryOp::Multiply),
113
        Rule::DataExprAdd => format!("{}", DataExprBinaryOp::Add),
114
        Rule::DataExprSubtract => format!("{}", DataExprBinaryOp::Subtract),
115
        Rule::DataExprAt => format!("{}", DataExprBinaryOp::At),
116
        Rule::DataExprCons => format!("{}", DataExprBinaryOp::Cons),
117
        Rule::DataExprSnoc => format!("{}", DataExprBinaryOp::Snoc),
118
        Rule::DataExprConcat => format!("{}", DataExprBinaryOp::Concat),
119

            
120
        // Regular Formulas
121
        Rule::RegFrmAlternative => "RegFrm + RegFrm".to_string(),
122
        Rule::RegFrmComposition => "RegFrm . RegFrm".to_string(),
123
        Rule::RegFrmIteration => "RegFrm*".to_string(),
124
        Rule::RegFrmPlus => "RegFrm+".to_string(),
125

            
126
        // State formulas
127
        Rule::StateFrmAddition => format!("{}", StateFrmOp::Addition),
128
        Rule::StateFrmLeftConstantMultiply => "Number * StateFrm".to_string(),
129
        Rule::StateFrmImplication => format!("{}", StateFrmOp::Implies),
130
        Rule::StateFrmDisjunction => format!("{}", StateFrmOp::Disjunction),
131
        Rule::StateFrmConjunction => format!("{}", StateFrmOp::Conjunction),
132
        Rule::StateFrmRightConstantMultiply => "StateFrm * Number".to_string(),
133
        _ => format!("{rule:?}"),
134
    })
135
}