Start on top-level constructs, const declarations

pull/261/head
Max Brunsfeld 2016-08-16 21:02:37 +07:00
commit d29ad53a43
18 changed files with 3280 additions and 0 deletions

1
.gitattributes vendored

@ -0,0 +1 @@
/src/** linguist-vendored

3
.gitignore vendored

@ -0,0 +1,3 @@
node_modules
build
*.log

@ -0,0 +1,3 @@
grammar_test
build
script

@ -0,0 +1,14 @@
language: node_js
sudo: false
node_js:
- "node"
compiler: clang-3.6
env:
- CXX=clang-3.6
addons:
apt:
sources:
- llvm-toolchain-precise-3.6
- ubuntu-toolchain-r-test
packages:
- clang-3.6

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014 Max Brunsfeld
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -0,0 +1,8 @@
tree-sitter-go
===========================
[![Build Status](https://travis-ci.org/tree-sitter/tree-sitter-go.svg?branch=master)](https://travis-ci.org/tree-sitter/tree-sitter-go)
Golang grammar for [tree-sitter][].
[tree-sitter]: https://github.com/tree-sitter/tree-sitter

@ -0,0 +1,18 @@
{
"targets": [
{
"target_name": "ts_language_go_binding",
"include_dirs": [
"<!(node -e \"require('nan')\")",
"src"
],
"sources": [
"src/parser.c",
"src/binding.cc"
],
"cflags_c": [
"-std=c99",
]
}
]
}

@ -0,0 +1,169 @@
const
unicodeLetter = /[a-zA-Z]/,
unicodeDigit = /[0-9]/,
unicodeChar = /./,
unicodeValue = unicodeChar,
hexDigit = /[0-7]/,
octalDigit = /[0-7]/,
decimalDigit = /[0-9]/,
hexByteValue = seq('\\', 'x', hexDigit, hexDigit),
octalByteValue = seq('\\', octalDigit, octalDigit, octalDigit)
byteValue = choice(octalByteValue, hexByteValue),
hexLiteral = token(seq('0', choice('x', 'X'), repeat1(hexDigit))),
octalLiteral = token(seq('0', repeat(octalDigit))),
decimalLiteral = token(seq(/[1-9]/, repeat(decimalDigit))),
newline = '\n',
letter = choice(unicodeLetter, '_'),
terminator = token(choice(newline, ';'))
const NOT_IMPLEMENTED = choice()
module.exports = grammar({
name: 'go',
extras: $ => [
$.comment,
/\s/
],
rules: {
source_file: $ => seq(
$.package_clause,
repeat($.import_declaration),
repeat($._top_level_declaration)
),
package_clause: $ => seq(
'package',
$.identifier
),
import_declaration: $ => seq(
'import',
choice(
$.import_spec,
seq(
'(',
repeat(seq(
$.import_spec,
terminator
)),
')'
)
)
),
import_spec: $ => seq(
optional(choice($.identifier, '.')),
$._string_literal
),
_top_level_declaration: $ => choice(
$._declaration,
$.function_declaration,
$.method_declaration
),
_declaration: $ => choice(
$.const_declaration,
$.type_declaration,
$.var_declaration
),
const_declaration: $ => seq(
'const',
choice(
$.const_spec,
seq(
'(',
repeat(seq($.const_spec, terminator)),
')'
)
)
),
const_spec: $ => seq(
$.identifier_list,
optional($._type),
'=',
$.expression_list
),
function_declaration: $ => NOT_IMPLEMENTED,
method_declaration: $ => NOT_IMPLEMENTED,
type_declaration: $ => NOT_IMPLEMENTED,
var_declaration: $ => NOT_IMPLEMENTED,
identifier_list: $ => seq(
$.identifier,
repeat(seq(',', $.identifier))
),
expression_list: $ => seq(
$._expression,
repeat(seq(',', $._expression))
),
_type: $ => choice(
$.identifier
),
_expression: $ => choice(
$.unary_expression,
$.binary_expression,
$._primary_expression
),
unary_expression: $ => NOT_IMPLEMENTED,
binary_expression: $ => NOT_IMPLEMENTED,
_primary_expression: $ => choice(
// Basic literal
$._string_literal,
$.int_literal,
$.float_literal,
// Operand name
$.identifier
),
identifier: $ => token(seq(
letter,
repeat(choice(letter, unicodeDigit))
)),
_string_literal: $ => choice(
$.raw_string_literal,
$.interpreted_string_literal
),
raw_string_literal: $ => token(seq(
'`',
repeat(choice(unicodeChar, newline)),
'`'
)),
interpreted_string_literal: $ => token(seq(
'"',
repeat(choice(unicodeValue, byteValue)),
'"'
)),
int_literal: $ => choice(decimalLiteral, octalLiteral, hexLiteral),
float_literal: $ => NOT_IMPLEMENTED,
comment: $ => token(seq(
'//',
/.*/
))
}
})

