AST generation

After parsing, a MiniZinc AST is generated from the CST. This provides type-safe accessors to the nodes in the syntax tree. No desugaring takes place at this stage, and all semantic nodes are are made available other than parentheses (which made explicit in the tree structure). So nodes like whitespace, comments and semicolons from the CST are removed in the AST.

This is still too low level for most analysis, and there several constructs which are semantically the same, but with different syntactic representations. Therefore, the next step is to resolve the include items, and then lower each model into HIR.

Example

The model

test foo() = true;
function bool: bar() = true;
var 1..3: x;

Gives the AST

MznModel(
    Model {
        items: [
            Predicate(
                Predicate {
                    cst_kind: "predicate",
                    declared_type: Test,
                    id: UnquotedIdentifier(
                        UnquotedIdentifier {
                            cst_kind: "identifier",
                            name: "foo",
                        },
                    ),
                    parameters: [],
                    body: Some(
                        BooleanLiteral(
                            BooleanLiteral {
                                cst_kind: "boolean_literal",
                                value: true,
                            },
                        ),
                    ),
                    annotations: [],
                },
            ),
            Function(
                Function {
                    cst_kind: "function_item",
                    return_type: TypeBase(
                        TypeBase {
                            cst_kind: "type_base",
                            var_type: None,
                            opt_type: None,
                            any_type: false,
                            domain: Unbounded(
                                UnboundedDomain {
                                    cst_kind: "primitive_type",
                                    primitive_type: Bool,
                                },
                            ),
                        },
                    ),
                    id: UnquotedIdentifier(
                        UnquotedIdentifier {
                            cst_kind: "identifier",
                            name: "bar",
                        },
                    ),
                    parameters: [],
                    body: Some(
                        BooleanLiteral(
                            BooleanLiteral {
                                cst_kind: "boolean_literal",
                                value: true,
                            },
                        ),
                    ),
                    annotations: [],
                },
            ),
            Declaration(
                Declaration {
                    cst_kind: "declaration",
                    pattern: Identifier(
                        UnquotedIdentifier(
                            UnquotedIdentifier {
                                cst_kind: "identifier",
                                name: "x",
                            },
                        ),
                    ),
                    declared_type: TypeBase(
                        TypeBase {
                            cst_kind: "type_base",
                            var_type: Some(
                                Var,
                            ),
                            opt_type: None,
                            any_type: false,
                            domain: Bounded(
                                InfixOperator(
                                    InfixOperator {
                                        cst_kind: "infix_operator",
                                        left: IntegerLiteral(
                                            IntegerLiteral {
                                                cst_kind: "integer_literal",
                                                value: Ok(
                                                    1,
                                                ),
                                            },
                                        ),
                                        operator: Operator {
                                            cst_kind: "..",
                                            name: "..",
                                        },
                                        right: IntegerLiteral(
                                            IntegerLiteral {
                                                cst_kind: "integer_literal",
                                                value: Ok(
                                                    3,
                                                ),
                                            },
                                        ),
                                    },
                                ),
                            ),
                        },
                    ),
                    definition: None,
                    annotations: [],
                },
            ),
        ],
    },
)