diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..4f26421
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+node_modules/
+build/
+.build/
+package-lock.json
diff --git a/.mise.toml b/.mise.toml
new file mode 100644
index 0000000..03eb9fa
--- /dev/null
+++ b/.mise.toml
@@ -0,0 +1,4 @@
+[tools]
+node = "22.15.0"
+prek = "0.3.1"
+tree-sitter = "0.26.8"
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000..38eed5d
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,26 @@
+# See https://pre-commit.com for more information
+# See https://pre-commit.com/hooks.html for more hooks
+repos:
+ - repo: https://github.com/pre-commit/pre-commit-hooks
+ rev: v6.0.0
+ hooks:
+ - id: trailing-whitespace
+ - id: end-of-file-fixer
+ - id: check-yaml
+ - id: check-added-large-files
+ - repo: local
+ hooks:
+ - id: tree-sitter-generate
+ name: Generate tree-sitter parser
+ entry: tree-sitter
+ args: ["generate"]
+ language: system
+ files: grammar\.js$
+ pass_filenames: false
+ - id: tree-sitter-test
+ name: Run tree-sitter tests
+ entry: tree-sitter
+ args: ["test"]
+ language: system
+ types: [file]
+ pass_filenames: false
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..2252f67
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2026 Emil Lerch
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..f504d26
--- /dev/null
+++ b/README.md
@@ -0,0 +1,52 @@
+# srf-tree-sitter
+
+Tree-sitter grammar for [SRF (Simple Record Format)](https://git.lerch.org/lobo/srf).
+
+## Setup
+
+```sh
+mise install
+npm install
+```
+
+## Build & Test
+
+```sh
+mise exec -- tree-sitter generate
+mise exec -- tree-sitter test
+```
+
+## Neovim Integration
+
+Register the parser and configure highlighting in your Neovim config:
+
+```lua
+local parser_config = require("nvim-treesitter.parsers").get_parser_configs()
+parser_config.srf = {
+ install_info = {
+ url = "https://git.lerch.org/lobo/srf-tree-sitter.git",
+ files = { "src/parser.c" },
+ branch = "main",
+ },
+ filetype = "srf",
+}
+
+vim.filetype.add({
+ extension = {
+ srf = "srf",
+ },
+})
+```
+
+Then install the parser:
+
+```vim
+:TSInstall srf
+```
+
+Copy `queries/highlights.scm` to your Neovim runtime queries directory:
+
+```sh
+mkdir -p ~/.config/nvim/queries/srf
+cp queries/highlights.scm ~/.config/nvim/queries/srf/highlights.scm
+```
diff --git a/grammar.js b/grammar.js
new file mode 100644
index 0000000..3b6bd56
--- /dev/null
+++ b/grammar.js
@@ -0,0 +1,114 @@
+/**
+ * @file SRF (Simple Record Format) grammar for tree-sitter
+ * @author Emil Lerch
+ * @license MIT
+ */
+
+///
+// @ts-check
+
+module.exports = grammar({
+ name: 'srf',
+
+ extras: _ => [],
+
+ rules: {
+ document: $ => repeat($._line),
+
+ _line: $ => choice(
+ $.magic,
+ $.directive,
+ $.comment,
+ $.field,
+ $.blank_line,
+ ),
+
+ magic: $ => seq(
+ '#!srfv1',
+ optional($.inline_comment),
+ '\n',
+ ),
+
+ inline_comment: _ => /[ \t]+#[^\n]*/,
+
+ directive: $ => choice(
+ $.directive_long,
+ $.directive_compact,
+ $.directive_requireeof,
+ $.directive_eof,
+ $.directive_expires,
+ $.directive_created,
+ $.directive_modified,
+ $.directive_unknown,
+ ),
+
+ directive_long: $ => seq('#!long', optional($.inline_comment), '\n'),
+ directive_compact: $ => seq('#!compact', optional($.inline_comment), '\n'),
+ directive_requireeof: $ => seq('#!requireeof', optional($.inline_comment), '\n'),
+ directive_eof: $ => seq('#!eof', optional($.inline_comment), '\n'),
+ directive_expires: $ => seq(
+ '#!expires=',
+ field('value', $.timestamp),
+ optional($.inline_comment),
+ '\n',
+ ),
+ directive_created: $ => seq(
+ '#!created=',
+ field('value', $.timestamp),
+ optional($.inline_comment),
+ '\n',
+ ),
+ directive_modified: $ => seq(
+ '#!modified=',
+ field('value', $.timestamp),
+ optional($.inline_comment),
+ '\n',
+ ),
+ directive_unknown: _ => seq(
+ /#!/,
+ /[a-zA-Z][a-zA-Z0-9_]*/,
+ optional(seq('=', /[^\n]*/)),
+ '\n',
+ ),
+
+ timestamp: _ => /[0-9-]+/,
+
+ comment: _ => token(seq('#', optional(seq(/[^!\n]/, /[^\n]*/)), '\n')),
+
+ blank_line: _ => token(/[ \t]*\n/),
+
+ field: $ => choice(
+ $.typed_field,
+ $.untyped_field,
+ ),
+
+ typed_field: $ => seq(
+ $.key,
+ ':',
+ $.type_hint,
+ ':',
+ optional($.value),
+ /[,\n]/,
+ ),
+
+ untyped_field: $ => seq(
+ $.key,
+ '::',
+ optional($.value),
+ /[,\n]/,
+ ),
+
+ key: _ => /[^#\n:, \t][^:,]*/,
+
+ type_hint: _ => choice(
+ 'string',
+ 'num',
+ 'bool',
+ 'null',
+ 'binary',
+ /[0-9]+/,
+ ),
+
+ value: _ => /[^\n,]+/,
+ },
+});
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..8f4db9e
--- /dev/null
+++ b/package.json
@@ -0,0 +1,16 @@
+{
+ "name": "tree-sitter-srf",
+ "version": "0.0.1",
+ "description": "SRF (Simple Record Format) grammar for tree-sitter",
+ "main": "index.js",
+ "author": "Emil Lerch",
+ "license": "MIT",
+ "devDependencies": {
+ "tree-sitter-cli": "^0.26.0"
+ },
+ "scripts": {
+ "generate": "tree-sitter generate",
+ "test": "tree-sitter test",
+ "build": "tree-sitter generate && tree-sitter test"
+ }
+}
diff --git a/queries/highlights.scm b/queries/highlights.scm
new file mode 100644
index 0000000..e52ab69
--- /dev/null
+++ b/queries/highlights.scm
@@ -0,0 +1,24 @@
+(magic) @keyword.directive
+
+(directive_long) @keyword.directive
+(directive_compact) @keyword.directive
+(directive_requireeof) @keyword.directive
+(directive_eof) @keyword.directive
+(directive_expires) @keyword.directive
+(directive_created) @keyword.directive
+(directive_modified) @keyword.directive
+(directive_unknown) @keyword.directive
+
+(timestamp) @number
+
+(comment) @comment
+(inline_comment) @comment
+
+(key) @property
+
+(type_hint) @type
+
+(value) @string
+
+":" @punctuation.delimiter
+"::" @punctuation.delimiter
diff --git a/src/grammar.json b/src/grammar.json
new file mode 100644
index 0000000..73f7f06
--- /dev/null
+++ b/src/grammar.json
@@ -0,0 +1,512 @@
+{
+ "$schema": "https://tree-sitter.github.io/tree-sitter/assets/schemas/grammar.schema.json",
+ "name": "srf",
+ "rules": {
+ "document": {
+ "type": "REPEAT",
+ "content": {
+ "type": "SYMBOL",
+ "name": "_line"
+ }
+ },
+ "_line": {
+ "type": "CHOICE",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "magic"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "directive"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "comment"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "field"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "blank_line"
+ }
+ ]
+ },
+ "magic": {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "STRING",
+ "value": "#!srfv1"
+ },
+ {
+ "type": "CHOICE",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "inline_comment"
+ },
+ {
+ "type": "BLANK"
+ }
+ ]
+ },
+ {
+ "type": "STRING",
+ "value": "\n"
+ }
+ ]
+ },
+ "inline_comment": {
+ "type": "PATTERN",
+ "value": "[ \\t]+#[^\\n]*"
+ },
+ "directive": {
+ "type": "CHOICE",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "directive_long"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "directive_compact"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "directive_requireeof"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "directive_eof"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "directive_expires"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "directive_created"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "directive_modified"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "directive_unknown"
+ }
+ ]
+ },
+ "directive_long": {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "STRING",
+ "value": "#!long"
+ },
+ {
+ "type": "CHOICE",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "inline_comment"
+ },
+ {
+ "type": "BLANK"
+ }
+ ]
+ },
+ {
+ "type": "STRING",
+ "value": "\n"
+ }
+ ]
+ },
+ "directive_compact": {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "STRING",
+ "value": "#!compact"
+ },
+ {
+ "type": "CHOICE",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "inline_comment"
+ },
+ {
+ "type": "BLANK"
+ }
+ ]
+ },
+ {
+ "type": "STRING",
+ "value": "\n"
+ }
+ ]
+ },
+ "directive_requireeof": {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "STRING",
+ "value": "#!requireeof"
+ },
+ {
+ "type": "CHOICE",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "inline_comment"
+ },
+ {
+ "type": "BLANK"
+ }
+ ]
+ },
+ {
+ "type": "STRING",
+ "value": "\n"
+ }
+ ]
+ },
+ "directive_eof": {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "STRING",
+ "value": "#!eof"
+ },
+ {
+ "type": "CHOICE",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "inline_comment"
+ },
+ {
+ "type": "BLANK"
+ }
+ ]
+ },
+ {
+ "type": "STRING",
+ "value": "\n"
+ }
+ ]
+ },
+ "directive_expires": {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "STRING",
+ "value": "#!expires="
+ },
+ {
+ "type": "FIELD",
+ "name": "value",
+ "content": {
+ "type": "SYMBOL",
+ "name": "timestamp"
+ }
+ },
+ {
+ "type": "CHOICE",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "inline_comment"
+ },
+ {
+ "type": "BLANK"
+ }
+ ]
+ },
+ {
+ "type": "STRING",
+ "value": "\n"
+ }
+ ]
+ },
+ "directive_created": {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "STRING",
+ "value": "#!created="
+ },
+ {
+ "type": "FIELD",
+ "name": "value",
+ "content": {
+ "type": "SYMBOL",
+ "name": "timestamp"
+ }
+ },
+ {
+ "type": "CHOICE",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "inline_comment"
+ },
+ {
+ "type": "BLANK"
+ }
+ ]
+ },
+ {
+ "type": "STRING",
+ "value": "\n"
+ }
+ ]
+ },
+ "directive_modified": {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "STRING",
+ "value": "#!modified="
+ },
+ {
+ "type": "FIELD",
+ "name": "value",
+ "content": {
+ "type": "SYMBOL",
+ "name": "timestamp"
+ }
+ },
+ {
+ "type": "CHOICE",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "inline_comment"
+ },
+ {
+ "type": "BLANK"
+ }
+ ]
+ },
+ {
+ "type": "STRING",
+ "value": "\n"
+ }
+ ]
+ },
+ "directive_unknown": {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "PATTERN",
+ "value": "#!"
+ },
+ {
+ "type": "PATTERN",
+ "value": "[a-zA-Z][a-zA-Z0-9_]*"
+ },
+ {
+ "type": "CHOICE",
+ "members": [
+ {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "STRING",
+ "value": "="
+ },
+ {
+ "type": "PATTERN",
+ "value": "[^\\n]*"
+ }
+ ]
+ },
+ {
+ "type": "BLANK"
+ }
+ ]
+ },
+ {
+ "type": "STRING",
+ "value": "\n"
+ }
+ ]
+ },
+ "timestamp": {
+ "type": "PATTERN",
+ "value": "[0-9-]+"
+ },
+ "comment": {
+ "type": "TOKEN",
+ "content": {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "STRING",
+ "value": "#"
+ },
+ {
+ "type": "CHOICE",
+ "members": [
+ {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "PATTERN",
+ "value": "[^!\\n]"
+ },
+ {
+ "type": "PATTERN",
+ "value": "[^\\n]*"
+ }
+ ]
+ },
+ {
+ "type": "BLANK"
+ }
+ ]
+ },
+ {
+ "type": "STRING",
+ "value": "\n"
+ }
+ ]
+ }
+ },
+ "blank_line": {
+ "type": "TOKEN",
+ "content": {
+ "type": "PATTERN",
+ "value": "[ \\t]*\\n"
+ }
+ },
+ "field": {
+ "type": "CHOICE",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "typed_field"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "untyped_field"
+ }
+ ]
+ },
+ "typed_field": {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "key"
+ },
+ {
+ "type": "STRING",
+ "value": ":"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "type_hint"
+ },
+ {
+ "type": "STRING",
+ "value": ":"
+ },
+ {
+ "type": "CHOICE",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "value"
+ },
+ {
+ "type": "BLANK"
+ }
+ ]
+ },
+ {
+ "type": "PATTERN",
+ "value": "[,\\n]"
+ }
+ ]
+ },
+ "untyped_field": {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "key"
+ },
+ {
+ "type": "STRING",
+ "value": "::"
+ },
+ {
+ "type": "CHOICE",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "value"
+ },
+ {
+ "type": "BLANK"
+ }
+ ]
+ },
+ {
+ "type": "PATTERN",
+ "value": "[,\\n]"
+ }
+ ]
+ },
+ "key": {
+ "type": "PATTERN",
+ "value": "[^#\\n:, \\t][^:,]*"
+ },
+ "type_hint": {
+ "type": "CHOICE",
+ "members": [
+ {
+ "type": "STRING",
+ "value": "string"
+ },
+ {
+ "type": "STRING",
+ "value": "num"
+ },
+ {
+ "type": "STRING",
+ "value": "bool"
+ },
+ {
+ "type": "STRING",
+ "value": "null"
+ },
+ {
+ "type": "STRING",
+ "value": "binary"
+ },
+ {
+ "type": "PATTERN",
+ "value": "[0-9]+"
+ }
+ ]
+ },
+ "value": {
+ "type": "PATTERN",
+ "value": "[^\\n,]+"
+ }
+ },
+ "extras": [],
+ "conflicts": [],
+ "precedences": [],
+ "externals": [],
+ "inline": [],
+ "supertypes": [],
+ "reserved": {}
+}
\ No newline at end of file
diff --git a/src/node-types.json b/src/node-types.json
new file mode 100644
index 0000000..a844e49
--- /dev/null
+++ b/src/node-types.json
@@ -0,0 +1,393 @@
+[
+ {
+ "type": "directive",
+ "named": true,
+ "fields": {},
+ "children": {
+ "multiple": false,
+ "required": true,
+ "types": [
+ {
+ "type": "directive_compact",
+ "named": true
+ },
+ {
+ "type": "directive_created",
+ "named": true
+ },
+ {
+ "type": "directive_eof",
+ "named": true
+ },
+ {
+ "type": "directive_expires",
+ "named": true
+ },
+ {
+ "type": "directive_long",
+ "named": true
+ },
+ {
+ "type": "directive_modified",
+ "named": true
+ },
+ {
+ "type": "directive_requireeof",
+ "named": true
+ },
+ {
+ "type": "directive_unknown",
+ "named": true
+ }
+ ]
+ }
+ },
+ {
+ "type": "directive_compact",
+ "named": true,
+ "fields": {},
+ "children": {
+ "multiple": false,
+ "required": false,
+ "types": [
+ {
+ "type": "inline_comment",
+ "named": true
+ }
+ ]
+ }
+ },
+ {
+ "type": "directive_created",
+ "named": true,
+ "fields": {
+ "value": {
+ "multiple": false,
+ "required": true,
+ "types": [
+ {
+ "type": "timestamp",
+ "named": true
+ }
+ ]
+ }
+ },
+ "children": {
+ "multiple": false,
+ "required": false,
+ "types": [
+ {
+ "type": "inline_comment",
+ "named": true
+ }
+ ]
+ }
+ },
+ {
+ "type": "directive_eof",
+ "named": true,
+ "fields": {},
+ "children": {
+ "multiple": false,
+ "required": false,
+ "types": [
+ {
+ "type": "inline_comment",
+ "named": true
+ }
+ ]
+ }
+ },
+ {
+ "type": "directive_expires",
+ "named": true,
+ "fields": {
+ "value": {
+ "multiple": false,
+ "required": true,
+ "types": [
+ {
+ "type": "timestamp",
+ "named": true
+ }
+ ]
+ }
+ },
+ "children": {
+ "multiple": false,
+ "required": false,
+ "types": [
+ {
+ "type": "inline_comment",
+ "named": true
+ }
+ ]
+ }
+ },
+ {
+ "type": "directive_long",
+ "named": true,
+ "fields": {},
+ "children": {
+ "multiple": false,
+ "required": false,
+ "types": [
+ {
+ "type": "inline_comment",
+ "named": true
+ }
+ ]
+ }
+ },
+ {
+ "type": "directive_modified",
+ "named": true,
+ "fields": {
+ "value": {
+ "multiple": false,
+ "required": true,
+ "types": [
+ {
+ "type": "timestamp",
+ "named": true
+ }
+ ]
+ }
+ },
+ "children": {
+ "multiple": false,
+ "required": false,
+ "types": [
+ {
+ "type": "inline_comment",
+ "named": true
+ }
+ ]
+ }
+ },
+ {
+ "type": "directive_requireeof",
+ "named": true,
+ "fields": {},
+ "children": {
+ "multiple": false,
+ "required": false,
+ "types": [
+ {
+ "type": "inline_comment",
+ "named": true
+ }
+ ]
+ }
+ },
+ {
+ "type": "directive_unknown",
+ "named": true,
+ "fields": {}
+ },
+ {
+ "type": "document",
+ "named": true,
+ "root": true,
+ "fields": {},
+ "children": {
+ "multiple": true,
+ "required": false,
+ "types": [
+ {
+ "type": "blank_line",
+ "named": true
+ },
+ {
+ "type": "comment",
+ "named": true
+ },
+ {
+ "type": "directive",
+ "named": true
+ },
+ {
+ "type": "field",
+ "named": true
+ },
+ {
+ "type": "magic",
+ "named": true
+ }
+ ]
+ }
+ },
+ {
+ "type": "field",
+ "named": true,
+ "fields": {},
+ "children": {
+ "multiple": false,
+ "required": true,
+ "types": [
+ {
+ "type": "typed_field",
+ "named": true
+ },
+ {
+ "type": "untyped_field",
+ "named": true
+ }
+ ]
+ }
+ },
+ {
+ "type": "magic",
+ "named": true,
+ "fields": {},
+ "children": {
+ "multiple": false,
+ "required": false,
+ "types": [
+ {
+ "type": "inline_comment",
+ "named": true
+ }
+ ]
+ }
+ },
+ {
+ "type": "type_hint",
+ "named": true,
+ "fields": {}
+ },
+ {
+ "type": "typed_field",
+ "named": true,
+ "fields": {},
+ "children": {
+ "multiple": true,
+ "required": true,
+ "types": [
+ {
+ "type": "key",
+ "named": true
+ },
+ {
+ "type": "type_hint",
+ "named": true
+ },
+ {
+ "type": "value",
+ "named": true
+ }
+ ]
+ }
+ },
+ {
+ "type": "untyped_field",
+ "named": true,
+ "fields": {},
+ "children": {
+ "multiple": true,
+ "required": true,
+ "types": [
+ {
+ "type": "key",
+ "named": true
+ },
+ {
+ "type": "value",
+ "named": true
+ }
+ ]
+ }
+ },
+ {
+ "type": "\n",
+ "named": false
+ },
+ {
+ "type": "#!compact",
+ "named": false
+ },
+ {
+ "type": "#!created=",
+ "named": false
+ },
+ {
+ "type": "#!eof",
+ "named": false
+ },
+ {
+ "type": "#!expires=",
+ "named": false
+ },
+ {
+ "type": "#!long",
+ "named": false
+ },
+ {
+ "type": "#!modified=",
+ "named": false
+ },
+ {
+ "type": "#!requireeof",
+ "named": false
+ },
+ {
+ "type": "#!srfv1",
+ "named": false
+ },
+ {
+ "type": ":",
+ "named": false
+ },
+ {
+ "type": "::",
+ "named": false
+ },
+ {
+ "type": "=",
+ "named": false
+ },
+ {
+ "type": "binary",
+ "named": false
+ },
+ {
+ "type": "blank_line",
+ "named": true
+ },
+ {
+ "type": "bool",
+ "named": false
+ },
+ {
+ "type": "comment",
+ "named": true
+ },
+ {
+ "type": "inline_comment",
+ "named": true
+ },
+ {
+ "type": "key",
+ "named": true
+ },
+ {
+ "type": "null",
+ "named": false
+ },
+ {
+ "type": "num",
+ "named": false
+ },
+ {
+ "type": "string",
+ "named": false
+ },
+ {
+ "type": "timestamp",
+ "named": true
+ },
+ {
+ "type": "value",
+ "named": true
+ }
+]
\ No newline at end of file
diff --git a/src/parser.c b/src/parser.c
new file mode 100644
index 0000000..1a375cc
--- /dev/null
+++ b/src/parser.c
@@ -0,0 +1,1917 @@
+/* Automatically @generated by tree-sitter */
+
+#include "tree_sitter/parser.h"
+
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
+#endif
+
+#define LANGUAGE_VERSION 15
+#define STATE_COUNT 60
+#define LARGE_STATE_COUNT 4
+#define SYMBOL_COUNT 46
+#define ALIAS_COUNT 0
+#define TOKEN_COUNT 29
+#define EXTERNAL_TOKEN_COUNT 0
+#define FIELD_COUNT 1
+#define MAX_ALIAS_SEQUENCE_LENGTH 6
+#define MAX_RESERVED_WORD_SET_SIZE 0
+#define PRODUCTION_ID_COUNT 2
+#define SUPERTYPE_COUNT 0
+
+enum ts_symbol_identifiers {
+ anon_sym_POUND_BANGsrfv1 = 1,
+ anon_sym_LF = 2,
+ sym_inline_comment = 3,
+ anon_sym_POUND_BANGlong = 4,
+ anon_sym_POUND_BANGcompact = 5,
+ anon_sym_POUND_BANGrequireeof = 6,
+ anon_sym_POUND_BANGeof = 7,
+ anon_sym_POUND_BANGexpires_EQ = 8,
+ anon_sym_POUND_BANGcreated_EQ = 9,
+ anon_sym_POUND_BANGmodified_EQ = 10,
+ aux_sym_directive_unknown_token1 = 11,
+ aux_sym_directive_unknown_token2 = 12,
+ anon_sym_EQ = 13,
+ aux_sym_directive_unknown_token3 = 14,
+ sym_timestamp = 15,
+ sym_comment = 16,
+ sym_blank_line = 17,
+ anon_sym_COLON = 18,
+ aux_sym_typed_field_token1 = 19,
+ anon_sym_COLON_COLON = 20,
+ sym_key = 21,
+ anon_sym_string = 22,
+ anon_sym_num = 23,
+ anon_sym_bool = 24,
+ anon_sym_null = 25,
+ anon_sym_binary = 26,
+ aux_sym_type_hint_token1 = 27,
+ sym_value = 28,
+ sym_document = 29,
+ sym__line = 30,
+ sym_magic = 31,
+ sym_directive = 32,
+ sym_directive_long = 33,
+ sym_directive_compact = 34,
+ sym_directive_requireeof = 35,
+ sym_directive_eof = 36,
+ sym_directive_expires = 37,
+ sym_directive_created = 38,
+ sym_directive_modified = 39,
+ sym_directive_unknown = 40,
+ sym_field = 41,
+ sym_typed_field = 42,
+ sym_untyped_field = 43,
+ sym_type_hint = 44,
+ aux_sym_document_repeat1 = 45,
+};
+
+static const char * const ts_symbol_names[] = {
+ [ts_builtin_sym_end] = "end",
+ [anon_sym_POUND_BANGsrfv1] = "#!srfv1",
+ [anon_sym_LF] = "\n",
+ [sym_inline_comment] = "inline_comment",
+ [anon_sym_POUND_BANGlong] = "#!long",
+ [anon_sym_POUND_BANGcompact] = "#!compact",
+ [anon_sym_POUND_BANGrequireeof] = "#!requireeof",
+ [anon_sym_POUND_BANGeof] = "#!eof",
+ [anon_sym_POUND_BANGexpires_EQ] = "#!expires=",
+ [anon_sym_POUND_BANGcreated_EQ] = "#!created=",
+ [anon_sym_POUND_BANGmodified_EQ] = "#!modified=",
+ [aux_sym_directive_unknown_token1] = "directive_unknown_token1",
+ [aux_sym_directive_unknown_token2] = "directive_unknown_token2",
+ [anon_sym_EQ] = "=",
+ [aux_sym_directive_unknown_token3] = "directive_unknown_token3",
+ [sym_timestamp] = "timestamp",
+ [sym_comment] = "comment",
+ [sym_blank_line] = "blank_line",
+ [anon_sym_COLON] = ":",
+ [aux_sym_typed_field_token1] = "typed_field_token1",
+ [anon_sym_COLON_COLON] = "::",
+ [sym_key] = "key",
+ [anon_sym_string] = "string",
+ [anon_sym_num] = "num",
+ [anon_sym_bool] = "bool",
+ [anon_sym_null] = "null",
+ [anon_sym_binary] = "binary",
+ [aux_sym_type_hint_token1] = "type_hint_token1",
+ [sym_value] = "value",
+ [sym_document] = "document",
+ [sym__line] = "_line",
+ [sym_magic] = "magic",
+ [sym_directive] = "directive",
+ [sym_directive_long] = "directive_long",
+ [sym_directive_compact] = "directive_compact",
+ [sym_directive_requireeof] = "directive_requireeof",
+ [sym_directive_eof] = "directive_eof",
+ [sym_directive_expires] = "directive_expires",
+ [sym_directive_created] = "directive_created",
+ [sym_directive_modified] = "directive_modified",
+ [sym_directive_unknown] = "directive_unknown",
+ [sym_field] = "field",
+ [sym_typed_field] = "typed_field",
+ [sym_untyped_field] = "untyped_field",
+ [sym_type_hint] = "type_hint",
+ [aux_sym_document_repeat1] = "document_repeat1",
+};
+
+static const TSSymbol ts_symbol_map[] = {
+ [ts_builtin_sym_end] = ts_builtin_sym_end,
+ [anon_sym_POUND_BANGsrfv1] = anon_sym_POUND_BANGsrfv1,
+ [anon_sym_LF] = anon_sym_LF,
+ [sym_inline_comment] = sym_inline_comment,
+ [anon_sym_POUND_BANGlong] = anon_sym_POUND_BANGlong,
+ [anon_sym_POUND_BANGcompact] = anon_sym_POUND_BANGcompact,
+ [anon_sym_POUND_BANGrequireeof] = anon_sym_POUND_BANGrequireeof,
+ [anon_sym_POUND_BANGeof] = anon_sym_POUND_BANGeof,
+ [anon_sym_POUND_BANGexpires_EQ] = anon_sym_POUND_BANGexpires_EQ,
+ [anon_sym_POUND_BANGcreated_EQ] = anon_sym_POUND_BANGcreated_EQ,
+ [anon_sym_POUND_BANGmodified_EQ] = anon_sym_POUND_BANGmodified_EQ,
+ [aux_sym_directive_unknown_token1] = aux_sym_directive_unknown_token1,
+ [aux_sym_directive_unknown_token2] = aux_sym_directive_unknown_token2,
+ [anon_sym_EQ] = anon_sym_EQ,
+ [aux_sym_directive_unknown_token3] = aux_sym_directive_unknown_token3,
+ [sym_timestamp] = sym_timestamp,
+ [sym_comment] = sym_comment,
+ [sym_blank_line] = sym_blank_line,
+ [anon_sym_COLON] = anon_sym_COLON,
+ [aux_sym_typed_field_token1] = aux_sym_typed_field_token1,
+ [anon_sym_COLON_COLON] = anon_sym_COLON_COLON,
+ [sym_key] = sym_key,
+ [anon_sym_string] = anon_sym_string,
+ [anon_sym_num] = anon_sym_num,
+ [anon_sym_bool] = anon_sym_bool,
+ [anon_sym_null] = anon_sym_null,
+ [anon_sym_binary] = anon_sym_binary,
+ [aux_sym_type_hint_token1] = aux_sym_type_hint_token1,
+ [sym_value] = sym_value,
+ [sym_document] = sym_document,
+ [sym__line] = sym__line,
+ [sym_magic] = sym_magic,
+ [sym_directive] = sym_directive,
+ [sym_directive_long] = sym_directive_long,
+ [sym_directive_compact] = sym_directive_compact,
+ [sym_directive_requireeof] = sym_directive_requireeof,
+ [sym_directive_eof] = sym_directive_eof,
+ [sym_directive_expires] = sym_directive_expires,
+ [sym_directive_created] = sym_directive_created,
+ [sym_directive_modified] = sym_directive_modified,
+ [sym_directive_unknown] = sym_directive_unknown,
+ [sym_field] = sym_field,
+ [sym_typed_field] = sym_typed_field,
+ [sym_untyped_field] = sym_untyped_field,
+ [sym_type_hint] = sym_type_hint,
+ [aux_sym_document_repeat1] = aux_sym_document_repeat1,
+};
+
+static const TSSymbolMetadata ts_symbol_metadata[] = {
+ [ts_builtin_sym_end] = {
+ .visible = false,
+ .named = true,
+ },
+ [anon_sym_POUND_BANGsrfv1] = {
+ .visible = true,
+ .named = false,
+ },
+ [anon_sym_LF] = {
+ .visible = true,
+ .named = false,
+ },
+ [sym_inline_comment] = {
+ .visible = true,
+ .named = true,
+ },
+ [anon_sym_POUND_BANGlong] = {
+ .visible = true,
+ .named = false,
+ },
+ [anon_sym_POUND_BANGcompact] = {
+ .visible = true,
+ .named = false,
+ },
+ [anon_sym_POUND_BANGrequireeof] = {
+ .visible = true,
+ .named = false,
+ },
+ [anon_sym_POUND_BANGeof] = {
+ .visible = true,
+ .named = false,
+ },
+ [anon_sym_POUND_BANGexpires_EQ] = {
+ .visible = true,
+ .named = false,
+ },
+ [anon_sym_POUND_BANGcreated_EQ] = {
+ .visible = true,
+ .named = false,
+ },
+ [anon_sym_POUND_BANGmodified_EQ] = {
+ .visible = true,
+ .named = false,
+ },
+ [aux_sym_directive_unknown_token1] = {
+ .visible = false,
+ .named = false,
+ },
+ [aux_sym_directive_unknown_token2] = {
+ .visible = false,
+ .named = false,
+ },
+ [anon_sym_EQ] = {
+ .visible = true,
+ .named = false,
+ },
+ [aux_sym_directive_unknown_token3] = {
+ .visible = false,
+ .named = false,
+ },
+ [sym_timestamp] = {
+ .visible = true,
+ .named = true,
+ },
+ [sym_comment] = {
+ .visible = true,
+ .named = true,
+ },
+ [sym_blank_line] = {
+ .visible = true,
+ .named = true,
+ },
+ [anon_sym_COLON] = {
+ .visible = true,
+ .named = false,
+ },
+ [aux_sym_typed_field_token1] = {
+ .visible = false,
+ .named = false,
+ },
+ [anon_sym_COLON_COLON] = {
+ .visible = true,
+ .named = false,
+ },
+ [sym_key] = {
+ .visible = true,
+ .named = true,
+ },
+ [anon_sym_string] = {
+ .visible = true,
+ .named = false,
+ },
+ [anon_sym_num] = {
+ .visible = true,
+ .named = false,
+ },
+ [anon_sym_bool] = {
+ .visible = true,
+ .named = false,
+ },
+ [anon_sym_null] = {
+ .visible = true,
+ .named = false,
+ },
+ [anon_sym_binary] = {
+ .visible = true,
+ .named = false,
+ },
+ [aux_sym_type_hint_token1] = {
+ .visible = false,
+ .named = false,
+ },
+ [sym_value] = {
+ .visible = true,
+ .named = true,
+ },
+ [sym_document] = {
+ .visible = true,
+ .named = true,
+ },
+ [sym__line] = {
+ .visible = false,
+ .named = true,
+ },
+ [sym_magic] = {
+ .visible = true,
+ .named = true,
+ },
+ [sym_directive] = {
+ .visible = true,
+ .named = true,
+ },
+ [sym_directive_long] = {
+ .visible = true,
+ .named = true,
+ },
+ [sym_directive_compact] = {
+ .visible = true,
+ .named = true,
+ },
+ [sym_directive_requireeof] = {
+ .visible = true,
+ .named = true,
+ },
+ [sym_directive_eof] = {
+ .visible = true,
+ .named = true,
+ },
+ [sym_directive_expires] = {
+ .visible = true,
+ .named = true,
+ },
+ [sym_directive_created] = {
+ .visible = true,
+ .named = true,
+ },
+ [sym_directive_modified] = {
+ .visible = true,
+ .named = true,
+ },
+ [sym_directive_unknown] = {
+ .visible = true,
+ .named = true,
+ },
+ [sym_field] = {
+ .visible = true,
+ .named = true,
+ },
+ [sym_typed_field] = {
+ .visible = true,
+ .named = true,
+ },
+ [sym_untyped_field] = {
+ .visible = true,
+ .named = true,
+ },
+ [sym_type_hint] = {
+ .visible = true,
+ .named = true,
+ },
+ [aux_sym_document_repeat1] = {
+ .visible = false,
+ .named = false,
+ },
+};
+
+enum ts_field_identifiers {
+ field_value = 1,
+};
+
+static const char * const ts_field_names[] = {
+ [0] = NULL,
+ [field_value] = "value",
+};
+
+static const TSMapSlice ts_field_map_slices[PRODUCTION_ID_COUNT] = {
+ [1] = {.index = 0, .length = 1},
+};
+
+static const TSFieldMapEntry ts_field_map_entries[] = {
+ [0] =
+ {field_value, 1},
+};
+
+static const TSSymbol ts_alias_sequences[PRODUCTION_ID_COUNT][MAX_ALIAS_SEQUENCE_LENGTH] = {
+ [0] = {0},
+};
+
+static const uint16_t ts_non_terminal_alias_map[] = {
+ 0,
+};
+
+static const TSStateId ts_primary_state_ids[STATE_COUNT] = {
+ [0] = 0,
+ [1] = 1,
+ [2] = 2,
+ [3] = 3,
+ [4] = 4,
+ [5] = 5,
+ [6] = 6,
+ [7] = 7,
+ [8] = 8,
+ [9] = 9,
+ [10] = 10,
+ [11] = 11,
+ [12] = 12,
+ [13] = 13,
+ [14] = 14,
+ [15] = 15,
+ [16] = 16,
+ [17] = 17,
+ [18] = 18,
+ [19] = 19,
+ [20] = 20,
+ [21] = 21,
+ [22] = 22,
+ [23] = 23,
+ [24] = 24,
+ [25] = 25,
+ [26] = 26,
+ [27] = 27,
+ [28] = 28,
+ [29] = 29,
+ [30] = 30,
+ [31] = 31,
+ [32] = 32,
+ [33] = 33,
+ [34] = 34,
+ [35] = 35,
+ [36] = 36,
+ [37] = 37,
+ [38] = 38,
+ [39] = 39,
+ [40] = 40,
+ [41] = 41,
+ [42] = 42,
+ [43] = 43,
+ [44] = 44,
+ [45] = 45,
+ [46] = 46,
+ [47] = 47,
+ [48] = 48,
+ [49] = 49,
+ [50] = 50,
+ [51] = 51,
+ [52] = 52,
+ [53] = 53,
+ [54] = 54,
+ [55] = 55,
+ [56] = 56,
+ [57] = 57,
+ [58] = 58,
+ [59] = 59,
+};
+
+static bool ts_lex(TSLexer *lexer, TSStateId state) {
+ START_LEXER();
+ eof = lexer->eof(lexer);
+ switch (state) {
+ case 0:
+ if (eof) ADVANCE(69);
+ ADVANCE_MAP(
+ '\n', 71,
+ '#', 2,
+ ',', 105,
+ '-', 100,
+ ':', 104,
+ '=', 97,
+ 'b', 83,
+ 'n', 94,
+ 's', 93,
+ '\t', 4,
+ ' ', 4,
+ );
+ if (('0' <= lookahead && lookahead <= '9')) ADVANCE(99);
+ if (('A' <= lookahead && lookahead <= 'Z') ||
+ ('a' <= lookahead && lookahead <= 'z')) ADVANCE(96);
+ END_STATE();
+ case 1:
+ if (lookahead == '\n') ADVANCE(71);
+ if (lookahead == '=') ADVANCE(97);
+ if (lookahead == 'b') ADVANCE(32);
+ if (lookahead == 'n') ADVANCE(62);
+ if (lookahead == 's') ADVANCE(61);
+ if (lookahead == '\t' ||
+ lookahead == ' ') ADVANCE(6);
+ if (('0' <= lookahead && lookahead <= '9')) ADVANCE(118);
+ END_STATE();
+ case 2:
+ if (lookahead == '\n') ADVANCE(101);
+ if (lookahead == '!') ADVANCE(80);
+ if (lookahead != 0) ADVANCE(3);
+ END_STATE();
+ case 3:
+ if (lookahead == '\n') ADVANCE(101);
+ if (lookahead != 0) ADVANCE(3);
+ END_STATE();
+ case 4:
+ if (lookahead == '\n') ADVANCE(102);
+ if (lookahead == '#') ADVANCE(72);
+ if (lookahead == '\t' ||
+ lookahead == ' ') ADVANCE(4);
+ END_STATE();
+ case 5:
+ if (lookahead == '\n') ADVANCE(102);
+ if (lookahead == '\t' ||
+ lookahead == ' ') ADVANCE(5);
+ END_STATE();
+ case 6:
+ if (lookahead == '#') ADVANCE(72);
+ if (lookahead == '\t' ||
+ lookahead == ' ') ADVANCE(6);
+ END_STATE();
+ case 7:
+ if (lookahead == '1') ADVANCE(70);
+ END_STATE();
+ case 8:
+ if (lookahead == '=') ADVANCE(78);
+ END_STATE();
+ case 9:
+ if (lookahead == '=') ADVANCE(77);
+ END_STATE();
+ case 10:
+ if (lookahead == '=') ADVANCE(79);
+ END_STATE();
+ case 11:
+ if (lookahead == 'a') ADVANCE(60);
+ END_STATE();
+ case 12:
+ if (lookahead == 'a') ADVANCE(14);
+ END_STATE();
+ case 13:
+ if (lookahead == 'a') ADVANCE(53);
+ END_STATE();
+ case 14:
+ if (lookahead == 'c') ADVANCE(59);
+ END_STATE();
+ case 15:
+ if (lookahead == 'd') ADVANCE(8);
+ END_STATE();
+ case 16:
+ if (lookahead == 'd') ADVANCE(33);
+ END_STATE();
+ case 17:
+ if (lookahead == 'd') ADVANCE(10);
+ END_STATE();
+ case 18:
+ if (lookahead == 'e') ADVANCE(52);
+ END_STATE();
+ case 19:
+ if (lookahead == 'e') ADVANCE(11);
+ END_STATE();
+ case 20:
+ if (lookahead == 'e') ADVANCE(58);
+ END_STATE();
+ case 21:
+ if (lookahead == 'e') ADVANCE(15);
+ END_STATE();
+ case 22:
+ if (lookahead == 'e') ADVANCE(49);
+ END_STATE();
+ case 23:
+ if (lookahead == 'e') ADVANCE(17);
+ END_STATE();
+ case 24:
+ if (lookahead == 'e') ADVANCE(22);
+ END_STATE();
+ case 25:
+ if (lookahead == 'f') ADVANCE(76);
+ END_STATE();
+ case 26:
+ if (lookahead == 'f') ADVANCE(64);
+ END_STATE();
+ case 27:
+ if (lookahead == 'f') ADVANCE(75);
+ END_STATE();
+ case 28:
+ if (lookahead == 'f') ADVANCE(34);
+ END_STATE();
+ case 29:
+ if (lookahead == 'g') ADVANCE(73);
+ END_STATE();
+ case 30:
+ if (lookahead == 'g') ADVANCE(108);
+ END_STATE();
+ case 31:
+ if (lookahead == 'i') ADVANCE(55);
+ END_STATE();
+ case 32:
+ if (lookahead == 'i') ADVANCE(43);
+ if (lookahead == 'o') ADVANCE(48);
+ END_STATE();
+ case 33:
+ if (lookahead == 'i') ADVANCE(28);
+ END_STATE();
+ case 34:
+ if (lookahead == 'i') ADVANCE(23);
+ END_STATE();
+ case 35:
+ if (lookahead == 'i') ADVANCE(42);
+ END_STATE();
+ case 36:
+ if (lookahead == 'i') ADVANCE(57);
+ END_STATE();
+ case 37:
+ if (lookahead == 'l') ADVANCE(112);
+ END_STATE();
+ case 38:
+ if (lookahead == 'l') ADVANCE(114);
+ END_STATE();
+ case 39:
+ if (lookahead == 'l') ADVANCE(38);
+ if (lookahead == 'm') ADVANCE(110);
+ END_STATE();
+ case 40:
+ if (lookahead == 'm') ADVANCE(51);
+ END_STATE();
+ case 41:
+ if (lookahead == 'n') ADVANCE(29);
+ END_STATE();
+ case 42:
+ if (lookahead == 'n') ADVANCE(30);
+ END_STATE();
+ case 43:
+ if (lookahead == 'n') ADVANCE(13);
+ END_STATE();
+ case 44:
+ if (lookahead == 'o') ADVANCE(40);
+ if (lookahead == 'r') ADVANCE(19);
+ END_STATE();
+ case 45:
+ if (lookahead == 'o') ADVANCE(25);
+ if (lookahead == 'x') ADVANCE(50);
+ END_STATE();
+ case 46:
+ if (lookahead == 'o') ADVANCE(41);
+ END_STATE();
+ case 47:
+ if (lookahead == 'o') ADVANCE(16);
+ END_STATE();
+ case 48:
+ if (lookahead == 'o') ADVANCE(37);
+ END_STATE();
+ case 49:
+ if (lookahead == 'o') ADVANCE(27);
+ END_STATE();
+ case 50:
+ if (lookahead == 'p') ADVANCE(31);
+ END_STATE();
+ case 51:
+ if (lookahead == 'p') ADVANCE(12);
+ END_STATE();
+ case 52:
+ if (lookahead == 'q') ADVANCE(63);
+ END_STATE();
+ case 53:
+ if (lookahead == 'r') ADVANCE(65);
+ END_STATE();
+ case 54:
+ if (lookahead == 'r') ADVANCE(26);
+ END_STATE();
+ case 55:
+ if (lookahead == 'r') ADVANCE(20);
+ END_STATE();
+ case 56:
+ if (lookahead == 'r') ADVANCE(35);
+ END_STATE();
+ case 57:
+ if (lookahead == 'r') ADVANCE(24);
+ END_STATE();
+ case 58:
+ if (lookahead == 's') ADVANCE(9);
+ END_STATE();
+ case 59:
+ if (lookahead == 't') ADVANCE(74);
+ END_STATE();
+ case 60:
+ if (lookahead == 't') ADVANCE(21);
+ END_STATE();
+ case 61:
+ if (lookahead == 't') ADVANCE(56);
+ END_STATE();
+ case 62:
+ if (lookahead == 'u') ADVANCE(39);
+ END_STATE();
+ case 63:
+ if (lookahead == 'u') ADVANCE(36);
+ END_STATE();
+ case 64:
+ if (lookahead == 'v') ADVANCE(7);
+ END_STATE();
+ case 65:
+ if (lookahead == 'y') ADVANCE(116);
+ END_STATE();
+ case 66:
+ if (lookahead == '\n' ||
+ lookahead == ',') ADVANCE(105);
+ if (lookahead != 0) ADVANCE(119);
+ END_STATE();
+ case 67:
+ if (lookahead == '-' ||
+ ('0' <= lookahead && lookahead <= '9')) ADVANCE(100);
+ if (('A' <= lookahead && lookahead <= 'Z') ||
+ ('a' <= lookahead && lookahead <= 'z')) ADVANCE(96);
+ END_STATE();
+ case 68:
+ if (eof) ADVANCE(69);
+ if (lookahead == '\n') ADVANCE(102);
+ if (lookahead == '#') ADVANCE(2);
+ if (lookahead == ':') ADVANCE(103);
+ if (lookahead == '\t' ||
+ lookahead == ' ') ADVANCE(5);
+ if (lookahead != 0 &&
+ lookahead != ',') ADVANCE(107);
+ END_STATE();
+ case 69:
+ ACCEPT_TOKEN(ts_builtin_sym_end);
+ END_STATE();
+ case 70:
+ ACCEPT_TOKEN(anon_sym_POUND_BANGsrfv1);
+ END_STATE();
+ case 71:
+ ACCEPT_TOKEN(anon_sym_LF);
+ END_STATE();
+ case 72:
+ ACCEPT_TOKEN(sym_inline_comment);
+ if (lookahead != 0 &&
+ lookahead != '\n') ADVANCE(72);
+ END_STATE();
+ case 73:
+ ACCEPT_TOKEN(anon_sym_POUND_BANGlong);
+ END_STATE();
+ case 74:
+ ACCEPT_TOKEN(anon_sym_POUND_BANGcompact);
+ END_STATE();
+ case 75:
+ ACCEPT_TOKEN(anon_sym_POUND_BANGrequireeof);
+ END_STATE();
+ case 76:
+ ACCEPT_TOKEN(anon_sym_POUND_BANGeof);
+ END_STATE();
+ case 77:
+ ACCEPT_TOKEN(anon_sym_POUND_BANGexpires_EQ);
+ END_STATE();
+ case 78:
+ ACCEPT_TOKEN(anon_sym_POUND_BANGcreated_EQ);
+ END_STATE();
+ case 79:
+ ACCEPT_TOKEN(anon_sym_POUND_BANGmodified_EQ);
+ END_STATE();
+ case 80:
+ ACCEPT_TOKEN(aux_sym_directive_unknown_token1);
+ if (lookahead == 'c') ADVANCE(44);
+ if (lookahead == 'e') ADVANCE(45);
+ if (lookahead == 'l') ADVANCE(46);
+ if (lookahead == 'm') ADVANCE(47);
+ if (lookahead == 'r') ADVANCE(18);
+ if (lookahead == 's') ADVANCE(54);
+ END_STATE();
+ case 81:
+ ACCEPT_TOKEN(aux_sym_directive_unknown_token2);
+ if (lookahead == 'a') ADVANCE(92);
+ if (('0' <= lookahead && lookahead <= '9') ||
+ ('A' <= lookahead && lookahead <= 'Z') ||
+ lookahead == '_' ||
+ ('b' <= lookahead && lookahead <= 'z')) ADVANCE(96);
+ END_STATE();
+ case 82:
+ ACCEPT_TOKEN(aux_sym_directive_unknown_token2);
+ if (lookahead == 'g') ADVANCE(109);
+ if (('0' <= lookahead && lookahead <= '9') ||
+ ('A' <= lookahead && lookahead <= 'Z') ||
+ lookahead == '_' ||
+ ('a' <= lookahead && lookahead <= 'z')) ADVANCE(96);
+ END_STATE();
+ case 83:
+ ACCEPT_TOKEN(aux_sym_directive_unknown_token2);
+ if (lookahead == 'i') ADVANCE(88);
+ if (lookahead == 'o') ADVANCE(90);
+ if (('0' <= lookahead && lookahead <= '9') ||
+ ('A' <= lookahead && lookahead <= 'Z') ||
+ lookahead == '_' ||
+ ('a' <= lookahead && lookahead <= 'z')) ADVANCE(96);
+ END_STATE();
+ case 84:
+ ACCEPT_TOKEN(aux_sym_directive_unknown_token2);
+ if (lookahead == 'i') ADVANCE(89);
+ if (('0' <= lookahead && lookahead <= '9') ||
+ ('A' <= lookahead && lookahead <= 'Z') ||
+ lookahead == '_' ||
+ ('a' <= lookahead && lookahead <= 'z')) ADVANCE(96);
+ END_STATE();
+ case 85:
+ ACCEPT_TOKEN(aux_sym_directive_unknown_token2);
+ if (lookahead == 'l') ADVANCE(113);
+ if (('0' <= lookahead && lookahead <= '9') ||
+ ('A' <= lookahead && lookahead <= 'Z') ||
+ lookahead == '_' ||
+ ('a' <= lookahead && lookahead <= 'z')) ADVANCE(96);
+ END_STATE();
+ case 86:
+ ACCEPT_TOKEN(aux_sym_directive_unknown_token2);
+ if (lookahead == 'l') ADVANCE(115);
+ if (('0' <= lookahead && lookahead <= '9') ||
+ ('A' <= lookahead && lookahead <= 'Z') ||
+ lookahead == '_' ||
+ ('a' <= lookahead && lookahead <= 'z')) ADVANCE(96);
+ END_STATE();
+ case 87:
+ ACCEPT_TOKEN(aux_sym_directive_unknown_token2);
+ if (lookahead == 'l') ADVANCE(86);
+ if (lookahead == 'm') ADVANCE(111);
+ if (('0' <= lookahead && lookahead <= '9') ||
+ ('A' <= lookahead && lookahead <= 'Z') ||
+ lookahead == '_' ||
+ ('a' <= lookahead && lookahead <= 'z')) ADVANCE(96);
+ END_STATE();
+ case 88:
+ ACCEPT_TOKEN(aux_sym_directive_unknown_token2);
+ if (lookahead == 'n') ADVANCE(81);
+ if (('0' <= lookahead && lookahead <= '9') ||
+ ('A' <= lookahead && lookahead <= 'Z') ||
+ lookahead == '_' ||
+ ('a' <= lookahead && lookahead <= 'z')) ADVANCE(96);
+ END_STATE();
+ case 89:
+ ACCEPT_TOKEN(aux_sym_directive_unknown_token2);
+ if (lookahead == 'n') ADVANCE(82);
+ if (('0' <= lookahead && lookahead <= '9') ||
+ ('A' <= lookahead && lookahead <= 'Z') ||
+ lookahead == '_' ||
+ ('a' <= lookahead && lookahead <= 'z')) ADVANCE(96);
+ END_STATE();
+ case 90:
+ ACCEPT_TOKEN(aux_sym_directive_unknown_token2);
+ if (lookahead == 'o') ADVANCE(85);
+ if (('0' <= lookahead && lookahead <= '9') ||
+ ('A' <= lookahead && lookahead <= 'Z') ||
+ lookahead == '_' ||
+ ('a' <= lookahead && lookahead <= 'z')) ADVANCE(96);
+ END_STATE();
+ case 91:
+ ACCEPT_TOKEN(aux_sym_directive_unknown_token2);
+ if (lookahead == 'r') ADVANCE(84);
+ if (('0' <= lookahead && lookahead <= '9') ||
+ ('A' <= lookahead && lookahead <= 'Z') ||
+ lookahead == '_' ||
+ ('a' <= lookahead && lookahead <= 'z')) ADVANCE(96);
+ END_STATE();
+ case 92:
+ ACCEPT_TOKEN(aux_sym_directive_unknown_token2);
+ if (lookahead == 'r') ADVANCE(95);
+ if (('0' <= lookahead && lookahead <= '9') ||
+ ('A' <= lookahead && lookahead <= 'Z') ||
+ lookahead == '_' ||
+ ('a' <= lookahead && lookahead <= 'z')) ADVANCE(96);
+ END_STATE();
+ case 93:
+ ACCEPT_TOKEN(aux_sym_directive_unknown_token2);
+ if (lookahead == 't') ADVANCE(91);
+ if (('0' <= lookahead && lookahead <= '9') ||
+ ('A' <= lookahead && lookahead <= 'Z') ||
+ lookahead == '_' ||
+ ('a' <= lookahead && lookahead <= 'z')) ADVANCE(96);
+ END_STATE();
+ case 94:
+ ACCEPT_TOKEN(aux_sym_directive_unknown_token2);
+ if (lookahead == 'u') ADVANCE(87);
+ if (('0' <= lookahead && lookahead <= '9') ||
+ ('A' <= lookahead && lookahead <= 'Z') ||
+ lookahead == '_' ||
+ ('a' <= lookahead && lookahead <= 'z')) ADVANCE(96);
+ END_STATE();
+ case 95:
+ ACCEPT_TOKEN(aux_sym_directive_unknown_token2);
+ if (lookahead == 'y') ADVANCE(117);
+ if (('0' <= lookahead && lookahead <= '9') ||
+ ('A' <= lookahead && lookahead <= 'Z') ||
+ lookahead == '_' ||
+ ('a' <= lookahead && lookahead <= 'z')) ADVANCE(96);
+ END_STATE();
+ case 96:
+ ACCEPT_TOKEN(aux_sym_directive_unknown_token2);
+ if (('0' <= lookahead && lookahead <= '9') ||
+ ('A' <= lookahead && lookahead <= 'Z') ||
+ lookahead == '_' ||
+ ('a' <= lookahead && lookahead <= 'z')) ADVANCE(96);
+ END_STATE();
+ case 97:
+ ACCEPT_TOKEN(anon_sym_EQ);
+ END_STATE();
+ case 98:
+ ACCEPT_TOKEN(aux_sym_directive_unknown_token3);
+ if (lookahead != 0 &&
+ lookahead != '\n') ADVANCE(98);
+ END_STATE();
+ case 99:
+ ACCEPT_TOKEN(sym_timestamp);
+ if (lookahead == '-') ADVANCE(100);
+ if (('0' <= lookahead && lookahead <= '9')) ADVANCE(99);
+ END_STATE();
+ case 100:
+ ACCEPT_TOKEN(sym_timestamp);
+ if (lookahead == '-' ||
+ ('0' <= lookahead && lookahead <= '9')) ADVANCE(100);
+ END_STATE();
+ case 101:
+ ACCEPT_TOKEN(sym_comment);
+ END_STATE();
+ case 102:
+ ACCEPT_TOKEN(sym_blank_line);
+ END_STATE();
+ case 103:
+ ACCEPT_TOKEN(anon_sym_COLON);
+ END_STATE();
+ case 104:
+ ACCEPT_TOKEN(anon_sym_COLON);
+ if (lookahead == ':') ADVANCE(106);
+ END_STATE();
+ case 105:
+ ACCEPT_TOKEN(aux_sym_typed_field_token1);
+ END_STATE();
+ case 106:
+ ACCEPT_TOKEN(anon_sym_COLON_COLON);
+ END_STATE();
+ case 107:
+ ACCEPT_TOKEN(sym_key);
+ if (lookahead != 0 &&
+ lookahead != ',' &&
+ lookahead != ':') ADVANCE(107);
+ END_STATE();
+ case 108:
+ ACCEPT_TOKEN(anon_sym_string);
+ END_STATE();
+ case 109:
+ ACCEPT_TOKEN(anon_sym_string);
+ if (('0' <= lookahead && lookahead <= '9') ||
+ ('A' <= lookahead && lookahead <= 'Z') ||
+ lookahead == '_' ||
+ ('a' <= lookahead && lookahead <= 'z')) ADVANCE(96);
+ END_STATE();
+ case 110:
+ ACCEPT_TOKEN(anon_sym_num);
+ END_STATE();
+ case 111:
+ ACCEPT_TOKEN(anon_sym_num);
+ if (('0' <= lookahead && lookahead <= '9') ||
+ ('A' <= lookahead && lookahead <= 'Z') ||
+ lookahead == '_' ||
+ ('a' <= lookahead && lookahead <= 'z')) ADVANCE(96);
+ END_STATE();
+ case 112:
+ ACCEPT_TOKEN(anon_sym_bool);
+ END_STATE();
+ case 113:
+ ACCEPT_TOKEN(anon_sym_bool);
+ if (('0' <= lookahead && lookahead <= '9') ||
+ ('A' <= lookahead && lookahead <= 'Z') ||
+ lookahead == '_' ||
+ ('a' <= lookahead && lookahead <= 'z')) ADVANCE(96);
+ END_STATE();
+ case 114:
+ ACCEPT_TOKEN(anon_sym_null);
+ END_STATE();
+ case 115:
+ ACCEPT_TOKEN(anon_sym_null);
+ if (('0' <= lookahead && lookahead <= '9') ||
+ ('A' <= lookahead && lookahead <= 'Z') ||
+ lookahead == '_' ||
+ ('a' <= lookahead && lookahead <= 'z')) ADVANCE(96);
+ END_STATE();
+ case 116:
+ ACCEPT_TOKEN(anon_sym_binary);
+ END_STATE();
+ case 117:
+ ACCEPT_TOKEN(anon_sym_binary);
+ if (('0' <= lookahead && lookahead <= '9') ||
+ ('A' <= lookahead && lookahead <= 'Z') ||
+ lookahead == '_' ||
+ ('a' <= lookahead && lookahead <= 'z')) ADVANCE(96);
+ END_STATE();
+ case 118:
+ ACCEPT_TOKEN(aux_sym_type_hint_token1);
+ if (('0' <= lookahead && lookahead <= '9')) ADVANCE(118);
+ END_STATE();
+ case 119:
+ ACCEPT_TOKEN(sym_value);
+ if (lookahead != 0 &&
+ lookahead != '\n' &&
+ lookahead != ',') ADVANCE(119);
+ END_STATE();
+ default:
+ return false;
+ }
+}
+
+static const TSLexerMode ts_lex_modes[STATE_COUNT] = {
+ [0] = {.lex_state = 0},
+ [1] = {.lex_state = 68},
+ [2] = {.lex_state = 68},
+ [3] = {.lex_state = 68},
+ [4] = {.lex_state = 68},
+ [5] = {.lex_state = 68},
+ [6] = {.lex_state = 68},
+ [7] = {.lex_state = 68},
+ [8] = {.lex_state = 68},
+ [9] = {.lex_state = 68},
+ [10] = {.lex_state = 68},
+ [11] = {.lex_state = 68},
+ [12] = {.lex_state = 68},
+ [13] = {.lex_state = 68},
+ [14] = {.lex_state = 68},
+ [15] = {.lex_state = 68},
+ [16] = {.lex_state = 68},
+ [17] = {.lex_state = 68},
+ [18] = {.lex_state = 68},
+ [19] = {.lex_state = 68},
+ [20] = {.lex_state = 68},
+ [21] = {.lex_state = 68},
+ [22] = {.lex_state = 68},
+ [23] = {.lex_state = 68},
+ [24] = {.lex_state = 68},
+ [25] = {.lex_state = 68},
+ [26] = {.lex_state = 68},
+ [27] = {.lex_state = 68},
+ [28] = {.lex_state = 1},
+ [29] = {.lex_state = 1},
+ [30] = {.lex_state = 0},
+ [31] = {.lex_state = 66},
+ [32] = {.lex_state = 1},
+ [33] = {.lex_state = 1},
+ [34] = {.lex_state = 1},
+ [35] = {.lex_state = 1},
+ [36] = {.lex_state = 1},
+ [37] = {.lex_state = 1},
+ [38] = {.lex_state = 1},
+ [39] = {.lex_state = 66},
+ [40] = {.lex_state = 1},
+ [41] = {.lex_state = 0},
+ [42] = {.lex_state = 1},
+ [43] = {.lex_state = 1},
+ [44] = {.lex_state = 1},
+ [45] = {.lex_state = 1},
+ [46] = {.lex_state = 67},
+ [47] = {.lex_state = 1},
+ [48] = {.lex_state = 1},
+ [49] = {.lex_state = 67},
+ [50] = {.lex_state = 66},
+ [51] = {.lex_state = 98},
+ [52] = {.lex_state = 67},
+ [53] = {.lex_state = 1},
+ [54] = {.lex_state = 1},
+ [55] = {.lex_state = 68},
+ [56] = {.lex_state = 68},
+ [57] = {.lex_state = 1},
+ [58] = {.lex_state = 67},
+ [59] = {.lex_state = 66},
+};
+
+static const uint16_t ts_parse_table[LARGE_STATE_COUNT][SYMBOL_COUNT] = {
+ [STATE(0)] = {
+ [ts_builtin_sym_end] = ACTIONS(1),
+ [anon_sym_POUND_BANGsrfv1] = ACTIONS(1),
+ [anon_sym_LF] = ACTIONS(1),
+ [sym_inline_comment] = ACTIONS(1),
+ [anon_sym_POUND_BANGlong] = ACTIONS(1),
+ [anon_sym_POUND_BANGcompact] = ACTIONS(1),
+ [anon_sym_POUND_BANGrequireeof] = ACTIONS(1),
+ [anon_sym_POUND_BANGeof] = ACTIONS(1),
+ [anon_sym_POUND_BANGexpires_EQ] = ACTIONS(1),
+ [anon_sym_POUND_BANGcreated_EQ] = ACTIONS(1),
+ [anon_sym_POUND_BANGmodified_EQ] = ACTIONS(1),
+ [aux_sym_directive_unknown_token1] = ACTIONS(1),
+ [aux_sym_directive_unknown_token2] = ACTIONS(1),
+ [anon_sym_EQ] = ACTIONS(1),
+ [sym_timestamp] = ACTIONS(1),
+ [sym_comment] = ACTIONS(1),
+ [sym_blank_line] = ACTIONS(1),
+ [anon_sym_COLON] = ACTIONS(1),
+ [aux_sym_typed_field_token1] = ACTIONS(1),
+ [anon_sym_COLON_COLON] = ACTIONS(1),
+ [anon_sym_string] = ACTIONS(1),
+ [anon_sym_num] = ACTIONS(1),
+ [anon_sym_bool] = ACTIONS(1),
+ [anon_sym_null] = ACTIONS(1),
+ [anon_sym_binary] = ACTIONS(1),
+ [aux_sym_type_hint_token1] = ACTIONS(1),
+ },
+ [STATE(1)] = {
+ [sym_document] = STATE(41),
+ [sym__line] = STATE(3),
+ [sym_magic] = STATE(3),
+ [sym_directive] = STATE(3),
+ [sym_directive_long] = STATE(5),
+ [sym_directive_compact] = STATE(5),
+ [sym_directive_requireeof] = STATE(5),
+ [sym_directive_eof] = STATE(5),
+ [sym_directive_expires] = STATE(5),
+ [sym_directive_created] = STATE(5),
+ [sym_directive_modified] = STATE(5),
+ [sym_directive_unknown] = STATE(5),
+ [sym_field] = STATE(3),
+ [sym_typed_field] = STATE(9),
+ [sym_untyped_field] = STATE(9),
+ [aux_sym_document_repeat1] = STATE(3),
+ [ts_builtin_sym_end] = ACTIONS(3),
+ [anon_sym_POUND_BANGsrfv1] = ACTIONS(5),
+ [anon_sym_POUND_BANGlong] = ACTIONS(7),
+ [anon_sym_POUND_BANGcompact] = ACTIONS(9),
+ [anon_sym_POUND_BANGrequireeof] = ACTIONS(11),
+ [anon_sym_POUND_BANGeof] = ACTIONS(13),
+ [anon_sym_POUND_BANGexpires_EQ] = ACTIONS(15),
+ [anon_sym_POUND_BANGcreated_EQ] = ACTIONS(17),
+ [anon_sym_POUND_BANGmodified_EQ] = ACTIONS(19),
+ [aux_sym_directive_unknown_token1] = ACTIONS(21),
+ [sym_comment] = ACTIONS(23),
+ [sym_blank_line] = ACTIONS(23),
+ [sym_key] = ACTIONS(25),
+ },
+ [STATE(2)] = {
+ [sym__line] = STATE(2),
+ [sym_magic] = STATE(2),
+ [sym_directive] = STATE(2),
+ [sym_directive_long] = STATE(5),
+ [sym_directive_compact] = STATE(5),
+ [sym_directive_requireeof] = STATE(5),
+ [sym_directive_eof] = STATE(5),
+ [sym_directive_expires] = STATE(5),
+ [sym_directive_created] = STATE(5),
+ [sym_directive_modified] = STATE(5),
+ [sym_directive_unknown] = STATE(5),
+ [sym_field] = STATE(2),
+ [sym_typed_field] = STATE(9),
+ [sym_untyped_field] = STATE(9),
+ [aux_sym_document_repeat1] = STATE(2),
+ [ts_builtin_sym_end] = ACTIONS(27),
+ [anon_sym_POUND_BANGsrfv1] = ACTIONS(29),
+ [anon_sym_POUND_BANGlong] = ACTIONS(32),
+ [anon_sym_POUND_BANGcompact] = ACTIONS(35),
+ [anon_sym_POUND_BANGrequireeof] = ACTIONS(38),
+ [anon_sym_POUND_BANGeof] = ACTIONS(41),
+ [anon_sym_POUND_BANGexpires_EQ] = ACTIONS(44),
+ [anon_sym_POUND_BANGcreated_EQ] = ACTIONS(47),
+ [anon_sym_POUND_BANGmodified_EQ] = ACTIONS(50),
+ [aux_sym_directive_unknown_token1] = ACTIONS(53),
+ [sym_comment] = ACTIONS(56),
+ [sym_blank_line] = ACTIONS(56),
+ [sym_key] = ACTIONS(59),
+ },
+ [STATE(3)] = {
+ [sym__line] = STATE(2),
+ [sym_magic] = STATE(2),
+ [sym_directive] = STATE(2),
+ [sym_directive_long] = STATE(5),
+ [sym_directive_compact] = STATE(5),
+ [sym_directive_requireeof] = STATE(5),
+ [sym_directive_eof] = STATE(5),
+ [sym_directive_expires] = STATE(5),
+ [sym_directive_created] = STATE(5),
+ [sym_directive_modified] = STATE(5),
+ [sym_directive_unknown] = STATE(5),
+ [sym_field] = STATE(2),
+ [sym_typed_field] = STATE(9),
+ [sym_untyped_field] = STATE(9),
+ [aux_sym_document_repeat1] = STATE(2),
+ [ts_builtin_sym_end] = ACTIONS(62),
+ [anon_sym_POUND_BANGsrfv1] = ACTIONS(5),
+ [anon_sym_POUND_BANGlong] = ACTIONS(7),
+ [anon_sym_POUND_BANGcompact] = ACTIONS(9),
+ [anon_sym_POUND_BANGrequireeof] = ACTIONS(11),
+ [anon_sym_POUND_BANGeof] = ACTIONS(13),
+ [anon_sym_POUND_BANGexpires_EQ] = ACTIONS(15),
+ [anon_sym_POUND_BANGcreated_EQ] = ACTIONS(17),
+ [anon_sym_POUND_BANGmodified_EQ] = ACTIONS(19),
+ [aux_sym_directive_unknown_token1] = ACTIONS(21),
+ [sym_comment] = ACTIONS(64),
+ [sym_blank_line] = ACTIONS(64),
+ [sym_key] = ACTIONS(25),
+ },
+};
+
+static const uint16_t ts_small_parse_table[] = {
+ [0] = 2,
+ ACTIONS(68), 1,
+ aux_sym_directive_unknown_token1,
+ ACTIONS(66), 12,
+ ts_builtin_sym_end,
+ anon_sym_POUND_BANGsrfv1,
+ anon_sym_POUND_BANGlong,
+ anon_sym_POUND_BANGcompact,
+ anon_sym_POUND_BANGrequireeof,
+ anon_sym_POUND_BANGeof,
+ anon_sym_POUND_BANGexpires_EQ,
+ anon_sym_POUND_BANGcreated_EQ,
+ anon_sym_POUND_BANGmodified_EQ,
+ sym_comment,
+ sym_blank_line,
+ sym_key,
+ [18] = 2,
+ ACTIONS(72), 1,
+ aux_sym_directive_unknown_token1,
+ ACTIONS(70), 12,
+ ts_builtin_sym_end,
+ anon_sym_POUND_BANGsrfv1,
+ anon_sym_POUND_BANGlong,
+ anon_sym_POUND_BANGcompact,
+ anon_sym_POUND_BANGrequireeof,
+ anon_sym_POUND_BANGeof,
+ anon_sym_POUND_BANGexpires_EQ,
+ anon_sym_POUND_BANGcreated_EQ,
+ anon_sym_POUND_BANGmodified_EQ,
+ sym_comment,
+ sym_blank_line,
+ sym_key,
+ [36] = 2,
+ ACTIONS(76), 1,
+ aux_sym_directive_unknown_token1,
+ ACTIONS(74), 12,
+ ts_builtin_sym_end,
+ anon_sym_POUND_BANGsrfv1,
+ anon_sym_POUND_BANGlong,
+ anon_sym_POUND_BANGcompact,
+ anon_sym_POUND_BANGrequireeof,
+ anon_sym_POUND_BANGeof,
+ anon_sym_POUND_BANGexpires_EQ,
+ anon_sym_POUND_BANGcreated_EQ,
+ anon_sym_POUND_BANGmodified_EQ,
+ sym_comment,
+ sym_blank_line,
+ sym_key,
+ [54] = 2,
+ ACTIONS(80), 1,
+ aux_sym_directive_unknown_token1,
+ ACTIONS(78), 12,
+ ts_builtin_sym_end,
+ anon_sym_POUND_BANGsrfv1,
+ anon_sym_POUND_BANGlong,
+ anon_sym_POUND_BANGcompact,
+ anon_sym_POUND_BANGrequireeof,
+ anon_sym_POUND_BANGeof,
+ anon_sym_POUND_BANGexpires_EQ,
+ anon_sym_POUND_BANGcreated_EQ,
+ anon_sym_POUND_BANGmodified_EQ,
+ sym_comment,
+ sym_blank_line,
+ sym_key,
+ [72] = 2,
+ ACTIONS(84), 1,
+ aux_sym_directive_unknown_token1,
+ ACTIONS(82), 12,
+ ts_builtin_sym_end,
+ anon_sym_POUND_BANGsrfv1,
+ anon_sym_POUND_BANGlong,
+ anon_sym_POUND_BANGcompact,
+ anon_sym_POUND_BANGrequireeof,
+ anon_sym_POUND_BANGeof,
+ anon_sym_POUND_BANGexpires_EQ,
+ anon_sym_POUND_BANGcreated_EQ,
+ anon_sym_POUND_BANGmodified_EQ,
+ sym_comment,
+ sym_blank_line,
+ sym_key,
+ [90] = 2,
+ ACTIONS(88), 1,
+ aux_sym_directive_unknown_token1,
+ ACTIONS(86), 12,
+ ts_builtin_sym_end,
+ anon_sym_POUND_BANGsrfv1,
+ anon_sym_POUND_BANGlong,
+ anon_sym_POUND_BANGcompact,
+ anon_sym_POUND_BANGrequireeof,
+ anon_sym_POUND_BANGeof,
+ anon_sym_POUND_BANGexpires_EQ,
+ anon_sym_POUND_BANGcreated_EQ,
+ anon_sym_POUND_BANGmodified_EQ,
+ sym_comment,
+ sym_blank_line,
+ sym_key,
+ [108] = 2,
+ ACTIONS(92), 1,
+ aux_sym_directive_unknown_token1,
+ ACTIONS(90), 12,
+ ts_builtin_sym_end,
+ anon_sym_POUND_BANGsrfv1,
+ anon_sym_POUND_BANGlong,
+ anon_sym_POUND_BANGcompact,
+ anon_sym_POUND_BANGrequireeof,
+ anon_sym_POUND_BANGeof,
+ anon_sym_POUND_BANGexpires_EQ,
+ anon_sym_POUND_BANGcreated_EQ,
+ anon_sym_POUND_BANGmodified_EQ,
+ sym_comment,
+ sym_blank_line,
+ sym_key,
+ [126] = 2,
+ ACTIONS(96), 1,
+ aux_sym_directive_unknown_token1,
+ ACTIONS(94), 12,
+ ts_builtin_sym_end,
+ anon_sym_POUND_BANGsrfv1,
+ anon_sym_POUND_BANGlong,
+ anon_sym_POUND_BANGcompact,
+ anon_sym_POUND_BANGrequireeof,
+ anon_sym_POUND_BANGeof,
+ anon_sym_POUND_BANGexpires_EQ,
+ anon_sym_POUND_BANGcreated_EQ,
+ anon_sym_POUND_BANGmodified_EQ,
+ sym_comment,
+ sym_blank_line,
+ sym_key,
+ [144] = 2,
+ ACTIONS(100), 1,
+ aux_sym_directive_unknown_token1,
+ ACTIONS(98), 12,
+ ts_builtin_sym_end,
+ anon_sym_POUND_BANGsrfv1,
+ anon_sym_POUND_BANGlong,
+ anon_sym_POUND_BANGcompact,
+ anon_sym_POUND_BANGrequireeof,
+ anon_sym_POUND_BANGeof,
+ anon_sym_POUND_BANGexpires_EQ,
+ anon_sym_POUND_BANGcreated_EQ,
+ anon_sym_POUND_BANGmodified_EQ,
+ sym_comment,
+ sym_blank_line,
+ sym_key,
+ [162] = 2,
+ ACTIONS(104), 1,
+ aux_sym_directive_unknown_token1,
+ ACTIONS(102), 12,
+ ts_builtin_sym_end,
+ anon_sym_POUND_BANGsrfv1,
+ anon_sym_POUND_BANGlong,
+ anon_sym_POUND_BANGcompact,
+ anon_sym_POUND_BANGrequireeof,
+ anon_sym_POUND_BANGeof,
+ anon_sym_POUND_BANGexpires_EQ,
+ anon_sym_POUND_BANGcreated_EQ,
+ anon_sym_POUND_BANGmodified_EQ,
+ sym_comment,
+ sym_blank_line,
+ sym_key,
+ [180] = 2,
+ ACTIONS(108), 1,
+ aux_sym_directive_unknown_token1,
+ ACTIONS(106), 12,
+ ts_builtin_sym_end,
+ anon_sym_POUND_BANGsrfv1,
+ anon_sym_POUND_BANGlong,
+ anon_sym_POUND_BANGcompact,
+ anon_sym_POUND_BANGrequireeof,
+ anon_sym_POUND_BANGeof,
+ anon_sym_POUND_BANGexpires_EQ,
+ anon_sym_POUND_BANGcreated_EQ,
+ anon_sym_POUND_BANGmodified_EQ,
+ sym_comment,
+ sym_blank_line,
+ sym_key,
+ [198] = 2,
+ ACTIONS(112), 1,
+ aux_sym_directive_unknown_token1,
+ ACTIONS(110), 12,
+ ts_builtin_sym_end,
+ anon_sym_POUND_BANGsrfv1,
+ anon_sym_POUND_BANGlong,
+ anon_sym_POUND_BANGcompact,
+ anon_sym_POUND_BANGrequireeof,
+ anon_sym_POUND_BANGeof,
+ anon_sym_POUND_BANGexpires_EQ,
+ anon_sym_POUND_BANGcreated_EQ,
+ anon_sym_POUND_BANGmodified_EQ,
+ sym_comment,
+ sym_blank_line,
+ sym_key,
+ [216] = 2,
+ ACTIONS(116), 1,
+ aux_sym_directive_unknown_token1,
+ ACTIONS(114), 12,
+ ts_builtin_sym_end,
+ anon_sym_POUND_BANGsrfv1,
+ anon_sym_POUND_BANGlong,
+ anon_sym_POUND_BANGcompact,
+ anon_sym_POUND_BANGrequireeof,
+ anon_sym_POUND_BANGeof,
+ anon_sym_POUND_BANGexpires_EQ,
+ anon_sym_POUND_BANGcreated_EQ,
+ anon_sym_POUND_BANGmodified_EQ,
+ sym_comment,
+ sym_blank_line,
+ sym_key,
+ [234] = 2,
+ ACTIONS(120), 1,
+ aux_sym_directive_unknown_token1,
+ ACTIONS(118), 12,
+ ts_builtin_sym_end,
+ anon_sym_POUND_BANGsrfv1,
+ anon_sym_POUND_BANGlong,
+ anon_sym_POUND_BANGcompact,
+ anon_sym_POUND_BANGrequireeof,
+ anon_sym_POUND_BANGeof,
+ anon_sym_POUND_BANGexpires_EQ,
+ anon_sym_POUND_BANGcreated_EQ,
+ anon_sym_POUND_BANGmodified_EQ,
+ sym_comment,
+ sym_blank_line,
+ sym_key,
+ [252] = 2,
+ ACTIONS(124), 1,
+ aux_sym_directive_unknown_token1,
+ ACTIONS(122), 12,
+ ts_builtin_sym_end,
+ anon_sym_POUND_BANGsrfv1,
+ anon_sym_POUND_BANGlong,
+ anon_sym_POUND_BANGcompact,
+ anon_sym_POUND_BANGrequireeof,
+ anon_sym_POUND_BANGeof,
+ anon_sym_POUND_BANGexpires_EQ,
+ anon_sym_POUND_BANGcreated_EQ,
+ anon_sym_POUND_BANGmodified_EQ,
+ sym_comment,
+ sym_blank_line,
+ sym_key,
+ [270] = 2,
+ ACTIONS(128), 1,
+ aux_sym_directive_unknown_token1,
+ ACTIONS(126), 12,
+ ts_builtin_sym_end,
+ anon_sym_POUND_BANGsrfv1,
+ anon_sym_POUND_BANGlong,
+ anon_sym_POUND_BANGcompact,
+ anon_sym_POUND_BANGrequireeof,
+ anon_sym_POUND_BANGeof,
+ anon_sym_POUND_BANGexpires_EQ,
+ anon_sym_POUND_BANGcreated_EQ,
+ anon_sym_POUND_BANGmodified_EQ,
+ sym_comment,
+ sym_blank_line,
+ sym_key,
+ [288] = 2,
+ ACTIONS(132), 1,
+ aux_sym_directive_unknown_token1,
+ ACTIONS(130), 12,
+ ts_builtin_sym_end,
+ anon_sym_POUND_BANGsrfv1,
+ anon_sym_POUND_BANGlong,
+ anon_sym_POUND_BANGcompact,
+ anon_sym_POUND_BANGrequireeof,
+ anon_sym_POUND_BANGeof,
+ anon_sym_POUND_BANGexpires_EQ,
+ anon_sym_POUND_BANGcreated_EQ,
+ anon_sym_POUND_BANGmodified_EQ,
+ sym_comment,
+ sym_blank_line,
+ sym_key,
+ [306] = 2,
+ ACTIONS(136), 1,
+ aux_sym_directive_unknown_token1,
+ ACTIONS(134), 12,
+ ts_builtin_sym_end,
+ anon_sym_POUND_BANGsrfv1,
+ anon_sym_POUND_BANGlong,
+ anon_sym_POUND_BANGcompact,
+ anon_sym_POUND_BANGrequireeof,
+ anon_sym_POUND_BANGeof,
+ anon_sym_POUND_BANGexpires_EQ,
+ anon_sym_POUND_BANGcreated_EQ,
+ anon_sym_POUND_BANGmodified_EQ,
+ sym_comment,
+ sym_blank_line,
+ sym_key,
+ [324] = 2,
+ ACTIONS(140), 1,
+ aux_sym_directive_unknown_token1,
+ ACTIONS(138), 12,
+ ts_builtin_sym_end,
+ anon_sym_POUND_BANGsrfv1,
+ anon_sym_POUND_BANGlong,
+ anon_sym_POUND_BANGcompact,
+ anon_sym_POUND_BANGrequireeof,
+ anon_sym_POUND_BANGeof,
+ anon_sym_POUND_BANGexpires_EQ,
+ anon_sym_POUND_BANGcreated_EQ,
+ anon_sym_POUND_BANGmodified_EQ,
+ sym_comment,
+ sym_blank_line,
+ sym_key,
+ [342] = 2,
+ ACTIONS(144), 1,
+ aux_sym_directive_unknown_token1,
+ ACTIONS(142), 12,
+ ts_builtin_sym_end,
+ anon_sym_POUND_BANGsrfv1,
+ anon_sym_POUND_BANGlong,
+ anon_sym_POUND_BANGcompact,
+ anon_sym_POUND_BANGrequireeof,
+ anon_sym_POUND_BANGeof,
+ anon_sym_POUND_BANGexpires_EQ,
+ anon_sym_POUND_BANGcreated_EQ,
+ anon_sym_POUND_BANGmodified_EQ,
+ sym_comment,
+ sym_blank_line,
+ sym_key,
+ [360] = 2,
+ ACTIONS(148), 1,
+ aux_sym_directive_unknown_token1,
+ ACTIONS(146), 12,
+ ts_builtin_sym_end,
+ anon_sym_POUND_BANGsrfv1,
+ anon_sym_POUND_BANGlong,
+ anon_sym_POUND_BANGcompact,
+ anon_sym_POUND_BANGrequireeof,
+ anon_sym_POUND_BANGeof,
+ anon_sym_POUND_BANGexpires_EQ,
+ anon_sym_POUND_BANGcreated_EQ,
+ anon_sym_POUND_BANGmodified_EQ,
+ sym_comment,
+ sym_blank_line,
+ sym_key,
+ [378] = 2,
+ ACTIONS(152), 1,
+ aux_sym_directive_unknown_token1,
+ ACTIONS(150), 12,
+ ts_builtin_sym_end,
+ anon_sym_POUND_BANGsrfv1,
+ anon_sym_POUND_BANGlong,
+ anon_sym_POUND_BANGcompact,
+ anon_sym_POUND_BANGrequireeof,
+ anon_sym_POUND_BANGeof,
+ anon_sym_POUND_BANGexpires_EQ,
+ anon_sym_POUND_BANGcreated_EQ,
+ anon_sym_POUND_BANGmodified_EQ,
+ sym_comment,
+ sym_blank_line,
+ sym_key,
+ [396] = 2,
+ ACTIONS(156), 1,
+ aux_sym_directive_unknown_token1,
+ ACTIONS(154), 12,
+ ts_builtin_sym_end,
+ anon_sym_POUND_BANGsrfv1,
+ anon_sym_POUND_BANGlong,
+ anon_sym_POUND_BANGcompact,
+ anon_sym_POUND_BANGrequireeof,
+ anon_sym_POUND_BANGeof,
+ anon_sym_POUND_BANGexpires_EQ,
+ anon_sym_POUND_BANGcreated_EQ,
+ anon_sym_POUND_BANGmodified_EQ,
+ sym_comment,
+ sym_blank_line,
+ sym_key,
+ [414] = 2,
+ ACTIONS(160), 1,
+ aux_sym_directive_unknown_token1,
+ ACTIONS(158), 12,
+ ts_builtin_sym_end,
+ anon_sym_POUND_BANGsrfv1,
+ anon_sym_POUND_BANGlong,
+ anon_sym_POUND_BANGcompact,
+ anon_sym_POUND_BANGrequireeof,
+ anon_sym_POUND_BANGeof,
+ anon_sym_POUND_BANGexpires_EQ,
+ anon_sym_POUND_BANGcreated_EQ,
+ anon_sym_POUND_BANGmodified_EQ,
+ sym_comment,
+ sym_blank_line,
+ sym_key,
+ [432] = 2,
+ STATE(55), 1,
+ sym_type_hint,
+ ACTIONS(162), 6,
+ anon_sym_string,
+ anon_sym_num,
+ anon_sym_bool,
+ anon_sym_null,
+ anon_sym_binary,
+ aux_sym_type_hint_token1,
+ [444] = 2,
+ ACTIONS(164), 1,
+ anon_sym_LF,
+ ACTIONS(166), 1,
+ sym_inline_comment,
+ [451] = 2,
+ ACTIONS(168), 1,
+ anon_sym_COLON,
+ ACTIONS(170), 1,
+ anon_sym_COLON_COLON,
+ [458] = 2,
+ ACTIONS(172), 1,
+ aux_sym_typed_field_token1,
+ ACTIONS(174), 1,
+ sym_value,
+ [465] = 2,
+ ACTIONS(176), 1,
+ anon_sym_LF,
+ ACTIONS(178), 1,
+ sym_inline_comment,
+ [472] = 2,
+ ACTIONS(180), 1,
+ anon_sym_LF,
+ ACTIONS(182), 1,
+ sym_inline_comment,
+ [479] = 2,
+ ACTIONS(184), 1,
+ anon_sym_LF,
+ ACTIONS(186), 1,
+ sym_inline_comment,
+ [486] = 2,
+ ACTIONS(188), 1,
+ anon_sym_LF,
+ ACTIONS(190), 1,
+ sym_inline_comment,
+ [493] = 2,
+ ACTIONS(192), 1,
+ anon_sym_LF,
+ ACTIONS(194), 1,
+ sym_inline_comment,
+ [500] = 2,
+ ACTIONS(196), 1,
+ anon_sym_LF,
+ ACTIONS(198), 1,
+ sym_inline_comment,
+ [507] = 2,
+ ACTIONS(200), 1,
+ anon_sym_LF,
+ ACTIONS(202), 1,
+ sym_inline_comment,
+ [514] = 2,
+ ACTIONS(204), 1,
+ aux_sym_typed_field_token1,
+ ACTIONS(206), 1,
+ sym_value,
+ [521] = 2,
+ ACTIONS(208), 1,
+ anon_sym_LF,
+ ACTIONS(210), 1,
+ anon_sym_EQ,
+ [528] = 1,
+ ACTIONS(212), 1,
+ ts_builtin_sym_end,
+ [532] = 1,
+ ACTIONS(214), 1,
+ anon_sym_LF,
+ [536] = 1,
+ ACTIONS(216), 1,
+ anon_sym_LF,
+ [540] = 1,
+ ACTIONS(218), 1,
+ anon_sym_LF,
+ [544] = 1,
+ ACTIONS(220), 1,
+ anon_sym_LF,
+ [548] = 1,
+ ACTIONS(222), 1,
+ sym_timestamp,
+ [552] = 1,
+ ACTIONS(224), 1,
+ anon_sym_LF,
+ [556] = 1,
+ ACTIONS(226), 1,
+ anon_sym_LF,
+ [560] = 1,
+ ACTIONS(228), 1,
+ sym_timestamp,
+ [564] = 1,
+ ACTIONS(230), 1,
+ aux_sym_typed_field_token1,
+ [568] = 1,
+ ACTIONS(232), 1,
+ aux_sym_directive_unknown_token3,
+ [572] = 1,
+ ACTIONS(234), 1,
+ sym_timestamp,
+ [576] = 1,
+ ACTIONS(236), 1,
+ anon_sym_LF,
+ [580] = 1,
+ ACTIONS(238), 1,
+ anon_sym_LF,
+ [584] = 1,
+ ACTIONS(240), 1,
+ anon_sym_COLON,
+ [588] = 1,
+ ACTIONS(242), 1,
+ anon_sym_COLON,
+ [592] = 1,
+ ACTIONS(244), 1,
+ anon_sym_LF,
+ [596] = 1,
+ ACTIONS(246), 1,
+ aux_sym_directive_unknown_token2,
+ [600] = 1,
+ ACTIONS(248), 1,
+ aux_sym_typed_field_token1,
+};
+
+static const uint32_t ts_small_parse_table_map[] = {
+ [SMALL_STATE(4)] = 0,
+ [SMALL_STATE(5)] = 18,
+ [SMALL_STATE(6)] = 36,
+ [SMALL_STATE(7)] = 54,
+ [SMALL_STATE(8)] = 72,
+ [SMALL_STATE(9)] = 90,
+ [SMALL_STATE(10)] = 108,
+ [SMALL_STATE(11)] = 126,
+ [SMALL_STATE(12)] = 144,
+ [SMALL_STATE(13)] = 162,
+ [SMALL_STATE(14)] = 180,
+ [SMALL_STATE(15)] = 198,
+ [SMALL_STATE(16)] = 216,
+ [SMALL_STATE(17)] = 234,
+ [SMALL_STATE(18)] = 252,
+ [SMALL_STATE(19)] = 270,
+ [SMALL_STATE(20)] = 288,
+ [SMALL_STATE(21)] = 306,
+ [SMALL_STATE(22)] = 324,
+ [SMALL_STATE(23)] = 342,
+ [SMALL_STATE(24)] = 360,
+ [SMALL_STATE(25)] = 378,
+ [SMALL_STATE(26)] = 396,
+ [SMALL_STATE(27)] = 414,
+ [SMALL_STATE(28)] = 432,
+ [SMALL_STATE(29)] = 444,
+ [SMALL_STATE(30)] = 451,
+ [SMALL_STATE(31)] = 458,
+ [SMALL_STATE(32)] = 465,
+ [SMALL_STATE(33)] = 472,
+ [SMALL_STATE(34)] = 479,
+ [SMALL_STATE(35)] = 486,
+ [SMALL_STATE(36)] = 493,
+ [SMALL_STATE(37)] = 500,
+ [SMALL_STATE(38)] = 507,
+ [SMALL_STATE(39)] = 514,
+ [SMALL_STATE(40)] = 521,
+ [SMALL_STATE(41)] = 528,
+ [SMALL_STATE(42)] = 532,
+ [SMALL_STATE(43)] = 536,
+ [SMALL_STATE(44)] = 540,
+ [SMALL_STATE(45)] = 544,
+ [SMALL_STATE(46)] = 548,
+ [SMALL_STATE(47)] = 552,
+ [SMALL_STATE(48)] = 556,
+ [SMALL_STATE(49)] = 560,
+ [SMALL_STATE(50)] = 564,
+ [SMALL_STATE(51)] = 568,
+ [SMALL_STATE(52)] = 572,
+ [SMALL_STATE(53)] = 576,
+ [SMALL_STATE(54)] = 580,
+ [SMALL_STATE(55)] = 584,
+ [SMALL_STATE(56)] = 588,
+ [SMALL_STATE(57)] = 592,
+ [SMALL_STATE(58)] = 596,
+ [SMALL_STATE(59)] = 600,
+};
+
+static const TSParseActionEntry ts_parse_actions[] = {
+ [0] = {.entry = {.count = 0, .reusable = false}},
+ [1] = {.entry = {.count = 1, .reusable = false}}, RECOVER(),
+ [3] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_document, 0, 0, 0),
+ [5] = {.entry = {.count = 1, .reusable = true}}, SHIFT(32),
+ [7] = {.entry = {.count = 1, .reusable = true}}, SHIFT(34),
+ [9] = {.entry = {.count = 1, .reusable = true}}, SHIFT(35),
+ [11] = {.entry = {.count = 1, .reusable = true}}, SHIFT(33),
+ [13] = {.entry = {.count = 1, .reusable = true}}, SHIFT(36),
+ [15] = {.entry = {.count = 1, .reusable = true}}, SHIFT(46),
+ [17] = {.entry = {.count = 1, .reusable = true}}, SHIFT(49),
+ [19] = {.entry = {.count = 1, .reusable = true}}, SHIFT(52),
+ [21] = {.entry = {.count = 1, .reusable = false}}, SHIFT(58),
+ [23] = {.entry = {.count = 1, .reusable = true}}, SHIFT(3),
+ [25] = {.entry = {.count = 1, .reusable = true}}, SHIFT(30),
+ [27] = {.entry = {.count = 1, .reusable = true}}, REDUCE(aux_sym_document_repeat1, 2, 0, 0),
+ [29] = {.entry = {.count = 2, .reusable = true}}, REDUCE(aux_sym_document_repeat1, 2, 0, 0), SHIFT_REPEAT(32),
+ [32] = {.entry = {.count = 2, .reusable = true}}, REDUCE(aux_sym_document_repeat1, 2, 0, 0), SHIFT_REPEAT(34),
+ [35] = {.entry = {.count = 2, .reusable = true}}, REDUCE(aux_sym_document_repeat1, 2, 0, 0), SHIFT_REPEAT(35),
+ [38] = {.entry = {.count = 2, .reusable = true}}, REDUCE(aux_sym_document_repeat1, 2, 0, 0), SHIFT_REPEAT(33),
+ [41] = {.entry = {.count = 2, .reusable = true}}, REDUCE(aux_sym_document_repeat1, 2, 0, 0), SHIFT_REPEAT(36),
+ [44] = {.entry = {.count = 2, .reusable = true}}, REDUCE(aux_sym_document_repeat1, 2, 0, 0), SHIFT_REPEAT(46),
+ [47] = {.entry = {.count = 2, .reusable = true}}, REDUCE(aux_sym_document_repeat1, 2, 0, 0), SHIFT_REPEAT(49),
+ [50] = {.entry = {.count = 2, .reusable = true}}, REDUCE(aux_sym_document_repeat1, 2, 0, 0), SHIFT_REPEAT(52),
+ [53] = {.entry = {.count = 2, .reusable = false}}, REDUCE(aux_sym_document_repeat1, 2, 0, 0), SHIFT_REPEAT(58),
+ [56] = {.entry = {.count = 2, .reusable = true}}, REDUCE(aux_sym_document_repeat1, 2, 0, 0), SHIFT_REPEAT(2),
+ [59] = {.entry = {.count = 2, .reusable = true}}, REDUCE(aux_sym_document_repeat1, 2, 0, 0), SHIFT_REPEAT(30),
+ [62] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_document, 1, 0, 0),
+ [64] = {.entry = {.count = 1, .reusable = true}}, SHIFT(2),
+ [66] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_magic, 2, 0, 0),
+ [68] = {.entry = {.count = 1, .reusable = false}}, REDUCE(sym_magic, 2, 0, 0),
+ [70] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_directive, 1, 0, 0),
+ [72] = {.entry = {.count = 1, .reusable = false}}, REDUCE(sym_directive, 1, 0, 0),
+ [74] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_directive_compact, 2, 0, 0),
+ [76] = {.entry = {.count = 1, .reusable = false}}, REDUCE(sym_directive_compact, 2, 0, 0),
+ [78] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_directive_requireeof, 2, 0, 0),
+ [80] = {.entry = {.count = 1, .reusable = false}}, REDUCE(sym_directive_requireeof, 2, 0, 0),
+ [82] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_directive_eof, 2, 0, 0),
+ [84] = {.entry = {.count = 1, .reusable = false}}, REDUCE(sym_directive_eof, 2, 0, 0),
+ [86] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_field, 1, 0, 0),
+ [88] = {.entry = {.count = 1, .reusable = false}}, REDUCE(sym_field, 1, 0, 0),
+ [90] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_magic, 3, 0, 0),
+ [92] = {.entry = {.count = 1, .reusable = false}}, REDUCE(sym_magic, 3, 0, 0),
+ [94] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_directive_long, 2, 0, 0),
+ [96] = {.entry = {.count = 1, .reusable = false}}, REDUCE(sym_directive_long, 2, 0, 0),
+ [98] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_directive_long, 3, 0, 0),
+ [100] = {.entry = {.count = 1, .reusable = false}}, REDUCE(sym_directive_long, 3, 0, 0),
+ [102] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_directive_compact, 3, 0, 0),
+ [104] = {.entry = {.count = 1, .reusable = false}}, REDUCE(sym_directive_compact, 3, 0, 0),
+ [106] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_directive_requireeof, 3, 0, 0),
+ [108] = {.entry = {.count = 1, .reusable = false}}, REDUCE(sym_directive_requireeof, 3, 0, 0),
+ [110] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_directive_eof, 3, 0, 0),
+ [112] = {.entry = {.count = 1, .reusable = false}}, REDUCE(sym_directive_eof, 3, 0, 0),
+ [114] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_directive_expires, 3, 0, 1),
+ [116] = {.entry = {.count = 1, .reusable = false}}, REDUCE(sym_directive_expires, 3, 0, 1),
+ [118] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_directive_created, 3, 0, 1),
+ [120] = {.entry = {.count = 1, .reusable = false}}, REDUCE(sym_directive_created, 3, 0, 1),
+ [122] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_directive_modified, 3, 0, 1),
+ [124] = {.entry = {.count = 1, .reusable = false}}, REDUCE(sym_directive_modified, 3, 0, 1),
+ [126] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_directive_unknown, 3, 0, 0),
+ [128] = {.entry = {.count = 1, .reusable = false}}, REDUCE(sym_directive_unknown, 3, 0, 0),
+ [130] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_untyped_field, 3, 0, 0),
+ [132] = {.entry = {.count = 1, .reusable = false}}, REDUCE(sym_untyped_field, 3, 0, 0),
+ [134] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_directive_expires, 4, 0, 1),
+ [136] = {.entry = {.count = 1, .reusable = false}}, REDUCE(sym_directive_expires, 4, 0, 1),
+ [138] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_directive_created, 4, 0, 1),
+ [140] = {.entry = {.count = 1, .reusable = false}}, REDUCE(sym_directive_created, 4, 0, 1),
+ [142] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_directive_modified, 4, 0, 1),
+ [144] = {.entry = {.count = 1, .reusable = false}}, REDUCE(sym_directive_modified, 4, 0, 1),
+ [146] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_untyped_field, 4, 0, 0),
+ [148] = {.entry = {.count = 1, .reusable = false}}, REDUCE(sym_untyped_field, 4, 0, 0),
+ [150] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_directive_unknown, 5, 0, 0),
+ [152] = {.entry = {.count = 1, .reusable = false}}, REDUCE(sym_directive_unknown, 5, 0, 0),
+ [154] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_typed_field, 5, 0, 0),
+ [156] = {.entry = {.count = 1, .reusable = false}}, REDUCE(sym_typed_field, 5, 0, 0),
+ [158] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_typed_field, 6, 0, 0),
+ [160] = {.entry = {.count = 1, .reusable = false}}, REDUCE(sym_typed_field, 6, 0, 0),
+ [162] = {.entry = {.count = 1, .reusable = true}}, SHIFT(56),
+ [164] = {.entry = {.count = 1, .reusable = true}}, SHIFT(18),
+ [166] = {.entry = {.count = 1, .reusable = true}}, SHIFT(47),
+ [168] = {.entry = {.count = 1, .reusable = false}}, SHIFT(28),
+ [170] = {.entry = {.count = 1, .reusable = true}}, SHIFT(31),
+ [172] = {.entry = {.count = 1, .reusable = true}}, SHIFT(20),
+ [174] = {.entry = {.count = 1, .reusable = true}}, SHIFT(50),
+ [176] = {.entry = {.count = 1, .reusable = true}}, SHIFT(4),
+ [178] = {.entry = {.count = 1, .reusable = true}}, SHIFT(42),
+ [180] = {.entry = {.count = 1, .reusable = true}}, SHIFT(7),
+ [182] = {.entry = {.count = 1, .reusable = true}}, SHIFT(57),
+ [184] = {.entry = {.count = 1, .reusable = true}}, SHIFT(11),
+ [186] = {.entry = {.count = 1, .reusable = true}}, SHIFT(44),
+ [188] = {.entry = {.count = 1, .reusable = true}}, SHIFT(6),
+ [190] = {.entry = {.count = 1, .reusable = true}}, SHIFT(48),
+ [192] = {.entry = {.count = 1, .reusable = true}}, SHIFT(8),
+ [194] = {.entry = {.count = 1, .reusable = true}}, SHIFT(53),
+ [196] = {.entry = {.count = 1, .reusable = true}}, SHIFT(17),
+ [198] = {.entry = {.count = 1, .reusable = true}}, SHIFT(45),
+ [200] = {.entry = {.count = 1, .reusable = true}}, SHIFT(16),
+ [202] = {.entry = {.count = 1, .reusable = true}}, SHIFT(43),
+ [204] = {.entry = {.count = 1, .reusable = true}}, SHIFT(26),
+ [206] = {.entry = {.count = 1, .reusable = true}}, SHIFT(59),
+ [208] = {.entry = {.count = 1, .reusable = true}}, SHIFT(19),
+ [210] = {.entry = {.count = 1, .reusable = true}}, SHIFT(51),
+ [212] = {.entry = {.count = 1, .reusable = true}}, ACCEPT_INPUT(),
+ [214] = {.entry = {.count = 1, .reusable = true}}, SHIFT(10),
+ [216] = {.entry = {.count = 1, .reusable = true}}, SHIFT(21),
+ [218] = {.entry = {.count = 1, .reusable = true}}, SHIFT(12),
+ [220] = {.entry = {.count = 1, .reusable = true}}, SHIFT(22),
+ [222] = {.entry = {.count = 1, .reusable = true}}, SHIFT(38),
+ [224] = {.entry = {.count = 1, .reusable = true}}, SHIFT(23),
+ [226] = {.entry = {.count = 1, .reusable = true}}, SHIFT(13),
+ [228] = {.entry = {.count = 1, .reusable = true}}, SHIFT(37),
+ [230] = {.entry = {.count = 1, .reusable = true}}, SHIFT(24),
+ [232] = {.entry = {.count = 1, .reusable = true}}, SHIFT(54),
+ [234] = {.entry = {.count = 1, .reusable = true}}, SHIFT(29),
+ [236] = {.entry = {.count = 1, .reusable = true}}, SHIFT(15),
+ [238] = {.entry = {.count = 1, .reusable = true}}, SHIFT(25),
+ [240] = {.entry = {.count = 1, .reusable = true}}, SHIFT(39),
+ [242] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_type_hint, 1, 0, 0),
+ [244] = {.entry = {.count = 1, .reusable = true}}, SHIFT(14),
+ [246] = {.entry = {.count = 1, .reusable = true}}, SHIFT(40),
+ [248] = {.entry = {.count = 1, .reusable = true}}, SHIFT(27),
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef TREE_SITTER_HIDE_SYMBOLS
+#define TS_PUBLIC
+#elif defined(_WIN32)
+#define TS_PUBLIC __declspec(dllexport)
+#else
+#define TS_PUBLIC __attribute__((visibility("default")))
+#endif
+
+TS_PUBLIC const TSLanguage *tree_sitter_srf(void) {
+ static const TSLanguage language = {
+ .abi_version = LANGUAGE_VERSION,
+ .symbol_count = SYMBOL_COUNT,
+ .alias_count = ALIAS_COUNT,
+ .token_count = TOKEN_COUNT,
+ .external_token_count = EXTERNAL_TOKEN_COUNT,
+ .state_count = STATE_COUNT,
+ .large_state_count = LARGE_STATE_COUNT,
+ .production_id_count = PRODUCTION_ID_COUNT,
+ .supertype_count = SUPERTYPE_COUNT,
+ .field_count = FIELD_COUNT,
+ .max_alias_sequence_length = MAX_ALIAS_SEQUENCE_LENGTH,
+ .parse_table = &ts_parse_table[0][0],
+ .small_parse_table = ts_small_parse_table,
+ .small_parse_table_map = ts_small_parse_table_map,
+ .parse_actions = ts_parse_actions,
+ .symbol_names = ts_symbol_names,
+ .field_names = ts_field_names,
+ .field_map_slices = ts_field_map_slices,
+ .field_map_entries = ts_field_map_entries,
+ .symbol_metadata = ts_symbol_metadata,
+ .public_symbol_map = ts_symbol_map,
+ .alias_map = ts_non_terminal_alias_map,
+ .alias_sequences = &ts_alias_sequences[0][0],
+ .lex_modes = (const void*)ts_lex_modes,
+ .lex_fn = ts_lex,
+ .primary_state_ids = ts_primary_state_ids,
+ .name = "srf",
+ .max_reserved_word_set_size = 0,
+ .metadata = {
+ .major_version = 0,
+ .minor_version = 0,
+ .patch_version = 1,
+ },
+ };
+ return &language;
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/tree_sitter/alloc.h b/src/tree_sitter/alloc.h
new file mode 100644
index 0000000..1abdd12
--- /dev/null
+++ b/src/tree_sitter/alloc.h
@@ -0,0 +1,54 @@
+#ifndef TREE_SITTER_ALLOC_H_
+#define TREE_SITTER_ALLOC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include
+#include
+#include
+
+// Allow clients to override allocation functions
+#ifdef TREE_SITTER_REUSE_ALLOCATOR
+
+extern void *(*ts_current_malloc)(size_t size);
+extern void *(*ts_current_calloc)(size_t count, size_t size);
+extern void *(*ts_current_realloc)(void *ptr, size_t size);
+extern void (*ts_current_free)(void *ptr);
+
+#ifndef ts_malloc
+#define ts_malloc ts_current_malloc
+#endif
+#ifndef ts_calloc
+#define ts_calloc ts_current_calloc
+#endif
+#ifndef ts_realloc
+#define ts_realloc ts_current_realloc
+#endif
+#ifndef ts_free
+#define ts_free ts_current_free
+#endif
+
+#else
+
+#ifndef ts_malloc
+#define ts_malloc malloc
+#endif
+#ifndef ts_calloc
+#define ts_calloc calloc
+#endif
+#ifndef ts_realloc
+#define ts_realloc realloc
+#endif
+#ifndef ts_free
+#define ts_free free
+#endif
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // TREE_SITTER_ALLOC_H_
diff --git a/src/tree_sitter/array.h b/src/tree_sitter/array.h
new file mode 100644
index 0000000..56fc8cd
--- /dev/null
+++ b/src/tree_sitter/array.h
@@ -0,0 +1,330 @@
+#ifndef TREE_SITTER_ARRAY_H_
+#define TREE_SITTER_ARRAY_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "./alloc.h"
+
+#include
+#include
+#include
+#include
+#include
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable : 4101)
+#elif defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#endif
+
+#define Array(T) \
+ struct { \
+ T *contents; \
+ uint32_t size; \
+ uint32_t capacity; \
+ }
+
+/// Initialize an array.
+#define array_init(self) \
+ ((self)->size = 0, (self)->capacity = 0, (self)->contents = NULL)
+
+/// Create an empty array.
+#define array_new() \
+ { NULL, 0, 0 }
+
+/// Get a pointer to the element at a given `index` in the array.
+#define array_get(self, _index) \
+ (assert((uint32_t)(_index) < (self)->size), &(self)->contents[_index])
+
+/// Get a pointer to the first element in the array.
+#define array_front(self) array_get(self, 0)
+
+/// Get a pointer to the last element in the array.
+#define array_back(self) array_get(self, (self)->size - 1)
+
+/// Clear the array, setting its size to zero. Note that this does not free any
+/// memory allocated for the array's contents.
+#define array_clear(self) ((self)->size = 0)
+
+/// Reserve `new_capacity` elements of space in the array. If `new_capacity` is
+/// less than the array's current capacity, this function has no effect.
+#define array_reserve(self, new_capacity) \
+ ((self)->contents = _array__reserve( \
+ (void *)(self)->contents, &(self)->capacity, \
+ array_elem_size(self), new_capacity) \
+ )
+
+/// Free any memory allocated for this array. Note that this does not free any
+/// memory allocated for the array's contents.
+#define array_delete(self) \
+ do { \
+ if ((self)->contents) ts_free((self)->contents); \
+ (self)->contents = NULL; \
+ (self)->size = 0; \
+ (self)->capacity = 0; \
+ } while (0)
+
+/// Push a new `element` onto the end of the array.
+#define array_push(self, element) \
+ do { \
+ (self)->contents = _array__grow( \
+ (void *)(self)->contents, (self)->size, &(self)->capacity, \
+ 1, array_elem_size(self) \
+ ); \
+ (self)->contents[(self)->size++] = (element); \
+ } while(0)
+
+/// Increase the array's size by `count` elements.
+/// New elements are zero-initialized.
+#define array_grow_by(self, count) \
+ do { \
+ if ((count) == 0) break; \
+ (self)->contents = _array__grow( \
+ (self)->contents, (self)->size, &(self)->capacity, \
+ count, array_elem_size(self) \
+ ); \
+ memset((self)->contents + (self)->size, 0, (count) * array_elem_size(self)); \
+ (self)->size += (count); \
+ } while (0)
+
+/// Append all elements from one array to the end of another.
+#define array_push_all(self, other) \
+ array_extend((self), (other)->size, (other)->contents)
+
+/// Append `count` elements to the end of the array, reading their values from the
+/// `contents` pointer.
+#define array_extend(self, count, other_contents) \
+ (self)->contents = _array__splice( \
+ (void*)(self)->contents, &(self)->size, &(self)->capacity, \
+ array_elem_size(self), (self)->size, 0, count, other_contents \
+ )
+
+/// Remove `old_count` elements from the array starting at the given `index`. At
+/// the same index, insert `new_count` new elements, reading their values from the
+/// `new_contents` pointer.
+#define array_splice(self, _index, old_count, new_count, new_contents) \
+ (self)->contents = _array__splice( \
+ (void *)(self)->contents, &(self)->size, &(self)->capacity, \
+ array_elem_size(self), _index, old_count, new_count, new_contents \
+ )
+
+/// Insert one `element` into the array at the given `index`.
+#define array_insert(self, _index, element) \
+ (self)->contents = _array__splice( \
+ (void *)(self)->contents, &(self)->size, &(self)->capacity, \
+ array_elem_size(self), _index, 0, 1, &(element) \
+ )
+
+/// Remove one element from the array at the given `index`.
+#define array_erase(self, _index) \
+ _array__erase((void *)(self)->contents, &(self)->size, array_elem_size(self), _index)
+
+/// Pop the last element off the array, returning the element by value.
+#define array_pop(self) ((self)->contents[--(self)->size])
+
+/// Assign the contents of one array to another, reallocating if necessary.
+#define array_assign(self, other) \
+ (self)->contents = _array__assign( \
+ (void *)(self)->contents, &(self)->size, &(self)->capacity, \
+ (const void *)(other)->contents, (other)->size, array_elem_size(self) \
+ )
+
+/// Swap one array with another
+#define array_swap(self, other) \
+ do { \
+ void *_array_swap_tmp = (void *)(self)->contents; \
+ (self)->contents = (other)->contents; \
+ (other)->contents = _array_swap_tmp; \
+ _array__swap(&(self)->size, &(self)->capacity, \
+ &(other)->size, &(other)->capacity); \
+ } while (0)
+
+/// Get the size of the array contents
+#define array_elem_size(self) (sizeof *(self)->contents)
+
+/// Search a sorted array for a given `needle` value, using the given `compare`
+/// callback to determine the order.
+///
+/// If an existing element is found to be equal to `needle`, then the `index`
+/// out-parameter is set to the existing value's index, and the `exists`
+/// out-parameter is set to true. Otherwise, `index` is set to an index where
+/// `needle` should be inserted in order to preserve the sorting, and `exists`
+/// is set to false.
+#define array_search_sorted_with(self, compare, needle, _index, _exists) \
+ _array__search_sorted(self, 0, compare, , needle, _index, _exists)
+
+/// Search a sorted array for a given `needle` value, using integer comparisons
+/// of a given struct field (specified with a leading dot) to determine the order.
+///
+/// See also `array_search_sorted_with`.
+#define array_search_sorted_by(self, field, needle, _index, _exists) \
+ _array__search_sorted(self, 0, _compare_int, field, needle, _index, _exists)
+
+/// Insert a given `value` into a sorted array, using the given `compare`
+/// callback to determine the order.
+#define array_insert_sorted_with(self, compare, value) \
+ do { \
+ unsigned _index, _exists; \
+ array_search_sorted_with(self, compare, &(value), &_index, &_exists); \
+ if (!_exists) array_insert(self, _index, value); \
+ } while (0)
+
+/// Insert a given `value` into a sorted array, using integer comparisons of
+/// a given struct field (specified with a leading dot) to determine the order.
+///
+/// See also `array_search_sorted_by`.
+#define array_insert_sorted_by(self, field, value) \
+ do { \
+ unsigned _index, _exists; \
+ array_search_sorted_by(self, field, (value) field, &_index, &_exists); \
+ if (!_exists) array_insert(self, _index, value); \
+ } while (0)
+
+// Private
+
+// Pointers to individual `Array` fields (rather than the entire `Array` itself)
+// are passed to the various `_array__*` functions below to address strict aliasing
+// violations that arises when the _entire_ `Array` struct is passed as `Array(void)*`.
+//
+// The `Array` type itself was not altered as a solution in order to avoid breakage
+// with existing consumers (in particular, parsers with external scanners).
+
+/// This is not what you're looking for, see `array_erase`.
+static inline void _array__erase(void* self_contents, uint32_t *size,
+ size_t element_size, uint32_t index) {
+ assert(index < *size);
+ char *contents = (char *)self_contents;
+ memmove(contents + index * element_size, contents + (index + 1) * element_size,
+ (*size - index - 1) * element_size);
+ (*size)--;
+}
+
+/// This is not what you're looking for, see `array_reserve`.
+static inline void *_array__reserve(void *contents, uint32_t *capacity,
+ size_t element_size, uint32_t new_capacity) {
+ void *new_contents = contents;
+ if (new_capacity > *capacity) {
+ if (contents) {
+ new_contents = ts_realloc(contents, new_capacity * element_size);
+ } else {
+ new_contents = ts_malloc(new_capacity * element_size);
+ }
+ *capacity = new_capacity;
+ }
+ return new_contents;
+}
+
+/// This is not what you're looking for, see `array_assign`.
+static inline void *_array__assign(void* self_contents, uint32_t *self_size, uint32_t *self_capacity,
+ const void *other_contents, uint32_t other_size, size_t element_size) {
+ void *new_contents = _array__reserve(self_contents, self_capacity, element_size, other_size);
+ *self_size = other_size;
+ memcpy(new_contents, other_contents, *self_size * element_size);
+ return new_contents;
+}
+
+/// This is not what you're looking for, see `array_swap`.
+static inline void _array__swap(uint32_t *self_size, uint32_t *self_capacity,
+ uint32_t *other_size, uint32_t *other_capacity) {
+ uint32_t tmp_size = *self_size;
+ uint32_t tmp_capacity = *self_capacity;
+ *self_size = *other_size;
+ *self_capacity = *other_capacity;
+ *other_size = tmp_size;
+ *other_capacity = tmp_capacity;
+}
+
+/// This is not what you're looking for, see `array_push` or `array_grow_by`.
+static inline void *_array__grow(void *contents, uint32_t size, uint32_t *capacity,
+ uint32_t count, size_t element_size) {
+ void *new_contents = contents;
+ uint32_t new_size = size + count;
+ if (new_size > *capacity) {
+ uint32_t new_capacity = *capacity * 2;
+ if (new_capacity < 8) new_capacity = 8;
+ if (new_capacity < new_size) new_capacity = new_size;
+ new_contents = _array__reserve(contents, capacity, element_size, new_capacity);
+ }
+ return new_contents;
+}
+
+/// This is not what you're looking for, see `array_splice`.
+static inline void *_array__splice(void *self_contents, uint32_t *size, uint32_t *capacity,
+ size_t element_size,
+ uint32_t index, uint32_t old_count,
+ uint32_t new_count, const void *elements) {
+ uint32_t new_size = *size + new_count - old_count;
+ uint32_t old_end = index + old_count;
+ uint32_t new_end = index + new_count;
+ assert(old_end <= *size);
+
+ void *new_contents = _array__reserve(self_contents, capacity, element_size, new_size);
+
+ char *contents = (char *)new_contents;
+ if (*size > old_end) {
+ memmove(
+ contents + new_end * element_size,
+ contents + old_end * element_size,
+ (*size - old_end) * element_size
+ );
+ }
+ if (new_count > 0) {
+ if (elements) {
+ memcpy(
+ (contents + index * element_size),
+ elements,
+ new_count * element_size
+ );
+ } else {
+ memset(
+ (contents + index * element_size),
+ 0,
+ new_count * element_size
+ );
+ }
+ }
+ *size += new_count - old_count;
+
+ return new_contents;
+}
+
+/// A binary search routine, based on Rust's `std::slice::binary_search_by`.
+/// This is not what you're looking for, see `array_search_sorted_with` or `array_search_sorted_by`.
+#define _array__search_sorted(self, start, compare, suffix, needle, _index, _exists) \
+ do { \
+ *(_index) = start; \
+ *(_exists) = false; \
+ uint32_t size = (self)->size - *(_index); \
+ if (size == 0) break; \
+ int comparison; \
+ while (size > 1) { \
+ uint32_t half_size = size / 2; \
+ uint32_t mid_index = *(_index) + half_size; \
+ comparison = compare(&((self)->contents[mid_index] suffix), (needle)); \
+ if (comparison <= 0) *(_index) = mid_index; \
+ size -= half_size; \
+ } \
+ comparison = compare(&((self)->contents[*(_index)] suffix), (needle)); \
+ if (comparison == 0) *(_exists) = true; \
+ else if (comparison < 0) *(_index) += 1; \
+ } while (0)
+
+/// Helper macro for the `_sorted_by` routines below. This takes the left (existing)
+/// parameter by reference in order to work with the generic sorting function above.
+#define _compare_int(a, b) ((int)*(a) - (int)(b))
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#elif defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // TREE_SITTER_ARRAY_H_
diff --git a/src/tree_sitter/parser.h b/src/tree_sitter/parser.h
new file mode 100644
index 0000000..858107d
--- /dev/null
+++ b/src/tree_sitter/parser.h
@@ -0,0 +1,286 @@
+#ifndef TREE_SITTER_PARSER_H_
+#define TREE_SITTER_PARSER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include
+#include
+#include
+
+#define ts_builtin_sym_error ((TSSymbol)-1)
+#define ts_builtin_sym_end 0
+#define TREE_SITTER_SERIALIZATION_BUFFER_SIZE 1024
+
+#ifndef TREE_SITTER_API_H_
+typedef uint16_t TSStateId;
+typedef uint16_t TSSymbol;
+typedef uint16_t TSFieldId;
+typedef struct TSLanguage TSLanguage;
+typedef struct TSLanguageMetadata {
+ uint8_t major_version;
+ uint8_t minor_version;
+ uint8_t patch_version;
+} TSLanguageMetadata;
+#endif
+
+typedef struct {
+ TSFieldId field_id;
+ uint8_t child_index;
+ bool inherited;
+} TSFieldMapEntry;
+
+// Used to index the field and supertype maps.
+typedef struct {
+ uint16_t index;
+ uint16_t length;
+} TSMapSlice;
+
+typedef struct {
+ bool visible;
+ bool named;
+ bool supertype;
+} TSSymbolMetadata;
+
+typedef struct TSLexer TSLexer;
+
+struct TSLexer {
+ int32_t lookahead;
+ TSSymbol result_symbol;
+ void (*advance)(TSLexer *, bool);
+ void (*mark_end)(TSLexer *);
+ uint32_t (*get_column)(TSLexer *);
+ bool (*is_at_included_range_start)(const TSLexer *);
+ bool (*eof)(const TSLexer *);
+ void (*log)(const TSLexer *, const char *, ...);
+};
+
+typedef enum {
+ TSParseActionTypeShift,
+ TSParseActionTypeReduce,
+ TSParseActionTypeAccept,
+ TSParseActionTypeRecover,
+} TSParseActionType;
+
+typedef union {
+ struct {
+ uint8_t type;
+ TSStateId state;
+ bool extra;
+ bool repetition;
+ } shift;
+ struct {
+ uint8_t type;
+ uint8_t child_count;
+ TSSymbol symbol;
+ int16_t dynamic_precedence;
+ uint16_t production_id;
+ } reduce;
+ uint8_t type;
+} TSParseAction;
+
+typedef struct {
+ uint16_t lex_state;
+ uint16_t external_lex_state;
+} TSLexMode;
+
+typedef struct {
+ uint16_t lex_state;
+ uint16_t external_lex_state;
+ uint16_t reserved_word_set_id;
+} TSLexerMode;
+
+typedef union {
+ TSParseAction action;
+ struct {
+ uint8_t count;
+ bool reusable;
+ } entry;
+} TSParseActionEntry;
+
+typedef struct {
+ int32_t start;
+ int32_t end;
+} TSCharacterRange;
+
+struct TSLanguage {
+ uint32_t abi_version;
+ uint32_t symbol_count;
+ uint32_t alias_count;
+ uint32_t token_count;
+ uint32_t external_token_count;
+ uint32_t state_count;
+ uint32_t large_state_count;
+ uint32_t production_id_count;
+ uint32_t field_count;
+ uint16_t max_alias_sequence_length;
+ const uint16_t *parse_table;
+ const uint16_t *small_parse_table;
+ const uint32_t *small_parse_table_map;
+ const TSParseActionEntry *parse_actions;
+ const char * const *symbol_names;
+ const char * const *field_names;
+ const TSMapSlice *field_map_slices;
+ const TSFieldMapEntry *field_map_entries;
+ const TSSymbolMetadata *symbol_metadata;
+ const TSSymbol *public_symbol_map;
+ const uint16_t *alias_map;
+ const TSSymbol *alias_sequences;
+ const TSLexerMode *lex_modes;
+ bool (*lex_fn)(TSLexer *, TSStateId);
+ bool (*keyword_lex_fn)(TSLexer *, TSStateId);
+ TSSymbol keyword_capture_token;
+ struct {
+ const bool *states;
+ const TSSymbol *symbol_map;
+ void *(*create)(void);
+ void (*destroy)(void *);
+ bool (*scan)(void *, TSLexer *, const bool *symbol_whitelist);
+ unsigned (*serialize)(void *, char *);
+ void (*deserialize)(void *, const char *, unsigned);
+ } external_scanner;
+ const TSStateId *primary_state_ids;
+ const char *name;
+ const TSSymbol *reserved_words;
+ uint16_t max_reserved_word_set_size;
+ uint32_t supertype_count;
+ const TSSymbol *supertype_symbols;
+ const TSMapSlice *supertype_map_slices;
+ const TSSymbol *supertype_map_entries;
+ TSLanguageMetadata metadata;
+};
+
+static inline bool set_contains(const TSCharacterRange *ranges, uint32_t len, int32_t lookahead) {
+ uint32_t index = 0;
+ uint32_t size = len - index;
+ while (size > 1) {
+ uint32_t half_size = size / 2;
+ uint32_t mid_index = index + half_size;
+ const TSCharacterRange *range = &ranges[mid_index];
+ if (lookahead >= range->start && lookahead <= range->end) {
+ return true;
+ } else if (lookahead > range->end) {
+ index = mid_index;
+ }
+ size -= half_size;
+ }
+ const TSCharacterRange *range = &ranges[index];
+ return (lookahead >= range->start && lookahead <= range->end);
+}
+
+/*
+ * Lexer Macros
+ */
+
+#ifdef _MSC_VER
+#define UNUSED __pragma(warning(suppress : 4101))
+#else
+#define UNUSED __attribute__((unused))
+#endif
+
+#define START_LEXER() \
+ bool result = false; \
+ bool skip = false; \
+ UNUSED \
+ bool eof = false; \
+ int32_t lookahead; \
+ goto start; \
+ next_state: \
+ lexer->advance(lexer, skip); \
+ start: \
+ skip = false; \
+ lookahead = lexer->lookahead;
+
+#define ADVANCE(state_value) \
+ { \
+ state = state_value; \
+ goto next_state; \
+ }
+
+#define ADVANCE_MAP(...) \
+ { \
+ static const uint16_t map[] = { __VA_ARGS__ }; \
+ for (uint32_t i = 0; i < sizeof(map) / sizeof(map[0]); i += 2) { \
+ if (map[i] == lookahead) { \
+ state = map[i + 1]; \
+ goto next_state; \
+ } \
+ } \
+ }
+
+#define SKIP(state_value) \
+ { \
+ skip = true; \
+ state = state_value; \
+ goto next_state; \
+ }
+
+#define ACCEPT_TOKEN(symbol_value) \
+ result = true; \
+ lexer->result_symbol = symbol_value; \
+ lexer->mark_end(lexer);
+
+#define END_STATE() return result;
+
+/*
+ * Parse Table Macros
+ */
+
+#define SMALL_STATE(id) ((id) - LARGE_STATE_COUNT)
+
+#define STATE(id) id
+
+#define ACTIONS(id) id
+
+#define SHIFT(state_value) \
+ {{ \
+ .shift = { \
+ .type = TSParseActionTypeShift, \
+ .state = (state_value) \
+ } \
+ }}
+
+#define SHIFT_REPEAT(state_value) \
+ {{ \
+ .shift = { \
+ .type = TSParseActionTypeShift, \
+ .state = (state_value), \
+ .repetition = true \
+ } \
+ }}
+
+#define SHIFT_EXTRA() \
+ {{ \
+ .shift = { \
+ .type = TSParseActionTypeShift, \
+ .extra = true \
+ } \
+ }}
+
+#define REDUCE(symbol_name, children, precedence, prod_id) \
+ {{ \
+ .reduce = { \
+ .type = TSParseActionTypeReduce, \
+ .symbol = symbol_name, \
+ .child_count = children, \
+ .dynamic_precedence = precedence, \
+ .production_id = prod_id \
+ }, \
+ }}
+
+#define RECOVER() \
+ {{ \
+ .type = TSParseActionTypeRecover \
+ }}
+
+#define ACCEPT_INPUT() \
+ {{ \
+ .type = TSParseActionTypeAccept \
+ }}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // TREE_SITTER_PARSER_H_
diff --git a/test/corpus/basics.txt b/test/corpus/basics.txt
new file mode 100644
index 0000000..6c52e48
--- /dev/null
+++ b/test/corpus/basics.txt
@@ -0,0 +1,214 @@
+==================
+Basic long format
+==================
+
+#!srfv1
+#!long
+name::alice
+age:num:30
+
+---
+
+(document
+ (blank_line)
+ (magic)
+ (directive
+ (directive_long))
+ (field
+ (untyped_field
+ (key)
+ (value)))
+ (field
+ (typed_field
+ (key)
+ (type_hint)
+ (value))))
+
+==================
+Basic compact format
+==================
+
+#!srfv1
+name::alice,age:num:30
+
+---
+
+(document
+ (blank_line)
+ (magic)
+ (field
+ (untyped_field
+ (key)
+ (value)))
+ (field
+ (typed_field
+ (key)
+ (type_hint)
+ (value))))
+
+==================
+Directives
+==================
+
+#!srfv1
+#!requireeof
+#!long
+#!expires=1772589213
+#!created=1772500000
+#!modified=1772500001
+name::alice
+
+#!eof
+
+---
+
+(document
+ (blank_line)
+ (magic)
+ (directive
+ (directive_requireeof))
+ (directive
+ (directive_long))
+ (directive
+ (directive_expires
+ value: (timestamp)))
+ (directive
+ (directive_created
+ value: (timestamp)))
+ (directive
+ (directive_modified
+ value: (timestamp)))
+ (field
+ (untyped_field
+ (key)
+ (value)))
+ (blank_line)
+ (directive
+ (directive_eof)))
+
+==================
+Comments
+==================
+
+#!srfv1
+# This is a comment
+name::alice
+
+---
+
+(document
+ (blank_line)
+ (magic)
+ (comment)
+ (field
+ (untyped_field
+ (key)
+ (value))))
+
+==================
+All type hints
+==================
+
+#!srfv1
+name:string:alice
+age:num:30
+active:bool:true
+missing:null:
+data:binary:aGVsbG8=
+bio:12:hello world!
+
+---
+
+(document
+ (blank_line)
+ (magic)
+ (field
+ (typed_field
+ (key)
+ (type_hint)
+ (value)))
+ (field
+ (typed_field
+ (key)
+ (type_hint)
+ (value)))
+ (field
+ (typed_field
+ (key)
+ (type_hint)
+ (value)))
+ (field
+ (typed_field
+ (key)
+ (type_hint)))
+ (field
+ (typed_field
+ (key)
+ (type_hint)
+ (value)))
+ (field
+ (typed_field
+ (key)
+ (type_hint)
+ (value))))
+
+==================
+Inline comments on directives
+==================
+
+#!srfv1 # version header
+#!long # use long format
+name::alice
+
+---
+
+(document
+ (blank_line)
+ (magic
+ (inline_comment))
+ (directive
+ (directive_long
+ (inline_comment)))
+ (field
+ (untyped_field
+ (key)
+ (value))))
+
+==================
+Multiple records long format
+==================
+
+#!srfv1
+#!long
+name::alice
+age:num:30
+
+name::bob
+age:num:25
+
+---
+
+(document
+ (blank_line)
+ (magic)
+ (directive
+ (directive_long))
+ (field
+ (untyped_field
+ (key)
+ (value)))
+ (field
+ (typed_field
+ (key)
+ (type_hint)
+ (value)))
+ (blank_line)
+ (field
+ (untyped_field
+ (key)
+ (value)))
+ (field
+ (typed_field
+ (key)
+ (type_hint)
+ (value))))
diff --git a/tree-sitter.json b/tree-sitter.json
new file mode 100644
index 0000000..8fbf167
--- /dev/null
+++ b/tree-sitter.json
@@ -0,0 +1,30 @@
+{
+ "grammars": [
+ {
+ "name": "srf",
+ "camelcase": "SRF",
+ "scope": "source.srf",
+ "path": ".",
+ "file-types": [
+ "srf"
+ ],
+ "highlights": "queries/highlights.scm"
+ }
+ ],
+ "metadata": {
+ "version": "0.0.1",
+ "license": "MIT",
+ "description": "SRF (Simple Record Format) grammar for tree-sitter",
+ "authors": [
+ {
+ "name": "Emil Lerch"
+ }
+ ],
+ "links": {
+ "repository": "https://git.lerch.org/lobo/srf-tree-sitter"
+ }
+ },
+ "bindings": {
+ "c": true
+ }
+}