@ -0,0 +1,68 @@
============================================
Single const declarations without types
============================================
package main
const zero = 0
const one, two = 1, 2
const three, four, five = 3, 4, 5
----
(source_file
(package_clause (identifier))
(const_declaration (const_spec
(identifier_list (identifier))
(expression_list (int_literal))))
(const_declaration (const_spec
(identifier_list (identifier) (identifier))
(expression_list (int_literal) (int_literal))))
(const_declaration (const_spec
(identifier_list (identifier) (identifier) (identifier))
(expression_list (int_literal) (int_literal) (int_literal)))))
============================================
Single const declarations with types
============================================
package main
const zero int = 0
const one, two uint64 = 1, 2
----
(source_file
(package_clause (identifier))
(const_declaration (const_spec
(identifier_list (identifier))
(identifier)
(expression_list (int_literal))))
(const_declaration (const_spec
(identifier_list (identifier) (identifier))
(identifier)
(expression_list (int_literal) (int_literal)))))
============================================
Grouped const declarations
============================================
package main
const (
zero = 0
one = 1
)
----
(source_file
(package_clause (identifier))
(const_declaration
(const_spec
(identifier_list (identifier))
(expression_list (int_literal)))
(const_spec
(identifier_list (identifier))
(expression_list (int_literal)))))

@ -0,0 +1,49 @@
============================================
Package clauses
============================================
package main
----
(source_file
(package_clause (identifier)))
============================================
Single import declarations
============================================
package a
import "net/http"
import . "some/dsl"
import alias "some/package"
----
(source_file
(package_clause (identifier))
(import_declaration (import_spec (interpreted_string_literal)))
(import_declaration (import_spec (interpreted_string_literal)))
(import_declaration (import_spec (identifier) (interpreted_string_literal))))
============================================
Grouped import declarations
============================================
package a
import (
"net/http"
. "some/dsl"
alias "some/package"
)
----
(source_file
(package_clause (identifier))
(import_declaration
(import_spec (interpreted_string_literal))
(import_spec (interpreted_string_literal))
(import_spec (identifier) (interpreted_string_literal))))

@ -0,0 +1 @@
module.exports = require("./build/Release/ts_language_go_binding");

@ -0,0 +1,23 @@
{
"name": "tree-sitter-go",
"version": "0.0.1",
"description": "Go grammar for tree-sitter",
"main": "index.js",
"keywords": [
"parser",
"lexer"
],
"author": "Max Brunsfeld",
"license": "MIT",
"dependencies": {
"bindings": "1.2.x",
"nan": "^2.0.0"
},
"devDependencies": {
"tree-sitter-compiler": ">= 0.0.45"
},
"scripts": {
"build": "tree-sitter compile && node-gyp build",
"test": "tree-sitter test"
}
}

