/// // @ts-check module.exports = grammar({ name: "jrpc", rules: { document: ($) => repeat($._statement), _statement: ($) => choice( $.type_declaration, $.define_declaration, $.import_declaration, $.service_declaration, $.enum_declaration, ), type_declaration: ($) => seq("type", $.identifier, optional($.attributes)), attributes: ($) => seq("{", optional(seq($.attribute, repeat($.attribute))), "}"), attribute: ($) => seq($.pair, ";"), enum_declaration: ($) => seq("enum", $.identifier, $.enum_values), enum_values: ($) => seq( "{", optional(seq($._enum_value, repeat(seq(",", $._enum_value)))), "}", ), _enum_value: ($) => choice($.enum_value_declaration, $.enum_value_assignment), enum_value_assignment: ($) => seq($.identifier, "=", $.number), enum_value_declaration: ($) => seq($.identifier), define_declaration: ($) => seq("define", $.identifier, choice($.string, $.identifier), ";"), import_declaration: ($) => seq("import", $.string, ";"), service_declaration: ($) => seq("service", $.identifier, $.service_functions), service_functions: ($) => seq( "{", optional( repeat( seq( repeat($.function_decorator), choice($.service_function, $.service_notification), ), ), ), "}", ), function_decorator: ($) => seq("@", $.identifier, $.decorator_arguments), decorator_arguments: ($) => seq( "(", optional(seq($.string, optional(repeat(seq(",", $.string))))), ")", ), service_notification: ($) => seq( "notification", field("name", $.identifier), field("parameters", $.function_arguments), ";", ), service_function: ($) => seq( field("name", $.identifier), field("parameters", $.function_arguments), ":", field("return_type", $.type), ";", ), function_arguments: ($) => seq( "(", optional( seq($.function_argument, repeat(seq(",", $.function_argument))), ), ")", ), function_argument: ($) => seq( field("argument_identifier", $.identifier), ":", field("argument_type", $.type), ), pair: ($) => seq( field("key", $.identifier), optional("?"), ":", field("value", $.type), ), type: ($) => choice($.map_type, $.array_type, $.primitive_type, $.identifier), primitive_type: ($) => choice("int", "string", "float", "boolean", "void"), array_type: ($) => seq(choice($.primitive_type, $.identifier), "[]"), map_type: ($) => seq("{", $.map_key_type, ",", $.type, "}"), map_key_type: ($) => choice("int", "string"), identifier: ($) => /[a-zA-Z_][a-zA-Z_0-9]*/, string: ($) => choice(seq('"', '"'), seq('"', $._string_content, '"')), _string_content: ($) => repeat1(choice($.string_content, $.escape_sequence)), string_content: (_) => token.immediate(prec(1, /[^\\"\n]+/)), escape_sequence: (_) => token.immediate(seq("\\", /(\"|\\|\/|b|f|n|r|t|u)/)), number: ($) => /[0-9]+/, }, });