feat(tree-sitter): add Tree-sitter grammar for Storybook DSL
This commit is contained in:
25
tree-sitter-storybook/Cargo.toml
Normal file
25
tree-sitter-storybook/Cargo.toml
Normal file
@@ -0,0 +1,25 @@
|
||||
[package]
|
||||
name = "tree-sitter-storybook"
|
||||
version = "0.1.0"
|
||||
description = "Tree-sitter grammar for Storybook narrative DSL"
|
||||
authors = ["Storybook Contributors"]
|
||||
license = "MIT"
|
||||
readme = "README.md"
|
||||
keywords = ["tree-sitter", "parser", "storybook"]
|
||||
repository = "https://github.com/yourusername/storybook"
|
||||
edition = "2021"
|
||||
include = [
|
||||
"bindings/rust/*",
|
||||
"grammar.js",
|
||||
"queries/*",
|
||||
"src/*"
|
||||
]
|
||||
|
||||
[lib]
|
||||
path = "bindings/rust/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
tree-sitter = "~0.20"
|
||||
|
||||
[build-dependencies]
|
||||
cc = "1.0"
|
||||
88
tree-sitter-storybook/README.md
Normal file
88
tree-sitter-storybook/README.md
Normal file
@@ -0,0 +1,88 @@
|
||||
# tree-sitter-storybook
|
||||
|
||||
Tree-sitter grammar for the Storybook narrative DSL.
|
||||
|
||||
## Overview
|
||||
|
||||
This is a Tree-sitter grammar for Storybook, a domain-specific language for narrative design and character development. The grammar provides syntax highlighting, code navigation, and other editor features through Tree-sitter.
|
||||
|
||||
## Features
|
||||
|
||||
- **Syntax highlighting** for all Storybook constructs
|
||||
- **Symbol outline** for navigating characters, templates, relationships, etc.
|
||||
- **Bracket matching** including special handling for prose blocks
|
||||
- **Auto-indentation** support
|
||||
|
||||
## Installation
|
||||
|
||||
### For development
|
||||
|
||||
```bash
|
||||
# Install dependencies
|
||||
npm install
|
||||
|
||||
# Generate parser
|
||||
npm run build
|
||||
|
||||
# Run tests
|
||||
npm run test
|
||||
```
|
||||
|
||||
### For Zed editor
|
||||
|
||||
This grammar is integrated into the Zed Storybook extension. See the `zed-storybook` directory for the extension.
|
||||
|
||||
## Grammar Structure
|
||||
|
||||
The grammar supports the following top-level declarations:
|
||||
|
||||
- `use` - Import statements
|
||||
- `character` - Character definitions
|
||||
- `template` - Reusable field templates
|
||||
- `life_arc` - State machines for character development
|
||||
- `schedule` - Daily schedules and routines
|
||||
- `behavior` - Behavior trees for AI
|
||||
- `institution` - Organizations and groups
|
||||
- `relationship` - Multi-party relationships
|
||||
- `location` - Places and settings
|
||||
- `species` - Species definitions with templates
|
||||
- `enum` - Enumeration types
|
||||
|
||||
## Special Features
|
||||
|
||||
### Prose Blocks
|
||||
|
||||
The grammar includes an external scanner (written in C) to handle prose blocks:
|
||||
|
||||
```storybook
|
||||
---backstory
|
||||
This is a prose block that can contain
|
||||
multiple lines of narrative text.
|
||||
---
|
||||
```
|
||||
|
||||
### Expression Support
|
||||
|
||||
Full support for expressions in life arc transitions:
|
||||
|
||||
```storybook
|
||||
on self.age >= 18 and self.location is wonderland -> adult_state
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
The grammar includes comprehensive tests. Run them with:
|
||||
|
||||
```bash
|
||||
tree-sitter test
|
||||
```
|
||||
|
||||
To test parsing a specific file:
|
||||
|
||||
```bash
|
||||
tree-sitter parse path/to/file.sb
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
19
tree-sitter-storybook/binding.gyp
Normal file
19
tree-sitter-storybook/binding.gyp
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"targets": [
|
||||
{
|
||||
"target_name": "tree_sitter_storybook_binding",
|
||||
"include_dirs": [
|
||||
"<!(node -e \"require('nan')\")",
|
||||
"src"
|
||||
],
|
||||
"sources": [
|
||||
"bindings/node/binding.cc",
|
||||
"src/parser.c",
|
||||
"src/scanner.c"
|
||||
],
|
||||
"cflags_c": [
|
||||
"-std=c99",
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
28
tree-sitter-storybook/bindings/node/binding.cc
Normal file
28
tree-sitter-storybook/bindings/node/binding.cc
Normal file
@@ -0,0 +1,28 @@
|
||||
#include "tree_sitter/parser.h"
|
||||
#include <node.h>
|
||||
#include "nan.h"
|
||||
|
||||
using namespace v8;
|
||||
|
||||
extern "C" TSLanguage * tree_sitter_storybook();
|
||||
|
||||
namespace {
|
||||
|
||||
NAN_METHOD(New) {}
|
||||
|
||||
void Init(Local<Object> exports, Local<Object> module) {
|
||||
Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
|
||||
tpl->SetClassName(Nan::New("Language").ToLocalChecked());
|
||||
tpl->InstanceTemplate()->SetInternalFieldCount(1);
|
||||
|
||||
Local<Function> constructor = Nan::GetFunction(tpl).ToLocalChecked();
|
||||
Local<Object> instance = constructor->NewInstance(Nan::GetCurrentContext()).ToLocalChecked();
|
||||
Nan::SetInternalFieldPointer(instance, 0, tree_sitter_storybook());
|
||||
|
||||
Nan::Set(instance, Nan::New("name").ToLocalChecked(), Nan::New("storybook").ToLocalChecked());
|
||||
Nan::Set(module, Nan::New("exports").ToLocalChecked(), instance);
|
||||
}
|
||||
|
||||
NODE_MODULE(tree_sitter_storybook_binding, Init)
|
||||
|
||||
} // namespace
|
||||
19
tree-sitter-storybook/bindings/node/index.js
Normal file
19
tree-sitter-storybook/bindings/node/index.js
Normal file
@@ -0,0 +1,19 @@
|
||||
try {
|
||||
module.exports = require("../../build/Release/tree_sitter_storybook_binding");
|
||||
} catch (error1) {
|
||||
if (error1.code !== 'MODULE_NOT_FOUND') {
|
||||
throw error1;
|
||||
}
|
||||
try {
|
||||
module.exports = require("../../build/Debug/tree_sitter_storybook_binding");
|
||||
} catch (error2) {
|
||||
if (error2.code !== 'MODULE_NOT_FOUND') {
|
||||
throw error2;
|
||||
}
|
||||
throw error1
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
module.exports.nodeTypeInfo = require("../../src/node-types.json");
|
||||
} catch (_) {}
|
||||
40
tree-sitter-storybook/bindings/rust/build.rs
Normal file
40
tree-sitter-storybook/bindings/rust/build.rs
Normal file
@@ -0,0 +1,40 @@
|
||||
fn main() {
|
||||
let src_dir = std::path::Path::new("src");
|
||||
|
||||
let mut c_config = cc::Build::new();
|
||||
c_config.include(&src_dir);
|
||||
c_config
|
||||
.flag_if_supported("-Wno-unused-parameter")
|
||||
.flag_if_supported("-Wno-unused-but-set-variable")
|
||||
.flag_if_supported("-Wno-trigraphs");
|
||||
let parser_path = src_dir.join("parser.c");
|
||||
c_config.file(&parser_path);
|
||||
|
||||
// If your language uses an external scanner written in C,
|
||||
// then include this block of code:
|
||||
|
||||
/*
|
||||
let scanner_path = src_dir.join("scanner.c");
|
||||
c_config.file(&scanner_path);
|
||||
println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap());
|
||||
*/
|
||||
|
||||
c_config.compile("parser");
|
||||
println!("cargo:rerun-if-changed={}", parser_path.to_str().unwrap());
|
||||
|
||||
// If your language uses an external scanner written in C++,
|
||||
// then include this block of code:
|
||||
|
||||
/*
|
||||
let mut cpp_config = cc::Build::new();
|
||||
cpp_config.cpp(true);
|
||||
cpp_config.include(&src_dir);
|
||||
cpp_config
|
||||
.flag_if_supported("-Wno-unused-parameter")
|
||||
.flag_if_supported("-Wno-unused-but-set-variable");
|
||||
let scanner_path = src_dir.join("scanner.cc");
|
||||
cpp_config.file(&scanner_path);
|
||||
cpp_config.compile("scanner");
|
||||
println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap());
|
||||
*/
|
||||
}
|
||||
52
tree-sitter-storybook/bindings/rust/lib.rs
Normal file
52
tree-sitter-storybook/bindings/rust/lib.rs
Normal file
@@ -0,0 +1,52 @@
|
||||
//! This crate provides storybook language support for the [tree-sitter][] parsing library.
|
||||
//!
|
||||
//! Typically, you will use the [language][language func] function to add this language to a
|
||||
//! tree-sitter [Parser][], and then use the parser to parse some code:
|
||||
//!
|
||||
//! ```
|
||||
//! let code = "";
|
||||
//! let mut parser = tree_sitter::Parser::new();
|
||||
//! parser.set_language(tree_sitter_storybook::language()).expect("Error loading storybook grammar");
|
||||
//! let tree = parser.parse(code, None).unwrap();
|
||||
//! ```
|
||||
//!
|
||||
//! [Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html
|
||||
//! [language func]: fn.language.html
|
||||
//! [Parser]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Parser.html
|
||||
//! [tree-sitter]: https://tree-sitter.github.io/
|
||||
|
||||
use tree_sitter::Language;
|
||||
|
||||
extern "C" {
|
||||
fn tree_sitter_storybook() -> Language;
|
||||
}
|
||||
|
||||
/// Get the tree-sitter [Language][] for this grammar.
|
||||
///
|
||||
/// [Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html
|
||||
pub fn language() -> Language {
|
||||
unsafe { tree_sitter_storybook() }
|
||||
}
|
||||
|
||||
/// The content of the [`node-types.json`][] file for this grammar.
|
||||
///
|
||||
/// [`node-types.json`]: https://tree-sitter.github.io/tree-sitter/using-parsers#static-node-types
|
||||
pub const NODE_TYPES: &'static str = include_str!("../../src/node-types.json");
|
||||
|
||||
// Uncomment these to include any queries that this grammar contains
|
||||
|
||||
// pub const HIGHLIGHTS_QUERY: &'static str = include_str!("../../queries/highlights.scm");
|
||||
// pub const INJECTIONS_QUERY: &'static str = include_str!("../../queries/injections.scm");
|
||||
// pub const LOCALS_QUERY: &'static str = include_str!("../../queries/locals.scm");
|
||||
// pub const TAGS_QUERY: &'static str = include_str!("../../queries/tags.scm");
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn test_can_load_grammar() {
|
||||
let mut parser = tree_sitter::Parser::new();
|
||||
parser
|
||||
.set_language(super::language())
|
||||
.expect("Error loading storybook language");
|
||||
}
|
||||
}
|
||||
20
tree-sitter-storybook/build.rs
Normal file
20
tree-sitter-storybook/build.rs
Normal file
@@ -0,0 +1,20 @@
|
||||
fn main() {
|
||||
let src_dir = std::path::Path::new("src");
|
||||
|
||||
let mut c_config = cc::Build::new();
|
||||
c_config.include(src_dir);
|
||||
c_config
|
||||
.flag_if_supported("-Wno-unused-parameter")
|
||||
.flag_if_supported("-Wno-unused-but-set-variable")
|
||||
.flag_if_supported("-Wno-trigraphs");
|
||||
let parser_path = src_dir.join("parser.c");
|
||||
c_config.file(&parser_path);
|
||||
|
||||
// If we have a scanner
|
||||
let scanner_path = src_dir.join("scanner.c");
|
||||
if scanner_path.exists() {
|
||||
c_config.file(&scanner_path);
|
||||
}
|
||||
|
||||
c_config.compile("tree-sitter-storybook");
|
||||
}
|
||||
379
tree-sitter-storybook/grammar.js
Normal file
379
tree-sitter-storybook/grammar.js
Normal file
@@ -0,0 +1,379 @@
|
||||
/**
|
||||
* Tree-sitter grammar for Storybook DSL
|
||||
*
|
||||
* This grammar defines the syntax for the Storybook narrative DSL,
|
||||
* including characters, templates, relationships, life arcs, behaviors, etc.
|
||||
*/
|
||||
|
||||
module.exports = grammar({
|
||||
name: 'storybook',
|
||||
|
||||
// externals: $ => [
|
||||
// $._prose_block_content,
|
||||
// $._prose_block_end
|
||||
// ],
|
||||
|
||||
extras: $ => [
|
||||
/\s/, // Whitespace
|
||||
$.line_comment,
|
||||
$.block_comment
|
||||
],
|
||||
|
||||
conflicts: $ => [
|
||||
[$.path_segments]
|
||||
],
|
||||
|
||||
word: $ => $.identifier,
|
||||
|
||||
rules: {
|
||||
// Top-level structure
|
||||
source_file: $ => repeat($.declaration),
|
||||
|
||||
// Comments
|
||||
line_comment: $ => token(seq('//', /.*/)),
|
||||
block_comment: $ => token(seq('/*', /[^*]*\*+([^/*][^*]*\*+)*/, '/')),
|
||||
|
||||
// Declarations
|
||||
declaration: $ => choice(
|
||||
$.use_declaration,
|
||||
$.character,
|
||||
$.template,
|
||||
$.life_arc,
|
||||
$.schedule,
|
||||
$.behavior,
|
||||
$.institution,
|
||||
$.relationship,
|
||||
$.location,
|
||||
$.species,
|
||||
$.enum_declaration
|
||||
),
|
||||
|
||||
// Use declarations
|
||||
use_declaration: $ => seq(
|
||||
'use',
|
||||
$.path_segments,
|
||||
optional(choice(
|
||||
seq('::', '{', commaSep1($.identifier), '}'),
|
||||
seq('::', '*')
|
||||
)),
|
||||
';'
|
||||
),
|
||||
|
||||
path: $ => $.path_segments,
|
||||
|
||||
path_segments: $ => sep1($.identifier, token('::')),
|
||||
|
||||
// Character declaration
|
||||
character: $ => seq(
|
||||
'character',
|
||||
field('name', $.identifier),
|
||||
optional(seq(':', field('species', $.identifier))),
|
||||
optional(field('template', $.template_clause)),
|
||||
field('body', $.block)
|
||||
),
|
||||
|
||||
template_clause: $ => seq('from', commaSep1($.identifier)),
|
||||
|
||||
// Template declaration
|
||||
template: $ => seq(
|
||||
'template',
|
||||
field('name', $.identifier),
|
||||
optional('strict'),
|
||||
'{',
|
||||
repeat($.include),
|
||||
repeat($.field),
|
||||
'}'
|
||||
),
|
||||
|
||||
include: $ => seq('include', $.identifier),
|
||||
|
||||
// Fields (key: value pairs)
|
||||
field: $ => choice(
|
||||
seq(
|
||||
field('name', $.dotted_path),
|
||||
':',
|
||||
field('value', $.value)
|
||||
),
|
||||
$.prose_block
|
||||
),
|
||||
|
||||
dotted_path: $ => sep1($.identifier, '.'),
|
||||
|
||||
// Values
|
||||
value: $ => choice(
|
||||
$.integer,
|
||||
$.float,
|
||||
$.string,
|
||||
$.boolean,
|
||||
$.range,
|
||||
$.time,
|
||||
$.duration,
|
||||
$.path,
|
||||
$.prose_block,
|
||||
$.list,
|
||||
$.object,
|
||||
$.override
|
||||
),
|
||||
|
||||
integer: $ => /-?[0-9]+/,
|
||||
|
||||
float: $ => /-?[0-9]+\.[0-9]+/,
|
||||
|
||||
string: $ => /"([^"\\]|\\.)*"/,
|
||||
|
||||
boolean: $ => choice('true', 'false'),
|
||||
|
||||
range: $ => choice(
|
||||
seq($.integer, '..', $.integer),
|
||||
seq($.float, '..', $.float)
|
||||
),
|
||||
|
||||
time: $ => /[0-9]{2}:[0-9]{2}(:[0-9]{2})?/,
|
||||
|
||||
duration: $ => /[0-9]+[hms]([0-9]+[hms])*/,
|
||||
|
||||
list: $ => seq('[', commaSep($.value), ']'),
|
||||
|
||||
object: $ => $.block,
|
||||
|
||||
block: $ => seq('{', repeat($.field), '}'),
|
||||
|
||||
// Override (@base { remove field, field: value })
|
||||
override: $ => seq(
|
||||
'@',
|
||||
$.path,
|
||||
'{',
|
||||
repeat($.override_op),
|
||||
'}'
|
||||
),
|
||||
|
||||
override_op: $ => choice(
|
||||
seq('remove', $.identifier),
|
||||
seq('append', $.field),
|
||||
$.field
|
||||
),
|
||||
|
||||
// Prose blocks (---tag content ---)
|
||||
prose_block: $ => seq(
|
||||
field('marker', $.prose_marker),
|
||||
field('tag', $.identifier),
|
||||
optional(/[^\n]*/), // Rest of opening line
|
||||
field('content', $.prose_content),
|
||||
field('end', $.prose_marker)
|
||||
),
|
||||
|
||||
prose_marker: $ => '---',
|
||||
|
||||
// Capture prose content as a single token for markdown injection
|
||||
prose_content: $ => token(prec(-1, repeat1(choice(
|
||||
/[^\-]+/, // Any non-dash characters
|
||||
/-[^\-]/, // Single dash not followed by another dash
|
||||
/-\-[^\-]/, // Two dashes not followed by another dash
|
||||
)))),
|
||||
|
||||
// Life arc declaration
|
||||
life_arc: $ => seq(
|
||||
'life_arc',
|
||||
field('name', $.identifier),
|
||||
'{',
|
||||
repeat($.field),
|
||||
repeat($.arc_state),
|
||||
'}'
|
||||
),
|
||||
|
||||
arc_state: $ => seq(
|
||||
'state',
|
||||
field('name', $.identifier),
|
||||
'{',
|
||||
optional($.on_enter),
|
||||
repeat($.field),
|
||||
repeat($.transition),
|
||||
'}'
|
||||
),
|
||||
|
||||
on_enter: $ => seq('on', 'enter', $.block),
|
||||
|
||||
transition: $ => seq(
|
||||
'on',
|
||||
field('condition', $.expression),
|
||||
'->',
|
||||
field('target', $.identifier)
|
||||
),
|
||||
|
||||
// Schedule declaration
|
||||
schedule: $ => seq(
|
||||
'schedule',
|
||||
field('name', $.identifier),
|
||||
'{',
|
||||
repeat($.field),
|
||||
repeat($.schedule_block),
|
||||
'}'
|
||||
),
|
||||
|
||||
schedule_block: $ => seq(
|
||||
field('start', $.time),
|
||||
'->',
|
||||
field('end', $.time),
|
||||
':',
|
||||
field('activity', $.identifier),
|
||||
$.block
|
||||
),
|
||||
|
||||
// Behavior tree declaration
|
||||
behavior: $ => seq(
|
||||
'behavior',
|
||||
field('name', $.identifier),
|
||||
'{',
|
||||
repeat($.field),
|
||||
field('root', $.behavior_node),
|
||||
'}'
|
||||
),
|
||||
|
||||
behavior_node: $ => choice(
|
||||
$.selector_node,
|
||||
$.sequence_node,
|
||||
$.repeat_node,
|
||||
$.action_node,
|
||||
$.subtree_node
|
||||
),
|
||||
|
||||
selector_node: $ => seq('?', '{', repeat1($.behavior_node), '}'),
|
||||
|
||||
sequence_node: $ => seq('>', '{', repeat1($.behavior_node), '}'),
|
||||
|
||||
repeat_node: $ => seq('*', '{', $.behavior_node, '}'),
|
||||
|
||||
action_node: $ => choice(
|
||||
seq($.identifier, '(', commaSep($.action_param), ')'),
|
||||
$.identifier
|
||||
),
|
||||
|
||||
action_param: $ => choice(
|
||||
// Named parameter: name: value
|
||||
seq($.dotted_path, ':', $.value),
|
||||
// Positional parameter: just value
|
||||
$.value
|
||||
),
|
||||
|
||||
subtree_node: $ => seq('@', $.path),
|
||||
|
||||
// Institution declaration
|
||||
institution: $ => seq(
|
||||
'institution',
|
||||
field('name', $.identifier),
|
||||
$.block
|
||||
),
|
||||
|
||||
// Relationship declaration
|
||||
relationship: $ => seq(
|
||||
'relationship',
|
||||
field('name', $.identifier),
|
||||
'{',
|
||||
repeat1($.participant),
|
||||
repeat($.field),
|
||||
'}'
|
||||
),
|
||||
|
||||
participant: $ => choice(
|
||||
// name { fields }
|
||||
seq($.path, $.block),
|
||||
// name as role { fields }
|
||||
seq($.path, 'as', $.identifier, $.block),
|
||||
// bare name
|
||||
$.path
|
||||
),
|
||||
|
||||
// Location declaration
|
||||
location: $ => seq(
|
||||
'location',
|
||||
field('name', $.identifier),
|
||||
$.block
|
||||
),
|
||||
|
||||
// Species declaration
|
||||
species: $ => seq(
|
||||
'species',
|
||||
field('name', $.identifier),
|
||||
'{',
|
||||
repeat($.include),
|
||||
repeat($.field),
|
||||
'}'
|
||||
),
|
||||
|
||||
// Enum declaration
|
||||
enum_declaration: $ => seq(
|
||||
'enum',
|
||||
field('name', $.identifier),
|
||||
'{',
|
||||
commaSep1($.identifier),
|
||||
'}'
|
||||
),
|
||||
|
||||
// Expressions (for conditions in life arcs)
|
||||
expression: $ => choice(
|
||||
$.or_expression,
|
||||
$.and_expression,
|
||||
$.not_expression,
|
||||
$.comparison,
|
||||
$.field_access,
|
||||
$.primary_expression
|
||||
),
|
||||
|
||||
or_expression: $ => prec.left(1, seq(
|
||||
$.expression,
|
||||
'or',
|
||||
$.expression
|
||||
)),
|
||||
|
||||
and_expression: $ => prec.left(2, seq(
|
||||
$.expression,
|
||||
'and',
|
||||
$.expression
|
||||
)),
|
||||
|
||||
not_expression: $ => prec(3, seq('not', $.expression)),
|
||||
|
||||
comparison: $ => prec.left(4, seq(
|
||||
$.expression,
|
||||
field('operator', choice('is', '>', '>=', '<', '<=')),
|
||||
$.expression
|
||||
)),
|
||||
|
||||
field_access: $ => prec.left(5, seq(
|
||||
$.expression,
|
||||
'.',
|
||||
$.identifier
|
||||
)),
|
||||
|
||||
primary_expression: $ => choice(
|
||||
'self',
|
||||
'other',
|
||||
$.integer,
|
||||
$.float,
|
||||
$.string,
|
||||
$.boolean,
|
||||
$.path
|
||||
),
|
||||
|
||||
// Identifiers
|
||||
identifier: $ => /[a-zA-Z_][a-zA-Z0-9_]*/,
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Helper to create comma-separated lists with optional trailing comma
|
||||
*/
|
||||
function commaSep(rule) {
|
||||
return optional(commaSep1(rule));
|
||||
}
|
||||
|
||||
function commaSep1(rule) {
|
||||
return seq(rule, repeat(seq(',', rule)), optional(','));
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to create separator-based lists (e.g., :: or .)
|
||||
*/
|
||||
function sep1(rule, separator) {
|
||||
return seq(rule, repeat(seq(separator, rule)));
|
||||
}
|
||||
554
tree-sitter-storybook/package-lock.json
generated
Normal file
554
tree-sitter-storybook/package-lock.json
generated
Normal file
@@ -0,0 +1,554 @@
|
||||
{
|
||||
"name": "tree-sitter-storybook",
|
||||
"version": "0.1.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "tree-sitter-storybook",
|
||||
"version": "0.1.0",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"node-addon-api": "^7.1.0",
|
||||
"node-gyp-build": "^4.8.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"prebuildify": "^6.0.0",
|
||||
"tree-sitter-cli": "^0.20.8"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"tree-sitter": "^0.20.4"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"tree_sitter": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/base64-js": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/bl": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
|
||||
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"buffer": "^5.5.0",
|
||||
"inherits": "^2.0.4",
|
||||
"readable-stream": "^3.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
|
||||
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"base64-js": "^1.3.1",
|
||||
"ieee754": "^1.1.13"
|
||||
}
|
||||
},
|
||||
"node_modules/chownr": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
|
||||
"integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/decompress-response": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
|
||||
"integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"mimic-response": "^3.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/deep-extend": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
|
||||
"integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/detect-libc": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
|
||||
"integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/end-of-stream": {
|
||||
"version": "1.4.5",
|
||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz",
|
||||
"integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/expand-template": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
|
||||
"integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
|
||||
"license": "(MIT OR WTFPL)",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/fs-constants": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
|
||||
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/github-from-package": {
|
||||
"version": "0.0.0",
|
||||
"resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
|
||||
"integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/ieee754": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/ini": {
|
||||
"version": "1.3.8",
|
||||
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
|
||||
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
|
||||
"license": "ISC",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/mimic-response": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
|
||||
"integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/minimist": {
|
||||
"version": "1.2.8",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
|
||||
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/mkdirp-classic": {
|
||||
"version": "0.5.3",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
|
||||
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/nan": {
|
||||
"version": "2.25.0",
|
||||
"resolved": "https://registry.npmjs.org/nan/-/nan-2.25.0.tgz",
|
||||
"integrity": "sha512-0M90Ag7Xn5KMLLZ7zliPWP3rT90P6PN+IzVFS0VqmnPktBk3700xUVv8Ikm9EUaUE5SDWdp/BIxdENzVznpm1g==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/napi-build-utils": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz",
|
||||
"integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/node-abi": {
|
||||
"version": "3.87.0",
|
||||
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.87.0.tgz",
|
||||
"integrity": "sha512-+CGM1L1CgmtheLcBuleyYOn7NWPVu0s0EJH2C4puxgEZb9h8QpR9G2dBfZJOAUhi7VQxuBPMd0hiISWcTyiYyQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"semver": "^7.3.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/node-addon-api": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
|
||||
"integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/node-gyp-build": {
|
||||
"version": "4.8.4",
|
||||
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz",
|
||||
"integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"node-gyp-build": "bin.js",
|
||||
"node-gyp-build-optional": "optional.js",
|
||||
"node-gyp-build-test": "build-test.js"
|
||||
}
|
||||
},
|
||||
"node_modules/npm-run-path": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-3.1.0.tgz",
|
||||
"integrity": "sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"path-key": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/path-key": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
|
||||
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/prebuild-install": {
|
||||
"version": "7.1.3",
|
||||
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz",
|
||||
"integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"detect-libc": "^2.0.0",
|
||||
"expand-template": "^2.0.3",
|
||||
"github-from-package": "0.0.0",
|
||||
"minimist": "^1.2.3",
|
||||
"mkdirp-classic": "^0.5.3",
|
||||
"napi-build-utils": "^2.0.0",
|
||||
"node-abi": "^3.3.0",
|
||||
"pump": "^3.0.0",
|
||||
"rc": "^1.2.7",
|
||||
"simple-get": "^4.0.0",
|
||||
"tar-fs": "^2.0.0",
|
||||
"tunnel-agent": "^0.6.0"
|
||||
},
|
||||
"bin": {
|
||||
"prebuild-install": "bin.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/prebuildify": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/prebuildify/-/prebuildify-6.0.1.tgz",
|
||||
"integrity": "sha512-8Y2oOOateom/s8dNBsGIcnm6AxPmLH4/nanQzL5lQMU+sC0CMhzARZHizwr36pUPLdvBnOkCNQzxg4djuFSgIw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"minimist": "^1.2.5",
|
||||
"mkdirp-classic": "^0.5.3",
|
||||
"node-abi": "^3.3.0",
|
||||
"npm-run-path": "^3.1.0",
|
||||
"pump": "^3.0.0",
|
||||
"tar-fs": "^2.1.0"
|
||||
},
|
||||
"bin": {
|
||||
"prebuildify": "bin.js"
|
||||
}
|
||||
},
|
||||
"node_modules/pump": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz",
|
||||
"integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"end-of-stream": "^1.1.0",
|
||||
"once": "^1.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/rc": {
|
||||
"version": "1.2.8",
|
||||
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
|
||||
"integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
|
||||
"license": "(BSD-2-Clause OR MIT OR Apache-2.0)",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"deep-extend": "^0.6.0",
|
||||
"ini": "~1.3.0",
|
||||
"minimist": "^1.2.0",
|
||||
"strip-json-comments": "~2.0.1"
|
||||
},
|
||||
"bin": {
|
||||
"rc": "cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/readable-stream": {
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
||||
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "7.7.4",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
|
||||
"integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/simple-concat": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
|
||||
"integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/simple-get": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz",
|
||||
"integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"decompress-response": "^6.0.0",
|
||||
"once": "^1.3.1",
|
||||
"simple-concat": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/string_decoder": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
||||
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"safe-buffer": "~5.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/strip-json-comments": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
|
||||
"integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tar-fs": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz",
|
||||
"integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"chownr": "^1.1.1",
|
||||
"mkdirp-classic": "^0.5.2",
|
||||
"pump": "^3.0.0",
|
||||
"tar-stream": "^2.1.4"
|
||||
}
|
||||
},
|
||||
"node_modules/tar-stream": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
|
||||
"integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"bl": "^4.0.3",
|
||||
"end-of-stream": "^1.4.1",
|
||||
"fs-constants": "^1.0.0",
|
||||
"inherits": "^2.0.3",
|
||||
"readable-stream": "^3.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/tree-sitter": {
|
||||
"version": "0.20.6",
|
||||
"resolved": "https://registry.npmjs.org/tree-sitter/-/tree-sitter-0.20.6.tgz",
|
||||
"integrity": "sha512-GxJodajVpfgb3UREzzIbtA1hyRnTxVbWVXrbC6sk4xTMH5ERMBJk9HJNq4c8jOJeUaIOmLcwg+t6mez/PDvGqg==",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"nan": "^2.18.0",
|
||||
"prebuild-install": "^7.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/tree-sitter-cli": {
|
||||
"version": "0.20.8",
|
||||
"resolved": "https://registry.npmjs.org/tree-sitter-cli/-/tree-sitter-cli-0.20.8.tgz",
|
||||
"integrity": "sha512-XjTcS3wdTy/2cc/ptMLc/WRyOLECRYcMTrSWyhZnj1oGSOWbHLTklgsgRICU3cPfb0vy+oZCC33M43u6R1HSCA==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"tree-sitter": "cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/tunnel-agent": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
|
||||
"integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"safe-buffer": "^5.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
|
||||
"license": "ISC"
|
||||
}
|
||||
}
|
||||
}
|
||||
55
tree-sitter-storybook/package.json
Normal file
55
tree-sitter-storybook/package.json
Normal file
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"name": "tree-sitter-storybook",
|
||||
"version": "0.1.0",
|
||||
"description": "Tree-sitter grammar for Storybook narrative DSL",
|
||||
"main": "bindings/node",
|
||||
"types": "bindings/node",
|
||||
"keywords": [
|
||||
"tree-sitter",
|
||||
"parser",
|
||||
"storybook"
|
||||
],
|
||||
"files": [
|
||||
"grammar.js",
|
||||
"binding.gyp",
|
||||
"prebuilds/**",
|
||||
"bindings/node/*",
|
||||
"queries/*",
|
||||
"src/**"
|
||||
],
|
||||
"dependencies": {
|
||||
"node-addon-api": "^7.1.0",
|
||||
"node-gyp-build": "^4.8.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"tree-sitter-cli": "^0.20.8",
|
||||
"prebuildify": "^6.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"tree-sitter": "^0.20.4"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"tree_sitter": {
|
||||
"optional": true
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"install": "node-gyp-build",
|
||||
"prebuildify": "prebuildify --napi --strip",
|
||||
"build": "tree-sitter generate && node-gyp-build",
|
||||
"build-wasm": "tree-sitter build-wasm",
|
||||
"test": "tree-sitter test"
|
||||
},
|
||||
"tree-sitter": [
|
||||
{
|
||||
"scope": "source.storybook",
|
||||
"file-types": ["sb"],
|
||||
"highlights": "queries/highlights.scm"
|
||||
}
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/yourusername/storybook"
|
||||
},
|
||||
"license": "MIT"
|
||||
}
|
||||
16
tree-sitter-storybook/queries/brackets.scm
Normal file
16
tree-sitter-storybook/queries/brackets.scm
Normal file
@@ -0,0 +1,16 @@
|
||||
; Bracket matching for Storybook DSL
|
||||
|
||||
; Curly braces
|
||||
("{" @open "}" @close) @bracket
|
||||
|
||||
; Parentheses
|
||||
("(" @open ")" @close) @bracket
|
||||
|
||||
; Square brackets
|
||||
("[" @open "]" @close) @bracket
|
||||
|
||||
; Prose blocks (special bracket matching for --- markers)
|
||||
; Note: Both markers are the same node type
|
||||
(prose_block
|
||||
(prose_marker) @open
|
||||
(prose_marker) @close) @bracket
|
||||
153
tree-sitter-storybook/queries/highlights.scm
Normal file
153
tree-sitter-storybook/queries/highlights.scm
Normal file
@@ -0,0 +1,153 @@
|
||||
; Highlights query for Storybook DSL
|
||||
; Maps grammar nodes to standard highlight groups
|
||||
|
||||
; Comments
|
||||
(line_comment) @comment.line
|
||||
(block_comment) @comment.block
|
||||
|
||||
; Keywords - Declaration keywords
|
||||
[
|
||||
"character"
|
||||
"template"
|
||||
"life_arc"
|
||||
"schedule"
|
||||
"behavior"
|
||||
"institution"
|
||||
"relationship"
|
||||
"location"
|
||||
"species"
|
||||
"enum"
|
||||
"state"
|
||||
] @keyword.declaration
|
||||
|
||||
; Keywords - Control flow and modifiers
|
||||
[
|
||||
"and"
|
||||
"or"
|
||||
"not"
|
||||
"on"
|
||||
"enter"
|
||||
"strict"
|
||||
] @keyword.control
|
||||
|
||||
; Keywords - Import/module
|
||||
[
|
||||
"use"
|
||||
"include"
|
||||
"from"
|
||||
] @keyword.import
|
||||
|
||||
; Keywords - Special
|
||||
[
|
||||
"as"
|
||||
"self"
|
||||
"other"
|
||||
"remove"
|
||||
"append"
|
||||
"is"
|
||||
] @keyword.special
|
||||
|
||||
; Boolean literals
|
||||
[
|
||||
"true"
|
||||
"false"
|
||||
] @constant.builtin.boolean
|
||||
|
||||
; Numbers
|
||||
(integer) @constant.numeric.integer
|
||||
(float) @constant.numeric.float
|
||||
(time) @constant.numeric.time
|
||||
(duration) @constant.numeric.duration
|
||||
|
||||
; Strings
|
||||
(string) @string
|
||||
|
||||
; Identifiers in different contexts
|
||||
(character name: (identifier) @type.character)
|
||||
(template name: (identifier) @type.template)
|
||||
(life_arc name: (identifier) @type.life_arc)
|
||||
(schedule name: (identifier) @type.schedule)
|
||||
(behavior name: (identifier) @type.behavior)
|
||||
(institution name: (identifier) @type.institution)
|
||||
(relationship name: (identifier) @type.relationship)
|
||||
(location name: (identifier) @type.location)
|
||||
(species name: (identifier) @type.species)
|
||||
(enum_declaration name: (identifier) @type.enum)
|
||||
(arc_state name: (identifier) @type.state)
|
||||
|
||||
; Field names
|
||||
(field name: (dotted_path) @property)
|
||||
|
||||
; Species reference
|
||||
(character species: (identifier) @type.builtin)
|
||||
|
||||
; Paths and identifiers
|
||||
(path) @namespace
|
||||
(identifier) @variable
|
||||
|
||||
; Prose blocks - tag and content
|
||||
(prose_block tag: (identifier) @tag)
|
||||
(prose_block marker: (prose_marker) @punctuation.delimiter)
|
||||
(prose_content) @markup.raw
|
||||
|
||||
; Operators
|
||||
[
|
||||
">"
|
||||
">="
|
||||
"<"
|
||||
"<="
|
||||
"->"
|
||||
"is"
|
||||
] @operator
|
||||
|
||||
; Punctuation
|
||||
[
|
||||
"{"
|
||||
"}"
|
||||
] @punctuation.bracket
|
||||
|
||||
[
|
||||
"("
|
||||
")"
|
||||
] @punctuation.bracket
|
||||
|
||||
[
|
||||
"["
|
||||
"]"
|
||||
] @punctuation.bracket
|
||||
|
||||
[
|
||||
":"
|
||||
"::"
|
||||
";"
|
||||
","
|
||||
"."
|
||||
".."
|
||||
"*"
|
||||
"?"
|
||||
"@"
|
||||
] @punctuation.delimiter
|
||||
|
||||
; Behavior tree nodes
|
||||
(selector_node "?" @keyword.behavior.selector)
|
||||
(sequence_node ">" @keyword.behavior.sequence)
|
||||
(repeat_node "*" @keyword.behavior.repeat)
|
||||
(action_node (identifier) @function.action)
|
||||
|
||||
; Transitions
|
||||
(transition "->" @operator.transition)
|
||||
(transition target: (identifier) @type.state)
|
||||
|
||||
; Schedule blocks
|
||||
(schedule_block activity: (identifier) @function.activity)
|
||||
|
||||
; Override operations
|
||||
(override "@" @keyword.override)
|
||||
(override_op "remove" @keyword.override)
|
||||
(override_op "append" @keyword.override)
|
||||
|
||||
; Template clause
|
||||
(template_clause "from" @keyword.import)
|
||||
|
||||
; Error handling
|
||||
(ERROR) @error
|
||||
45
tree-sitter-storybook/queries/indents.scm
Normal file
45
tree-sitter-storybook/queries/indents.scm
Normal file
@@ -0,0 +1,45 @@
|
||||
; Indentation query for Storybook DSL
|
||||
|
||||
; Increase indent after opening braces
|
||||
[
|
||||
"{"
|
||||
"("
|
||||
"["
|
||||
] @indent.begin
|
||||
|
||||
; Decrease indent before closing braces
|
||||
[
|
||||
"}"
|
||||
")"
|
||||
"]"
|
||||
] @indent.end
|
||||
|
||||
; Special handling for prose blocks
|
||||
(prose_block
|
||||
marker: (prose_marker) @indent.begin
|
||||
content: (_)
|
||||
end: (_) @indent.end
|
||||
)
|
||||
|
||||
; Block structures that should indent their contents
|
||||
[
|
||||
(block)
|
||||
(character)
|
||||
(template)
|
||||
(life_arc)
|
||||
(arc_state)
|
||||
(schedule)
|
||||
(schedule_block)
|
||||
(behavior)
|
||||
(institution)
|
||||
(relationship)
|
||||
(location)
|
||||
(species)
|
||||
(enum_declaration)
|
||||
(selector_node)
|
||||
(sequence_node)
|
||||
(repeat_node)
|
||||
] @indent.begin
|
||||
|
||||
; Dedent after semicolon at top level
|
||||
(use_declaration ";" @indent.end)
|
||||
12
tree-sitter-storybook/queries/injections.scm
Normal file
12
tree-sitter-storybook/queries/injections.scm
Normal file
@@ -0,0 +1,12 @@
|
||||
; Injections for embedded languages in Storybook
|
||||
|
||||
; Treat prose block content as Markdown
|
||||
((prose_content) @injection.content
|
||||
(#set! injection.language "markdown"))
|
||||
|
||||
; Alternative: If you want to be more specific and only inject for certain tags:
|
||||
; ((prose_block
|
||||
; tag: (identifier) @tag
|
||||
; content: (_) @injection.content)
|
||||
; (#match? @tag "^(description|backstory|narrative|details|notes)$")
|
||||
; (#set! injection.language "markdown"))
|
||||
57
tree-sitter-storybook/queries/outline.scm
Normal file
57
tree-sitter-storybook/queries/outline.scm
Normal file
@@ -0,0 +1,57 @@
|
||||
; Outline/symbols query for Storybook DSL
|
||||
; Defines what symbols appear in the document outline
|
||||
|
||||
; Characters
|
||||
(character
|
||||
name: (identifier) @name
|
||||
) @symbol.character
|
||||
|
||||
; Templates
|
||||
(template
|
||||
name: (identifier) @name
|
||||
) @symbol.template
|
||||
|
||||
; Life arcs
|
||||
(life_arc
|
||||
name: (identifier) @name
|
||||
) @symbol.life_arc
|
||||
|
||||
; Life arc states
|
||||
(arc_state
|
||||
name: (identifier) @name
|
||||
) @symbol.state
|
||||
|
||||
; Schedules
|
||||
(schedule
|
||||
name: (identifier) @name
|
||||
) @symbol.schedule
|
||||
|
||||
; Behaviors
|
||||
(behavior
|
||||
name: (identifier) @name
|
||||
) @symbol.behavior
|
||||
|
||||
; Institutions
|
||||
(institution
|
||||
name: (identifier) @name
|
||||
) @symbol.institution
|
||||
|
||||
; Relationships
|
||||
(relationship
|
||||
name: (identifier) @name
|
||||
) @symbol.relationship
|
||||
|
||||
; Locations
|
||||
(location
|
||||
name: (identifier) @name
|
||||
) @symbol.location
|
||||
|
||||
; Species
|
||||
(species
|
||||
name: (identifier) @name
|
||||
) @symbol.species
|
||||
|
||||
; Enums
|
||||
(enum_declaration
|
||||
name: (identifier) @name
|
||||
) @symbol.enum
|
||||
1713
tree-sitter-storybook/src/grammar.json
Normal file
1713
tree-sitter-storybook/src/grammar.json
Normal file
File diff suppressed because it is too large
Load Diff
1401
tree-sitter-storybook/src/node-types.json
Normal file
1401
tree-sitter-storybook/src/node-types.json
Normal file
File diff suppressed because it is too large
Load Diff
7086
tree-sitter-storybook/src/parser.c
Normal file
7086
tree-sitter-storybook/src/parser.c
Normal file
File diff suppressed because it is too large
Load Diff
157
tree-sitter-storybook/src/scanner.c
Normal file
157
tree-sitter-storybook/src/scanner.c
Normal file
@@ -0,0 +1,157 @@
|
||||
/**
|
||||
* External scanner for Storybook Tree-sitter grammar
|
||||
*
|
||||
* This scanner handles prose blocks (---tag content ---) which require
|
||||
* stateful scanning to properly match opening and closing delimiters.
|
||||
*/
|
||||
|
||||
#include <tree_sitter/parser.h>
|
||||
#include <wctype.h>
|
||||
#include <string.h>
|
||||
|
||||
enum TokenType {
|
||||
PROSE_BLOCK_CONTENT,
|
||||
PROSE_BLOCK_END,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
bool in_prose_block;
|
||||
} Scanner;
|
||||
|
||||
void *tree_sitter_storybook_external_scanner_create() {
|
||||
Scanner *scanner = (Scanner *)malloc(sizeof(Scanner));
|
||||
scanner->in_prose_block = false;
|
||||
return scanner;
|
||||
}
|
||||
|
||||
void tree_sitter_storybook_external_scanner_destroy(void *payload) {
|
||||
Scanner *scanner = (Scanner *)payload;
|
||||
free(scanner);
|
||||
}
|
||||
|
||||
unsigned tree_sitter_storybook_external_scanner_serialize(
|
||||
void *payload,
|
||||
char *buffer
|
||||
) {
|
||||
Scanner *scanner = (Scanner *)payload;
|
||||
buffer[0] = scanner->in_prose_block ? 1 : 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void tree_sitter_storybook_external_scanner_deserialize(
|
||||
void *payload,
|
||||
const char *buffer,
|
||||
unsigned length
|
||||
) {
|
||||
Scanner *scanner = (Scanner *)payload;
|
||||
scanner->in_prose_block = (length > 0 && buffer[0] == 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if we're at the start of a line (only whitespace before)
|
||||
*/
|
||||
static bool at_line_start(TSLexer *lexer) {
|
||||
// Look back to see if there's only whitespace since last newline
|
||||
// For simplicity, we'll assume --- at start of content is line-start
|
||||
return true; // Tree-sitter will handle this check via grammar
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan prose block content
|
||||
*
|
||||
* Returns true if we successfully scanned content, false otherwise
|
||||
*/
|
||||
static bool scan_prose_content(Scanner *scanner, TSLexer *lexer) {
|
||||
bool has_content = false;
|
||||
|
||||
// Consume characters until we see --- at line start
|
||||
for (;;) {
|
||||
// Check for end-of-file
|
||||
if (lexer->eof(lexer)) {
|
||||
// If we have content, return it; otherwise error
|
||||
if (has_content) {
|
||||
lexer->result_symbol = PROSE_BLOCK_CONTENT;
|
||||
scanner->in_prose_block = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for closing ---
|
||||
if (lexer->lookahead == '-') {
|
||||
// Look ahead to see if it's ---
|
||||
lexer->mark_end(lexer);
|
||||
lexer->advance(lexer, false);
|
||||
|
||||
if (lexer->lookahead == '-') {
|
||||
lexer->advance(lexer, false);
|
||||
if (lexer->lookahead == '-') {
|
||||
// Found closing ---, stop here
|
||||
// Mark end before the ---
|
||||
scanner->in_prose_block = false;
|
||||
if (has_content) {
|
||||
lexer->result_symbol = PROSE_BLOCK_CONTENT;
|
||||
return true;
|
||||
}
|
||||
// No content, scan the closing marker
|
||||
lexer->result_symbol = PROSE_BLOCK_END;
|
||||
lexer->advance(lexer, false); // Consume final -
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// Not a closing marker, continue with content
|
||||
has_content = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Regular content character
|
||||
lexer->advance(lexer, false);
|
||||
has_content = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan for closing prose block marker (---)
|
||||
*/
|
||||
static bool scan_prose_end(Scanner *scanner, TSLexer *lexer) {
|
||||
// We should be at ---
|
||||
if (lexer->lookahead == '-') {
|
||||
lexer->advance(lexer, false);
|
||||
if (lexer->lookahead == '-') {
|
||||
lexer->advance(lexer, false);
|
||||
if (lexer->lookahead == '-') {
|
||||
lexer->advance(lexer, false);
|
||||
lexer->result_symbol = PROSE_BLOCK_END;
|
||||
scanner->in_prose_block = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool tree_sitter_storybook_external_scanner_scan(
|
||||
void *payload,
|
||||
TSLexer *lexer,
|
||||
const bool *valid_symbols
|
||||
) {
|
||||
Scanner *scanner = (Scanner *)payload;
|
||||
|
||||
// Skip whitespace at the start
|
||||
while (iswspace(lexer->lookahead)) {
|
||||
lexer->advance(lexer, true);
|
||||
}
|
||||
|
||||
// If we're looking for prose content
|
||||
if (valid_symbols[PROSE_BLOCK_CONTENT]) {
|
||||
scanner->in_prose_block = true;
|
||||
return scan_prose_content(scanner, lexer);
|
||||
}
|
||||
|
||||
// If we're looking for prose end
|
||||
if (valid_symbols[PROSE_BLOCK_END]) {
|
||||
return scan_prose_end(scanner, lexer);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
54
tree-sitter-storybook/src/tree_sitter/alloc.h
Normal file
54
tree-sitter-storybook/src/tree_sitter/alloc.h
Normal file
@@ -0,0 +1,54 @@
|
||||
#ifndef TREE_SITTER_ALLOC_H_
|
||||
#define TREE_SITTER_ALLOC_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// 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_
|
||||
347
tree-sitter-storybook/src/tree_sitter/array.h
Normal file
347
tree-sitter-storybook/src/tree_sitter/array.h
Normal file
@@ -0,0 +1,347 @@
|
||||
#ifndef TREE_SITTER_ARRAY_H_
|
||||
#define TREE_SITTER_ARRAY_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "./alloc.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#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) _array__delete((self), (void *)(self)->contents, sizeof(*self))
|
||||
|
||||
/// 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 { \
|
||||
struct Swap swapped_contents = _array__swap( \
|
||||
(void *)(self)->contents, &(self)->size, &(self)->capacity, \
|
||||
(void *)(other)->contents, &(other)->size, &(other)->capacity \
|
||||
); \
|
||||
(self)->contents = swapped_contents.self_contents; \
|
||||
(other)->contents = swapped_contents.other_contents; \
|
||||
} 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_delete`.
|
||||
static inline void _array__delete(void *self, void *contents, size_t self_size) {
|
||||
if (contents) ts_free(contents);
|
||||
if (self) memset(self, 0, self_size);
|
||||
}
|
||||
|
||||
/// 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;
|
||||
}
|
||||
|
||||
struct Swap {
|
||||
void *self_contents;
|
||||
void *other_contents;
|
||||
};
|
||||
|
||||
/// This is not what you're looking for, see `array_swap`.
|
||||
// static inline void _array__swap(Array *self, Array *other) {
|
||||
static inline struct Swap _array__swap(void *self_contents, uint32_t *self_size, uint32_t *self_capacity,
|
||||
void *other_contents, uint32_t *other_size, uint32_t *other_capacity) {
|
||||
void *new_self_contents = other_contents;
|
||||
uint32_t new_self_size = *other_size;
|
||||
uint32_t new_self_capacity = *other_capacity;
|
||||
|
||||
void *new_other_contents = self_contents;
|
||||
*other_size = *self_size;
|
||||
*other_capacity = *self_capacity;
|
||||
|
||||
*self_size = new_self_size;
|
||||
*self_capacity = new_self_capacity;
|
||||
|
||||
struct Swap out = {
|
||||
.self_contents = new_self_contents,
|
||||
.other_contents = new_other_contents,
|
||||
};
|
||||
return out;
|
||||
}
|
||||
|
||||
/// 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_
|
||||
224
tree-sitter-storybook/src/tree_sitter/parser.h
Normal file
224
tree-sitter-storybook/src/tree_sitter/parser.h
Normal file
@@ -0,0 +1,224 @@
|
||||
#ifndef TREE_SITTER_PARSER_H_
|
||||
#define TREE_SITTER_PARSER_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define ts_builtin_sym_error ((TSSymbol)-1)
|
||||
#define ts_builtin_sym_end 0
|
||||
#define TREE_SITTER_SERIALIZATION_BUFFER_SIZE 1024
|
||||
|
||||
typedef uint16_t TSStateId;
|
||||
|
||||
#ifndef TREE_SITTER_API_H_
|
||||
typedef uint16_t TSSymbol;
|
||||
typedef uint16_t TSFieldId;
|
||||
typedef struct TSLanguage TSLanguage;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
TSFieldId field_id;
|
||||
uint8_t child_index;
|
||||
bool inherited;
|
||||
} TSFieldMapEntry;
|
||||
|
||||
typedef struct {
|
||||
uint16_t index;
|
||||
uint16_t length;
|
||||
} TSFieldMapSlice;
|
||||
|
||||
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 *);
|
||||
};
|
||||
|
||||
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 union {
|
||||
TSParseAction action;
|
||||
struct {
|
||||
uint8_t count;
|
||||
bool reusable;
|
||||
} entry;
|
||||
} TSParseActionEntry;
|
||||
|
||||
struct TSLanguage {
|
||||
uint32_t 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 TSFieldMapSlice *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 TSLexMode *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;
|
||||
};
|
||||
|
||||
/*
|
||||
* Lexer Macros
|
||||
*/
|
||||
|
||||
#define START_LEXER() \
|
||||
bool result = false; \
|
||||
bool skip = false; \
|
||||
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 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_val, child_count_val, ...) \
|
||||
{{ \
|
||||
.reduce = { \
|
||||
.type = TSParseActionTypeReduce, \
|
||||
.symbol = symbol_val, \
|
||||
.child_count = child_count_val, \
|
||||
__VA_ARGS__ \
|
||||
}, \
|
||||
}}
|
||||
|
||||
#define RECOVER() \
|
||||
{{ \
|
||||
.type = TSParseActionTypeRecover \
|
||||
}}
|
||||
|
||||
#define ACCEPT_INPUT() \
|
||||
{{ \
|
||||
.type = TSParseActionTypeAccept \
|
||||
}}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TREE_SITTER_PARSER_H_
|
||||
58
tree-sitter-storybook/test/corpus/basic.txt
Normal file
58
tree-sitter-storybook/test/corpus/basic.txt
Normal file
@@ -0,0 +1,58 @@
|
||||
==================
|
||||
Simple character
|
||||
==================
|
||||
|
||||
character Alice {
|
||||
age: 7
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(declaration
|
||||
(character
|
||||
name: (identifier)
|
||||
body: (block
|
||||
(field
|
||||
name: (dotted_path (identifier))
|
||||
value: (value (integer)))))))
|
||||
|
||||
==================
|
||||
Use declaration
|
||||
==================
|
||||
|
||||
use schema::core::Item;
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(declaration
|
||||
(use_declaration
|
||||
(path_segments
|
||||
(identifier)
|
||||
(identifier)
|
||||
(identifier)))))
|
||||
|
||||
==================
|
||||
Prose block
|
||||
==================
|
||||
|
||||
character Bob {
|
||||
---backstory
|
||||
This is Bob's story.
|
||||
---
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(declaration
|
||||
(character
|
||||
name: (identifier)
|
||||
body: (block
|
||||
(field
|
||||
(prose_block
|
||||
marker: (prose_marker)
|
||||
tag: (identifier)
|
||||
content: (prose_content)
|
||||
end: (prose_marker)))))))
|
||||
180
tree-sitter-storybook/test/corpus/behaviors.txt
Normal file
180
tree-sitter-storybook/test/corpus/behaviors.txt
Normal file
@@ -0,0 +1,180 @@
|
||||
==================
|
||||
Simple Behavior
|
||||
==================
|
||||
|
||||
behavior SimpleBehavior {
|
||||
walk_around
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(declaration
|
||||
(behavior
|
||||
name: (identifier)
|
||||
root: (behavior_node
|
||||
(action_node (identifier))))))
|
||||
|
||||
==================
|
||||
Selector Behavior
|
||||
==================
|
||||
|
||||
behavior SelectorBehavior {
|
||||
? {
|
||||
try_option_a
|
||||
try_option_b
|
||||
fallback
|
||||
}
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(declaration
|
||||
(behavior
|
||||
name: (identifier)
|
||||
root: (behavior_node
|
||||
(selector_node
|
||||
(behavior_node (action_node (identifier)))
|
||||
(behavior_node (action_node (identifier)))
|
||||
(behavior_node (action_node (identifier))))))))
|
||||
|
||||
==================
|
||||
Sequence Behavior
|
||||
==================
|
||||
|
||||
behavior SequenceBehavior {
|
||||
> {
|
||||
check_energy
|
||||
move_to_location
|
||||
perform_action
|
||||
}
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(declaration
|
||||
(behavior
|
||||
name: (identifier)
|
||||
root: (behavior_node
|
||||
(sequence_node
|
||||
(behavior_node (action_node (identifier)))
|
||||
(behavior_node (action_node (identifier)))
|
||||
(behavior_node (action_node (identifier))))))))
|
||||
|
||||
==================
|
||||
Nested Behavior
|
||||
==================
|
||||
|
||||
behavior NestedBehavior {
|
||||
> {
|
||||
? {
|
||||
check_condition_a
|
||||
check_condition_b
|
||||
}
|
||||
perform_action
|
||||
}
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(declaration
|
||||
(behavior
|
||||
name: (identifier)
|
||||
root: (behavior_node
|
||||
(sequence_node
|
||||
(behavior_node
|
||||
(selector_node
|
||||
(behavior_node (action_node (identifier)))
|
||||
(behavior_node (action_node (identifier)))))
|
||||
(behavior_node (action_node (identifier))))))))
|
||||
|
||||
==================
|
||||
Repeat Behavior
|
||||
==================
|
||||
|
||||
behavior RepeatBehavior {
|
||||
* {
|
||||
patrol
|
||||
}
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(declaration
|
||||
(behavior
|
||||
name: (identifier)
|
||||
root: (behavior_node
|
||||
(repeat_node
|
||||
(behavior_node (action_node (identifier))))))))
|
||||
|
||||
==================
|
||||
Behavior with Subtree
|
||||
==================
|
||||
|
||||
behavior WithSubtree {
|
||||
> {
|
||||
@helpers::check_preconditions
|
||||
main_action
|
||||
}
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(declaration
|
||||
(behavior
|
||||
name: (identifier)
|
||||
root: (behavior_node
|
||||
(sequence_node
|
||||
(behavior_node
|
||||
(subtree_node
|
||||
(path
|
||||
(path_segments
|
||||
(identifier)
|
||||
(identifier)))))
|
||||
(behavior_node (action_node (identifier))))))))
|
||||
|
||||
==================
|
||||
Complex Nested Behavior
|
||||
==================
|
||||
|
||||
behavior ComplexBehavior {
|
||||
? {
|
||||
> {
|
||||
check_threat
|
||||
flee_to_safety
|
||||
}
|
||||
> {
|
||||
check_resources
|
||||
gather_resources
|
||||
}
|
||||
* {
|
||||
idle
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(declaration
|
||||
(behavior
|
||||
name: (identifier)
|
||||
root: (behavior_node
|
||||
(selector_node
|
||||
(behavior_node
|
||||
(sequence_node
|
||||
(behavior_node (action_node (identifier)))
|
||||
(behavior_node (action_node (identifier)))))
|
||||
(behavior_node
|
||||
(sequence_node
|
||||
(behavior_node (action_node (identifier)))
|
||||
(behavior_node (action_node (identifier)))))
|
||||
(behavior_node
|
||||
(repeat_node
|
||||
(behavior_node (action_node (identifier))))))))))
|
||||
|
||||
577
tree-sitter-storybook/test/corpus/declarations.txt
Normal file
577
tree-sitter-storybook/test/corpus/declarations.txt
Normal file
@@ -0,0 +1,577 @@
|
||||
==================
|
||||
Use declaration - simple
|
||||
==================
|
||||
|
||||
use schema::core::Item;
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(declaration
|
||||
(use_declaration
|
||||
(path_segments
|
||||
(identifier)
|
||||
(identifier)
|
||||
(identifier)))))
|
||||
|
||||
==================
|
||||
Use declaration - grouped import
|
||||
==================
|
||||
|
||||
use schema::core::{Item1, Item2, Item3};
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(declaration
|
||||
(use_declaration
|
||||
(path_segments
|
||||
(identifier)
|
||||
(identifier))
|
||||
(identifier)
|
||||
(identifier)
|
||||
(identifier))))
|
||||
|
||||
==================
|
||||
Use declaration - wildcard
|
||||
==================
|
||||
|
||||
use schema::beings::*;
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(declaration
|
||||
(use_declaration
|
||||
(path_segments
|
||||
(identifier)
|
||||
(identifier)))))
|
||||
|
||||
==================
|
||||
Character - full featured
|
||||
==================
|
||||
|
||||
character Alice: Human from Curious {
|
||||
age: 7
|
||||
height: 4.2
|
||||
name: "Alice Liddell"
|
||||
curious: true
|
||||
age_range: 5..10
|
||||
|
||||
---backstory
|
||||
A curious young girl.
|
||||
---
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(declaration
|
||||
(character
|
||||
name: (identifier)
|
||||
species: (identifier)
|
||||
template: (template_clause (identifier))
|
||||
body: (block
|
||||
(field
|
||||
name: (dotted_path (identifier))
|
||||
value: (value (integer)))
|
||||
(field
|
||||
name: (dotted_path (identifier))
|
||||
value: (value (float)))
|
||||
(field
|
||||
name: (dotted_path (identifier))
|
||||
value: (value (string)))
|
||||
(field
|
||||
name: (dotted_path (identifier))
|
||||
value: (value (boolean)))
|
||||
(field
|
||||
name: (dotted_path (identifier))
|
||||
value: (value (range (integer) (integer))))
|
||||
(field
|
||||
(prose_block
|
||||
marker: (prose_marker)
|
||||
tag: (identifier)
|
||||
content: (prose_content)
|
||||
end: (prose_marker)))))))
|
||||
|
||||
==================
|
||||
Template with includes
|
||||
==================
|
||||
|
||||
template BaseCharacter strict {
|
||||
include Physical
|
||||
include Mental
|
||||
|
||||
age: 0
|
||||
name: ""
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(declaration
|
||||
(template
|
||||
name: (identifier)
|
||||
(include (identifier))
|
||||
(include (identifier))
|
||||
(field
|
||||
name: (dotted_path (identifier))
|
||||
value: (value (integer)))
|
||||
(field
|
||||
name: (dotted_path (identifier))
|
||||
value: (value (string))))))
|
||||
|
||||
==================
|
||||
Life arc with states and transitions
|
||||
==================
|
||||
|
||||
life_arc Journey {
|
||||
---description
|
||||
The character's journey.
|
||||
---
|
||||
|
||||
state young {
|
||||
on enter {
|
||||
age: 5
|
||||
}
|
||||
|
||||
on age >= 18 -> adult
|
||||
}
|
||||
|
||||
state adult {
|
||||
on retire is true -> retired
|
||||
}
|
||||
|
||||
state retired {
|
||||
}
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(declaration
|
||||
(life_arc
|
||||
name: (identifier)
|
||||
(field
|
||||
(prose_block
|
||||
marker: (prose_marker)
|
||||
tag: (identifier)
|
||||
content: (prose_content)
|
||||
end: (prose_marker)))
|
||||
(arc_state
|
||||
name: (identifier)
|
||||
(on_enter
|
||||
(block
|
||||
(field
|
||||
name: (dotted_path (identifier))
|
||||
value: (value (integer)))))
|
||||
(transition
|
||||
condition: (expression
|
||||
(comparison
|
||||
(expression (primary_expression (path (path_segments (identifier)))))
|
||||
(expression (primary_expression (integer)))))
|
||||
target: (identifier)))
|
||||
(arc_state
|
||||
name: (identifier)
|
||||
(transition
|
||||
condition: (expression
|
||||
(comparison
|
||||
(expression (primary_expression (path (path_segments (identifier)))))
|
||||
(expression (primary_expression (boolean)))))
|
||||
target: (identifier)))
|
||||
(arc_state
|
||||
name: (identifier)))))
|
||||
|
||||
==================
|
||||
Schedule with time blocks
|
||||
==================
|
||||
|
||||
schedule DailyRoutine {
|
||||
08:00 -> 09:00: breakfast {
|
||||
location: kitchen
|
||||
}
|
||||
|
||||
09:00 -> 12:00: work {
|
||||
duration: 3h
|
||||
}
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(declaration
|
||||
(schedule
|
||||
name: (identifier)
|
||||
(schedule_block
|
||||
start: (time)
|
||||
end: (time)
|
||||
activity: (identifier)
|
||||
(block
|
||||
(field
|
||||
name: (dotted_path (identifier))
|
||||
value: (value (path (path_segments (identifier)))))))
|
||||
(schedule_block
|
||||
start: (time)
|
||||
end: (time)
|
||||
activity: (identifier)
|
||||
(block
|
||||
(field
|
||||
name: (dotted_path (identifier))
|
||||
value: (value (duration))))))))
|
||||
|
||||
==================
|
||||
Behavior tree - all node types
|
||||
==================
|
||||
|
||||
behavior GuardBehavior {
|
||||
? {
|
||||
patrol
|
||||
> {
|
||||
detect_threat
|
||||
alert(priority: high, "Guard duty")
|
||||
}
|
||||
* {
|
||||
watch
|
||||
}
|
||||
@base::behaviors::Idle
|
||||
}
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(declaration
|
||||
(behavior
|
||||
name: (identifier)
|
||||
root: (behavior_node
|
||||
(selector_node
|
||||
(behavior_node (action_node (identifier)))
|
||||
(behavior_node
|
||||
(sequence_node
|
||||
(behavior_node (action_node (identifier)))
|
||||
(behavior_node
|
||||
(action_node
|
||||
(identifier)
|
||||
(action_param
|
||||
(dotted_path (identifier))
|
||||
(value (path (path_segments (identifier)))))
|
||||
(action_param
|
||||
(value (string)))))))
|
||||
(behavior_node
|
||||
(repeat_node
|
||||
(behavior_node (action_node (identifier)))))
|
||||
(behavior_node
|
||||
(subtree_node
|
||||
(path
|
||||
(path_segments
|
||||
(identifier)
|
||||
(identifier)
|
||||
(identifier))))))))))
|
||||
|
||||
==================
|
||||
Institution
|
||||
==================
|
||||
|
||||
institution Wonderland {
|
||||
type: "fantasy_realm"
|
||||
ruler: "Queen of Hearts"
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(declaration
|
||||
(institution
|
||||
name: (identifier)
|
||||
(block
|
||||
(field
|
||||
name: (dotted_path (identifier))
|
||||
value: (value (string)))
|
||||
(field
|
||||
name: (dotted_path (identifier))
|
||||
value: (value (string)))))))
|
||||
|
||||
==================
|
||||
Relationship with participants
|
||||
==================
|
||||
|
||||
relationship Friendship {
|
||||
Alice {
|
||||
bond_strength: 5
|
||||
}
|
||||
|
||||
WhiteRabbit as friend {
|
||||
trust: 0.8
|
||||
}
|
||||
|
||||
Caterpillar
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(declaration
|
||||
(relationship
|
||||
name: (identifier)
|
||||
(participant
|
||||
(path (path_segments (identifier)))
|
||||
(block
|
||||
(field
|
||||
name: (dotted_path (identifier))
|
||||
value: (value (integer)))))
|
||||
(participant
|
||||
(path (path_segments (identifier)))
|
||||
(identifier)
|
||||
(block
|
||||
(field
|
||||
name: (dotted_path (identifier))
|
||||
value: (value (float)))))
|
||||
(participant
|
||||
(path (path_segments (identifier)))))))
|
||||
|
||||
==================
|
||||
Location
|
||||
==================
|
||||
|
||||
location TeaParty {
|
||||
description: "A mad tea party"
|
||||
capacity: 10
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(declaration
|
||||
(location
|
||||
name: (identifier)
|
||||
(block
|
||||
(field
|
||||
name: (dotted_path (identifier))
|
||||
value: (value (string)))
|
||||
(field
|
||||
name: (dotted_path (identifier))
|
||||
value: (value (integer)))))))
|
||||
|
||||
==================
|
||||
Species with includes
|
||||
==================
|
||||
|
||||
species Cat {
|
||||
include Mammal
|
||||
|
||||
purrs: true
|
||||
lives: 9
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(declaration
|
||||
(species
|
||||
name: (identifier)
|
||||
(include (identifier))
|
||||
(field
|
||||
name: (dotted_path (identifier))
|
||||
value: (value (boolean)))
|
||||
(field
|
||||
name: (dotted_path (identifier))
|
||||
value: (value (integer))))))
|
||||
|
||||
==================
|
||||
Enum declaration
|
||||
==================
|
||||
|
||||
enum EmotionalState {
|
||||
happy, sad, angry, confused, curious
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(declaration
|
||||
(enum_declaration
|
||||
name: (identifier)
|
||||
(identifier)
|
||||
(identifier)
|
||||
(identifier)
|
||||
(identifier)
|
||||
(identifier))))
|
||||
|
||||
==================
|
||||
Override syntax
|
||||
==================
|
||||
|
||||
character SpecialAlice {
|
||||
base: @Alice {
|
||||
remove backstory
|
||||
append age_category: "child"
|
||||
curious: false
|
||||
}
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(declaration
|
||||
(character
|
||||
name: (identifier)
|
||||
body: (block
|
||||
(field
|
||||
name: (dotted_path (identifier))
|
||||
value: (value
|
||||
(override
|
||||
(path (path_segments (identifier)))
|
||||
(override_op (identifier))
|
||||
(override_op
|
||||
(field
|
||||
name: (dotted_path (identifier))
|
||||
value: (value (string))))
|
||||
(override_op
|
||||
(field
|
||||
name: (dotted_path (identifier))
|
||||
value: (value (boolean)))))))))))
|
||||
|
||||
==================
|
||||
Complex expressions in conditions
|
||||
==================
|
||||
|
||||
life_arc ComplexLogic {
|
||||
state test {
|
||||
on self.age > 18 and other.trust >= 0.5 -> trusted
|
||||
on not self.valid or self.expired is true -> invalid
|
||||
}
|
||||
|
||||
state trusted {
|
||||
}
|
||||
|
||||
state invalid {
|
||||
}
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(declaration
|
||||
(life_arc
|
||||
name: (identifier)
|
||||
(arc_state
|
||||
name: (identifier)
|
||||
(transition
|
||||
condition: (expression
|
||||
(and_expression
|
||||
(expression
|
||||
(comparison
|
||||
(expression
|
||||
(field_access
|
||||
(expression (primary_expression))
|
||||
(identifier)))
|
||||
(expression (primary_expression (integer)))))
|
||||
(expression
|
||||
(comparison
|
||||
(expression
|
||||
(field_access
|
||||
(expression (primary_expression))
|
||||
(identifier)))
|
||||
(expression (primary_expression (float)))))))
|
||||
target: (identifier))
|
||||
(transition
|
||||
condition: (expression
|
||||
(or_expression
|
||||
(expression
|
||||
(not_expression
|
||||
(expression
|
||||
(field_access
|
||||
(expression (primary_expression))
|
||||
(identifier)))))
|
||||
(expression
|
||||
(comparison
|
||||
(expression
|
||||
(field_access
|
||||
(expression (primary_expression))
|
||||
(identifier)))
|
||||
(expression (primary_expression (boolean)))))))
|
||||
target: (identifier)))
|
||||
(arc_state
|
||||
name: (identifier))
|
||||
(arc_state
|
||||
name: (identifier)))))
|
||||
|
||||
==================
|
||||
List and object values
|
||||
==================
|
||||
|
||||
character DataRich {
|
||||
tags: ["smart", "brave", "curious"]
|
||||
stats: {
|
||||
strength: 10
|
||||
intelligence: 15
|
||||
}
|
||||
matrix: [[1, 2], [3, 4]]
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(declaration
|
||||
(character
|
||||
name: (identifier)
|
||||
body: (block
|
||||
(field
|
||||
name: (dotted_path (identifier))
|
||||
value: (value
|
||||
(list
|
||||
(value (string))
|
||||
(value (string))
|
||||
(value (string)))))
|
||||
(field
|
||||
name: (dotted_path (identifier))
|
||||
value: (value
|
||||
(object
|
||||
(block
|
||||
(field
|
||||
name: (dotted_path (identifier))
|
||||
value: (value (integer)))
|
||||
(field
|
||||
name: (dotted_path (identifier))
|
||||
value: (value (integer)))))))
|
||||
(field
|
||||
name: (dotted_path (identifier))
|
||||
value: (value
|
||||
(list
|
||||
(value
|
||||
(list
|
||||
(value (integer))
|
||||
(value (integer))))
|
||||
(value
|
||||
(list
|
||||
(value (integer))
|
||||
(value (integer)))))))))))
|
||||
|
||||
==================
|
||||
Dotted field paths
|
||||
==================
|
||||
|
||||
character Nested {
|
||||
appearance.hair.color: "blonde"
|
||||
stats.mental.intelligence: 15
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(declaration
|
||||
(character
|
||||
name: (identifier)
|
||||
body: (block
|
||||
(field
|
||||
name: (dotted_path
|
||||
(identifier)
|
||||
(identifier)
|
||||
(identifier))
|
||||
value: (value (string)))
|
||||
(field
|
||||
name: (dotted_path
|
||||
(identifier)
|
||||
(identifier)
|
||||
(identifier))
|
||||
value: (value (integer)))))))
|
||||
24
tree-sitter-storybook/tree-sitter.json
Normal file
24
tree-sitter-storybook/tree-sitter.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"grammars": [
|
||||
{
|
||||
"name": "storybook",
|
||||
"path": ".",
|
||||
"scope": "source.storybook",
|
||||
"file-types": ["sb"],
|
||||
"highlights": ["queries/highlights.scm"],
|
||||
"injections": ["queries/injections.scm"]
|
||||
}
|
||||
],
|
||||
"bindings": {
|
||||
"c": {},
|
||||
"node": {},
|
||||
"python": {},
|
||||
"rust": {},
|
||||
"go": {},
|
||||
"swift": {}
|
||||
},
|
||||
"metadata": {
|
||||
"version": "0.1.0",
|
||||
"license": "MIT"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user