@ -0,0 +1,68 @@
#!/usr/bin/env node
'use strict';
const fs = require('fs')
const assert = require('assert');
const babylon = require('babylon');
const esprima = require('esprima');
const treesitter = require('tree-sitter-compiler/node_modules/tree-sitter');
const jsLanguage = require('..');
const ITERATION_COUNT = 50;
if (process.argv.length < 3) {
console.log("Usage: script/benchmark.js <javascript-file>")
process.exit(1);
}
const fileName = process.argv[2];
const code = fs.readFileSync(fileName, 'utf8');
// profile("Babylon", () => {
// let rootNode = babylon.parse(code);
// assert(rootNode.type === 'File');
// });
//
//
// profile("Esprima", () => {
// let rootNode = esprima.parse(code);
// assert(rootNode.type === 'Program');
// });
let document = null
profile("Tree-sitter", () => {
document = new treesitter.Document()
.setInputString(code)
.setLanguage(jsLanguage)
.parse();
assert(document.rootNode.type === 'program');
});
assert(!/ERROR/.test(document.rootNode.toString()))
function profile (name, action) {
console.log(name + ":")
let durations = [];
for (let i = 0; i < ITERATION_COUNT; i++) {
let startTime = Date.now();
try {
action();
} catch (e) {
console.log("FAILED", e.message);
return
}
let endTime = Date.now();
durations.push(endTime - startTime);
}
durations.sort((a, b) => a - b);
const average = durations.reduce((sum, term) => sum + term) / ITERATION_COUNT;
const min = durations[0];
const max = durations[durations.length - 1];
console.log("Average:", average, "Min:", min, "Max:", max);
}

28
src/binding.cc vendored

@ -0,0 +1,28 @@
#include "tree_sitter/runtime.h"
#include <node.h>
#include "nan.h"
using namespace v8;
extern "C" TSLanguage * ts_language_go();
namespace tree_sitter_go {
NAN_METHOD(New) {}
void Init(Handle<Object> exports, Handle<Object> module) {
Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
tpl->SetClassName(Nan::New("Language").ToLocalChecked());
tpl->InstanceTemplate()->SetInternalFieldCount(1);
Local<Function> constructor = tpl->GetFunction();
Local<Object> instance = constructor->NewInstance(0, NULL);
Nan::SetInternalFieldPointer(instance, 0, ts_language_go());
instance->Set(Nan::New("name").ToLocalChecked(), Nan::New("go").ToLocalChecked());
module->Set(Nan::New("exports").ToLocalChecked(), instance);
}
NODE_MODULE(ts_language_go_binding, Init)
} // namespace tree_sitter_go

645
src/grammar.json vendored

