tree-sitter-vvk/grammar.js
2026-01-18 22:42:21 +01:00

90 lines
1.9 KiB
JavaScript

/**
* @file A parser for the vishvakarma build system from pantheon
* @author traxys <traxys@familleboyer.net>
* @license MIT
*/
/// <reference types="tree-sitter-cli/dsl" />
// @ts-check
module.exports = grammar({
name: "vvk",
extras: $ => [
/\s/,
$.comment,
],
rules: {
source_file: $ => repeat($._statement),
_statement: $ => choice($.mod_statement, $._directive_statement),
_directive_statement: $ => seq(
repeat($.directive),
choice($.assign_statement, $.expression)
),
mod_statement: $ => seq('mod', $.identifier, ';'),
assign_statement: $ => seq(
field('name', $.identifier),
'=',
$.expression
),
expression: $ => choice(
$.item_path,
$.string_literal,
$.array,
$.target,
),
_item_path: $ => prec.left(repeat1(seq('::', $.identifier))),
item_path: $ => $._item_path,
relative_item_path: $ => seq($.identifier, optional($._item_path)),
array: $ => seq(
'[',
optional(seq(
$.expression,
repeat(seq(',', $.expression)),
optional(','),
)),
']'
),
target: $ => seq(
field('name', $.identifier),
$._arguments,
),
argument: $ => seq(
field('name', $.identifier),
':',
field('value', $.expression),
),
_arguments: $ => seq(
'{',
optional(seq(
$.argument,
repeat(seq(',', $.argument)),
optional(','),
)),
'}'
),
string_literal: $ => seq(
'\'',
repeat(choice(
alias(token.immediate(prec(1, /[^\\'\n]+/)), $.string_content),
$.escape_sequence,
)),
'\''
),
escape_sequence: _ => token(prec(1, seq(
'\\',
/./,
))),
identifier: $ => /[a-zA-Z][a-zA-Z0-9_-]*/,
directive: $ => /@[a-z]+/,
comment: $ => token(seq('#', /[^\n]*/)),
}
});