[LIGO-25] Add grammar for ReasonLIGO and move it to squirrel

Problem: Before making parser for ReasonLIGO we need to construct
its grammar so that we can collect *all* errors and simplify our
further work with AST. Also since we use those grammars in squirrel
it would be conscise to use them from the project directory directly.

Solution: Add grammar for ReasonLIGO and move grammar to squirrel.
This commit is contained in:
Anton Myasnikov 2020-08-11 13:30:46 +03:00
parent 0fbfd134ec
commit 99321a59bb
No known key found for this signature in database
GPG Key ID: FEB685E6DAA0A95F
9 changed files with 801 additions and 79 deletions

View File

@ -7,7 +7,7 @@ let sepBy1 = (sep, rule) =>
let sepBy = (sep, rule) => optional(sepBy1(sep, rule))
let par = x => seq('(', x, ')')
let par = x => seq('(', x, ')')
let brackets = x => seq('[', x, ']')
let ne_injection = (Kind, element) =>
@ -40,7 +40,7 @@ let injection = (Kind, element) =>
),
)
let tuple = x => seq(x, ',', x, repeat(seq(',', x)))
let tuple = x => seq(x, ',', x, repeat(seq(',', x)))
let list__ = x => brackets(sepBy(';', x))
let nseq = x => seq(x, repeat(x))
@ -57,7 +57,7 @@ let lop = (l, x, r) => op(l, x, r, l)
module.exports = grammar({
name: 'CAMLigo',
word: $ => $.Keyword,
word: $ => $.Keyword,
extras: $ => [$.ocaml_comment, $.comment, /\s/],
conflicts: $ => [[$.call, $.if_then_else]],
@ -65,7 +65,8 @@ module.exports = grammar({
rules: {
// debug: $ => $.expr,
contract: $ => repeat($.declaration),
// contract: $ => repeat($.declaration),
contract: $ => $.expr,
expr: $ =>
choice(
@ -91,9 +92,9 @@ module.exports = grammar({
disj: $ => prec.left(3, rop($.disj, $.or, $.conj)),
conj: $ => prec.left(4, rop($.conj, $.and, $.comp)),
comp: $ => prec.left(5, rop($.comp, $.compare, $.cat)),
cat: $ => prec.left(6, lop($.cons, $.catenate, $.cat)),
cat: $ => prec.left(6, lop($.cons, $.catenate, $.cat)),
cons: $ => prec.right(7, lop($.add, $.consolidate, $.cons)),
add: $ => prec.left(8, rop($.add, $.plus, $.mult)),
add: $ => prec.left(8, rop($.add, $.plus, $.mult)),
mult: $ => prec.left(9, rop($.mult, $.times, $.unary)),
unary: $ =>
@ -341,9 +342,9 @@ module.exports = grammar({
field_decl: $ =>
seq(
$.field_name,
':',
$.type_expr,
$.field_name,
':',
$.type_expr,
),
let_declaration: $ =>
@ -414,7 +415,7 @@ module.exports = grammar({
$.pattern,
),
pattern: $ => sepBy1('::', $.pattern_tuple),
pattern: $ => sepBy1('::', $.pattern_tuple),
pattern_tuple: $ => sepBy1(',', $.construct),
construct: $ =>
@ -423,7 +424,7 @@ module.exports = grammar({
$.pattern_term,
),
///////////////////////////////////////////
///////////////////////////////////////////
type_name: $ => $.ident,
field_name: $ => $.ident,
@ -448,23 +449,23 @@ module.exports = grammar({
include: $ => seq('#include', $.String),
String: $ => /\"(\\.|[^"])*\"/,
Int: $ => /-?([1-9][0-9_]*|0)/,
Nat: $ => /([1-9][0-9_]*|0)n/,
Tez: $ => /([1-9][0-9_]*|0)(\.[0-9_]+)?(tz|tez|mutez)/,
Bytes: $ => /0x[0-9a-fA-F]+/,
Name: $ => /[a-z][a-zA-Z0-9_]*/,
String: $ => /\"(\\.|[^"])*\"/,
Int: $ => /-?([1-9][0-9_]*|0)/,
Nat: $ => /([1-9][0-9_]*|0)n/,
Tez: $ => /([1-9][0-9_]*|0)(\.[0-9_]+)?(tz|tez|mutez)/,
Bytes: $ => /0x[0-9a-fA-F]+/,
Name: $ => /[a-z][a-zA-Z0-9_]*/,
Name_Capital: $ => /[A-Z][a-zA-Z0-9_]*/,
Keyword: $ => /[A-Za-z][a-z]*/,
Keyword: $ => /[A-Za-z][a-z]*/,
False: $ => 'False',
True: $ => 'True',
Unit: $ => 'Unit',
None: $ => 'None',
Some: $ => 'Some',
skip: $ => 'skip',
rec: $ => 'rec',
False: $ => 'False',
True: $ => 'True',
Unit: $ => 'Unit',
None: $ => 'None',
Some: $ => 'Some',
skip: $ => 'skip',
rec: $ => 'rec',
attr: $ => seq('[@@', $.name, ']'),
attr: $ => seq('[@@', $.name, ']'),
}
});

View File

@ -0,0 +1,13 @@
try {
module.exports = require("./build/Release/tree_sitter_CAMLigo_binding");
} catch (error) {
try {
module.exports = require("./build/Debug/tree_sitter_CAMLigo_binding");
} catch (_) {
throw error
}
}
try {
module.exports.nodeTypeInfo = require("./src/node-types.json");
} catch (_) {}

View File

@ -14,7 +14,7 @@ let op = (name, left, right, term) =>
)
let right_op = (name, left, right) => op(name, left, right, right)
let left_op = (name, left, right) => op(name, left, right, left)
let left_op = (name, left, right) => op(name, left, right, left)
let par = x => seq('(', x, ')')
let brackets = x => seq('[', x, ']')
@ -52,7 +52,7 @@ let injection = (Kind, element) =>
module.exports = grammar({
name: 'PascaLigo',
word: $ => $.Keyword,
word: $ => $.Keyword,
extras: $ => [$.ocaml_comment, $.comment, /\s/],
rules: {
@ -119,30 +119,30 @@ module.exports = grammar({
michelsonTypeOr: $ =>
seq(
"michelson_or",
"(",
field("left_type", $._type_expr),
",",
field("left_type_name", $.String),
",",
field("right_type", $._type_expr),
",",
field("right_type_name", $.String),
")",
"michelson_or",
"(",
field("left_type", $._type_expr),
",",
field("left_type_name", $.String),
",",
field("right_type", $._type_expr),
",",
field("right_type_name", $.String),
")",
),
michelsonTypeAnd: $ =>
seq(
"michelson_pair",
"(",
field("left_type", $._type_expr),
",",
field("left_type_name", $.String),
",",
field("right_type", $._type_expr),
",",
field("right_type_name", $.String),
")",
"michelson_pair",
"(",
field("left_type", $._type_expr),
",",
field("left_type_name", $.String),
",",
field("right_type", $._type_expr),
",",
field("right_type_name", $.String),
")",
),
invokeBinary: $ =>
@ -157,10 +157,10 @@ module.exports = grammar({
par(field("arguments", $._type_expr)),
),
map: $ => 'map',
map: $ => 'map',
big_map: $ => 'big_map',
list: $ => 'list',
set: $ => 'set',
list: $ => 'list',
set: $ => 'set',
type_tuple: $ => par(sepBy1(',', field("element", $._type_expr))),
@ -184,7 +184,7 @@ module.exports = grammar({
record_type: $ =>
choice(
seq('record', sepBy(';', field("field", $.field_decl)), 'end'),
seq('record', sepBy(';', field("field", $.field_decl)), 'end'),
seq('record', '[', sepBy(';', field("field", $.field_decl)), ']'),
),
@ -525,22 +525,22 @@ module.exports = grammar({
binop: $ =>
choice(
prec.left (0, seq(field("arg1", $._op_expr), field("op", 'or'), field("arg2", $._op_expr))),
prec.left (1, seq(field("arg1", $._op_expr), field("op", 'and'), field("arg2", $._op_expr))),
prec.right(2, seq(field("arg1", $._core_expr), field("op", 'contains'), field("arg2", $._op_expr))),
prec.left (3, seq(field("arg1", $._op_expr), field("op", $.comparison), field("arg2", $._op_expr))),
prec.right(4, seq(field("arg1", $._op_expr), field("op", '^'), field("arg2", $._op_expr))),
prec.right(5, seq(field("arg1", $._op_expr), field("op", '#'), field("arg2", $._op_expr))),
prec.left (6, seq(field("arg1", $._op_expr), field("op", $.adder), field("arg2", $._op_expr))),
prec.left (7, seq(field("arg1", $._op_expr), field("op", $.multiplier), field("arg2", $._op_expr))),
prec.left(0, seq(field("arg1", $._op_expr), field("op", 'or'), field("arg2", $._op_expr))),
prec.left(1, seq(field("arg1", $._op_expr), field("op", 'and'), field("arg2", $._op_expr))),
prec.right(2, seq(field("arg1", $._core_expr), field("op", 'contains'), field("arg2", $._op_expr))),
prec.left(3, seq(field("arg1", $._op_expr), field("op", $.comparison), field("arg2", $._op_expr))),
prec.right(4, seq(field("arg1", $._op_expr), field("op", '^'), field("arg2", $._op_expr))),
prec.right(5, seq(field("arg1", $._op_expr), field("op", '#'), field("arg2", $._op_expr))),
prec.left(6, seq(field("arg1", $._op_expr), field("op", $.adder), field("arg2", $._op_expr))),
prec.left(7, seq(field("arg1", $._op_expr), field("op", $.multiplier), field("arg2", $._op_expr))),
),
unop: $ => prec.right(8, seq(field("negate", $.negate), field("arg", $._core_expr))),
comparison: $ => choice('<', '<=', '>', '>=', '=', '=/='),
adder: $ => choice('-', '+'),
adder: $ => choice('-', '+'),
multiplier: $ => choice('/', '*', 'mod'),
negate: $ => choice('-', 'not'),
negate: $ => choice('-', 'not'),
_core_expr: $ =>
choice(
@ -718,8 +718,8 @@ module.exports = grammar({
field("arguments", $.arguments),
),
tuple_expr: $ => par(sepBy1(',', field("element", $._expr))),
arguments: $ => par(sepBy(',', field("argument", $._expr))),
tuple_expr: $ => par(sepBy1(',', field("element", $._expr))),
arguments: $ => par(sepBy(',', field("argument", $._expr))),
_list_expr: $ => choice($.list_injection, 'nil'),
@ -802,22 +802,22 @@ module.exports = grammar({
include: $ => seq('#include', field("filename", $.String)),
String: $ => choice(/\"(\\.|[^"])*\"/, /{\|(\\.|[^\|])*\|}/),
Int: $ => /-?([1-9][0-9_]*|0)/,
Nat: $ => /([1-9][0-9_]*|0)n/,
Tez: $ => /([1-9][0-9_]*|0)(\.[0-9_]+)?(tz|tez|mutez)/,
Bytes: $ => /0x[0-9a-fA-F]+/,
FieldName: $ => /[a-z][a-zA-Z0-9_]*/,
TypeName: $ => /[a-z][a-zA-Z0-9_]*/,
Name: $ => /[a-z][a-zA-Z0-9_]*/,
String: $ => choice(/\"(\\.|[^"])*\"/, /{\|(\\.|[^\|])*\|}/),
Int: $ => /-?([1-9][0-9_]*|0)/,
Nat: $ => /([1-9][0-9_]*|0)n/,
Tez: $ => /([1-9][0-9_]*|0)(\.[0-9_]+)?(tz|tez|mutez)/,
Bytes: $ => /0x[0-9a-fA-F]+/,
FieldName: $ => /[a-z][a-zA-Z0-9_]*/,
TypeName: $ => /[a-z][a-zA-Z0-9_]*/,
Name: $ => /[a-z][a-zA-Z0-9_]*/,
Name_Capital: $ => /[A-Z][a-zA-Z0-9_]*/,
Keyword: $ => /[A-Za-z][a-z]*/,
Keyword: $ => /[A-Za-z][a-z]*/,
False: $ => 'False',
True: $ => 'True',
Unit: $ => 'Unit',
None: $ => 'None',
skip: $ => 'skip',
recursive: $ => 'recursive',
False: $ => 'False',
True: $ => 'True',
Unit: $ => 'Unit',
None: $ => 'None',
skip: $ => 'skip',
recursive: $ => 'recursive',
}
});

View File

@ -0,0 +1,13 @@
try {
module.exports = require("./build/Release/tree_sitter_PascaLigo_binding");
} catch (error) {
try {
module.exports = require("./build/Debug/tree_sitter_PascaLigo_binding");
} catch (_) {
throw error
}
}
try {
module.exports.nodeTypeInfo = require("./src/node-types.json");
} catch (_) {}

View File

@ -0,0 +1,682 @@
const PREC = {
CALL: 300000000,
OR: 0,
AND: 1,
COMPARE: 3,
CONCAT: 5,
PLUS: 6,
MINUS: 6,
MUL: 7,
DIV: 7,
ATTR: 1,
TYPE: 101,
LET: 100,
EXPR: 100000000,
CONSTR: 100000,
LAM: 1000,
};
const OPS = [
['+', PREC.PLUS],
['-', PREC.MINUS],
['mod', PREC.DIV],
['/', PREC.DIV],
['*', PREC.MUL],
['++', PREC.CONCAT],
['<', PREC.COMPARE],
['>', PREC.COMPARE],
['<=', PREC.COMPARE],
['>=', PREC.COMPARE],
['==', PREC.COMPARE],
['!=', PREC.COMPARE],
['&&', PREC.COMPARE],
['||', PREC.OR],
]
let sepBy1 = (sep, rule) =>
seq(
rule,
repeat(seq(sep, rule)),
optional(sep)
)
let sepBy = (sep, rule) => optional(sepBy1(sep, rule))
let par = x => seq('(', x, ')')
let opar = x => seq(optional('('), x, optional(')'))
let brackets = x => seq('[', x, ']')
let block = x => seq('{', x, '}')
let tuple = x => seq(x, ',', x, repeat(seq(',', x)))
let list__ = x => brackets(sepBy(';', x))
let nseq = x => seq(x, repeat(x))
module.exports = grammar({
name: 'ReasonLigo',
word: $ => $.Keyword,
extras: $ => [$.oneline_comment, $.block_comment, /\s/],
conflicts: $ => [
[$._fun_type, $.type_application],
[$._pattern, $.tuple_pattern],
[$._expr], // TODO: left-precendence is used for tuple_expr, right for nested `let`s
[$._exprf],
[$.tuple_expr, $.parameters],
[$.record_field, $._accessor], // TODO
[$.variant], // TODO: some alien stuff
[$.sum_type], // TODO: fix in `let_declaration`.
[$.bracket_block], // TODO: same as $.lambda_body
[$.type_decl],
[$.lambda],
[$._instruction, $._expr], // switch_instr
[$._functional_block, $.bracket_block], // TODO: remove
[$.list_access], // TODO: remove
[$.list_access, $._ident], // TODO
[$.record_field, $._ident], // TODO
[$._core_pattern, $._expr], //TODO: remove as soon as possible
[$.lambda_call], // TODO: remove
[$.lambda_call, $.binary_call],
[$._expr, $.bracket_block], // TODO
[$.lambda_call, $.parameters], // TODO
[$["-"], $.negate], // unary vs binary calls
[$.parameters, $.annot_expr], // TODO
[$.type_tuple, $._core_type],
[$._pattern, $.annot_pattern], // TODO: constr (pat) case
[$.annot_expr, $._type_annotation],
[$.annot_expr, $.lambda_call],
[$.annot_expr, $._functional_block],
// TODO: those are produced in conflicts of `fun_call` and `expr` in bracket blocks
[$.annot_expr, $._exprf],
[$.lambda_call, $._exprf],
[$.bracket_block, $._exprf],
[$._functional_block, $._exprf],
[$.tuple_expr, $._exprf],
[$._annot_fun_call, $._exprf],
],
rules: {
contract: $ => sepBy(optional(';'), field("declaration", $._declaration)),
_expr: $ =>
prec(PREC.EXPR,
seq(
choice(
$.lambda_call,
$.tuple_expr,
$._literal,
// $.fun_call,
$.constructor_call,
$.unary_call,
$.binary_call,
$.annot_expr,
$.list_expr,
$.record_expr,
$._ref,
$._ident,
$.switch_instr,
),
),
),
// TODO: workaround to move `fun_call` out of `expr` needed in bracket blocks
_exprf: $ => choice($.fun_call, $._expr),
_annot_expr: $ =>
par($.annot_expr),
annot_expr: $ =>
seq(
field("subject", $._expr),
':',
field("type", $._type_expr),
),
// TODO: same as tuple_pattern
// TODO: to annotate expression we do not need to enclose it in brackets
// TODO: possible ((a : p) : q, b)
tuple_expr: $ =>
par(sepBy1(',',
seq(
field("element", choice(
$.annot_expr,
$.fun_call,
$._expr,
)),
)
)),
constructor_call: $ =>
prec(PREC.CONSTR,
seq(
field("constructor",
choice(
$._constr,
$.module_qualified,
),
),
field("parameters", $.parameters),
),
),
lambda_call: $ =>
seq(
par(field("lambda", $.lambda)),
repeat1(
choice(
field("arguments", $._expr),
par(field("arguments", $.lambda))
)
), // TODO: workaround to move lambda out of expr
),
fun_call: $ =>
prec.right(PREC.CALL,
seq(
field("f", $.Name), // TODO: may be qualified
field("arguments", $.parameters),
)
),
binary_call: $ => choice(
...OPS
.map(([op, precendence]) =>
prec.left(precendence, seq(
field("left", $._exprf),
field("op", $[op]),
field("right", $._exprf),
))
)
),
// Workaround to make operators to be instructions as well
// so that they won't be stripped when naming them as fields
...OPS.reduce(
(acc, [e, _]) => ({ ...acc, [e]: $ => seq(e) }), {}
),
unary_call: $ => prec.right(8,
seq(
field("negate", $.negate),
field("arg", $._exprf)
)
),
negate: $ => choice('-', '!'),
// TODO: refactor
call: $ =>
prec.left(1,
choice(
seq($.call, par($._expr)),
par($._expr),
),
),
switch_instr: $ =>
prec.left(0, // TODO
seq(
'switch',
choice(
field('subject', $.Name),
par(field('subject', $._exprf)),
),
block(seq(
optional('|'),
sepBy1('|', field('case', $.alt)),
)),
),
),
// TODO: it may parse expr with ';' attached to the end
alt: $ =>
seq(
field("pattern", $._pattern),
'=>',
field("body", $._functional_block),
optional(';'),
),
_literal: $ =>
choice(
$.Nat,
$.Int,
$.Bool,
$.Tez,
$.String,
$.Bytes,
$.Unit,
$.Nil,
$.wildcard,
),
record_expr: $ =>
seq(
block(seq(
sepBy1(',', field("assignment", choice(
$.spread,
$.record_field,
))),
optional($._ident), // TODO: not need to be here
))
),
spread: $ => seq(
'...',
field("name", $._ident), // TODO: may be possible expression
),
record_field: $ =>
seq(
field("name", sepBy1('.', $.Name)),
':',
field("value", $._expr),
),
_statement: $ => choice(
$._instruction,
),
_instruction: $ =>
prec(PREC.EXPR, choice(
$.conditional,
$.switch_instr,
$.let_declaration,
)),
lambda: $ =>
seq(
field("lambda_head", seq(
field("arguments", $.parameters),
optional(seq(":",
field("lambda_type",
choice($._core_type, $.type_tuple),
),
))
)),
'=>',
field("lambda_body", $._functional_block)
),
parameters: $ =>
par(
sepBy(',', field("parameter", seq(
choice($._exprf, $.lambda), // TODO: workaround to move lambda our of expr
optional($._type_annotation), // TODO: move it somewhere
)))
),
_pattern: $ =>
choice(
$.cons_pattern,
$.annot_pattern,
$._core_pattern,
),
cons_pattern: $ =>
brackets(
seq(
field("head", $._core_pattern),
',',
field("tail", choice(
$.spread,
$._pattern,
)),
)
),
annot_pattern: $ =>
par(
seq(
field("subject", $._core_pattern),
':',
field("type", $._type_expr),
)
),
_core_pattern: $ =>
prec.right(PREC.CONSTR,
seq(
choice(
$.constr_pattern,
$.tuple_pattern,
$._literal,
$.Name,
),
)
),
tuple_pattern: $ =>
par(tuple(field("element", $._pattern))),
constr_pattern: $ =>
prec.right(PREC.CONSTR, // TODO: left precendence fails
seq(
field("constr", $._constr),
optional(
opar(
field("arguments", $._pattern)
),
)),
),
list_expr: $ => brackets(
sepBy(',', field("element", choice(
$.spread,
$._expr,
)))
),
conditional: $ =>
prec.left(PREC.LET,
seq(
'if',
par(field("selector", $._expr)),
field("then", $.bracket_block),
optional(seq(
'else',
field("else", $.bracket_block),
)),
),
),
_ref: $ =>
choice(
$.module_qualified,
$.struct_qualified,
$._constr,
$.list_access,
),
module_qualified: $ =>
seq(
field("module", $._constr),
nseq(seq('.', field("method", $.Name))), // TODO: capital letters
),
// TODO: may be the same as `list_access`
struct_qualified: $ =>
seq(
field("struct", $.Name),
nseq(seq('.', field("method", $._accessor))),
),
_accessor: $ => choice($.Name, $.Int),
list_access: $ =>
// prec.left(8,
seq(
field("name", $.Name),
repeat1(brackets(field("indexes", $.Int))),
// ),
),
_declaration: $ =>
field("declaration",
choice(
$.type_decl,
$.let_declaration,
$.include,
$.attr_decl,
)
),
attr_decl: $ =>
prec.left(PREC.ATTR,
nseq(brackets(
seq('@', field("name", $.Name))
))
),
type_decl: $ =>
seq(
'type',
field("type_name", $.TypeName),
'=',
field("type_value", $._type_expr),
),
_type_expr: $ =>
choice(
$._fun_type,
$.sum_type,
$.record_type,
),
_fun_type: $ =>
choice(
$.fun_type,
$._core_type,
$.type_tuple,
),
fun_type: $ =>
seq(
field("domain", choice($._core_type, $.type_tuple)),
'=>',
field("codomain", $._fun_type),
),
_core_type: $ =>
choice(
$.type_application,
$.TypeName,
$.type_string,
$.module_TypeName,
),
module_TypeName: $ =>
seq(
$.module_name,
'.',
$.TypeName,
),
type_application: $ =>
seq(
field("functor", $._core_type),
par(sepBy(',', field("parameter", $._type_expr))),
),
type_string: $ => $.String,
type_tuple: $ =>
par(sepBy1(',', field("element", $._type_expr))),
sum_type: $ =>
seq(
optional('|'),
sepBy1('|', field("variant", $.variant)),
),
variant: $ =>
seq(
field("constructor", $._constr),
optional(par(field("arguments", $._fun_type))),
),
record_type: $ =>
seq(
'{',
sepBy(',', field("field", $.field_decl)),
'}',
),
field_decl: $ =>
seq(
field("field_name", $._field_name),
':',
field("field_type", $._type_expr),
),
te: $ => choice(
$.lambda,
$._expr,
),
_functional_block: $ =>
choice(
$._statement,
$._expr,
$.fun_call,
$.bracket_block,
),
_annot_fun_call: $ => // Workaround used only in bracket blocks
par(seq(
$.fun_call,
':',
$._type_expr,
)),
bracket_block: $ =>
prec.right(1000000, // TODO: precendence
block(
choice(
seq(
sepBy(';', field("statement", choice(
$.constructor_call,
seq(
optional($.attr_decl),
$._statement,
),
$.fun_call,
// $._expr, // TODO: use only `fun_call` from there, somewhat fails if called directly
))),
optional(seq(
opar(
field("return",
choice(
$._expr,
seq( // TODO: maybe not all returned function calls need to be annotated
$.fun_call,
':',
$._type_expr, // TODO: maybe we'll need to annotate fields here, but so far we just return multiple 'return's
)
)
)
),
optional(';'),
))),
$.bracket_block,
), // TODO conflict: _group bracket_block
)
),
let_declaration: $ =>
prec.left(PREC.LET,
seq(
'let',
optional($.rec),
field("binding", choice(
sepBy1(',', $._core_pattern),
)),
optional(seq(':', field("type", $._type_expr))),
'=',
field("let_value",
choice(
$.lambda,
$._functional_block,
),
),
)
),
_type_annotation: $ =>
seq(
':',
field("type", $._type_expr)
),
pattern_term: $ =>
choice(
$.Name,
$.pattern_grouped,
),
pattern_grouped: $ =>
seq(
'(',
$._core_pattern,
optional($._type_annotation),
')',
),
pattern_list: $ => list__($._pattern),
pattern_constant: $ =>
choice(
$.Nat,
$.String,
$.Bytes,
$.Int,
),
pattern_tuple: $ => sepBy1(',', $._construct),
_construct: $ =>
choice(
seq($._constr, nseq($.pattern_term)),
par($.pattern_term),
),
///////////////////////////////////////////
_field_name: $ => $.Name,
fun_name: $ => $.Name,
struct_name: $ => $.Name,
var: $ => $.Name,
module_name: $ => $.Name_Capital,
_constr: $ => $.Name_Capital,
// TODO: remove
_ident: $ => $.Name,
comment: $ => choice(
$.oneline_comment,
$.block_comment
),
oneline_comment: $ => token(seq('//', /.*/)),
block_comment: $ => seq(
'/*',
repeat(/./),
'*/'
),
include: $ => seq('#include', $.String),
String: $ => /\"(\\.|[^"])*\"/,
Int: $ => /-?([1-9][0-9_]*|0)/,
Nat: $ => /([1-9][0-9_]*|0)n/,
Tez: $ => /([1-9][0-9_]*|0)(\.[0-9_]+)?(tz|tez|mutez)/,
Bytes: $ => /0x[0-9a-fA-F]+/,
Name: $ => /[a-z][a-zA-Z0-9_]*/,
TypeName: $ => /[a-z][a-zA-Z0-9_]*/,
Name_Capital: $ => /[A-Z][a-zA-Z0-9_]*/,
Keyword: $ => /[A-Za-z][a-z]*/,
Bool: $ => choice($.False, $.True),
include: $ => seq('#include', field("filename", $.String)),
False: $ => 'false',
True: $ => 'true',
Unit: $ => '()',
Nil: $ => '[]',
None: $ => 'None',
Some: $ => 'Some',
skip: $ => 'skip',
rec: $ => 'rec',
wildcard: $ => '_',
attr: $ => seq('[@@', $.Name, ']'),
}
});

View File

@ -0,0 +1,13 @@
try {
module.exports = require("./build/Release/tree_sitter_CAMLigo_binding");
} catch (error) {
try {
module.exports = require("./build/Debug/tree_sitter_CAMLigo_binding");
} catch (_) {
throw error
}
}
try {
module.exports.nodeTypeInfo = require("./src/node-types.json");
} catch (_) {}