@ -0,0 +1,645 @@
{
"name": "go",
"rules": {
"source_file": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "package_clause"
},
{
"type": "REPEAT",
"content": {
"type": "SYMBOL",
"name": "import_declaration"
}
},
{
"type": "REPEAT",
"content": {
"type": "SYMBOL",
"name": "_top_level_declaration"
}
}
]
},
"package_clause": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "package"
},
{
"type": "SYMBOL",
"name": "identifier"
}
]
},
"import_declaration": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "import"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "import_spec"
},
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "("
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "import_spec"
},
{
"type": "TOKEN",
"content": {
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "\n"
},
{
"type": "STRING",
"value": ";"
}
]
}
}
]
}
},
{
"type": "STRING",
"value": ")"
}
]
}
]
}
]
},
"import_spec": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "identifier"
},
{
"type": "STRING",
"value": "."
}
]
},
{
"type": "BLANK"
}
]
},
{
"type": "SYMBOL",
"name": "_string_literal"
}
]
},
"_top_level_declaration": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_declaration"
},
{
"type": "SYMBOL",
"name": "function_declaration"
},
{
"type": "SYMBOL",
"name": "method_declaration"
}
]
},
"_declaration": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "const_declaration"
},
{
"type": "SYMBOL",
"name": "type_declaration"
},
{
"type": "SYMBOL",
"name": "var_declaration"
}
]
},
"const_declaration": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "const"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "const_spec"
},
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "("
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "const_spec"
},
{
"type": "TOKEN",
"content": {
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "\n"
},
{
"type": "STRING",
"value": ";"
}
]
}
}
]
}
},
{
"type": "STRING",
"value": ")"
}
]
}
]
}
]
},
"const_spec": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "identifier_list"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_type"
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": "="
},
{
"type": "SYMBOL",
"name": "expression_list"
}
]
},
"function_declaration": {
"type": "CHOICE",
"members": []
},
"method_declaration": {
"type": "CHOICE",
"members": []
},
"type_declaration": {
"type": "CHOICE",
"members": []
},
"var_declaration": {
"type": "CHOICE",
"members": []
},
"identifier_list": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "identifier"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "SYMBOL",
"name": "identifier"
}
]
}
}
]
},
"expression_list": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_expression"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "SYMBOL",
"name": "_expression"
}
]
}
}
]
},
"_type": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "identifier"
}
]
},
"_expression": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "unary_expression"
},
{
"type": "SYMBOL",
"name": "binary_expression"
},
{
"type": "SYMBOL",
"name": "_primary_expression"
}
]
},
"unary_expression": {
"type": "CHOICE",
"members": []
},
"binary_expression": {
"type": "CHOICE",
"members": []
},
"_primary_expression": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_string_literal"
},
{
"type": "SYMBOL",
"name": "int_literal"
},
{
"type": "SYMBOL",
"name": "float_literal"
},
{
"type": "SYMBOL",
"name": "identifier"
}
]
},
"identifier": {
"type": "TOKEN",
"content": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "PATTERN",
"value": "[a-zA-Z]"
},
{
"type": "STRING",
"value": "_"
}
]
},
{
"type": "REPEAT",
"content": {
"type": "CHOICE",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "PATTERN",
"value": "[a-zA-Z]"
},
{
"type": "STRING",
"value": "_"
}
]
},
{
"type": "PATTERN",
"value": "[0-9]"
}
]
}
}
]
}
},
"_string_literal": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "raw_string_literal"
},
{
"type": "SYMBOL",
"name": "interpreted_string_literal"
}
]
},
"raw_string_literal": {
"type": "TOKEN",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "`"
},
{
"type": "REPEAT",
"content": {
"type": "CHOICE",
"members": [
{
"type": "PATTERN",
"value": "."
},
{
"type": "STRING",
"value": "\n"
}
]
}
},
{
"type": "STRING",
"value": "`"
}
]
}
},
"interpreted_string_literal": {
"type": "TOKEN",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "\""
},
{
"type": "REPEAT",
"content": {
"type": "CHOICE",
"members": [
{
"type": "PATTERN",
"value": "."
},
{
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "\\"
},
{
"type": "PATTERN",
"value": "[0-7]"
},
{
"type": "PATTERN",
"value": "[0-7]"
},
{
"type": "PATTERN",
"value": "[0-7]"
}
]
},
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "\\"
},
{
"type": "STRING",
"value": "x"
},
{
"type": "PATTERN",
"value": "[0-7]"
},
{
"type": "PATTERN",
"value": "[0-7]"
}
]
}
]
}
]
}
},
{
"type": "STRING",
"value": "\""
}
]
}
},
"int_literal": {
"type": "CHOICE",
"members": [
{
"type": "TOKEN",
"content": {
"type": "SEQ",
"members": [
{
"type": "PATTERN",
"value": "[1-9]"
},
{
"type": "REPEAT",
"content": {
"type": "PATTERN",
"value": "[0-9]"
}
}
]
}
},
{
"type": "TOKEN",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "0"
},
{
"type": "REPEAT",
"content": {
"type": "PATTERN",
"value": "[0-7]"
}
}
]
}
},
{
"type": "TOKEN",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "0"
},
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "x"
},
{
"type": "STRING",
"value": "X"
}
]
},
{
"type": "REPEAT1",
"content": {
"type": "PATTERN",
"value": "[0-7]"
}
}
]
}
}
]
},
"float_literal": {
"type": "CHOICE",
"members": []
},
"comment": {
"type": "TOKEN",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "//"
},
{
"type": "PATTERN",
"value": ".*"
}
]
}
}
},
"extras": [
{
"type": "SYMBOL",
"name": "comment"
},
{
"type": "PATTERN",
"value": "\\s"
}
],
"conflicts": []
}

1847
src/parser.c vendored

File diff suppressed because it is too large Load Diff

