Parsing
Tree-sitter is used to generate a concrete syntax tree from a MiniZinc model. The grammar is located in the
parsers/tree-sitter-minizinc/grammar.js file. There is also a corpus of tests which can be run to test the parser's
output.
Since this concrete syntax tree is too low level to perform most useful compilation steps, an abstract syntax tree will be constructed (with the AST nodes linked to the related CST nodes) during AST generation.
Example
The model
test foo() = true;
function bool: bar() = true;
var 1..3: x;
Gives the CST
CstNode {
kind: "source_file",
start: Point {
row: 0,
column: 0,
},
end: Point {
row: 2,
column: 12,
},
is_named: true,
has_error: false,
is_error: false,
is_missing: false,
is_extra: false,
field: None,
children: [
CstNode {
kind: "predicate",
start: Point {
row: 0,
column: 0,
},
end: Point {
row: 0,
column: 17,
},
is_named: true,
has_error: false,
is_error: false,
is_missing: false,
is_extra: false,
field: None,
children: [
CstNode {
kind: "test",
start: Point {
row: 0,
column: 0,
},
end: Point {
row: 0,
column: 4,
},
is_named: false,
has_error: false,
is_error: false,
is_missing: false,
is_extra: false,
field: None,
children: [],
},
CstNode {
kind: "identifier",
start: Point {
row: 0,
column: 5,
},
end: Point {
row: 0,
column: 8,
},
is_named: true,
has_error: false,
is_error: false,
is_missing: false,
is_extra: false,
field: None,
children: [],
},
CstNode {
kind: "(",
start: Point {
row: 0,
column: 8,
},
end: Point {
row: 0,
column: 9,
},
is_named: false,
has_error: false,
is_error: false,
is_missing: false,
is_extra: false,
field: None,
children: [],
},
CstNode {
kind: ")",
start: Point {
row: 0,
column: 9,
},
end: Point {
row: 0,
column: 10,
},
is_named: false,
has_error: false,
is_error: false,
is_missing: false,
is_extra: false,
field: None,
children: [],
},
CstNode {
kind: "=",
start: Point {
row: 0,
column: 11,
},
end: Point {
row: 0,
column: 12,
},
is_named: false,
has_error: false,
is_error: false,
is_missing: false,
is_extra: false,
field: None,
children: [],
},
CstNode {
kind: "boolean_literal",
start: Point {
row: 0,
column: 13,
},
end: Point {
row: 0,
column: 17,
},
is_named: true,
has_error: false,
is_error: false,
is_missing: false,
is_extra: false,
field: None,
children: [
CstNode {
kind: "true",
start: Point {
row: 0,
column: 13,
},
end: Point {
row: 0,
column: 17,
},
is_named: false,
has_error: false,
is_error: false,
is_missing: false,
is_extra: false,
field: None,
children: [],
},
],
},
],
},
CstNode {
kind: ";",
start: Point {
row: 0,
column: 17,
},
end: Point {
row: 0,
column: 18,
},
is_named: false,
has_error: false,
is_error: false,
is_missing: false,
is_extra: false,
field: None,
children: [],
},
CstNode {
kind: "function_item",
start: Point {
row: 1,
column: 0,
},
end: Point {
row: 1,
column: 27,
},
is_named: true,
has_error: false,
is_error: false,
is_missing: false,
is_extra: false,
field: None,
children: [
CstNode {
kind: "function",
start: Point {
row: 1,
column: 0,
},
end: Point {
row: 1,
column: 8,
},
is_named: false,
has_error: false,
is_error: false,
is_missing: false,
is_extra: false,
field: None,
children: [],
},
CstNode {
kind: "type_base",
start: Point {
row: 1,
column: 9,
},
end: Point {
row: 1,
column: 13,
},
is_named: true,
has_error: false,
is_error: false,
is_missing: false,
is_extra: false,
field: None,
children: [
CstNode {
kind: "primitive_type",
start: Point {
row: 1,
column: 9,
},
end: Point {
row: 1,
column: 13,
},
is_named: true,
has_error: false,
is_error: false,
is_missing: false,
is_extra: false,
field: None,
children: [
CstNode {
kind: "bool",
start: Point {
row: 1,
column: 9,
},
end: Point {
row: 1,
column: 13,
},
is_named: false,
has_error: false,
is_error: false,
is_missing: false,
is_extra: false,
field: None,
children: [],
},
],
},
],
},
CstNode {
kind: ":",
start: Point {
row: 1,
column: 13,
},
end: Point {
row: 1,
column: 14,
},
is_named: false,
has_error: false,
is_error: false,
is_missing: false,
is_extra: false,
field: None,
children: [],
},
CstNode {
kind: "identifier",
start: Point {
row: 1,
column: 15,
},
end: Point {
row: 1,
column: 18,
},
is_named: true,
has_error: false,
is_error: false,
is_missing: false,
is_extra: false,
field: None,
children: [],
},
CstNode {
kind: "(",
start: Point {
row: 1,
column: 18,
},
end: Point {
row: 1,
column: 19,
},
is_named: false,
has_error: false,
is_error: false,
is_missing: false,
is_extra: false,
field: None,
children: [],
},
CstNode {
kind: ")",
start: Point {
row: 1,
column: 19,
},
end: Point {
row: 1,
column: 20,
},
is_named: false,
has_error: false,
is_error: false,
is_missing: false,
is_extra: false,
field: None,
children: [],
},
CstNode {
kind: "=",
start: Point {
row: 1,
column: 21,
},
end: Point {
row: 1,
column: 22,
},
is_named: false,
has_error: false,
is_error: false,
is_missing: false,
is_extra: false,
field: None,
children: [],
},
CstNode {
kind: "boolean_literal",
start: Point {
row: 1,
column: 23,
},
end: Point {
row: 1,
column: 27,
},
is_named: true,
has_error: false,
is_error: false,
is_missing: false,
is_extra: false,
field: None,
children: [
CstNode {
kind: "true",
start: Point {
row: 1,
column: 23,
},
end: Point {
row: 1,
column: 27,
},
is_named: false,
has_error: false,
is_error: false,
is_missing: false,
is_extra: false,
field: None,
children: [],
},
],
},
],
},
CstNode {
kind: ";",
start: Point {
row: 1,
column: 27,
},
end: Point {
row: 1,
column: 28,
},
is_named: false,
has_error: false,
is_error: false,
is_missing: false,
is_extra: false,
field: None,
children: [],
},
CstNode {
kind: "declaration",
start: Point {
row: 2,
column: 0,
},
end: Point {
row: 2,
column: 11,
},
is_named: true,
has_error: false,
is_error: false,
is_missing: false,
is_extra: false,
field: None,
children: [
CstNode {
kind: "type_base",
start: Point {
row: 2,
column: 0,
},
end: Point {
row: 2,
column: 8,
},
is_named: true,
has_error: false,
is_error: false,
is_missing: false,
is_extra: false,
field: None,
children: [
CstNode {
kind: "var",
start: Point {
row: 2,
column: 0,
},
end: Point {
row: 2,
column: 3,
},
is_named: false,
has_error: false,
is_error: false,
is_missing: false,
is_extra: false,
field: None,
children: [],
},
CstNode {
kind: "infix_operator",
start: Point {
row: 2,
column: 4,
},
end: Point {
row: 2,
column: 8,
},
is_named: true,
has_error: false,
is_error: false,
is_missing: false,
is_extra: false,
field: None,
children: [
CstNode {
kind: "integer_literal",
start: Point {
row: 2,
column: 4,
},
end: Point {
row: 2,
column: 5,
},
is_named: true,
has_error: false,
is_error: false,
is_missing: false,
is_extra: false,
field: None,
children: [],
},
CstNode {
kind: "..",
start: Point {
row: 2,
column: 5,
},
end: Point {
row: 2,
column: 7,
},
is_named: false,
has_error: false,
is_error: false,
is_missing: false,
is_extra: false,
field: None,
children: [],
},
CstNode {
kind: "integer_literal",
start: Point {
row: 2,
column: 7,
},
end: Point {
row: 2,
column: 8,
},
is_named: true,
has_error: false,
is_error: false,
is_missing: false,
is_extra: false,
field: None,
children: [],
},
],
},
],
},
CstNode {
kind: ":",
start: Point {
row: 2,
column: 8,
},
end: Point {
row: 2,
column: 9,
},
is_named: false,
has_error: false,
is_error: false,
is_missing: false,
is_extra: false,
field: None,
children: [],
},
CstNode {
kind: "identifier",
start: Point {
row: 2,
column: 10,
},
end: Point {
row: 2,
column: 11,
},
is_named: true,
has_error: false,
is_error: false,
is_missing: false,
is_extra: false,
field: None,
children: [],
},
],
},
CstNode {
kind: ";",
start: Point {
row: 2,
column: 11,
},
end: Point {
row: 2,
column: 12,
},
is_named: false,
has_error: false,
is_error: false,
is_missing: false,
is_extra: false,
field: None,
children: [],
},
],
}