@ -0,0 +1,203 @@
#ifndef TREE_SITTER_PARSER_H_
#define TREE_SITTER_PARSER_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stdbool.h>
#include "tree_sitter/runtime.h"
#define ts_lex_state_error 0
#define TS_DEBUG_BUFFER_SIZE 512
typedef struct TSTree TSTree;
typedef unsigned short TSStateId;
typedef struct {
size_t bytes;
size_t chars;
size_t rows;
size_t columns;
} TSLength;
typedef struct {
bool visible : 1;
bool named : 1;
bool extra : 1;
bool structural : 1;
} TSSymbolMetadata;
typedef struct TSLexer {
void (*start_fn)(struct TSLexer *, TSStateId);
void (*start_token_fn)(struct TSLexer *);
bool (*advance_fn)(struct TSLexer *, TSStateId);
TSTree *(*accept_fn)(struct TSLexer *, TSSymbol, TSSymbolMetadata,
const char *, bool fragile);
const char *chunk;
size_t chunk_start;
size_t chunk_size;
TSLength current_position;
TSLength token_end_position;
TSLength token_start_position;
size_t lookahead_size;
int32_t lookahead;
TSStateId starting_state;
TSInput input;
TSDebugger debugger;
char debug_buffer[TS_DEBUG_BUFFER_SIZE];
} TSLexer;
typedef enum {
TSParseActionTypeError,
TSParseActionTypeShift,
TSParseActionTypeReduce,
TSParseActionTypeAccept,
} TSParseActionType;
typedef struct {
union {
TSStateId to_state;
struct {
TSSymbol symbol;
unsigned short child_count;
};
} data;
TSParseActionType type : 3;
bool extra : 1;
bool fragile : 1;
bool can_hide_split : 1;
} TSParseAction;
typedef union {
TSParseAction action;
unsigned int count;
} TSParseActionEntry;
struct TSLanguage {
size_t symbol_count;
const char **symbol_names;
const TSSymbolMetadata *symbol_metadata;
const unsigned short *parse_table;
const TSParseActionEntry *parse_actions;
const TSStateId *lex_states;
TSTree *(*lex_fn)(TSLexer *, TSStateId, bool);
};
/*
* Lexer Macros
*/
#define START_LEXER() \
lexer->start_fn(lexer, state); \
int32_t lookahead; \
next_state: \
lookahead = lexer->lookahead;
#define START_TOKEN() lexer->start_token_fn(lexer);
#define GO_TO_STATE(state_value) \
{ \
state = state_value; \
goto next_state; \
}
#define ADVANCE(state_value) \
{ \
lexer->advance_fn(lexer, state_value); \
GO_TO_STATE(state_value); \
}
#define ACCEPT_FRAGILE_TOKEN(symbol) \
return lexer->accept_fn(lexer, symbol, ts_symbol_metadata[symbol], \
ts_symbol_names[symbol], true);
#define ACCEPT_TOKEN(symbol) \
return lexer->accept_fn(lexer, symbol, ts_symbol_metadata[symbol], \
ts_symbol_names[symbol], false);
#define LEX_ERROR() \
if (error_mode) { \
if (state == ts_lex_state_error) \
lexer->advance_fn(lexer, state); \
GO_TO_STATE(ts_lex_state_error) \
} else { \
ACCEPT_TOKEN(ts_builtin_sym_error) \
}
/*
* Parse Table Macros
*/
enum {
FRAGILE = 1,
CAN_HIDE_SPLIT = 2,
};
#define ERROR() \
{ \
{ .type = TSParseActionTypeError } \
}
#define SHIFT(to_state_value, flags) \
{ \
{ \
.type = TSParseActionTypeShift, \
.can_hide_split = (flags & CAN_HIDE_SPLIT) != 0, \
.data = {.to_state = to_state_value } \
} \
}
#define SHIFT_EXTRA() \
{ \
{ .type = TSParseActionTypeShift, .extra = true } \
}
#define REDUCE_EXTRA(symbol_val) \
{ \
{ \
.type = TSParseActionTypeReduce, .extra = true, \
.data = {.symbol = symbol_val, .child_count = 1 } \
} \
}
#define REDUCE(symbol_val, child_count_val, flags) \
{ \
{ \
.type = TSParseActionTypeReduce, .fragile = (flags & FRAGILE) != 0, \
.can_hide_split = (flags & CAN_HIDE_SPLIT) != 0, \
.data = {.symbol = symbol_val, .child_count = child_count_val } \
} \
}
#define ACCEPT_INPUT() \
{ \
{ .type = TSParseActionTypeAccept } \
}
#define EXPORT_LANGUAGE(language_name) \
static TSLanguage language = { \
.symbol_count = SYMBOL_COUNT, \
.symbol_metadata = ts_symbol_metadata, \
.parse_table = (const unsigned short *)ts_parse_table, \
.parse_actions = ts_parse_actions, \
.lex_states = ts_lex_states, \
.symbol_names = ts_symbol_names, \
.lex_fn = ts_lex, \
}; \
\
const TSLanguage *language_name() { \
return &language; \
}
#ifdef __cplusplus
}
#endif
#endif // TREE_SITTER_PARSER_H_

@ -0,0 +1,111 @@
#ifndef TREE_SITTER_RUNTIME_H_
#define TREE_SITTER_RUNTIME_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdlib.h>
#include <stdbool.h>
typedef unsigned short TSSymbol;
typedef struct TSLanguage TSLanguage;
typedef struct TSDocument TSDocument;
typedef enum {
TSInputEncodingUTF8,
TSInputEncodingUTF16,
} TSInputEncoding;
typedef struct {
void *payload;
const char *(*read_fn)(void *payload, size_t *bytes_read);
int (*seek_fn)(void *payload, size_t character, size_t byte);
TSInputEncoding encoding;
} TSInput;
typedef enum {
TSDebugTypeParse,
TSDebugTypeLex,
} TSDebugType;
typedef struct {
void *payload;
void (*debug_fn)(void *payload, TSDebugType, const char *);
} TSDebugger;
typedef struct {
size_t position;
size_t chars_inserted;
size_t chars_removed;
} TSInputEdit;
typedef struct {
size_t row;
size_t column;
} TSPoint;
typedef struct {
const void *data;
size_t offset[3];
} TSNode;
typedef struct {
TSSymbol value;
bool done;
void *data;
} TSSymbolIterator;
size_t ts_node_start_char(TSNode);
size_t ts_node_start_byte(TSNode);
TSPoint ts_node_start_point(TSNode);
size_t ts_node_end_char(TSNode);
size_t ts_node_end_byte(TSNode);
TSPoint ts_node_end_point(TSNode);
TSSymbol ts_node_symbol(TSNode);
TSSymbolIterator ts_node_symbols(TSNode);
void ts_symbol_iterator_next(TSSymbolIterator *);
const char *ts_node_name(TSNode, const TSDocument *);
char *ts_node_string(TSNode, const TSDocument *);
bool ts_node_eq(TSNode, TSNode);
bool ts_node_is_named(TSNode);
bool ts_node_has_changes(TSNode);
TSNode ts_node_parent(TSNode);
TSNode ts_node_child(TSNode, size_t);
TSNode ts_node_named_child(TSNode, size_t);
size_t ts_node_child_count(TSNode);
size_t ts_node_named_child_count(TSNode);
TSNode ts_node_next_sibling(TSNode);
TSNode ts_node_next_named_sibling(TSNode);
TSNode ts_node_prev_sibling(TSNode);
TSNode ts_node_prev_named_sibling(TSNode);
TSNode ts_node_descendant_for_range(TSNode, size_t, size_t);
TSNode ts_node_named_descendant_for_range(TSNode, size_t, size_t);
TSDocument *ts_document_make();
void ts_document_free(TSDocument *);
const TSLanguage *ts_document_language(TSDocument *);
void ts_document_set_language(TSDocument *, const TSLanguage *);
TSInput ts_document_input(TSDocument *);
void ts_document_set_input(TSDocument *, TSInput);
void ts_document_set_input_string(TSDocument *, const char *);
TSDebugger ts_document_debugger(const TSDocument *);
void ts_document_set_debugger(TSDocument *, TSDebugger);
void ts_document_edit(TSDocument *, TSInputEdit);
int ts_document_parse(TSDocument *);
void ts_document_invalidate(TSDocument *);
TSNode ts_document_root_node(const TSDocument *);
size_t ts_document_parse_count(const TSDocument *);
size_t ts_language_symbol_count(const TSLanguage *);
const char *ts_language_symbol_name(const TSLanguage *, TSSymbol);
#define ts_builtin_sym_error 0
#define ts_builtin_sym_end 1
#define ts_builtin_sym_start 2
#ifdef __cplusplus
}
#endif
#endif // TREE_SITTER_RUNTIME_H_