mirror of https://github.com/Wilfred/difftastic/
Use tree-sitter-c and tree-sitter-cpp from crates.io
parent
6ea71e6983
commit
db379cf94d
@ -1 +0,0 @@
|
||||
../tree-sitter-c/queries/highlights.scm
|
||||
@ -1 +0,0 @@
|
||||
../tree-sitter-cpp/queries/highlights.scm
|
||||
@ -1,39 +0,0 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.{json,toml,yml,gyp}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.js]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.rs]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.{c,cc,h}]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.{py,pyi}]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.swift]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.go]
|
||||
indent_style = tab
|
||||
indent_size = 8
|
||||
|
||||
[Makefile]
|
||||
indent_style = tab
|
||||
indent_size = 8
|
||||
@ -1,14 +0,0 @@
|
||||
* text eol=lf
|
||||
test/corpus/crlf.txt text eol=crlf
|
||||
|
||||
examples/* linguist-vendored
|
||||
|
||||
src/*.json linguist-generated
|
||||
src/parser.c linguist-generated
|
||||
src/tree_sitter/* linguist-generated
|
||||
|
||||
bindings/** linguist-generated
|
||||
binding.gyp linguist-generated
|
||||
setup.py linguist-generated
|
||||
Makefile linguist-generated
|
||||
Package.swift linguist-generated
|
||||
@ -1,59 +0,0 @@
|
||||
name: Bug Report
|
||||
description: File a bug or issue
|
||||
title: "bug: "
|
||||
labels: [bug]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
**Before** reporting an issue, make sure to search [existing issues](https://github.com/tree-sitter/tree-sitter-c/issues). Usage questions such as ***"How do I...?"*** either belong in [Discussions](https://github.com/tree-sitter/tree-sitter/discussions) upstream or in our [Discord server](https://discord.gg/w7nTvsVJhm) and will be closed.
|
||||
If your issue is related to a bug in your editor-experience because your editor *leverages* tree-sitter and this parser, then it is likely your issue does *NOT* belong here and belongs in the relevant editor's repository.
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Did you check existing issues?
|
||||
description: Make sure you've checked all of the below before submitting an issue
|
||||
options:
|
||||
- label: I have read all the [tree-sitter docs](https://tree-sitter.github.io/tree-sitter/using-parsers) if it relates to using the parser
|
||||
required: false
|
||||
- label: I have searched the existing issues of tree-sitter-c
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: "Tree-Sitter CLI Version, if relevant (output of `tree-sitter --version`)"
|
||||
placeholder: "tree-sitter 0.20.8 (6bbb50bef8249e6460e7d69e42cc8146622fa4fd)"
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe the bug
|
||||
description: A clear and concise description of what the bug is. Please include any related errors you see such as parsing errors or tree-sitter cli errors.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Steps To Reproduce/Bad Parse Tree
|
||||
description: Steps to reproduce the behavior. If you have a bad parse tree, please include it here. You can get this by running `tree-sitter parse <path-to-file>` and copying the output.
|
||||
placeholder: |
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Expected Behavior/Parse Tree
|
||||
description: A concise description of what you expected to happen, or in the case of a bad parse tree, the expected parse tree.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Repro
|
||||
description: Minimal code to reproduce this issue. Ideally this should be reproducible with the C library or the tree-sitter cli, do not suggest an editor or external tool.
|
||||
value: |
|
||||
// Example code that causes the issue
|
||||
void foo() {
|
||||
// Code that fails to parse, or causes an error
|
||||
}
|
||||
render: C
|
||||
validations:
|
||||
required: false
|
||||
@ -1 +0,0 @@
|
||||
blank_issues_enabled: false
|
||||
@ -1,36 +0,0 @@
|
||||
name: Feature Request
|
||||
description: Suggest a new feature
|
||||
title: "feature: "
|
||||
labels: [enhancement]
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Did you check the tree-sitter docs?
|
||||
description: Make sure you read all the docs before submitting a feature request
|
||||
options:
|
||||
- label: I have read all the [tree-sitter docs](https://tree-sitter.github.io/tree-sitter/using-parsers) if it relates to using the parser
|
||||
required: false
|
||||
- type: textarea
|
||||
validations:
|
||||
required: true
|
||||
attributes:
|
||||
label: Is your feature request related to a problem? Please describe.
|
||||
description: A clear and concise description of what the problem is. Ex. I think the grammar models this rule incorrectly and can be improved, or the C spec has officially added a new feature that should be added to the grammar.
|
||||
- type: textarea
|
||||
validations:
|
||||
required: true
|
||||
attributes:
|
||||
label: Describe the solution you'd like
|
||||
description: A clear and concise description of what you want to happen.
|
||||
- type: textarea
|
||||
validations:
|
||||
required: true
|
||||
attributes:
|
||||
label: Describe alternatives you've considered
|
||||
description: A clear and concise description of any alternative solutions or features you've considered.
|
||||
- type: textarea
|
||||
validations:
|
||||
required: false
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Add any other context or screenshots about the feature request here. If your feature request is related to a new C feature, please include a link to the relevant **official** C documentation.
|
||||
@ -1,8 +0,0 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
commit-message:
|
||||
prefix: "ci"
|
||||
@ -1,44 +0,0 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
paths:
|
||||
- grammar.js
|
||||
- src/**
|
||||
- test/**
|
||||
- bindings/**
|
||||
- binding.gyp
|
||||
pull_request:
|
||||
paths:
|
||||
- grammar.js
|
||||
- src/**
|
||||
- test/**
|
||||
- bindings/**
|
||||
- binding.gyp
|
||||
|
||||
concurrency:
|
||||
group: ${{github.workflow}}-${{github.ref}}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: Test parser
|
||||
runs-on: ${{matrix.os}}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-14]
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Set up tree-sitter
|
||||
uses: tree-sitter/setup-action/cli@v1
|
||||
- name: Run tests
|
||||
uses: tree-sitter/parser-test-action@v2
|
||||
with:
|
||||
test-rust: ${{runner.os == 'Linux'}}
|
||||
- name: Parse examples
|
||||
uses: tree-sitter/parse-action@v4
|
||||
with:
|
||||
files: examples/*
|
||||
@ -1,26 +0,0 @@
|
||||
name: Lint
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
paths:
|
||||
- grammar.js
|
||||
pull_request:
|
||||
paths:
|
||||
- grammar.js
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: npm
|
||||
node-version: ${{vars.NODE_VERSION}}
|
||||
- name: Install modules
|
||||
run: npm ci --legacy-peer-deps
|
||||
- name: Run ESLint
|
||||
run: npm run lint
|
||||
@ -1,23 +0,0 @@
|
||||
name: Publish packages
|
||||
|
||||
on:
|
||||
push:
|
||||
tags: ["*"]
|
||||
|
||||
concurrency:
|
||||
group: ${{github.workflow}}-${{github.ref}}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
npm:
|
||||
uses: tree-sitter/workflows/.github/workflows/package-npm.yml@main
|
||||
secrets:
|
||||
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
|
||||
crates:
|
||||
uses: tree-sitter/workflows/.github/workflows/package-crates.yml@main
|
||||
secrets:
|
||||
CARGO_REGISTRY_TOKEN: ${{secrets.CARGO_REGISTRY_TOKEN}}
|
||||
pypi:
|
||||
uses: tree-sitter/workflows/.github/workflows/package-pypi.yml@main
|
||||
secrets:
|
||||
PYPI_API_TOKEN: ${{secrets.PYPI_API_TOKEN}}
|
||||
@ -1,32 +0,0 @@
|
||||
# Rust artifacts
|
||||
Cargo.lock
|
||||
target/
|
||||
|
||||
# Node artifacts
|
||||
build/
|
||||
prebuilds/
|
||||
node_modules/
|
||||
|
||||
# Swift artifacts
|
||||
.build/
|
||||
|
||||
# Python artifacts
|
||||
dist/
|
||||
*.egg-info
|
||||
*.whl
|
||||
|
||||
# C artifacts
|
||||
*.a
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
*.dll
|
||||
*.pc
|
||||
|
||||
# Examples
|
||||
/examples/*/
|
||||
|
||||
# Grammar volatiles
|
||||
*.wasm
|
||||
*.obj
|
||||
*.o
|
||||
@ -1,26 +0,0 @@
|
||||
[package]
|
||||
name = "tree-sitter-c"
|
||||
description = "C grammar for tree-sitter"
|
||||
version = "0.21.1"
|
||||
authors = [
|
||||
"Max Brunsfeld <maxbrunsfeld@gmail.com>",
|
||||
"Amaan Qureshi <amaanq12@gmail.com>",
|
||||
]
|
||||
license = "MIT"
|
||||
keywords = ["incremental", "parsing", "tree-sitter", "c"]
|
||||
categories = ["parsing", "text-editors"]
|
||||
repository = "https://github.com/tree-sitter/tree-sitter-c"
|
||||
edition = "2021"
|
||||
autoexamples = false
|
||||
|
||||
build = "bindings/rust/build.rs"
|
||||
include = ["bindings/rust/*", "grammar.js", "queries/*", "src/*"]
|
||||
|
||||
[lib]
|
||||
path = "bindings/rust/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
tree-sitter = ">=0.21.0"
|
||||
|
||||
[build-dependencies]
|
||||
cc = "1.0.90"
|
||||
@ -1,21 +0,0 @@
|
||||
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.
|
||||
@ -1,111 +0,0 @@
|
||||
VERSION := 0.21.1
|
||||
|
||||
LANGUAGE_NAME := tree-sitter-c
|
||||
|
||||
# repository
|
||||
SRC_DIR := src
|
||||
|
||||
PARSER_REPO_URL := $(shell git -C $(SRC_DIR) remote get-url origin 2>/dev/null)
|
||||
|
||||
ifeq ($(PARSER_URL),)
|
||||
PARSER_URL := $(subst .git,,$(PARSER_REPO_URL))
|
||||
ifeq ($(shell echo $(PARSER_URL) | grep '^[a-z][-+.0-9a-z]*://'),)
|
||||
PARSER_URL := $(subst :,/,$(PARSER_URL))
|
||||
PARSER_URL := $(subst git@,https://,$(PARSER_URL))
|
||||
endif
|
||||
endif
|
||||
|
||||
TS ?= tree-sitter
|
||||
|
||||
# ABI versioning
|
||||
SONAME_MAJOR := $(word 1,$(subst ., ,$(VERSION)))
|
||||
SONAME_MINOR := $(word 2,$(subst ., ,$(VERSION)))
|
||||
|
||||
# install directory layout
|
||||
PREFIX ?= /usr/local
|
||||
INCLUDEDIR ?= $(PREFIX)/include
|
||||
LIBDIR ?= $(PREFIX)/lib
|
||||
PCLIBDIR ?= $(LIBDIR)/pkgconfig
|
||||
|
||||
# object files
|
||||
OBJS := $(patsubst %.c,%.o,$(wildcard $(SRC_DIR)/*.c))
|
||||
|
||||
# flags
|
||||
ARFLAGS := rcs
|
||||
override CFLAGS += -I$(SRC_DIR) -std=c11 -fPIC
|
||||
|
||||
# OS-specific bits
|
||||
ifeq ($(OS),Windows_NT)
|
||||
$(error "Windows is not supported")
|
||||
else ifeq ($(shell uname),Darwin)
|
||||
SOEXT = dylib
|
||||
SOEXTVER_MAJOR = $(SONAME_MAJOR).dylib
|
||||
SOEXTVER = $(SONAME_MAJOR).$(SONAME_MINOR).dylib
|
||||
LINKSHARED := $(LINKSHARED)-dynamiclib -Wl,
|
||||
ifneq ($(ADDITIONAL_LIBS),)
|
||||
LINKSHARED := $(LINKSHARED)$(ADDITIONAL_LIBS),
|
||||
endif
|
||||
LINKSHARED := $(LINKSHARED)-install_name,$(LIBDIR)/lib$(LANGUAGE_NAME).$(SONAME_MAJOR).dylib,-rpath,@executable_path/../Frameworks
|
||||
else
|
||||
SOEXT = so
|
||||
SOEXTVER_MAJOR = so.$(SONAME_MAJOR)
|
||||
SOEXTVER = so.$(SONAME_MAJOR).$(SONAME_MINOR)
|
||||
LINKSHARED := $(LINKSHARED)-shared -Wl,
|
||||
ifneq ($(ADDITIONAL_LIBS),)
|
||||
LINKSHARED := $(LINKSHARED)$(ADDITIONAL_LIBS)
|
||||
endif
|
||||
LINKSHARED := $(LINKSHARED)-soname,lib$(LANGUAGE_NAME).so.$(SONAME_MAJOR)
|
||||
endif
|
||||
ifneq ($(filter $(shell uname),FreeBSD NetBSD DragonFly),)
|
||||
PCLIBDIR := $(PREFIX)/libdata/pkgconfig
|
||||
endif
|
||||
|
||||
all: lib$(LANGUAGE_NAME).a lib$(LANGUAGE_NAME).$(SOEXT) $(LANGUAGE_NAME).pc
|
||||
|
||||
lib$(LANGUAGE_NAME).a: $(OBJS)
|
||||
$(AR) $(ARFLAGS) $@ $^
|
||||
|
||||
lib$(LANGUAGE_NAME).$(SOEXT): $(OBJS)
|
||||
$(CC) $(LDFLAGS) $(LINKSHARED) $^ $(LDLIBS) -o $@
|
||||
ifneq ($(STRIP),)
|
||||
$(STRIP) $@
|
||||
endif
|
||||
|
||||
$(LANGUAGE_NAME).pc: bindings/c/$(LANGUAGE_NAME).pc.in
|
||||
sed -e 's|@URL@|$(PARSER_URL)|' \
|
||||
-e 's|@VERSION@|$(VERSION)|' \
|
||||
-e 's|@LIBDIR@|$(LIBDIR)|' \
|
||||
-e 's|@INCLUDEDIR@|$(INCLUDEDIR)|' \
|
||||
-e 's|@REQUIRES@|$(REQUIRES)|' \
|
||||
-e 's|@ADDITIONAL_LIBS@|$(ADDITIONAL_LIBS)|' \
|
||||
-e 's|=$(PREFIX)|=$${prefix}|' \
|
||||
-e 's|@PREFIX@|$(PREFIX)|' $< > $@
|
||||
|
||||
$(SRC_DIR)/parser.c: grammar.js
|
||||
$(TS) generate --no-bindings
|
||||
|
||||
install: all
|
||||
install -d '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter '$(DESTDIR)$(PCLIBDIR)' '$(DESTDIR)$(LIBDIR)'
|
||||
install -m644 bindings/c/$(LANGUAGE_NAME).h '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter/$(LANGUAGE_NAME).h
|
||||
install -m644 $(LANGUAGE_NAME).pc '$(DESTDIR)$(PCLIBDIR)'/$(LANGUAGE_NAME).pc
|
||||
install -m644 lib$(LANGUAGE_NAME).a '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).a
|
||||
install -m755 lib$(LANGUAGE_NAME).$(SOEXT) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER)
|
||||
ln -sf lib$(LANGUAGE_NAME).$(SOEXTVER) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR)
|
||||
ln -sf lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXT)
|
||||
|
||||
uninstall:
|
||||
$(RM) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).a \
|
||||
'$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER) \
|
||||
'$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR) \
|
||||
'$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXT) \
|
||||
'$(DESTDIR)$(INCLUDEDIR)'/tree_sitter/$(LANGUAGE_NAME).h \
|
||||
'$(DESTDIR)$(PCLIBDIR)'/$(LANGUAGE_NAME).pc
|
||||
|
||||
clean:
|
||||
$(RM) $(OBJS) $(LANGUAGE_NAME).pc lib$(LANGUAGE_NAME).a lib$(LANGUAGE_NAME).$(SOEXT)
|
||||
|
||||
test:
|
||||
$(TS) test
|
||||
$(TS) parse examples/* --quiet --time
|
||||
|
||||
.PHONY: all install uninstall clean test
|
||||
@ -1,46 +0,0 @@
|
||||
// swift-tools-version:5.3
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "TreeSitterC",
|
||||
products: [
|
||||
.library(name: "TreeSitterC", targets: ["TreeSitterC"]),
|
||||
],
|
||||
dependencies: [],
|
||||
targets: [
|
||||
.target(name: "TreeSitterC",
|
||||
path: ".",
|
||||
exclude: [
|
||||
"Cargo.toml",
|
||||
"Makefile",
|
||||
"binding.gyp",
|
||||
"bindings/c",
|
||||
"bindings/go",
|
||||
"bindings/node",
|
||||
"bindings/python",
|
||||
"bindings/rust",
|
||||
"prebuilds",
|
||||
"grammar.js",
|
||||
"package.json",
|
||||
"package-lock.json",
|
||||
"pyproject.toml",
|
||||
"setup.py",
|
||||
"test",
|
||||
"examples",
|
||||
".editorconfig",
|
||||
".github",
|
||||
".gitignore",
|
||||
".gitattributes",
|
||||
".gitmodules",
|
||||
],
|
||||
sources: [
|
||||
"src/parser.c",
|
||||
],
|
||||
resources: [
|
||||
.copy("queries")
|
||||
],
|
||||
publicHeadersPath: "bindings/swift",
|
||||
cSettings: [.headerSearchPath("src")])
|
||||
],
|
||||
cLanguageStandard: .c11
|
||||
)
|
||||
@ -1,18 +0,0 @@
|
||||
# tree-sitter-c
|
||||
|
||||
[![CI][ci]](https://github.com/tree-sitter/tree-sitter-c/actions/workflows/ci.yml)
|
||||
[![discord][discord]](https://discord.gg/w7nTvsVJhm)
|
||||
[![matrix][matrix]](https://matrix.to/#/#tree-sitter-chat:matrix.org)
|
||||
[![crates][crates]](https://crates.io/crates/tree-sitter-c)
|
||||
[![npm][npm]](https://www.npmjs.com/package/tree-sitter-c)
|
||||
[![pypi][pypi]](https://pypi.org/project/tree-sitter-c)
|
||||
|
||||
C grammar for [tree-sitter](https://github.com/tree-sitter/tree-sitter).
|
||||
Adapted from [this C99 grammar](http://slps.github.io/zoo/c/iso-9899-tc3.html).
|
||||
|
||||
[ci]: https://img.shields.io/github/actions/workflow/status/tree-sitter/tree-sitter-c/ci.yml?logo=github&label=CI
|
||||
[discord]: https://img.shields.io/discord/1063097320771698699?logo=discord&label=discord
|
||||
[matrix]: https://img.shields.io/matrix/tree-sitter-chat%3Amatrix.org?logo=matrix&label=matrix
|
||||
[npm]: https://img.shields.io/npm/v/tree-sitter-c?logo=npm
|
||||
[crates]: https://img.shields.io/crates/v/tree-sitter-c?logo=rust
|
||||
[pypi]: https://img.shields.io/pypi/v/tree-sitter-c?logo=pypi&logoColor=ffd242
|
||||
@ -1,20 +0,0 @@
|
||||
{
|
||||
"targets": [
|
||||
{
|
||||
"target_name": "tree_sitter_c_binding",
|
||||
"dependencies": [
|
||||
"<!(node -p \"require('node-addon-api').targets\"):node_addon_api_except",
|
||||
],
|
||||
"include_dirs": [
|
||||
"src",
|
||||
],
|
||||
"sources": [
|
||||
"bindings/node/binding.cc",
|
||||
"src/parser.c",
|
||||
],
|
||||
"cflags_c": [
|
||||
"-std=c11",
|
||||
],
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -1,16 +0,0 @@
|
||||
#ifndef TREE_SITTER_C_H_
|
||||
#define TREE_SITTER_C_H_
|
||||
|
||||
typedef struct TSLanguage TSLanguage;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
const TSLanguage *tree_sitter_c(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TREE_SITTER_C_H_
|
||||
@ -1,11 +0,0 @@
|
||||
prefix=@PREFIX@
|
||||
libdir=@LIBDIR@
|
||||
includedir=@INCLUDEDIR@
|
||||
|
||||
Name: tree-sitter-c
|
||||
Description: C grammar for tree-sitter
|
||||
URL: @URL@
|
||||
Version: @VERSION@
|
||||
Requires: @REQUIRES@
|
||||
Libs: -L${libdir} @ADDITIONAL_LIBS@ -ltree-sitter-c
|
||||
Cflags: -I${includedir}
|
||||
@ -1,12 +0,0 @@
|
||||
package tree_sitter_c
|
||||
|
||||
// #cgo CFLAGS: -std=c11 -fPIC
|
||||
// #include "../../src/parser.c"
|
||||
import "C"
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// Get the tree-sitter Language for this grammar.
|
||||
func Language() unsafe.Pointer {
|
||||
return unsafe.Pointer(C.tree_sitter_c())
|
||||
}
|
||||
@ -1,15 +0,0 @@
|
||||
package tree_sitter_c_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
tree_sitter "github.com/smacker/go-tree-sitter"
|
||||
"github.com/tree-sitter/tree-sitter-c"
|
||||
)
|
||||
|
||||
func TestCanLoadGrammar(t *testing.T) {
|
||||
language := tree_sitter.NewLanguage(tree_sitter_c.Language())
|
||||
if language == nil {
|
||||
t.Errorf("Error loading C grammar")
|
||||
}
|
||||
}
|
||||
@ -1,5 +0,0 @@
|
||||
module github.com/tree-sitter/tree-sitter-c
|
||||
|
||||
go 1.22
|
||||
|
||||
require github.com/smacker/go-tree-sitter v0.0.0-20230720070738-0d0a9f78d8f8
|
||||
@ -1,20 +0,0 @@
|
||||
#include <napi.h>
|
||||
|
||||
typedef struct TSLanguage TSLanguage;
|
||||
|
||||
extern "C" TSLanguage *tree_sitter_c();
|
||||
|
||||
// "tree-sitter", "language" hashed with BLAKE2
|
||||
const napi_type_tag LANGUAGE_TYPE_TAG = {
|
||||
0x8AF2E5212AD58ABF, 0xD5006CAD83ABBA16
|
||||
};
|
||||
|
||||
Napi::Object Init(Napi::Env env, Napi::Object exports) {
|
||||
exports["name"] = Napi::String::New(env, "c");
|
||||
auto language = Napi::External<TSLanguage>::New(env, tree_sitter_c());
|
||||
language.TypeTag(&LANGUAGE_TYPE_TAG);
|
||||
exports["language"] = language;
|
||||
return exports;
|
||||
}
|
||||
|
||||
NODE_API_MODULE(tree_sitter_c_binding, Init)
|
||||
@ -1,28 +0,0 @@
|
||||
type BaseNode = {
|
||||
type: string;
|
||||
named: boolean;
|
||||
};
|
||||
|
||||
type ChildNode = {
|
||||
multiple: boolean;
|
||||
required: boolean;
|
||||
types: BaseNode[];
|
||||
};
|
||||
|
||||
type NodeInfo =
|
||||
| (BaseNode & {
|
||||
subtypes: BaseNode[];
|
||||
})
|
||||
| (BaseNode & {
|
||||
fields: { [name: string]: ChildNode };
|
||||
children: ChildNode[];
|
||||
});
|
||||
|
||||
type Language = {
|
||||
name: string;
|
||||
language: unknown;
|
||||
nodeTypeInfo: NodeInfo[];
|
||||
};
|
||||
|
||||
declare const language: Language;
|
||||
export = language;
|
||||
@ -1,7 +0,0 @@
|
||||
const root = require("path").join(__dirname, "..", "..");
|
||||
|
||||
module.exports = require("node-gyp-build")(root);
|
||||
|
||||
try {
|
||||
module.exports.nodeTypeInfo = require("../../src/node-types.json");
|
||||
} catch (_) {}
|
||||
@ -1,5 +0,0 @@
|
||||
"C grammar for tree-sitter"
|
||||
|
||||
from ._binding import language
|
||||
|
||||
__all__ = ["language"]
|
||||
@ -1 +0,0 @@
|
||||
def language() -> int: ...
|
||||
@ -1,27 +0,0 @@
|
||||
#include <Python.h>
|
||||
|
||||
typedef struct TSLanguage TSLanguage;
|
||||
|
||||
TSLanguage *tree_sitter_c(void);
|
||||
|
||||
static PyObject* _binding_language(PyObject *self, PyObject *args) {
|
||||
return PyLong_FromVoidPtr(tree_sitter_c());
|
||||
}
|
||||
|
||||
static PyMethodDef methods[] = {
|
||||
{"language", _binding_language, METH_NOARGS,
|
||||
"Get the tree-sitter language for this grammar."},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
static struct PyModuleDef module = {
|
||||
.m_base = PyModuleDef_HEAD_INIT,
|
||||
.m_name = "_binding",
|
||||
.m_doc = NULL,
|
||||
.m_size = -1,
|
||||
.m_methods = methods
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC PyInit__binding(void) {
|
||||
return PyModule_Create(&module);
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
fn main() {
|
||||
let src_dir = std::path::Path::new("src");
|
||||
|
||||
let mut c_config = cc::Build::new();
|
||||
c_config.std("c11").include(src_dir);
|
||||
|
||||
let parser_path = src_dir.join("parser.c");
|
||||
c_config.file(&parser_path);
|
||||
println!("cargo:rerun-if-changed={}", parser_path.to_str().unwrap());
|
||||
|
||||
c_config.compile("tree-sitter-c");
|
||||
}
|
||||
@ -1,58 +0,0 @@
|
||||
//! This crate provides C 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:
|
||||
//!
|
||||
//! ```
|
||||
//! use tree_sitter::Parser;
|
||||
//!
|
||||
//! let code = r#"
|
||||
//! int double(int x) {
|
||||
//! return x * 2;
|
||||
//! }
|
||||
//! "#;
|
||||
//! let mut parser = Parser::new();
|
||||
//! parser.set_language(&tree_sitter_c::language()).expect("Error loading C grammar");
|
||||
//! let tree = parser.parse(code, None).unwrap();
|
||||
//! assert!(!tree.root_node().has_error());
|
||||
//! ```
|
||||
//!
|
||||
//! [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_c() -> 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_c() }
|
||||
}
|
||||
|
||||
/// 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: &str = include_str!("../../src/node-types.json");
|
||||
|
||||
/// The syntax highlighting query for this language.
|
||||
pub const HIGHLIGHT_QUERY: &str = include_str!("../../queries/highlights.scm");
|
||||
|
||||
/// The symbol tagging query for this language.
|
||||
pub const TAGS_QUERY: &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 C grammar");
|
||||
}
|
||||
}
|
||||
@ -1,16 +0,0 @@
|
||||
#ifndef TREE_SITTER_C_H_
|
||||
#define TREE_SITTER_C_H_
|
||||
|
||||
typedef struct TSLanguage TSLanguage;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
const TSLanguage *tree_sitter_c(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TREE_SITTER_C_H_
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,532 +0,0 @@
|
||||
#define _GNU_SOURCE
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
#include <sys/mman.h>
|
||||
#include "libc.h"
|
||||
#include "atomic.h"
|
||||
#include "pthread_impl.h"
|
||||
|
||||
#if defined(__GNUC__) && defined(__PIC__)
|
||||
#define inline inline __attribute__((always_inline))
|
||||
#endif
|
||||
|
||||
void *__mmap(void *, size_t, int, int, int, off_t);
|
||||
int __munmap(void *, size_t);
|
||||
void *__mremap(void *, size_t, size_t, int, ...);
|
||||
int __madvise(void *, size_t, int);
|
||||
|
||||
struct chunk {
|
||||
size_t psize, csize;
|
||||
struct chunk *next, *prev;
|
||||
};
|
||||
|
||||
struct bin {
|
||||
volatile int lock[2];
|
||||
struct chunk *head;
|
||||
struct chunk *tail;
|
||||
};
|
||||
|
||||
static struct {
|
||||
volatile uint64_t binmap;
|
||||
struct bin bins[64];
|
||||
volatile int free_lock[2];
|
||||
} mal;
|
||||
|
||||
|
||||
#define SIZE_ALIGN (4*sizeof(size_t))
|
||||
#define SIZE_MASK (-SIZE_ALIGN)
|
||||
#define OVERHEAD (2*sizeof(size_t))
|
||||
#define MMAP_THRESHOLD (0x1c00*SIZE_ALIGN)
|
||||
#define DONTCARE 16
|
||||
#define RECLAIM 163840
|
||||
|
||||
#define CHUNK_SIZE(c) ((c)->csize & -2)
|
||||
#define CHUNK_PSIZE(c) ((c)->psize & -2)
|
||||
#define PREV_CHUNK(c) ((struct chunk *)((char *)(c) - CHUNK_PSIZE(c)))
|
||||
#define NEXT_CHUNK(c) ((struct chunk *)((char *)(c) + CHUNK_SIZE(c)))
|
||||
#define MEM_TO_CHUNK(p) (struct chunk *)((char *)(p) - OVERHEAD)
|
||||
#define CHUNK_TO_MEM(c) (void *)((char *)(c) + OVERHEAD)
|
||||
#define BIN_TO_CHUNK(i) (MEM_TO_CHUNK(&mal.bins[i].head))
|
||||
|
||||
#define C_INUSE ((size_t)1)
|
||||
|
||||
#define IS_MMAPPED(c) !((c)->csize & (C_INUSE))
|
||||
|
||||
|
||||
/* Synchronization tools */
|
||||
|
||||
static inline void lock(volatile int *lk)
|
||||
{
|
||||
if (libc.threads_minus_1)
|
||||
while(a_swap(lk, 1)) __wait(lk, lk+1, 1, 1);
|
||||
}
|
||||
|
||||
static inline void unlock(volatile int *lk)
|
||||
{
|
||||
if (lk[0]) {
|
||||
a_store(lk, 0);
|
||||
if (lk[1]) __wake(lk, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void lock_bin(int i)
|
||||
{
|
||||
lock(mal.bins[i].lock);
|
||||
if (!mal.bins[i].head)
|
||||
mal.bins[i].head = mal.bins[i].tail = BIN_TO_CHUNK(i);
|
||||
}
|
||||
|
||||
static inline void unlock_bin(int i)
|
||||
{
|
||||
unlock(mal.bins[i].lock);
|
||||
}
|
||||
|
||||
static int first_set(uint64_t x)
|
||||
{
|
||||
#if 1
|
||||
return a_ctz_64(x);
|
||||
#else
|
||||
static const char debruijn64[64] = {
|
||||
0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28,
|
||||
62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11,
|
||||
63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10,
|
||||
51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12
|
||||
};
|
||||
static const char debruijn32[32] = {
|
||||
0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,
|
||||
31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14
|
||||
};
|
||||
if (sizeof(long) < 8) {
|
||||
uint32_t y = x;
|
||||
if (!y) {
|
||||
y = x>>32;
|
||||
return 32 + debruijn32[(y&-y)*0x076be629 >> 27];
|
||||
}
|
||||
return debruijn32[(y&-y)*0x076be629 >> 27];
|
||||
}
|
||||
return debruijn64[(x&-x)*0x022fdd63cc95386dull >> 58];
|
||||
#endif
|
||||
}
|
||||
|
||||
static const unsigned char bin_tab[60] = {
|
||||
32,33,34,35,36,36,37,37,38,38,39,39,
|
||||
40,40,40,40,41,41,41,41,42,42,42,42,43,43,43,43,
|
||||
44,44,44,44,44,44,44,44,45,45,45,45,45,45,45,45,
|
||||
46,46,46,46,46,46,46,46,47,47,47,47,47,47,47,47,
|
||||
};
|
||||
|
||||
static int bin_index(size_t x)
|
||||
{
|
||||
x = x / SIZE_ALIGN - 1;
|
||||
if (x <= 32) return x;
|
||||
if (x < 512) return bin_tab[x/8-4];
|
||||
if (x > 0x1c00) return 63;
|
||||
return bin_tab[x/128-4] + 16;
|
||||
}
|
||||
|
||||
static int bin_index_up(size_t x)
|
||||
{
|
||||
x = x / SIZE_ALIGN - 1;
|
||||
if (x <= 32) return x;
|
||||
x--;
|
||||
if (x < 512) return bin_tab[x/8-4] + 1;
|
||||
return bin_tab[x/128-4] + 17;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void __dump_heap(int x)
|
||||
{
|
||||
struct chunk *c;
|
||||
int i;
|
||||
for (c = (void *)mal.heap; CHUNK_SIZE(c); c = NEXT_CHUNK(c))
|
||||
fprintf(stderr, "base %p size %zu (%d) flags %d/%d\n",
|
||||
c, CHUNK_SIZE(c), bin_index(CHUNK_SIZE(c)),
|
||||
c->csize & 15,
|
||||
NEXT_CHUNK(c)->psize & 15);
|
||||
for (i=0; i<64; i++) {
|
||||
if (mal.bins[i].head != BIN_TO_CHUNK(i) && mal.bins[i].head) {
|
||||
fprintf(stderr, "bin %d: %p\n", i, mal.bins[i].head);
|
||||
if (!(mal.binmap & 1ULL<<i))
|
||||
fprintf(stderr, "missing from binmap!\n");
|
||||
} else if (mal.binmap & 1ULL<<i)
|
||||
fprintf(stderr, "binmap wrongly contains %d!\n", i);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void *__expand_heap(size_t *);
|
||||
|
||||
static struct chunk *expand_heap(size_t n)
|
||||
{
|
||||
static int heap_lock[2];
|
||||
static void *end;
|
||||
void *p;
|
||||
struct chunk *w;
|
||||
|
||||
/* The argument n already accounts for the caller's chunk
|
||||
* overhead needs, but if the heap can't be extended in-place,
|
||||
* we need room for an extra zero-sized sentinel chunk. */
|
||||
n += SIZE_ALIGN;
|
||||
|
||||
lock(heap_lock);
|
||||
|
||||
p = __expand_heap(&n);
|
||||
if (!p) {
|
||||
unlock(heap_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If not just expanding existing space, we need to make a
|
||||
* new sentinel chunk below the allocated space. */
|
||||
if (p != end) {
|
||||
/* Valid/safe because of the prologue increment. */
|
||||
n -= SIZE_ALIGN;
|
||||
p = (char *)p + SIZE_ALIGN;
|
||||
w = MEM_TO_CHUNK(p);
|
||||
w->psize = 0 | C_INUSE;
|
||||
}
|
||||
|
||||
/* Record new heap end and fill in footer. */
|
||||
end = (char *)p + n;
|
||||
w = MEM_TO_CHUNK(end);
|
||||
w->psize = n | C_INUSE;
|
||||
w->csize = 0 | C_INUSE;
|
||||
|
||||
/* Fill in header, which may be new or may be replacing a
|
||||
* zero-size sentinel header at the old end-of-heap. */
|
||||
w = MEM_TO_CHUNK(p);
|
||||
w->csize = n | C_INUSE;
|
||||
|
||||
unlock(heap_lock);
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
static int adjust_size(size_t *n)
|
||||
{
|
||||
/* Result of pointer difference must fit in ptrdiff_t. */
|
||||
if (*n-1 > PTRDIFF_MAX - SIZE_ALIGN - PAGE_SIZE) {
|
||||
if (*n) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
} else {
|
||||
*n = SIZE_ALIGN;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
*n = (*n + OVERHEAD + SIZE_ALIGN - 1) & SIZE_MASK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void unbin(struct chunk *c, int i)
|
||||
{
|
||||
if (c->prev == c->next)
|
||||
a_and_64(&mal.binmap, ~(1ULL<<i));
|
||||
c->prev->next = c->next;
|
||||
c->next->prev = c->prev;
|
||||
c->csize |= C_INUSE;
|
||||
NEXT_CHUNK(c)->psize |= C_INUSE;
|
||||
}
|
||||
|
||||
static int alloc_fwd(struct chunk *c)
|
||||
{
|
||||
int i;
|
||||
size_t k;
|
||||
while (!((k=c->csize) & C_INUSE)) {
|
||||
i = bin_index(k);
|
||||
lock_bin(i);
|
||||
if (c->csize == k) {
|
||||
unbin(c, i);
|
||||
unlock_bin(i);
|
||||
return 1;
|
||||
}
|
||||
unlock_bin(i);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int alloc_rev(struct chunk *c)
|
||||
{
|
||||
int i;
|
||||
size_t k;
|
||||
while (!((k=c->psize) & C_INUSE)) {
|
||||
i = bin_index(k);
|
||||
lock_bin(i);
|
||||
if (c->psize == k) {
|
||||
unbin(PREV_CHUNK(c), i);
|
||||
unlock_bin(i);
|
||||
return 1;
|
||||
}
|
||||
unlock_bin(i);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* pretrim - trims a chunk _prior_ to removing it from its bin.
|
||||
* Must be called with i as the ideal bin for size n, j the bin
|
||||
* for the _free_ chunk self, and bin j locked. */
|
||||
static int pretrim(struct chunk *self, size_t n, int i, int j)
|
||||
{
|
||||
size_t n1;
|
||||
struct chunk *next, *split;
|
||||
|
||||
/* We cannot pretrim if it would require re-binning. */
|
||||
if (j < 40) return 0;
|
||||
if (j < i+3) {
|
||||
if (j != 63) return 0;
|
||||
n1 = CHUNK_SIZE(self);
|
||||
if (n1-n <= MMAP_THRESHOLD) return 0;
|
||||
} else {
|
||||
n1 = CHUNK_SIZE(self);
|
||||
}
|
||||
if (bin_index(n1-n) != j) return 0;
|
||||
|
||||
next = NEXT_CHUNK(self);
|
||||
split = (void *)((char *)self + n);
|
||||
|
||||
split->prev = self->prev;
|
||||
split->next = self->next;
|
||||
split->prev->next = split;
|
||||
split->next->prev = split;
|
||||
split->psize = n | C_INUSE;
|
||||
split->csize = n1-n;
|
||||
next->psize = n1-n;
|
||||
self->csize = n | C_INUSE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void trim(struct chunk *self, size_t n)
|
||||
{
|
||||
size_t n1 = CHUNK_SIZE(self);
|
||||
struct chunk *next, *split;
|
||||
|
||||
if (n >= n1 - DONTCARE) return;
|
||||
|
||||
next = NEXT_CHUNK(self);
|
||||
split = (void *)((char *)self + n);
|
||||
|
||||
split->psize = n | C_INUSE;
|
||||
split->csize = n1-n | C_INUSE;
|
||||
next->psize = n1-n | C_INUSE;
|
||||
self->csize = n | C_INUSE;
|
||||
|
||||
free(CHUNK_TO_MEM(split));
|
||||
}
|
||||
|
||||
void *malloc(size_t n)
|
||||
{
|
||||
struct chunk *c;
|
||||
int i, j;
|
||||
|
||||
if (adjust_size(&n) < 0) return 0;
|
||||
|
||||
if (n > MMAP_THRESHOLD) {
|
||||
size_t len = n + OVERHEAD + PAGE_SIZE - 1 & -PAGE_SIZE;
|
||||
char *base = __mmap(0, len, PROT_READ|PROT_WRITE,
|
||||
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
|
||||
if (base == (void *)-1) return 0;
|
||||
c = (void *)(base + SIZE_ALIGN - OVERHEAD);
|
||||
c->csize = len - (SIZE_ALIGN - OVERHEAD);
|
||||
c->psize = SIZE_ALIGN - OVERHEAD;
|
||||
return CHUNK_TO_MEM(c);
|
||||
}
|
||||
|
||||
i = bin_index_up(n);
|
||||
for (;;) {
|
||||
uint64_t mask = mal.binmap & -(1ULL<<i);
|
||||
if (!mask) {
|
||||
c = expand_heap(n);
|
||||
if (!c) return 0;
|
||||
if (alloc_rev(c)) {
|
||||
struct chunk *x = c;
|
||||
c = PREV_CHUNK(c);
|
||||
NEXT_CHUNK(x)->psize = c->csize =
|
||||
x->csize + CHUNK_SIZE(c);
|
||||
}
|
||||
break;
|
||||
}
|
||||
j = first_set(mask);
|
||||
lock_bin(j);
|
||||
c = mal.bins[j].head;
|
||||
if (c != BIN_TO_CHUNK(j)) {
|
||||
if (!pretrim(c, n, i, j)) unbin(c, j);
|
||||
unlock_bin(j);
|
||||
break;
|
||||
}
|
||||
unlock_bin(j);
|
||||
}
|
||||
|
||||
/* Now patch up in case we over-allocated */
|
||||
trim(c, n);
|
||||
|
||||
return CHUNK_TO_MEM(c);
|
||||
}
|
||||
|
||||
void *__malloc0(size_t n)
|
||||
{
|
||||
void *p = malloc(n);
|
||||
if (p && !IS_MMAPPED(MEM_TO_CHUNK(p))) {
|
||||
size_t *z;
|
||||
n = (n + sizeof *z - 1)/sizeof *z;
|
||||
for (z=p; n; n--, z++) if (*z) *z=0;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
void *realloc(void *p, size_t n)
|
||||
{
|
||||
struct chunk *self, *next;
|
||||
size_t n0, n1;
|
||||
void *new;
|
||||
|
||||
if (!p) return malloc(n);
|
||||
|
||||
if (adjust_size(&n) < 0) return 0;
|
||||
|
||||
self = MEM_TO_CHUNK(p);
|
||||
n1 = n0 = CHUNK_SIZE(self);
|
||||
|
||||
if (IS_MMAPPED(self)) {
|
||||
size_t extra = self->psize;
|
||||
char *base = (char *)self - extra;
|
||||
size_t oldlen = n0 + extra;
|
||||
size_t newlen = n + extra;
|
||||
/* Crash on realloc of freed chunk */
|
||||
if (extra & 1) a_crash();
|
||||
if (newlen < PAGE_SIZE && (new = malloc(n))) {
|
||||
memcpy(new, p, n-OVERHEAD);
|
||||
free(p);
|
||||
return new;
|
||||
}
|
||||
newlen = (newlen + PAGE_SIZE-1) & -PAGE_SIZE;
|
||||
if (oldlen == newlen) return p;
|
||||
base = __mremap(base, oldlen, newlen, MREMAP_MAYMOVE);
|
||||
if (base == (void *)-1)
|
||||
goto copy_realloc;
|
||||
self = (void *)(base + extra);
|
||||
self->csize = newlen - extra;
|
||||
return CHUNK_TO_MEM(self);
|
||||
}
|
||||
|
||||
next = NEXT_CHUNK(self);
|
||||
|
||||
/* Crash on corrupted footer (likely from buffer overflow) */
|
||||
if (next->psize != self->csize) a_crash();
|
||||
|
||||
/* Merge adjacent chunks if we need more space. This is not
|
||||
* a waste of time even if we fail to get enough space, because our
|
||||
* subsequent call to free would otherwise have to do the merge. */
|
||||
if (n > n1 && alloc_fwd(next)) {
|
||||
n1 += CHUNK_SIZE(next);
|
||||
next = NEXT_CHUNK(next);
|
||||
}
|
||||
/* FIXME: find what's wrong here and reenable it..? */
|
||||
if (0 && n > n1 && alloc_rev(self)) {
|
||||
self = PREV_CHUNK(self);
|
||||
n1 += CHUNK_SIZE(self);
|
||||
}
|
||||
self->csize = n1 | C_INUSE;
|
||||
next->psize = n1 | C_INUSE;
|
||||
|
||||
/* If we got enough space, split off the excess and return */
|
||||
if (n <= n1) {
|
||||
//memmove(CHUNK_TO_MEM(self), p, n0-OVERHEAD);
|
||||
trim(self, n);
|
||||
return CHUNK_TO_MEM(self);
|
||||
}
|
||||
|
||||
copy_realloc:
|
||||
/* As a last resort, allocate a new chunk and copy to it. */
|
||||
new = malloc(n-OVERHEAD);
|
||||
if (!new) return 0;
|
||||
memcpy(new, p, n0-OVERHEAD);
|
||||
free(CHUNK_TO_MEM(self));
|
||||
return new;
|
||||
}
|
||||
|
||||
void free(void *p)
|
||||
{
|
||||
struct chunk *self = MEM_TO_CHUNK(p);
|
||||
struct chunk *next;
|
||||
size_t final_size, new_size, size;
|
||||
int reclaim=0;
|
||||
int i;
|
||||
|
||||
if (!p) return;
|
||||
|
||||
if (IS_MMAPPED(self)) {
|
||||
size_t extra = self->psize;
|
||||
char *base = (char *)self - extra;
|
||||
size_t len = CHUNK_SIZE(self) + extra;
|
||||
/* Crash on double free */
|
||||
if (extra & 1) a_crash();
|
||||
__munmap(base, len);
|
||||
return;
|
||||
}
|
||||
|
||||
final_size = new_size = CHUNK_SIZE(self);
|
||||
next = NEXT_CHUNK(self);
|
||||
|
||||
/* Crash on corrupted footer (likely from buffer overflow) */
|
||||
if (next->psize != self->csize) a_crash();
|
||||
|
||||
for (;;) {
|
||||
if (self->psize & next->csize & C_INUSE) {
|
||||
self->csize = final_size | C_INUSE;
|
||||
next->psize = final_size | C_INUSE;
|
||||
i = bin_index(final_size);
|
||||
lock_bin(i);
|
||||
lock(mal.free_lock);
|
||||
if (self->psize & next->csize & C_INUSE)
|
||||
break;
|
||||
unlock(mal.free_lock);
|
||||
unlock_bin(i);
|
||||
}
|
||||
|
||||
if (alloc_rev(self)) {
|
||||
self = PREV_CHUNK(self);
|
||||
size = CHUNK_SIZE(self);
|
||||
final_size += size;
|
||||
if (new_size+size > RECLAIM && (new_size+size^size) > size)
|
||||
reclaim = 1;
|
||||
}
|
||||
|
||||
if (alloc_fwd(next)) {
|
||||
size = CHUNK_SIZE(next);
|
||||
final_size += size;
|
||||
if (new_size+size > RECLAIM && (new_size+size^size) > size)
|
||||
reclaim = 1;
|
||||
next = NEXT_CHUNK(next);
|
||||
}
|
||||
}
|
||||
|
||||
if (!(mal.binmap & 1ULL<<i))
|
||||
a_or_64(&mal.binmap, 1ULL<<i);
|
||||
|
||||
self->csize = final_size;
|
||||
next->psize = final_size;
|
||||
unlock(mal.free_lock);
|
||||
|
||||
self->next = BIN_TO_CHUNK(i);
|
||||
self->prev = mal.bins[i].tail;
|
||||
self->next->prev = self;
|
||||
self->prev->next = self;
|
||||
|
||||
/* Replace middle of large chunks with fresh zero pages */
|
||||
if (reclaim) {
|
||||
uintptr_t a = (uintptr_t)self + SIZE_ALIGN+PAGE_SIZE-1 & -PAGE_SIZE;
|
||||
uintptr_t b = (uintptr_t)next - SIZE_ALIGN & -PAGE_SIZE;
|
||||
#if 1
|
||||
__madvise((void *)a, b-a, MADV_DONTNEED);
|
||||
#else
|
||||
__mmap((void *)a, b-a, PROT_READ|PROT_WRITE,
|
||||
MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
unlock_bin(i);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,108 +0,0 @@
|
||||
{
|
||||
"name": "tree-sitter-c",
|
||||
"version": "0.21.1",
|
||||
"description": "C grammar for tree-sitter",
|
||||
"repository": "github:tree-sitter/tree-sitter-c",
|
||||
"license": "MIT",
|
||||
"author": "Max Brunsfeld <maxbrunsfeld@gmail.com>",
|
||||
"contributors": [
|
||||
"Amaan Qureshi <amaanq12@gmail.com>"
|
||||
],
|
||||
"main": "bindings/node",
|
||||
"types": "bindings/node",
|
||||
"keywords": [
|
||||
"incremental",
|
||||
"parsing",
|
||||
"tree-sitter",
|
||||
"c"
|
||||
],
|
||||
"files": [
|
||||
"grammar.js",
|
||||
"binding.gyp",
|
||||
"prebuilds/**",
|
||||
"bindings/node/*",
|
||||
"queries/*",
|
||||
"src/**"
|
||||
],
|
||||
"dependencies": {
|
||||
"node-addon-api": "^8.0.0",
|
||||
"node-gyp-build": "^4.8.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"tree-sitter": "^0.21.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"tree_sitter": {
|
||||
"optional": true
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-google": "^0.14.0",
|
||||
"tree-sitter-cli": "^0.22.2",
|
||||
"prebuildify": "^6.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"install": "node-gyp-build",
|
||||
"prebuildify": "prebuildify --napi --strip",
|
||||
"build": "tree-sitter generate --no-bindings",
|
||||
"build-wasm": "tree-sitter build --wasm",
|
||||
"lint": "eslint grammar.js",
|
||||
"parse": "tree-sitter parse",
|
||||
"test": "tree-sitter test"
|
||||
},
|
||||
"tree-sitter": [
|
||||
{
|
||||
"scope": "source.c",
|
||||
"file-types": [
|
||||
"c",
|
||||
"h"
|
||||
],
|
||||
"injection-regex": "^(c|h)$",
|
||||
"highlights": "queries/highlights.scm",
|
||||
"tags": "queries/tags.scm"
|
||||
}
|
||||
],
|
||||
"eslintConfig": {
|
||||
"env": {
|
||||
"commonjs": true,
|
||||
"es2021": true
|
||||
},
|
||||
"extends": "google",
|
||||
"parserOptions": {
|
||||
"ecmaVersion": "latest",
|
||||
"sourceType": "module"
|
||||
},
|
||||
"rules": {
|
||||
"arrow-parens": "off",
|
||||
"camel-case": "off",
|
||||
"indent": [
|
||||
"error",
|
||||
2,
|
||||
{
|
||||
"SwitchCase": 1
|
||||
}
|
||||
],
|
||||
"max-len": [
|
||||
"error",
|
||||
{
|
||||
"code": 160,
|
||||
"ignoreComments": true,
|
||||
"ignoreUrls": true,
|
||||
"ignoreStrings": true
|
||||
}
|
||||
],
|
||||
"spaced-comment": [
|
||||
"warn",
|
||||
"always",
|
||||
{
|
||||
"line": {
|
||||
"markers": [
|
||||
"/"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,33 +0,0 @@
|
||||
[build-system]
|
||||
requires = ["setuptools>=42", "wheel"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "tree-sitter-c"
|
||||
description = "C grammar for tree-sitter"
|
||||
version = "0.21.1"
|
||||
keywords = ["incremental", "parsing", "tree-sitter", "c"]
|
||||
classifiers = [
|
||||
"Intended Audience :: Developers",
|
||||
"License :: OSI Approved :: MIT License",
|
||||
"Topic :: Software Development :: Compilers",
|
||||
"Topic :: Text Processing :: Linguistic",
|
||||
"Typing :: Typed",
|
||||
]
|
||||
authors = [
|
||||
{ name = "Max Brunsfeld", email = "maxbrunsfeld@gmail.com" },
|
||||
{ name = "Amaan Qureshi", email = "amaanq12@gmail.com" },
|
||||
]
|
||||
requires-python = ">=3.8"
|
||||
license.text = "MIT"
|
||||
readme = "README.md"
|
||||
|
||||
[project.urls]
|
||||
Homepage = "https://github.com/tree-sitter/tree-sitter-c"
|
||||
|
||||
[project.optional-dependencies]
|
||||
core = ["tree-sitter~=0.21"]
|
||||
|
||||
[tool.cibuildwheel]
|
||||
build = "cp38-*"
|
||||
build-frontend = "build"
|
||||
@ -1,81 +0,0 @@
|
||||
(identifier) @variable
|
||||
|
||||
((identifier) @constant
|
||||
(#match? @constant "^[A-Z][A-Z\\d_]*$"))
|
||||
|
||||
"break" @keyword
|
||||
"case" @keyword
|
||||
"const" @keyword
|
||||
"continue" @keyword
|
||||
"default" @keyword
|
||||
"do" @keyword
|
||||
"else" @keyword
|
||||
"enum" @keyword
|
||||
"extern" @keyword
|
||||
"for" @keyword
|
||||
"if" @keyword
|
||||
"inline" @keyword
|
||||
"return" @keyword
|
||||
"sizeof" @keyword
|
||||
"static" @keyword
|
||||
"struct" @keyword
|
||||
"switch" @keyword
|
||||
"typedef" @keyword
|
||||
"union" @keyword
|
||||
"volatile" @keyword
|
||||
"while" @keyword
|
||||
|
||||
"#define" @keyword
|
||||
"#elif" @keyword
|
||||
"#else" @keyword
|
||||
"#endif" @keyword
|
||||
"#if" @keyword
|
||||
"#ifdef" @keyword
|
||||
"#ifndef" @keyword
|
||||
"#include" @keyword
|
||||
(preproc_directive) @keyword
|
||||
|
||||
"--" @operator
|
||||
"-" @operator
|
||||
"-=" @operator
|
||||
"->" @operator
|
||||
"=" @operator
|
||||
"!=" @operator
|
||||
"*" @operator
|
||||
"&" @operator
|
||||
"&&" @operator
|
||||
"+" @operator
|
||||
"++" @operator
|
||||
"+=" @operator
|
||||
"<" @operator
|
||||
"==" @operator
|
||||
">" @operator
|
||||
"||" @operator
|
||||
|
||||
"." @delimiter
|
||||
";" @delimiter
|
||||
|
||||
(string_literal) @string
|
||||
(system_lib_string) @string
|
||||
|
||||
(null) @constant
|
||||
(number_literal) @number
|
||||
(char_literal) @number
|
||||
|
||||
(field_identifier) @property
|
||||
(statement_identifier) @label
|
||||
(type_identifier) @type
|
||||
(primitive_type) @type
|
||||
(sized_type_specifier) @type
|
||||
|
||||
(call_expression
|
||||
function: (identifier) @function)
|
||||
(call_expression
|
||||
function: (field_expression
|
||||
field: (field_identifier) @function))
|
||||
(function_declarator
|
||||
declarator: (identifier) @function)
|
||||
(preproc_function_def
|
||||
name: (identifier) @function.special)
|
||||
|
||||
(comment) @comment
|
||||
@ -1,9 +0,0 @@
|
||||
(struct_specifier name: (type_identifier) @name body:(_)) @definition.class
|
||||
|
||||
(declaration type: (union_specifier name: (type_identifier) @name)) @definition.class
|
||||
|
||||
(function_declarator declarator: (identifier) @name) @definition.function
|
||||
|
||||
(type_definition declarator: (type_identifier) @name) @definition.type
|
||||
|
||||
(enum_specifier name: (type_identifier) @name) @definition.type
|
||||
@ -1,56 +0,0 @@
|
||||
from os.path import isdir, join
|
||||
from platform import system
|
||||
|
||||
from setuptools import Extension, find_packages, setup
|
||||
from setuptools.command.build import build
|
||||
from wheel.bdist_wheel import bdist_wheel
|
||||
|
||||
|
||||
class Build(build):
|
||||
def run(self):
|
||||
if isdir("queries"):
|
||||
dest = join(self.build_lib, "tree_sitter_c", "queries")
|
||||
self.copy_tree("queries", dest)
|
||||
super().run()
|
||||
|
||||
|
||||
class BdistWheel(bdist_wheel):
|
||||
def get_tag(self):
|
||||
python, abi, platform = super().get_tag()
|
||||
if python.startswith("cp"):
|
||||
python, abi = "cp38", "abi3"
|
||||
return python, abi, platform
|
||||
|
||||
|
||||
setup(
|
||||
packages=find_packages("bindings/python"),
|
||||
package_dir={"": "bindings/python"},
|
||||
package_data={
|
||||
"tree_sitter_c": ["*.pyi", "py.typed"],
|
||||
"tree_sitter_c.queries": ["*.scm"],
|
||||
},
|
||||
ext_package="tree_sitter_c",
|
||||
ext_modules=[
|
||||
Extension(
|
||||
name="_binding",
|
||||
sources=[
|
||||
"bindings/python/tree_sitter_c/binding.c",
|
||||
"src/parser.c",
|
||||
],
|
||||
extra_compile_args=(
|
||||
["-std=c11"] if system() != 'Windows' else []
|
||||
),
|
||||
define_macros=[
|
||||
("Py_LIMITED_API", "0x03080000"),
|
||||
("PY_SSIZE_T_CLEAN", None)
|
||||
],
|
||||
include_dirs=["src"],
|
||||
py_limited_api=True,
|
||||
)
|
||||
],
|
||||
cmdclass={
|
||||
"build": Build,
|
||||
"bdist_wheel": BdistWheel
|
||||
},
|
||||
zip_safe=False
|
||||
)
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,54 +0,0 @@
|
||||
#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);
|
||||
extern void *(*ts_current_calloc)(size_t, size_t);
|
||||
extern void *(*ts_current_realloc)(void *, size_t);
|
||||
extern void (*ts_current_free)(void *);
|
||||
|
||||
#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_
|
||||
@ -1,290 +0,0 @@
|
||||
#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(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) \
|
||||
_array__reserve((Array *)(self), 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((Array *)(self))
|
||||
|
||||
/// Push a new `element` onto the end of the array.
|
||||
#define array_push(self, element) \
|
||||
(_array__grow((Array *)(self), 1, array_elem_size(self)), \
|
||||
(self)->contents[(self)->size++] = (element))
|
||||
|
||||
/// Increase the array's size by `count` elements.
|
||||
/// New elements are zero-initialized.
|
||||
#define array_grow_by(self, count) \
|
||||
do { \
|
||||
if ((count) == 0) break; \
|
||||
_array__grow((Array *)(self), 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, contents) \
|
||||
_array__splice( \
|
||||
(Array *)(self), array_elem_size(self), (self)->size, \
|
||||
0, count, 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) \
|
||||
_array__splice( \
|
||||
(Array *)(self), 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) \
|
||||
_array__splice((Array *)(self), 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((Array *)(self), 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) \
|
||||
_array__assign((Array *)(self), (const Array *)(other), array_elem_size(self))
|
||||
|
||||
/// Swap one array with another
|
||||
#define array_swap(self, other) \
|
||||
_array__swap((Array *)(self), (Array *)(other))
|
||||
|
||||
/// 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
|
||||
|
||||
typedef Array(void) Array;
|
||||
|
||||
/// This is not what you're looking for, see `array_delete`.
|
||||
static inline void _array__delete(Array *self) {
|
||||
if (self->contents) {
|
||||
ts_free(self->contents);
|
||||
self->contents = NULL;
|
||||
self->size = 0;
|
||||
self->capacity = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// This is not what you're looking for, see `array_erase`.
|
||||
static inline void _array__erase(Array *self, size_t element_size,
|
||||
uint32_t index) {
|
||||
assert(index < self->size);
|
||||
char *contents = (char *)self->contents;
|
||||
memmove(contents + index * element_size, contents + (index + 1) * element_size,
|
||||
(self->size - index - 1) * element_size);
|
||||
self->size--;
|
||||
}
|
||||
|
||||
/// This is not what you're looking for, see `array_reserve`.
|
||||
static inline void _array__reserve(Array *self, size_t element_size, uint32_t new_capacity) {
|
||||
if (new_capacity > self->capacity) {
|
||||
if (self->contents) {
|
||||
self->contents = ts_realloc(self->contents, new_capacity * element_size);
|
||||
} else {
|
||||
self->contents = ts_malloc(new_capacity * element_size);
|
||||
}
|
||||
self->capacity = new_capacity;
|
||||
}
|
||||
}
|
||||
|
||||
/// This is not what you're looking for, see `array_assign`.
|
||||
static inline void _array__assign(Array *self, const Array *other, size_t element_size) {
|
||||
_array__reserve(self, element_size, other->size);
|
||||
self->size = other->size;
|
||||
memcpy(self->contents, other->contents, self->size * element_size);
|
||||
}
|
||||
|
||||
/// This is not what you're looking for, see `array_swap`.
|
||||
static inline void _array__swap(Array *self, Array *other) {
|
||||
Array swap = *other;
|
||||
*other = *self;
|
||||
*self = swap;
|
||||
}
|
||||
|
||||
/// This is not what you're looking for, see `array_push` or `array_grow_by`.
|
||||
static inline void _array__grow(Array *self, uint32_t count, size_t element_size) {
|
||||
uint32_t new_size = self->size + count;
|
||||
if (new_size > self->capacity) {
|
||||
uint32_t new_capacity = self->capacity * 2;
|
||||
if (new_capacity < 8) new_capacity = 8;
|
||||
if (new_capacity < new_size) new_capacity = new_size;
|
||||
_array__reserve(self, element_size, new_capacity);
|
||||
}
|
||||
}
|
||||
|
||||
/// This is not what you're looking for, see `array_splice`.
|
||||
static inline void _array__splice(Array *self, size_t element_size,
|
||||
uint32_t index, uint32_t old_count,
|
||||
uint32_t new_count, const void *elements) {
|
||||
uint32_t new_size = self->size + new_count - old_count;
|
||||
uint32_t old_end = index + old_count;
|
||||
uint32_t new_end = index + new_count;
|
||||
assert(old_end <= self->size);
|
||||
|
||||
_array__reserve(self, element_size, new_size);
|
||||
|
||||
char *contents = (char *)self->contents;
|
||||
if (self->size > old_end) {
|
||||
memmove(
|
||||
contents + new_end * element_size,
|
||||
contents + old_end * element_size,
|
||||
(self->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
|
||||
);
|
||||
}
|
||||
}
|
||||
self->size += new_count - old_count;
|
||||
}
|
||||
|
||||
/// 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(default : 4101)
|
||||
#elif defined(__GNUC__) || defined(__clang__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TREE_SITTER_ARRAY_H_
|
||||
@ -1,230 +0,0 @@
|
||||
#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
|
||||
|
||||
#ifndef TREE_SITTER_API_H_
|
||||
typedef uint16_t TSStateId;
|
||||
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
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define UNUSED __pragma(warning(suppress : 4101))
|
||||
#else
|
||||
#define UNUSED __attribute__((unused))
|
||||
#endif
|
||||
|
||||
#define START_LEXER() \
|
||||
bool result = false; \
|
||||
bool skip = false; \
|
||||
UNUSED \
|
||||
bool eof = false; \
|
||||
int32_t lookahead; \
|
||||
goto start; \
|
||||
next_state: \
|
||||
lexer->advance(lexer, skip); \
|
||||
start: \
|
||||
skip = false; \
|
||||
lookahead = lexer->lookahead;
|
||||
|
||||
#define ADVANCE(state_value) \
|
||||
{ \
|
||||
state = state_value; \
|
||||
goto next_state; \
|
||||
}
|
||||
|
||||
#define 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_
|
||||
@ -1,274 +0,0 @@
|
||||
================================================================================
|
||||
pointer declarations vs expressions
|
||||
================================================================================
|
||||
|
||||
TSLanguage *(*lang_parser)(void);
|
||||
|
||||
char (*ptr_to_array)[];
|
||||
|
||||
int main() {
|
||||
// declare a function pointer
|
||||
T1 * b(T2 a);
|
||||
|
||||
// evaluate expressions
|
||||
c * d(5);
|
||||
e(f * g);
|
||||
}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(translation_unit
|
||||
(declaration
|
||||
(type_identifier)
|
||||
(pointer_declarator
|
||||
(function_declarator
|
||||
(parenthesized_declarator
|
||||
(pointer_declarator
|
||||
(identifier)))
|
||||
(parameter_list
|
||||
(parameter_declaration
|
||||
(primitive_type))))))
|
||||
(declaration
|
||||
(primitive_type)
|
||||
(array_declarator
|
||||
(parenthesized_declarator
|
||||
(pointer_declarator
|
||||
(identifier)))))
|
||||
(function_definition
|
||||
(primitive_type)
|
||||
(function_declarator
|
||||
(identifier)
|
||||
(parameter_list))
|
||||
(compound_statement
|
||||
(comment)
|
||||
(declaration
|
||||
(type_identifier)
|
||||
(pointer_declarator
|
||||
(function_declarator
|
||||
(identifier)
|
||||
(parameter_list
|
||||
(parameter_declaration
|
||||
(type_identifier)
|
||||
(identifier))))))
|
||||
(comment)
|
||||
(expression_statement
|
||||
(binary_expression
|
||||
(identifier)
|
||||
(call_expression
|
||||
(identifier)
|
||||
(argument_list
|
||||
(number_literal)))))
|
||||
(expression_statement
|
||||
(call_expression
|
||||
(identifier)
|
||||
(argument_list
|
||||
(binary_expression
|
||||
(identifier)
|
||||
(identifier))))))))
|
||||
|
||||
================================================================================
|
||||
casts vs multiplications
|
||||
================================================================================
|
||||
|
||||
/*
|
||||
* ambiguities
|
||||
*/
|
||||
|
||||
int main() {
|
||||
// cast
|
||||
a((B *)c);
|
||||
|
||||
// parenthesized product
|
||||
d((e * f));
|
||||
}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(translation_unit
|
||||
(comment)
|
||||
(function_definition
|
||||
(primitive_type)
|
||||
(function_declarator
|
||||
(identifier)
|
||||
(parameter_list))
|
||||
(compound_statement
|
||||
(comment)
|
||||
(expression_statement
|
||||
(call_expression
|
||||
(identifier)
|
||||
(argument_list
|
||||
(cast_expression
|
||||
(type_descriptor
|
||||
(type_identifier)
|
||||
(abstract_pointer_declarator))
|
||||
(identifier)))))
|
||||
(comment)
|
||||
(expression_statement
|
||||
(call_expression
|
||||
(identifier)
|
||||
(argument_list
|
||||
(parenthesized_expression
|
||||
(binary_expression
|
||||
(identifier)
|
||||
(identifier)))))))))
|
||||
|
||||
================================================================================
|
||||
function-like type macros vs function calls
|
||||
================================================================================
|
||||
|
||||
// this is a macro
|
||||
GIT_INLINE(int *) x = 5;
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(translation_unit
|
||||
(comment)
|
||||
(declaration
|
||||
(macro_type_specifier
|
||||
(identifier)
|
||||
(type_descriptor
|
||||
(primitive_type)
|
||||
(abstract_pointer_declarator)))
|
||||
(init_declarator
|
||||
(identifier)
|
||||
(number_literal))))
|
||||
|
||||
================================================================================
|
||||
function calls vs parenthesized declarators vs macro types
|
||||
================================================================================
|
||||
|
||||
int main() {
|
||||
/*
|
||||
* Could be either:
|
||||
* - function call
|
||||
* - declaration w/ parenthesized declarator
|
||||
* - declaration w/ macro type, no declarator
|
||||
*/
|
||||
ABC(d);
|
||||
|
||||
/*
|
||||
* Normal declaration
|
||||
*/
|
||||
efg hij;
|
||||
}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(translation_unit
|
||||
(function_definition
|
||||
(primitive_type)
|
||||
(function_declarator
|
||||
(identifier)
|
||||
(parameter_list))
|
||||
(compound_statement
|
||||
(comment)
|
||||
(expression_statement
|
||||
(call_expression
|
||||
(identifier)
|
||||
(argument_list
|
||||
(identifier))))
|
||||
(comment)
|
||||
(declaration
|
||||
(type_identifier)
|
||||
(identifier)))))
|
||||
|
||||
================================================================================
|
||||
Call expressions vs empty declarations w/ macros as types
|
||||
================================================================================
|
||||
|
||||
int main() {
|
||||
int a = 1;
|
||||
b(a);
|
||||
A(A *);
|
||||
}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(translation_unit
|
||||
(function_definition
|
||||
(primitive_type)
|
||||
(function_declarator
|
||||
(identifier)
|
||||
(parameter_list))
|
||||
(compound_statement
|
||||
(declaration
|
||||
(primitive_type)
|
||||
(init_declarator
|
||||
(identifier)
|
||||
(number_literal)))
|
||||
(expression_statement
|
||||
(call_expression
|
||||
(identifier)
|
||||
(argument_list
|
||||
(identifier))))
|
||||
(macro_type_specifier
|
||||
(identifier)
|
||||
(type_descriptor
|
||||
(type_identifier)
|
||||
(abstract_pointer_declarator))))))
|
||||
|
||||
================================================================================
|
||||
Comments after for loops with ambiguities
|
||||
================================================================================
|
||||
|
||||
int main() {
|
||||
for (a *b = c; d; e) {
|
||||
aff;
|
||||
}
|
||||
|
||||
// a-comment
|
||||
|
||||
g;
|
||||
}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(translation_unit
|
||||
(function_definition
|
||||
(primitive_type)
|
||||
(function_declarator
|
||||
(identifier)
|
||||
(parameter_list))
|
||||
(compound_statement
|
||||
(for_statement
|
||||
(declaration
|
||||
(type_identifier)
|
||||
(init_declarator
|
||||
(pointer_declarator
|
||||
(identifier))
|
||||
(identifier)))
|
||||
(identifier)
|
||||
(identifier)
|
||||
(compound_statement
|
||||
(expression_statement
|
||||
(identifier))))
|
||||
(comment)
|
||||
(expression_statement
|
||||
(identifier)))))
|
||||
|
||||
================================================================================
|
||||
Top-level macro invocations
|
||||
================================================================================
|
||||
|
||||
DEFINE_SOMETHING(THING_A, "this is a thing a");
|
||||
DEFINE_SOMETHING(THING_B, "this is a thing b", "thanks");
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(translation_unit
|
||||
(expression_statement
|
||||
(call_expression
|
||||
(identifier)
|
||||
(argument_list
|
||||
(identifier)
|
||||
(string_literal
|
||||
(string_content)))))
|
||||
(expression_statement
|
||||
(call_expression
|
||||
(identifier)
|
||||
(argument_list
|
||||
(identifier)
|
||||
(string_literal
|
||||
(string_content))
|
||||
(string_literal
|
||||
(string_content))))))
|
||||
@ -1,13 +0,0 @@
|
||||
============================================
|
||||
Line comments with escaped CRLF line endings
|
||||
============================================
|
||||
|
||||
// hello \
|
||||
this is still a comment
|
||||
this_is_not a_comment;
|
||||
|
||||
---
|
||||
|
||||
(translation_unit
|
||||
(comment)
|
||||
(declaration (type_identifier) (identifier)))
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,298 +0,0 @@
|
||||
================================
|
||||
declaration specs
|
||||
================================
|
||||
|
||||
struct __declspec(dllexport) s2
|
||||
{
|
||||
};
|
||||
|
||||
union __declspec(noinline) u2 {
|
||||
};
|
||||
|
||||
---
|
||||
|
||||
(translation_unit
|
||||
(struct_specifier
|
||||
(ms_declspec_modifier
|
||||
(identifier))
|
||||
name: (type_identifier)
|
||||
body: (field_declaration_list))
|
||||
(union_specifier
|
||||
(ms_declspec_modifier
|
||||
(identifier))
|
||||
name: (type_identifier)
|
||||
body: (field_declaration_list)))
|
||||
|
||||
================================
|
||||
pointers
|
||||
================================
|
||||
|
||||
struct s2
|
||||
{
|
||||
int * __restrict x;
|
||||
int * __sptr psp;
|
||||
int * __uptr pup;
|
||||
int * __unaligned pup;
|
||||
};
|
||||
|
||||
void sum2(int n, int * __restrict a, int * __restrict b,
|
||||
int * c, int * d) {
|
||||
int i;
|
||||
for (i = 0; i < n; i++) {
|
||||
a[i] = b[i] + c[i];
|
||||
c[i] = b[i] + d[i];
|
||||
}
|
||||
}
|
||||
|
||||
void MyFunction(char * __uptr myValue);
|
||||
|
||||
---
|
||||
|
||||
(translation_unit
|
||||
(struct_specifier
|
||||
name: (type_identifier)
|
||||
body: (field_declaration_list
|
||||
(field_declaration
|
||||
type: (primitive_type)
|
||||
declarator: (pointer_declarator
|
||||
(ms_pointer_modifier
|
||||
(ms_restrict_modifier))
|
||||
declarator: (field_identifier)))
|
||||
(field_declaration
|
||||
type: (primitive_type)
|
||||
declarator: (pointer_declarator
|
||||
(ms_pointer_modifier
|
||||
(ms_signed_ptr_modifier))
|
||||
declarator: (field_identifier)))
|
||||
(field_declaration
|
||||
type: (primitive_type)
|
||||
declarator: (pointer_declarator
|
||||
(ms_pointer_modifier
|
||||
(ms_unsigned_ptr_modifier))
|
||||
declarator: (field_identifier)))
|
||||
(field_declaration
|
||||
type: (primitive_type)
|
||||
declarator: (pointer_declarator
|
||||
(ms_pointer_modifier
|
||||
(ms_unaligned_ptr_modifier))
|
||||
declarator: (field_identifier)))))
|
||||
(function_definition
|
||||
type: (primitive_type)
|
||||
declarator: (function_declarator
|
||||
declarator: (identifier)
|
||||
parameters: (parameter_list
|
||||
(parameter_declaration
|
||||
type: (primitive_type)
|
||||
declarator: (identifier))
|
||||
(parameter_declaration
|
||||
type: (primitive_type)
|
||||
declarator: (pointer_declarator
|
||||
(ms_pointer_modifier
|
||||
(ms_restrict_modifier))
|
||||
declarator: (identifier)))
|
||||
(parameter_declaration
|
||||
type: (primitive_type)
|
||||
declarator: (pointer_declarator
|
||||
(ms_pointer_modifier
|
||||
(ms_restrict_modifier))
|
||||
declarator: (identifier)))
|
||||
(parameter_declaration
|
||||
type: (primitive_type)
|
||||
declarator: (pointer_declarator
|
||||
declarator: (identifier)))
|
||||
(parameter_declaration
|
||||
type: (primitive_type)
|
||||
declarator: (pointer_declarator
|
||||
declarator: (identifier)))))
|
||||
body: (compound_statement
|
||||
(declaration
|
||||
type: (primitive_type)
|
||||
declarator: (identifier))
|
||||
(for_statement
|
||||
initializer: (assignment_expression
|
||||
left: (identifier)
|
||||
right: (number_literal))
|
||||
condition: (binary_expression
|
||||
left: (identifier)
|
||||
right: (identifier))
|
||||
update: (update_expression
|
||||
argument: (identifier))
|
||||
body: (compound_statement
|
||||
(expression_statement
|
||||
(assignment_expression
|
||||
left: (subscript_expression
|
||||
argument: (identifier)
|
||||
index: (identifier))
|
||||
right: (binary_expression
|
||||
left: (subscript_expression
|
||||
argument: (identifier)
|
||||
index: (identifier))
|
||||
right: (subscript_expression
|
||||
argument: (identifier)
|
||||
index: (identifier)))))
|
||||
(expression_statement
|
||||
(assignment_expression
|
||||
left: (subscript_expression
|
||||
argument: (identifier)
|
||||
index: (identifier))
|
||||
right: (binary_expression
|
||||
left: (subscript_expression
|
||||
argument: (identifier)
|
||||
index: (identifier))
|
||||
right: (subscript_expression
|
||||
argument: (identifier)
|
||||
index: (identifier)))))))))
|
||||
(declaration
|
||||
type: (primitive_type)
|
||||
declarator: (function_declarator
|
||||
declarator: (identifier)
|
||||
parameters: (parameter_list
|
||||
(parameter_declaration
|
||||
type: (primitive_type)
|
||||
declarator: (pointer_declarator
|
||||
(ms_pointer_modifier
|
||||
(ms_unsigned_ptr_modifier))
|
||||
declarator: (identifier)))))))
|
||||
|
||||
================================
|
||||
call modifiers
|
||||
================================
|
||||
|
||||
__cdecl void mymethod(){
|
||||
return;
|
||||
}
|
||||
|
||||
__fastcall void mymethod(){
|
||||
return;
|
||||
}
|
||||
|
||||
void __stdcall f() { }
|
||||
|
||||
void (__stdcall g)() { }
|
||||
|
||||
void __stdcall h();
|
||||
|
||||
void (__stdcall j());
|
||||
|
||||
typedef void(__stdcall *fp)();
|
||||
|
||||
---
|
||||
|
||||
(translation_unit
|
||||
(function_definition
|
||||
(ms_call_modifier)
|
||||
type: (primitive_type)
|
||||
declarator: (function_declarator
|
||||
declarator: (identifier)
|
||||
parameters: (parameter_list))
|
||||
body: (compound_statement
|
||||
(return_statement)))
|
||||
(function_definition
|
||||
(ms_call_modifier)
|
||||
type: (primitive_type)
|
||||
declarator: (function_declarator
|
||||
declarator: (identifier)
|
||||
parameters: (parameter_list))
|
||||
body: (compound_statement
|
||||
(return_statement)))
|
||||
(function_definition
|
||||
type: (primitive_type)
|
||||
(ms_call_modifier)
|
||||
declarator: (function_declarator
|
||||
declarator: (identifier)
|
||||
parameters: (parameter_list))
|
||||
body: (compound_statement))
|
||||
(function_definition
|
||||
type: (primitive_type)
|
||||
declarator: (function_declarator
|
||||
declarator: (parenthesized_declarator
|
||||
(ms_call_modifier)
|
||||
(identifier))
|
||||
parameters: (parameter_list))
|
||||
body: (compound_statement))
|
||||
(declaration
|
||||
type: (primitive_type)
|
||||
declarator: (ms_call_modifier)
|
||||
declarator: (function_declarator
|
||||
declarator: (identifier)
|
||||
parameters: (parameter_list)))
|
||||
(declaration
|
||||
type: (primitive_type)
|
||||
declarator: (parenthesized_declarator
|
||||
(ms_call_modifier)
|
||||
(function_declarator
|
||||
declarator: (identifier)
|
||||
parameters: (parameter_list))))
|
||||
(type_definition
|
||||
type: (primitive_type)
|
||||
declarator: (function_declarator
|
||||
declarator: (parenthesized_declarator
|
||||
(ms_call_modifier)
|
||||
(pointer_declarator
|
||||
declarator: (type_identifier)))
|
||||
parameters: (parameter_list))))
|
||||
|
||||
================================
|
||||
SEH exception handling
|
||||
================================
|
||||
|
||||
int main() {
|
||||
int arg;
|
||||
__try {
|
||||
__try {
|
||||
arg = 1;
|
||||
__leave;
|
||||
} __except (-1) {
|
||||
arg = 2;
|
||||
}
|
||||
__leave;
|
||||
arg = 3;
|
||||
} __finally {
|
||||
printf("arg: %d\n", arg);
|
||||
}
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(translation_unit
|
||||
(function_definition
|
||||
(primitive_type)
|
||||
(function_declarator
|
||||
(identifier)
|
||||
(parameter_list))
|
||||
(compound_statement
|
||||
(declaration
|
||||
(primitive_type)
|
||||
(identifier))
|
||||
(seh_try_statement
|
||||
(compound_statement
|
||||
(seh_try_statement
|
||||
(compound_statement
|
||||
(expression_statement
|
||||
(assignment_expression
|
||||
(identifier)
|
||||
(number_literal)))
|
||||
(seh_leave_statement))
|
||||
(seh_except_clause
|
||||
(parenthesized_expression
|
||||
(number_literal))
|
||||
(compound_statement
|
||||
(expression_statement
|
||||
(assignment_expression
|
||||
(identifier)
|
||||
(number_literal))))))
|
||||
(seh_leave_statement)
|
||||
(expression_statement
|
||||
(assignment_expression
|
||||
(identifier)
|
||||
(number_literal))))
|
||||
(seh_finally_clause
|
||||
(compound_statement
|
||||
(expression_statement
|
||||
(call_expression
|
||||
(identifier)
|
||||
(argument_list
|
||||
(string_literal
|
||||
(string_content)
|
||||
(escape_sequence))
|
||||
(identifier))))))))))
|
||||
@ -1,449 +0,0 @@
|
||||
================================================================================
|
||||
Include directives
|
||||
================================================================================
|
||||
|
||||
#include "some/path.h"
|
||||
#include <stdint.h>
|
||||
#include MACRO
|
||||
#include MACRO(arg1, arg2)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(translation_unit
|
||||
(preproc_include
|
||||
path: (string_literal
|
||||
(string_content)))
|
||||
(preproc_include
|
||||
path: (system_lib_string))
|
||||
(preproc_include
|
||||
path: (identifier))
|
||||
(preproc_include
|
||||
path: (call_expression
|
||||
function: (identifier)
|
||||
arguments: (argument_list
|
||||
(identifier)
|
||||
(identifier)))))
|
||||
|
||||
================================================================================
|
||||
Object-like macro definitions
|
||||
================================================================================
|
||||
|
||||
#define ONE
|
||||
#define TWO int a = b;
|
||||
#define THREE \
|
||||
c == d ? \
|
||||
e : \
|
||||
f
|
||||
#define FOUR (mno * pq)
|
||||
#define FIVE(a,b) x \
|
||||
+ y
|
||||
#define SIX(a, \
|
||||
b) x \
|
||||
+ y
|
||||
#define SEVEN 7/* seven has an
|
||||
* annoying comment */
|
||||
#define EIGHT(x) do { \
|
||||
x = x + 1; \
|
||||
x = x / 2; \
|
||||
} while (x > 0);
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(translation_unit
|
||||
(preproc_def
|
||||
name: (identifier))
|
||||
(preproc_def
|
||||
name: (identifier)
|
||||
value: (preproc_arg))
|
||||
(preproc_def
|
||||
name: (identifier)
|
||||
value: (preproc_arg))
|
||||
(preproc_def
|
||||
name: (identifier)
|
||||
value: (preproc_arg))
|
||||
(preproc_function_def
|
||||
name: (identifier)
|
||||
parameters: (preproc_params
|
||||
(identifier)
|
||||
(identifier))
|
||||
value: (preproc_arg))
|
||||
(preproc_function_def
|
||||
name: (identifier)
|
||||
parameters: (preproc_params
|
||||
(identifier)
|
||||
(identifier))
|
||||
value: (preproc_arg))
|
||||
(preproc_def
|
||||
name: (identifier)
|
||||
value: (preproc_arg)
|
||||
(comment))
|
||||
(preproc_function_def
|
||||
name: (identifier)
|
||||
parameters: (preproc_params
|
||||
(identifier))
|
||||
value: (preproc_arg)))
|
||||
|
||||
================================================================================
|
||||
Function-like macro definitions
|
||||
================================================================================
|
||||
|
||||
#define ONE() a
|
||||
#define TWO(b) c
|
||||
#define THREE(d, e) f
|
||||
#define FOUR(...) g
|
||||
#define FIVE(h, i, ...) j
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(translation_unit
|
||||
(preproc_function_def
|
||||
name: (identifier)
|
||||
parameters: (preproc_params)
|
||||
value: (preproc_arg))
|
||||
(preproc_function_def
|
||||
name: (identifier)
|
||||
parameters: (preproc_params
|
||||
(identifier))
|
||||
value: (preproc_arg))
|
||||
(preproc_function_def
|
||||
name: (identifier)
|
||||
parameters: (preproc_params
|
||||
(identifier)
|
||||
(identifier))
|
||||
value: (preproc_arg))
|
||||
(preproc_function_def
|
||||
name: (identifier)
|
||||
parameters: (preproc_params)
|
||||
value: (preproc_arg))
|
||||
(preproc_function_def
|
||||
name: (identifier)
|
||||
parameters: (preproc_params
|
||||
(identifier)
|
||||
(identifier))
|
||||
value: (preproc_arg)))
|
||||
|
||||
================================================================================
|
||||
Ifdefs
|
||||
================================================================================
|
||||
|
||||
#ifndef DEFINE1
|
||||
int j;
|
||||
#endif
|
||||
|
||||
#ifdef DEFINE2
|
||||
ssize_t b;
|
||||
#define c 32
|
||||
#elif defined DEFINE3
|
||||
#else
|
||||
int b;
|
||||
#define c 16
|
||||
#endif
|
||||
|
||||
#ifdef DEFINE2
|
||||
#else
|
||||
# ifdef DEFINE3
|
||||
# else
|
||||
# endif
|
||||
#endif
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(translation_unit
|
||||
(preproc_ifdef
|
||||
name: (identifier)
|
||||
(declaration
|
||||
type: (primitive_type)
|
||||
declarator: (identifier)))
|
||||
(preproc_ifdef
|
||||
name: (identifier)
|
||||
(declaration
|
||||
type: (primitive_type)
|
||||
declarator: (identifier))
|
||||
(preproc_def
|
||||
name: (identifier)
|
||||
value: (preproc_arg))
|
||||
alternative: (preproc_elif
|
||||
condition: (preproc_defined
|
||||
(identifier))
|
||||
alternative: (preproc_else
|
||||
(declaration
|
||||
type: (primitive_type)
|
||||
declarator: (identifier))
|
||||
(preproc_def
|
||||
name: (identifier)
|
||||
value: (preproc_arg)))))
|
||||
(preproc_ifdef
|
||||
name: (identifier)
|
||||
alternative: (preproc_else
|
||||
(preproc_ifdef
|
||||
name: (identifier)
|
||||
alternative: (preproc_else)))))
|
||||
|
||||
================================================================================
|
||||
Elifdefs
|
||||
================================================================================
|
||||
|
||||
#ifndef DEFINE1
|
||||
int j;
|
||||
#elifndef DEFINE2
|
||||
int k;
|
||||
#endif
|
||||
|
||||
#ifdef DEFINE2
|
||||
ssize_t b;
|
||||
#elifdef DEFINE3
|
||||
ssize_t c;
|
||||
#else
|
||||
int b;
|
||||
#endif
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(translation_unit
|
||||
(preproc_ifdef
|
||||
(identifier)
|
||||
(declaration
|
||||
(primitive_type)
|
||||
(identifier))
|
||||
(preproc_elifdef
|
||||
(identifier)
|
||||
(declaration
|
||||
(primitive_type)
|
||||
(identifier))))
|
||||
(preproc_ifdef
|
||||
(identifier)
|
||||
(declaration
|
||||
(primitive_type)
|
||||
(identifier))
|
||||
(preproc_elifdef
|
||||
(identifier)
|
||||
(declaration
|
||||
(primitive_type)
|
||||
(identifier))
|
||||
(preproc_else
|
||||
(declaration
|
||||
(primitive_type)
|
||||
(identifier))))))
|
||||
|
||||
================================================================================
|
||||
Mixing #elif and #elifdef
|
||||
================================================================================
|
||||
|
||||
#ifndef DEFINE1
|
||||
int i;
|
||||
#elif defined(DEFINE2)
|
||||
int j;
|
||||
#endif
|
||||
|
||||
#if defined DEFINE3
|
||||
int a;
|
||||
#elifdef DEFINE4
|
||||
int b;
|
||||
#else
|
||||
int c;
|
||||
#endif
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(translation_unit
|
||||
(preproc_ifdef
|
||||
name: (identifier)
|
||||
(declaration
|
||||
type: (primitive_type)
|
||||
declarator: (identifier))
|
||||
alternative: (preproc_elif
|
||||
condition: (preproc_defined
|
||||
(identifier))
|
||||
(declaration
|
||||
type: (primitive_type)
|
||||
declarator: (identifier))))
|
||||
(preproc_if
|
||||
condition: (preproc_defined
|
||||
(identifier))
|
||||
(declaration
|
||||
type: (primitive_type)
|
||||
declarator: (identifier))
|
||||
alternative: (preproc_elifdef
|
||||
name: (identifier)
|
||||
(declaration
|
||||
type: (primitive_type)
|
||||
declarator: (identifier))
|
||||
alternative: (preproc_else
|
||||
(declaration
|
||||
type: (primitive_type)
|
||||
declarator: (identifier))))))
|
||||
|
||||
================================================================================
|
||||
General if blocks
|
||||
================================================================================
|
||||
|
||||
#if defined(__GNUC__) && defined(__PIC__)
|
||||
#define inline inline __attribute__((always_inline))
|
||||
#elif defined(_WIN32)
|
||||
#define something
|
||||
#elif !defined(SOMETHING_ELSE)
|
||||
#define SOMETHING_ELSE
|
||||
#else
|
||||
#include <something>
|
||||
#endif
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(translation_unit
|
||||
(preproc_if
|
||||
condition: (binary_expression
|
||||
left: (preproc_defined
|
||||
(identifier))
|
||||
right: (preproc_defined
|
||||
(identifier)))
|
||||
(preproc_def
|
||||
name: (identifier)
|
||||
value: (preproc_arg))
|
||||
alternative: (preproc_elif
|
||||
condition: (preproc_defined
|
||||
(identifier))
|
||||
(preproc_def
|
||||
name: (identifier))
|
||||
alternative: (preproc_elif
|
||||
condition: (unary_expression
|
||||
argument: (preproc_defined
|
||||
(identifier)))
|
||||
(preproc_def
|
||||
name: (identifier))
|
||||
alternative: (preproc_else
|
||||
(preproc_include
|
||||
path: (system_lib_string)))))))
|
||||
|
||||
================================================================================
|
||||
Preprocessor conditionals in functions
|
||||
================================================================================
|
||||
|
||||
int main() {
|
||||
#if d
|
||||
puts("1");
|
||||
#else
|
||||
puts("2");
|
||||
#endif
|
||||
|
||||
#if a
|
||||
return 0;
|
||||
#elif b
|
||||
return 1;
|
||||
#elif c
|
||||
return 2;
|
||||
#else
|
||||
return 3;
|
||||
#endif
|
||||
}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(translation_unit
|
||||
(function_definition
|
||||
(primitive_type)
|
||||
(function_declarator
|
||||
(identifier)
|
||||
(parameter_list))
|
||||
(compound_statement
|
||||
(preproc_if
|
||||
(identifier)
|
||||
(expression_statement
|
||||
(call_expression
|
||||
(identifier)
|
||||
(argument_list
|
||||
(string_literal
|
||||
(string_content)))))
|
||||
(preproc_else
|
||||
(expression_statement
|
||||
(call_expression
|
||||
(identifier)
|
||||
(argument_list
|
||||
(string_literal
|
||||
(string_content)))))))
|
||||
(preproc_if
|
||||
(identifier)
|
||||
(return_statement
|
||||
(number_literal))
|
||||
(preproc_elif
|
||||
(identifier)
|
||||
(return_statement
|
||||
(number_literal))
|
||||
(preproc_elif
|
||||
(identifier)
|
||||
(return_statement
|
||||
(number_literal))
|
||||
(preproc_else
|
||||
(return_statement
|
||||
(number_literal)))))))))
|
||||
|
||||
================================================================================
|
||||
Preprocessor conditionals in struct/union bodies
|
||||
================================================================================
|
||||
|
||||
struct S {
|
||||
#ifdef _WIN32
|
||||
LONG f2;
|
||||
#else
|
||||
uint32_t f2;
|
||||
#endif
|
||||
};
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(translation_unit
|
||||
(struct_specifier
|
||||
(type_identifier)
|
||||
(field_declaration_list
|
||||
(preproc_ifdef
|
||||
(identifier)
|
||||
(field_declaration
|
||||
(type_identifier)
|
||||
(field_identifier))
|
||||
(preproc_else
|
||||
(field_declaration
|
||||
(primitive_type)
|
||||
(field_identifier)))))))
|
||||
|
||||
================================================================================
|
||||
Unknown preprocessor directives
|
||||
================================================================================
|
||||
|
||||
#pragma mark - UIViewController
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(translation_unit
|
||||
(preproc_call
|
||||
directive: (preproc_directive)
|
||||
argument: (preproc_arg)))
|
||||
|
||||
================================================================================
|
||||
Preprocessor expressions
|
||||
================================================================================
|
||||
|
||||
#if A(B || C) && \
|
||||
!D(F)
|
||||
|
||||
uint32_t a;
|
||||
|
||||
#endif
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(translation_unit
|
||||
(preproc_if
|
||||
(binary_expression
|
||||
(call_expression
|
||||
(identifier)
|
||||
(argument_list
|
||||
(binary_expression
|
||||
(identifier)
|
||||
(identifier))))
|
||||
(unary_expression
|
||||
(call_expression
|
||||
(identifier)
|
||||
(argument_list
|
||||
(identifier)))))
|
||||
(declaration
|
||||
(primitive_type)
|
||||
(identifier))))
|
||||
@ -1,535 +0,0 @@
|
||||
================================================================================
|
||||
If statements
|
||||
================================================================================
|
||||
|
||||
int main() {
|
||||
if (a)
|
||||
1;
|
||||
|
||||
if (!a) {
|
||||
2;
|
||||
} else {
|
||||
3;
|
||||
}
|
||||
}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(translation_unit
|
||||
(function_definition
|
||||
(primitive_type)
|
||||
(function_declarator
|
||||
(identifier)
|
||||
(parameter_list))
|
||||
(compound_statement
|
||||
(if_statement
|
||||
(parenthesized_expression
|
||||
(identifier))
|
||||
(expression_statement
|
||||
(number_literal)))
|
||||
(if_statement
|
||||
(parenthesized_expression
|
||||
(unary_expression
|
||||
(identifier)))
|
||||
(compound_statement
|
||||
(expression_statement
|
||||
(number_literal)))
|
||||
(else_clause
|
||||
(compound_statement
|
||||
(expression_statement
|
||||
(number_literal))))))))
|
||||
|
||||
================================================================================
|
||||
For loops
|
||||
================================================================================
|
||||
|
||||
int main() {
|
||||
for (;;)
|
||||
1;
|
||||
|
||||
for (int i = 0; i < 5; next(), i++) {
|
||||
2;
|
||||
}
|
||||
|
||||
for (start(); check(); step())
|
||||
3;
|
||||
|
||||
for (i = 0, j = 0, k = 0, l = 0; i < 1, j < 1; i++, j++, k++, l++)
|
||||
1;
|
||||
}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(translation_unit
|
||||
(function_definition
|
||||
(primitive_type)
|
||||
(function_declarator
|
||||
(identifier)
|
||||
(parameter_list))
|
||||
(compound_statement
|
||||
(for_statement
|
||||
(expression_statement
|
||||
(number_literal)))
|
||||
(for_statement
|
||||
(declaration
|
||||
(primitive_type)
|
||||
(init_declarator
|
||||
(identifier)
|
||||
(number_literal)))
|
||||
(binary_expression
|
||||
(identifier)
|
||||
(number_literal))
|
||||
(comma_expression
|
||||
(call_expression
|
||||
(identifier)
|
||||
(argument_list))
|
||||
(update_expression
|
||||
(identifier)))
|
||||
(compound_statement
|
||||
(expression_statement
|
||||
(number_literal))))
|
||||
(for_statement
|
||||
(call_expression
|
||||
(identifier)
|
||||
(argument_list))
|
||||
(call_expression
|
||||
(identifier)
|
||||
(argument_list))
|
||||
(call_expression
|
||||
(identifier)
|
||||
(argument_list))
|
||||
(expression_statement
|
||||
(number_literal)))
|
||||
(for_statement
|
||||
(comma_expression
|
||||
(assignment_expression
|
||||
(identifier)
|
||||
(number_literal))
|
||||
(comma_expression
|
||||
(assignment_expression
|
||||
(identifier)
|
||||
(number_literal))
|
||||
(comma_expression
|
||||
(assignment_expression
|
||||
(identifier)
|
||||
(number_literal))
|
||||
(assignment_expression
|
||||
(identifier)
|
||||
(number_literal)))))
|
||||
(comma_expression
|
||||
(binary_expression
|
||||
(identifier)
|
||||
(number_literal))
|
||||
(binary_expression
|
||||
(identifier)
|
||||
(number_literal)))
|
||||
(comma_expression
|
||||
(update_expression
|
||||
(identifier))
|
||||
(comma_expression
|
||||
(update_expression
|
||||
(identifier))
|
||||
(comma_expression
|
||||
(update_expression
|
||||
(identifier))
|
||||
(update_expression
|
||||
(identifier)))))
|
||||
(expression_statement
|
||||
(number_literal))))))
|
||||
|
||||
================================================================================
|
||||
While loops
|
||||
================================================================================
|
||||
|
||||
int main() {
|
||||
while (x)
|
||||
printf("hi");
|
||||
}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(translation_unit
|
||||
(function_definition
|
||||
(primitive_type)
|
||||
(function_declarator
|
||||
(identifier)
|
||||
(parameter_list))
|
||||
(compound_statement
|
||||
(while_statement
|
||||
(parenthesized_expression
|
||||
(identifier))
|
||||
(expression_statement
|
||||
(call_expression
|
||||
(identifier)
|
||||
(argument_list
|
||||
(string_literal
|
||||
(string_content)))))))))
|
||||
|
||||
================================================================================
|
||||
Labeled statements
|
||||
================================================================================
|
||||
|
||||
void foo(T *t) {
|
||||
recur:
|
||||
t = t->next();
|
||||
if (t) goto recur;
|
||||
}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(translation_unit
|
||||
(function_definition
|
||||
(primitive_type)
|
||||
(function_declarator
|
||||
(identifier)
|
||||
(parameter_list
|
||||
(parameter_declaration
|
||||
(type_identifier)
|
||||
(pointer_declarator
|
||||
(identifier)))))
|
||||
(compound_statement
|
||||
(labeled_statement
|
||||
(statement_identifier)
|
||||
(expression_statement
|
||||
(assignment_expression
|
||||
(identifier)
|
||||
(call_expression
|
||||
(field_expression
|
||||
(identifier)
|
||||
(field_identifier))
|
||||
(argument_list)))))
|
||||
(if_statement
|
||||
(parenthesized_expression
|
||||
(identifier))
|
||||
(goto_statement
|
||||
(statement_identifier))))))
|
||||
|
||||
================================================================================
|
||||
Switch statements
|
||||
================================================================================
|
||||
|
||||
void foo(int a) {
|
||||
switch (a) {
|
||||
puts("entered switch!");
|
||||
|
||||
case 3:
|
||||
case 5:
|
||||
if (b) {
|
||||
c();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
c();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(translation_unit
|
||||
(function_definition
|
||||
(primitive_type)
|
||||
(function_declarator
|
||||
(identifier)
|
||||
(parameter_list
|
||||
(parameter_declaration
|
||||
(primitive_type)
|
||||
(identifier))))
|
||||
(compound_statement
|
||||
(switch_statement
|
||||
(parenthesized_expression
|
||||
(identifier))
|
||||
(compound_statement
|
||||
(expression_statement
|
||||
(call_expression
|
||||
(identifier)
|
||||
(argument_list
|
||||
(string_literal
|
||||
(string_content)))))
|
||||
(case_statement
|
||||
(number_literal))
|
||||
(case_statement
|
||||
(number_literal)
|
||||
(if_statement
|
||||
(parenthesized_expression
|
||||
(identifier))
|
||||
(compound_statement
|
||||
(expression_statement
|
||||
(call_expression
|
||||
(identifier)
|
||||
(argument_list)))))
|
||||
(break_statement))
|
||||
(case_statement
|
||||
(expression_statement
|
||||
(call_expression
|
||||
(identifier)
|
||||
(argument_list)))
|
||||
(break_statement)))))))
|
||||
|
||||
================================================================================
|
||||
Case statements separate from switch statements
|
||||
================================================================================
|
||||
|
||||
int main() {
|
||||
switch (count % 8) {
|
||||
case 0:
|
||||
do {
|
||||
*to = *from++;
|
||||
case 2: *to = *from++;
|
||||
case 1: *to = *from++;
|
||||
} while (--n > 0);
|
||||
}
|
||||
}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(translation_unit
|
||||
(function_definition
|
||||
(primitive_type)
|
||||
(function_declarator
|
||||
(identifier)
|
||||
(parameter_list))
|
||||
(compound_statement
|
||||
(switch_statement
|
||||
(parenthesized_expression
|
||||
(binary_expression
|
||||
(identifier)
|
||||
(number_literal)))
|
||||
(compound_statement
|
||||
(case_statement
|
||||
(number_literal)
|
||||
(do_statement
|
||||
(compound_statement
|
||||
(expression_statement
|
||||
(assignment_expression
|
||||
(pointer_expression
|
||||
(identifier))
|
||||
(pointer_expression
|
||||
(update_expression
|
||||
(identifier)))))
|
||||
(case_statement
|
||||
(number_literal)
|
||||
(expression_statement
|
||||
(assignment_expression
|
||||
(pointer_expression
|
||||
(identifier))
|
||||
(pointer_expression
|
||||
(update_expression
|
||||
(identifier))))))
|
||||
(case_statement
|
||||
(number_literal)
|
||||
(expression_statement
|
||||
(assignment_expression
|
||||
(pointer_expression
|
||||
(identifier))
|
||||
(pointer_expression
|
||||
(update_expression
|
||||
(identifier)))))))
|
||||
(parenthesized_expression
|
||||
(binary_expression
|
||||
(update_expression
|
||||
(identifier))
|
||||
(number_literal))))))))))
|
||||
|
||||
================================================================================
|
||||
Return statements
|
||||
================================================================================
|
||||
|
||||
void foo() {
|
||||
return;
|
||||
return a;
|
||||
return a, b;
|
||||
}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(translation_unit
|
||||
(function_definition
|
||||
(primitive_type)
|
||||
(function_declarator
|
||||
(identifier)
|
||||
(parameter_list))
|
||||
(compound_statement
|
||||
(return_statement)
|
||||
(return_statement
|
||||
(identifier))
|
||||
(return_statement
|
||||
(comma_expression
|
||||
(identifier)
|
||||
(identifier))))))
|
||||
|
||||
================================================================================
|
||||
Comments with asterisks
|
||||
================================================================================
|
||||
|
||||
/*************************
|
||||
* odd number of asterisks
|
||||
*************************/
|
||||
int a;
|
||||
|
||||
/**************************
|
||||
* even number of asterisks
|
||||
**************************/
|
||||
int b;
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(translation_unit
|
||||
(comment)
|
||||
(declaration
|
||||
(primitive_type)
|
||||
(identifier))
|
||||
(comment)
|
||||
(declaration
|
||||
(primitive_type)
|
||||
(identifier)))
|
||||
|
||||
================================================================================
|
||||
Comment with multiple backslashes
|
||||
================================================================================
|
||||
|
||||
int a = 3; // Hello \\
|
||||
World
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(translation_unit
|
||||
(declaration
|
||||
(primitive_type)
|
||||
(init_declarator
|
||||
(identifier)
|
||||
(number_literal)))
|
||||
(comment))
|
||||
|
||||
================================================================================
|
||||
Attributes
|
||||
================================================================================
|
||||
|
||||
void f() {
|
||||
[[a]] switch (b) {
|
||||
[[c]] case 1: {}
|
||||
case 2:
|
||||
[[fallthrough]];
|
||||
default:
|
||||
}
|
||||
[[a]] while (true) {}
|
||||
[[a]] if (true) {}
|
||||
[[a]] for (;;) {}
|
||||
[[a]] return;
|
||||
[[a]] a;
|
||||
[[a]];
|
||||
[[a]] label: {}
|
||||
[[a]] goto label;
|
||||
|
||||
// these are c++ specific, but their bind locations should be c-compatible
|
||||
if (true) [[likely]] {} else [[unlikely]] {}
|
||||
do [[likely]] {} while (true);
|
||||
}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(translation_unit
|
||||
(function_definition
|
||||
(primitive_type)
|
||||
(function_declarator
|
||||
(identifier)
|
||||
(parameter_list))
|
||||
(compound_statement
|
||||
(attributed_statement
|
||||
(attribute_declaration
|
||||
(attribute
|
||||
(identifier)))
|
||||
(switch_statement
|
||||
(parenthesized_expression
|
||||
(identifier))
|
||||
(compound_statement
|
||||
(attributed_statement
|
||||
(attribute_declaration
|
||||
(attribute
|
||||
(identifier)))
|
||||
(case_statement
|
||||
(number_literal)
|
||||
(compound_statement)))
|
||||
(case_statement
|
||||
(number_literal)
|
||||
(attributed_statement
|
||||
(attribute_declaration
|
||||
(attribute
|
||||
(identifier)))
|
||||
(expression_statement)))
|
||||
(case_statement))))
|
||||
(attributed_statement
|
||||
(attribute_declaration
|
||||
(attribute
|
||||
(identifier)))
|
||||
(while_statement
|
||||
(parenthesized_expression
|
||||
(true))
|
||||
(compound_statement)))
|
||||
(attributed_statement
|
||||
(attribute_declaration
|
||||
(attribute
|
||||
(identifier)))
|
||||
(if_statement
|
||||
(parenthesized_expression
|
||||
(true))
|
||||
(compound_statement)))
|
||||
(attributed_statement
|
||||
(attribute_declaration
|
||||
(attribute
|
||||
(identifier)))
|
||||
(for_statement
|
||||
(compound_statement)))
|
||||
(attributed_statement
|
||||
(attribute_declaration
|
||||
(attribute
|
||||
(identifier)))
|
||||
(return_statement))
|
||||
(attributed_statement
|
||||
(attribute_declaration
|
||||
(attribute
|
||||
(identifier)))
|
||||
(expression_statement
|
||||
(identifier)))
|
||||
(attributed_statement
|
||||
(attribute_declaration
|
||||
(attribute
|
||||
(identifier)))
|
||||
(expression_statement))
|
||||
(attributed_statement
|
||||
(attribute_declaration
|
||||
(attribute
|
||||
(identifier)))
|
||||
(labeled_statement
|
||||
(statement_identifier)
|
||||
(compound_statement)))
|
||||
(attributed_statement
|
||||
(attribute_declaration
|
||||
(attribute
|
||||
(identifier)))
|
||||
(goto_statement
|
||||
(statement_identifier)))
|
||||
(comment)
|
||||
(if_statement
|
||||
(parenthesized_expression
|
||||
(true))
|
||||
(attributed_statement
|
||||
(attribute_declaration
|
||||
(attribute
|
||||
(identifier)))
|
||||
(compound_statement))
|
||||
(else_clause
|
||||
(attributed_statement
|
||||
(attribute_declaration
|
||||
(attribute
|
||||
(identifier)))
|
||||
(compound_statement))))
|
||||
(do_statement
|
||||
(attributed_statement
|
||||
(attribute_declaration
|
||||
(attribute
|
||||
(identifier)))
|
||||
(compound_statement))
|
||||
(parenthesized_expression
|
||||
(true))))))
|
||||
@ -1,80 +0,0 @@
|
||||
========================================
|
||||
Primitive types
|
||||
========================================
|
||||
|
||||
int a;
|
||||
uint8_t a;
|
||||
uint16_t a;
|
||||
uint32_t a;
|
||||
uint64_t a;
|
||||
uintptr_t a;
|
||||
|
||||
int8_t a;
|
||||
int16_t a;
|
||||
int32_t a;
|
||||
int64_t a;
|
||||
intptr_t a;
|
||||
|
||||
char16_t a;
|
||||
char32_t a;
|
||||
|
||||
size_t a;
|
||||
ssize_t a;
|
||||
|
||||
---
|
||||
|
||||
(translation_unit
|
||||
(declaration (primitive_type) (identifier))
|
||||
(declaration (primitive_type) (identifier))
|
||||
(declaration (primitive_type) (identifier))
|
||||
(declaration (primitive_type) (identifier))
|
||||
(declaration (primitive_type) (identifier))
|
||||
(declaration (primitive_type) (identifier))
|
||||
(declaration (primitive_type) (identifier))
|
||||
(declaration (primitive_type) (identifier))
|
||||
(declaration (primitive_type) (identifier))
|
||||
(declaration (primitive_type) (identifier))
|
||||
(declaration (primitive_type) (identifier))
|
||||
(declaration (primitive_type) (identifier))
|
||||
(declaration (primitive_type) (identifier))
|
||||
(declaration (primitive_type) (identifier))
|
||||
(declaration (primitive_type) (identifier)))
|
||||
|
||||
========================================
|
||||
Type modifiers
|
||||
========================================
|
||||
|
||||
void f(unsigned);
|
||||
void f(unsigned int);
|
||||
void f(signed long int);
|
||||
void f(unsigned v1);
|
||||
void f(unsigned long v2);
|
||||
|
||||
---
|
||||
|
||||
(translation_unit
|
||||
(declaration
|
||||
(primitive_type)
|
||||
(function_declarator
|
||||
(identifier)
|
||||
(parameter_list (parameter_declaration (sized_type_specifier)))))
|
||||
(declaration
|
||||
(primitive_type)
|
||||
(function_declarator
|
||||
(identifier)
|
||||
(parameter_list (parameter_declaration (sized_type_specifier (primitive_type))))))
|
||||
(declaration
|
||||
(primitive_type)
|
||||
(function_declarator
|
||||
(identifier)
|
||||
(parameter_list (parameter_declaration (sized_type_specifier (primitive_type))))))
|
||||
(declaration
|
||||
(primitive_type)
|
||||
(function_declarator
|
||||
(identifier)
|
||||
(parameter_list (parameter_declaration (sized_type_specifier) (identifier)))))
|
||||
(declaration
|
||||
(primitive_type)
|
||||
(function_declarator
|
||||
(identifier)
|
||||
(parameter_list (parameter_declaration (sized_type_specifier) (identifier))))))
|
||||
@ -1,6 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
// ^ keyword
|
||||
// ^ string
|
||||
|
||||
#include "something.h"
|
||||
// ^ string
|
||||
@ -1,33 +0,0 @@
|
||||
typedef struct {
|
||||
// ^ keyword
|
||||
// ^ keyword
|
||||
a_t b;
|
||||
// <- type
|
||||
// ^ property
|
||||
|
||||
unsigned c_t (*d)[2];
|
||||
// ^ type
|
||||
// ^ type
|
||||
// ^ property
|
||||
}, T, V;
|
||||
// ^ type
|
||||
// ^ type
|
||||
|
||||
int main(const char string[SIZE]) {
|
||||
// <- type
|
||||
// ^ function
|
||||
// ^ keyword
|
||||
// ^ type
|
||||
// ^ variable
|
||||
// ^ constant
|
||||
|
||||
return foo.bar + foo.baz();
|
||||
// ^ keyword
|
||||
// ^ variable
|
||||
// ^ property
|
||||
// ^ function
|
||||
|
||||
error:
|
||||
// <- label
|
||||
return 0;
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
tree-sitter-cpp/src
|
||||
@ -1,39 +0,0 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.{json,toml,yml,gyp}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.js]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.rs]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.{c,cc,h}]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.{py,pyi}]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.swift]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.go]
|
||||
indent_style = tab
|
||||
indent_size = 8
|
||||
|
||||
[Makefile]
|
||||
indent_style = tab
|
||||
indent_size = 8
|
||||
@ -1,14 +0,0 @@
|
||||
* text eol=lf
|
||||
test/corpus/c/crlf.txt text eol=crlf
|
||||
|
||||
examples/* linguist-vendored
|
||||
|
||||
src/*.json linguist-generated
|
||||
src/parser.c linguist-generated
|
||||
src/tree_sitter/* linguist-generated
|
||||
|
||||
bindings/** linguist-generated
|
||||
binding.gyp linguist-generated
|
||||
setup.py linguist-generated
|
||||
Makefile linguist-generated
|
||||
Package.swift linguist-generated
|
||||
@ -1,59 +0,0 @@
|
||||
name: Bug Report
|
||||
description: File a bug or issue
|
||||
title: "bug: "
|
||||
labels: [bug]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
**Before** reporting an issue, make sure to search [existing issues](https://github.com/tree-sitter/tree-sitter-cpp/issues). Usage questions such as ***"How do I...?"*** either belong in [Discussions](https://github.com/tree-sitter/tree-sitter/discussions) upstream or in our [Discord server](https://discord.gg/w7nTvsVJhm) and will be closed.
|
||||
If your issue is related to a bug in your editor-experience because your editor *leverages* tree-sitter and this parser, then it is likely your issue does *NOT* belong here and belongs in the relevant editor's repository.
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Did you check existing issues?
|
||||
description: Make sure you've checked all of the below before submitting an issue
|
||||
options:
|
||||
- label: I have read all the [tree-sitter docs](https://tree-sitter.github.io/tree-sitter/using-parsers) if it relates to using the parser
|
||||
required: false
|
||||
- label: I have searched the existing issues of tree-sitter-cpp
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: "Tree-Sitter CLI Version, if relevant (output of `tree-sitter --version`)"
|
||||
placeholder: "tree-sitter 0.20.8 (6bbb50bef8249e6460e7d69e42cc8146622fa4fd)"
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe the bug
|
||||
description: A clear and concise description of what the bug is. Please include any related errors you see such as parsing errors or tree-sitter cli errors.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Steps To Reproduce/Bad Parse Tree
|
||||
description: Steps to reproduce the behavior. If you have a bad parse tree, please include it here. You can get this by running `tree-sitter parse <path-to-file>` and copying the output.
|
||||
placeholder: |
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Expected Behavior/Parse Tree
|
||||
description: A concise description of what you expected to happen, or in the case of a bad parse tree, the expected parse tree.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Repro
|
||||
description: Minimal code to reproduce this issue. Ideally this should be reproducible with the C library or the tree-sitter cli, do not suggest an editor or external tool.
|
||||
value: |
|
||||
// Example code that causes the issue
|
||||
void foo() {
|
||||
// Code that fails to parse, or causes an error
|
||||
}
|
||||
render: cpp
|
||||
validations:
|
||||
required: false
|
||||
@ -1 +0,0 @@
|
||||
blank_issues_enabled: false
|
||||
@ -1,36 +0,0 @@
|
||||
name: Feature Request
|
||||
description: Suggest a new feature
|
||||
title: "feature: "
|
||||
labels: [enhancement]
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Did you check the tree-sitter docs?
|
||||
description: Make sure you read all the docs before submitting a feature request
|
||||
options:
|
||||
- label: I have read all the [tree-sitter docs](https://tree-sitter.github.io/tree-sitter/using-parsers) if it relates to using the parser
|
||||
required: false
|
||||
- type: textarea
|
||||
validations:
|
||||
required: true
|
||||
attributes:
|
||||
label: Is your feature request related to a problem? Please describe.
|
||||
description: A clear and concise description of what the problem is. Ex. I think the grammar models this rule incorrectly and can be improved, or the scanner can be improved by doing [...], or C++ has officially added a new feature that should be added to the grammar.
|
||||
- type: textarea
|
||||
validations:
|
||||
required: true
|
||||
attributes:
|
||||
label: Describe the solution you'd like
|
||||
description: A clear and concise description of what you want to happen.
|
||||
- type: textarea
|
||||
validations:
|
||||
required: true
|
||||
attributes:
|
||||
label: Describe alternatives you've considered
|
||||
description: A clear and concise description of any alternative solutions or features you've considered.
|
||||
- type: textarea
|
||||
validations:
|
||||
required: false
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Add any other context or screenshots about the feature request here. If your feature request is related to a new C++ feature, please include a link to the relevant **official** C++ documentation.
|
||||
@ -1,8 +0,0 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
commit-message:
|
||||
prefix: "ci"
|
||||
@ -1,51 +0,0 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
paths:
|
||||
- grammar.js
|
||||
- src/**
|
||||
- test/**
|
||||
- bindings/**
|
||||
- binding.gyp
|
||||
pull_request:
|
||||
paths:
|
||||
- grammar.js
|
||||
- src/**
|
||||
- test/**
|
||||
- bindings/**
|
||||
- binding.gyp
|
||||
|
||||
concurrency:
|
||||
group: ${{github.workflow}}-${{github.ref}}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: Test parser
|
||||
runs-on: ${{matrix.os}}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-14]
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Checkout tree-sitter-c
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: tree-sitter/tree-sitter-c
|
||||
path: node_modules/tree-sitter-c
|
||||
sparse-checkout: queries/
|
||||
ref: v0.21.0
|
||||
- name: Set up tree-sitter
|
||||
uses: tree-sitter/setup-action/cli@v1
|
||||
- name: Run tests
|
||||
uses: tree-sitter/parser-test-action@v2
|
||||
with:
|
||||
test-rust: ${{runner.os == 'Linux'}}
|
||||
- name: Parse examples
|
||||
uses: tree-sitter/parse-action@v4
|
||||
with:
|
||||
files: examples/*
|
||||
@ -1,21 +0,0 @@
|
||||
name: Fuzz Parser
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
paths:
|
||||
- src/scanner.c
|
||||
pull_request:
|
||||
paths:
|
||||
- src/scanner.c
|
||||
|
||||
jobs:
|
||||
fuzz:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Run fuzzer
|
||||
uses: tree-sitter/fuzz-action@v4
|
||||
with:
|
||||
tree-sitter-version: v0.22.2
|
||||
@ -1,26 +0,0 @@
|
||||
name: Lint
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
paths:
|
||||
- grammar.js
|
||||
pull_request:
|
||||
paths:
|
||||
- grammar.js
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: npm
|
||||
node-version: ${{vars.NODE_VERSION}}
|
||||
- name: Install modules
|
||||
run: npm ci --legacy-peer-deps
|
||||
- name: Run ESLint
|
||||
run: npm run lint
|
||||
@ -1,23 +0,0 @@
|
||||
name: Publish packages
|
||||
|
||||
on:
|
||||
push:
|
||||
tags: ["*"]
|
||||
|
||||
concurrency:
|
||||
group: ${{github.workflow}}-${{github.ref}}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
npm:
|
||||
uses: tree-sitter/workflows/.github/workflows/package-npm.yml@main
|
||||
secrets:
|
||||
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
|
||||
crates:
|
||||
uses: tree-sitter/workflows/.github/workflows/package-crates.yml@main
|
||||
secrets:
|
||||
CARGO_REGISTRY_TOKEN: ${{secrets.CARGO_REGISTRY_TOKEN}}
|
||||
pypi:
|
||||
uses: tree-sitter/workflows/.github/workflows/package-pypi.yml@main
|
||||
secrets:
|
||||
PYPI_API_TOKEN: ${{secrets.PYPI_API_TOKEN}}
|
||||
@ -1,38 +0,0 @@
|
||||
# Rust artifacts
|
||||
Cargo.lock
|
||||
target/
|
||||
|
||||
# Node artifacts
|
||||
build/
|
||||
prebuilds/
|
||||
node_modules/
|
||||
*.tgz
|
||||
|
||||
# Swift artifacts
|
||||
.build/
|
||||
|
||||
# Go artifacts
|
||||
go.sum
|
||||
_obj/
|
||||
|
||||
# Python artifacts
|
||||
.venv/
|
||||
dist/
|
||||
*.egg-info
|
||||
*.whl
|
||||
|
||||
# C artifacts
|
||||
*.a
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
*.dll
|
||||
*.pc
|
||||
|
||||
# Example dirs
|
||||
/examples/*/
|
||||
|
||||
# Grammar volatiles
|
||||
*.wasm
|
||||
*.obj
|
||||
*.o
|
||||
@ -1,26 +0,0 @@
|
||||
[package]
|
||||
name = "tree-sitter-cpp"
|
||||
description = "C++ grammar for tree-sitter"
|
||||
version = "0.22.0"
|
||||
authors = [
|
||||
"Max Brunsfeld <maxbrunsfeld@gmail.com>",
|
||||
"Amaan Qureshi <amaanq12@gmail.com>",
|
||||
]
|
||||
license = "MIT"
|
||||
keywords = ["incremental", "parsing", "tree-sitter", "cpp"]
|
||||
categories = ["parsing", "text-editors"]
|
||||
repository = "https://github.com/tree-sitter/tree-sitter-cpp"
|
||||
edition = "2021"
|
||||
autoexamples = false
|
||||
|
||||
build = "bindings/rust/build.rs"
|
||||
include = ["bindings/rust/*", "grammar.js", "queries/*", "src/*"]
|
||||
|
||||
[lib]
|
||||
path = "bindings/rust/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
tree-sitter = ">=0.21.0"
|
||||
|
||||
[build-dependencies]
|
||||
cc = "1.0.94"
|
||||
@ -1,21 +0,0 @@
|
||||
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.
|
||||
@ -1,111 +0,0 @@
|
||||
VERSION := 0.22.0
|
||||
|
||||
LANGUAGE_NAME := tree-sitter-cpp
|
||||
|
||||
# repository
|
||||
SRC_DIR := src
|
||||
|
||||
PARSER_REPO_URL := $(shell git -C $(SRC_DIR) remote get-url origin 2>/dev/null)
|
||||
|
||||
ifeq ($(PARSER_URL),)
|
||||
PARSER_URL := $(subst .git,,$(PARSER_REPO_URL))
|
||||
ifeq ($(shell echo $(PARSER_URL) | grep '^[a-z][-+.0-9a-z]*://'),)
|
||||
PARSER_URL := $(subst :,/,$(PARSER_URL))
|
||||
PARSER_URL := $(subst git@,https://,$(PARSER_URL))
|
||||
endif
|
||||
endif
|
||||
|
||||
TS ?= tree-sitter
|
||||
|
||||
# ABI versioning
|
||||
SONAME_MAJOR := $(word 1,$(subst ., ,$(VERSION)))
|
||||
SONAME_MINOR := $(word 2,$(subst ., ,$(VERSION)))
|
||||
|
||||
# install directory layout
|
||||
PREFIX ?= /usr/local
|
||||
INCLUDEDIR ?= $(PREFIX)/include
|
||||
LIBDIR ?= $(PREFIX)/lib
|
||||
PCLIBDIR ?= $(LIBDIR)/pkgconfig
|
||||
|
||||
# object files
|
||||
OBJS := $(patsubst %.c,%.o,$(wildcard $(SRC_DIR)/*.c))
|
||||
|
||||
# flags
|
||||
ARFLAGS := rcs
|
||||
override CFLAGS += -I$(SRC_DIR) -std=c11 -fPIC
|
||||
|
||||
# OS-specific bits
|
||||
ifeq ($(OS),Windows_NT)
|
||||
$(error "Windows is not supported")
|
||||
else ifeq ($(shell uname),Darwin)
|
||||
SOEXT = dylib
|
||||
SOEXTVER_MAJOR = $(SONAME_MAJOR).dylib
|
||||
SOEXTVER = $(SONAME_MAJOR).$(SONAME_MINOR).dylib
|
||||
LINKSHARED := $(LINKSHARED)-dynamiclib -Wl,
|
||||
ifneq ($(ADDITIONAL_LIBS),)
|
||||
LINKSHARED := $(LINKSHARED)$(ADDITIONAL_LIBS),
|
||||
endif
|
||||
LINKSHARED := $(LINKSHARED)-install_name,$(LIBDIR)/lib$(LANGUAGE_NAME).$(SONAME_MAJOR).dylib,-rpath,@executable_path/../Frameworks
|
||||
else
|
||||
SOEXT = so
|
||||
SOEXTVER_MAJOR = so.$(SONAME_MAJOR)
|
||||
SOEXTVER = so.$(SONAME_MAJOR).$(SONAME_MINOR)
|
||||
LINKSHARED := $(LINKSHARED)-shared -Wl,
|
||||
ifneq ($(ADDITIONAL_LIBS),)
|
||||
LINKSHARED := $(LINKSHARED)$(ADDITIONAL_LIBS)
|
||||
endif
|
||||
LINKSHARED := $(LINKSHARED)-soname,lib$(LANGUAGE_NAME).so.$(SONAME_MAJOR)
|
||||
endif
|
||||
ifneq ($(filter $(shell uname),FreeBSD NetBSD DragonFly),)
|
||||
PCLIBDIR := $(PREFIX)/libdata/pkgconfig
|
||||
endif
|
||||
|
||||
all: lib$(LANGUAGE_NAME).a lib$(LANGUAGE_NAME).$(SOEXT) $(LANGUAGE_NAME).pc
|
||||
|
||||
lib$(LANGUAGE_NAME).a: $(OBJS)
|
||||
$(AR) $(ARFLAGS) $@ $^
|
||||
|
||||
lib$(LANGUAGE_NAME).$(SOEXT): $(OBJS)
|
||||
$(CC) $(LDFLAGS) $(LINKSHARED) $^ $(LDLIBS) -o $@
|
||||
ifneq ($(STRIP),)
|
||||
$(STRIP) $@
|
||||
endif
|
||||
|
||||
$(LANGUAGE_NAME).pc: bindings/c/$(LANGUAGE_NAME).pc.in
|
||||
sed -e 's|@URL@|$(PARSER_URL)|' \
|
||||
-e 's|@VERSION@|$(VERSION)|' \
|
||||
-e 's|@LIBDIR@|$(LIBDIR)|' \
|
||||
-e 's|@INCLUDEDIR@|$(INCLUDEDIR)|' \
|
||||
-e 's|@REQUIRES@|$(REQUIRES)|' \
|
||||
-e 's|@ADDITIONAL_LIBS@|$(ADDITIONAL_LIBS)|' \
|
||||
-e 's|=$(PREFIX)|=$${prefix}|' \
|
||||
-e 's|@PREFIX@|$(PREFIX)|' $< > $@
|
||||
|
||||
$(SRC_DIR)/parser.c: grammar.js
|
||||
$(TS) generate --no-bindings
|
||||
|
||||
install: all
|
||||
install -d '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter '$(DESTDIR)$(PCLIBDIR)' '$(DESTDIR)$(LIBDIR)'
|
||||
install -m644 bindings/c/$(LANGUAGE_NAME).h '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter/$(LANGUAGE_NAME).h
|
||||
install -m644 $(LANGUAGE_NAME).pc '$(DESTDIR)$(PCLIBDIR)'/$(LANGUAGE_NAME).pc
|
||||
install -m644 lib$(LANGUAGE_NAME).a '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).a
|
||||
install -m755 lib$(LANGUAGE_NAME).$(SOEXT) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER)
|
||||
ln -sf lib$(LANGUAGE_NAME).$(SOEXTVER) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR)
|
||||
ln -sf lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXT)
|
||||
|
||||
uninstall:
|
||||
$(RM) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).a \
|
||||
'$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER) \
|
||||
'$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR) \
|
||||
'$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXT) \
|
||||
'$(DESTDIR)$(INCLUDEDIR)'/tree_sitter/$(LANGUAGE_NAME).h \
|
||||
'$(DESTDIR)$(PCLIBDIR)'/$(LANGUAGE_NAME).pc
|
||||
|
||||
clean:
|
||||
$(RM) $(OBJS) $(LANGUAGE_NAME).pc lib$(LANGUAGE_NAME).a lib$(LANGUAGE_NAME).$(SOEXT)
|
||||
|
||||
test:
|
||||
$(TS) test
|
||||
$(TS) parse examples/* --quiet --time
|
||||
|
||||
.PHONY: all install uninstall clean test
|
||||
@ -1,47 +0,0 @@
|
||||
// swift-tools-version:5.3
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "TreeSitterCPP",
|
||||
products: [
|
||||
.library(name: "TreeSitterCPP", targets: ["TreeSitterCPP"]),
|
||||
],
|
||||
dependencies: [],
|
||||
targets: [
|
||||
.target(name: "TreeSitterCPP",
|
||||
path: ".",
|
||||
exclude: [
|
||||
"Cargo.toml",
|
||||
"Makefile",
|
||||
"binding.gyp",
|
||||
"bindings/c",
|
||||
"bindings/go",
|
||||
"bindings/node",
|
||||
"bindings/python",
|
||||
"bindings/rust",
|
||||
"prebuilds",
|
||||
"grammar.js",
|
||||
"package.json",
|
||||
"package-lock.json",
|
||||
"pyproject.toml",
|
||||
"setup.py",
|
||||
"test",
|
||||
"examples",
|
||||
".editorconfig",
|
||||
".github",
|
||||
".gitignore",
|
||||
".gitattributes",
|
||||
".gitmodules",
|
||||
],
|
||||
sources: [
|
||||
"src/parser.c",
|
||||
"src/scanner.c",
|
||||
],
|
||||
resources: [
|
||||
.copy("queries")
|
||||
],
|
||||
publicHeadersPath: "bindings/swift",
|
||||
cSettings: [.headerSearchPath("src")])
|
||||
],
|
||||
cLanguageStandard: .c11
|
||||
)
|
||||
@ -1,22 +0,0 @@
|
||||
# tree-sitter-cpp
|
||||
|
||||
[![CI][ci]](https://github.com/tree-sitter/tree-sitter-cpp/actions/workflows/ci.yml)
|
||||
[![discord][discord]](https://discord.gg/w7nTvsVJhm)
|
||||
[![matrix][matrix]](https://matrix.to/#/#tree-sitter-chat:matrix.org)
|
||||
[![crates][crates]](https://crates.io/crates/tree-sitter-cpp)
|
||||
[![npm][npm]](https://www.npmjs.com/package/tree-sitter-cpp)
|
||||
[![pypi][pypi]](https://pypi.org/project/tree-sitter-cpp)
|
||||
|
||||
C++ grammar for [tree-sitter](https://github.com/tree-sitter/tree-sitter).
|
||||
|
||||
## References
|
||||
|
||||
- [Hyperlinked C++ BNF Grammar](http://www.nongnu.org/hcb/)
|
||||
- [EBNF Syntax: C++](http://www.externsoft.ch/download/cpp-iso.html)
|
||||
|
||||
[ci]: https://img.shields.io/github/actions/workflow/status/tree-sitter/tree-sitter-cpp/ci.yml?logo=github&label=CI
|
||||
[discord]: https://img.shields.io/discord/1063097320771698699?logo=discord&label=discord
|
||||
[matrix]: https://img.shields.io/matrix/tree-sitter-chat%3Amatrix.org?logo=matrix&label=matrix
|
||||
[npm]: https://img.shields.io/npm/v/tree-sitter-cpp?logo=npm
|
||||
[crates]: https://img.shields.io/crates/v/tree-sitter-cpp?logo=rust
|
||||
[pypi]: https://img.shields.io/pypi/v/tree-sitter-cpp?logo=pypi&logoColor=ffd242
|
||||
@ -1,21 +0,0 @@
|
||||
{
|
||||
"targets": [
|
||||
{
|
||||
"target_name": "tree_sitter_cpp_binding",
|
||||
"dependencies": [
|
||||
"<!(node -p \"require('node-addon-api').targets\"):node_addon_api_except",
|
||||
],
|
||||
"include_dirs": [
|
||||
"src",
|
||||
],
|
||||
"sources": [
|
||||
"bindings/node/binding.cc",
|
||||
"src/parser.c",
|
||||
"src/scanner.c",
|
||||
],
|
||||
"cflags_c": [
|
||||
"-std=c11",
|
||||
],
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -1,16 +0,0 @@
|
||||
#ifndef TREE_SITTER_CPP_H_
|
||||
#define TREE_SITTER_CPP_H_
|
||||
|
||||
typedef struct TSLanguage TSLanguage;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
const TSLanguage *tree_sitter_cpp(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TREE_SITTER_CPP_H_
|
||||
@ -1,11 +0,0 @@
|
||||
prefix=@PREFIX@
|
||||
libdir=@LIBDIR@
|
||||
includedir=@INCLUDEDIR@
|
||||
|
||||
Name: tree-sitter-cpp
|
||||
Description: C++ grammar for tree-sitter
|
||||
URL: @URL@
|
||||
Version: @VERSION@
|
||||
Requires: @REQUIRES@
|
||||
Libs: -L${libdir} @ADDITIONAL_LIBS@ -ltree-sitter-cpp
|
||||
Cflags: -I${includedir}
|
||||
@ -1,13 +0,0 @@
|
||||
package tree_sitter_cpp
|
||||
|
||||
// #cgo CFLAGS: -std=c11 -fPIC
|
||||
// #include "../../src/parser.c"
|
||||
// #include "../../src/scanner.c"
|
||||
import "C"
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// Get the tree-sitter Language for this grammar.
|
||||
func Language() unsafe.Pointer {
|
||||
return unsafe.Pointer(C.tree_sitter_cpp())
|
||||
}
|
||||
@ -1,15 +0,0 @@
|
||||
package tree_sitter_cpp_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
tree_sitter "github.com/smacker/go-tree-sitter"
|
||||
"github.com/tree-sitter/tree-sitter-cpp"
|
||||
)
|
||||
|
||||
func TestCanLoadGrammar(t *testing.T) {
|
||||
language := tree_sitter.NewLanguage(tree_sitter_cpp.Language())
|
||||
if language == nil {
|
||||
t.Errorf("Error loading C++ grammar")
|
||||
}
|
||||
}
|
||||
@ -1,5 +0,0 @@
|
||||
module github.com/tree-sitter/tree-sitter-cpp
|
||||
|
||||
go 1.22
|
||||
|
||||
require github.com/smacker/go-tree-sitter v0.0.0-20230720070738-0d0a9f78d8f8
|
||||
@ -1,20 +0,0 @@
|
||||
#include <napi.h>
|
||||
|
||||
typedef struct TSLanguage TSLanguage;
|
||||
|
||||
extern "C" TSLanguage *tree_sitter_cpp();
|
||||
|
||||
// "tree-sitter", "language" hashed with BLAKE2
|
||||
const napi_type_tag LANGUAGE_TYPE_TAG = {
|
||||
0x8AF2E5212AD58ABF, 0xD5006CAD83ABBA16
|
||||
};
|
||||
|
||||
Napi::Object Init(Napi::Env env, Napi::Object exports) {
|
||||
exports["name"] = Napi::String::New(env, "cpp");
|
||||
auto language = Napi::External<TSLanguage>::New(env, tree_sitter_cpp());
|
||||
language.TypeTag(&LANGUAGE_TYPE_TAG);
|
||||
exports["language"] = language;
|
||||
return exports;
|
||||
}
|
||||
|
||||
NODE_API_MODULE(tree_sitter_cpp_binding, Init)
|
||||
@ -1,28 +0,0 @@
|
||||
type BaseNode = {
|
||||
type: string;
|
||||
named: boolean;
|
||||
};
|
||||
|
||||
type ChildNode = {
|
||||
multiple: boolean;
|
||||
required: boolean;
|
||||
types: BaseNode[];
|
||||
};
|
||||
|
||||
type NodeInfo =
|
||||
| (BaseNode & {
|
||||
subtypes: BaseNode[];
|
||||
})
|
||||
| (BaseNode & {
|
||||
fields: { [name: string]: ChildNode };
|
||||
children: ChildNode[];
|
||||
});
|
||||
|
||||
type Language = {
|
||||
name: string;
|
||||
language: unknown;
|
||||
nodeTypeInfo: NodeInfo[];
|
||||
};
|
||||
|
||||
declare const language: Language;
|
||||
export = language;
|
||||
@ -1,7 +0,0 @@
|
||||
const root = require("path").join(__dirname, "..", "..");
|
||||
|
||||
module.exports = require("node-gyp-build")(root);
|
||||
|
||||
try {
|
||||
module.exports.nodeTypeInfo = require("../../src/node-types.json");
|
||||
} catch (_) {}
|
||||
@ -1,5 +0,0 @@
|
||||
"C++ grammar for tree-sitter"
|
||||
|
||||
from ._binding import language
|
||||
|
||||
__all__ = ["language"]
|
||||
@ -1 +0,0 @@
|
||||
def language() -> int: ...
|
||||
@ -1,27 +0,0 @@
|
||||
#include <Python.h>
|
||||
|
||||
typedef struct TSLanguage TSLanguage;
|
||||
|
||||
TSLanguage *tree_sitter_cpp(void);
|
||||
|
||||
static PyObject* _binding_language(PyObject *self, PyObject *args) {
|
||||
return PyLong_FromVoidPtr(tree_sitter_cpp());
|
||||
}
|
||||
|
||||
static PyMethodDef methods[] = {
|
||||
{"language", _binding_language, METH_NOARGS,
|
||||
"Get the tree-sitter language for this grammar."},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
static struct PyModuleDef module = {
|
||||
.m_base = PyModuleDef_HEAD_INIT,
|
||||
.m_name = "_binding",
|
||||
.m_doc = NULL,
|
||||
.m_size = -1,
|
||||
.m_methods = methods
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC PyInit__binding(void) {
|
||||
return PyModule_Create(&module);
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
fn main() {
|
||||
let src_dir = std::path::Path::new("src");
|
||||
|
||||
let mut c_config = cc::Build::new();
|
||||
c_config.std("c11").include(src_dir);
|
||||
|
||||
#[cfg(target_env = "msvc")]
|
||||
c_config.flag("-utf-8");
|
||||
|
||||
let parser_path = src_dir.join("parser.c");
|
||||
c_config.file(&parser_path);
|
||||
println!("cargo:rerun-if-changed={}", parser_path.to_str().unwrap());
|
||||
|
||||
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("tree-sitter-cpp");
|
||||
}
|
||||
@ -1,58 +0,0 @@
|
||||
//! This crate provides a C++ grammar for the [tree-sitter][] parsing library.
|
||||
//!
|
||||
//! Typically, you will use the [language][language func] function to add this grammar to a
|
||||
//! tree-sitter [Parser][], and then use the parser to parse some code:
|
||||
//!
|
||||
//! ```
|
||||
//! use tree_sitter::Parser;
|
||||
//!
|
||||
//! let code = r#"
|
||||
//! int double(int x) {
|
||||
//! return x * 2;
|
||||
//! }
|
||||
//! "#;
|
||||
//! let mut parser = Parser::new();
|
||||
//! parser.set_language(&tree_sitter_cpp::language()).expect("Error loading C++ grammar");
|
||||
//! let tree = parser.parse(code, None).unwrap();
|
||||
//! assert!(!tree.root_node().has_error());
|
||||
//! ```
|
||||
//!
|
||||
//! [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_cpp() -> Language;
|
||||
}
|
||||
|
||||
/// Returns 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_cpp() }
|
||||
}
|
||||
|
||||
/// 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: &str = include_str!("../../src/node-types.json");
|
||||
|
||||
/// The syntax highlighting query for this language.
|
||||
pub const HIGHLIGHT_QUERY: &str = include_str!("../../queries/highlights.scm");
|
||||
|
||||
/// The symbol tagging query for this language.
|
||||
pub const TAGS_QUERY: &str = include_str!("../../queries/tags.scm");
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn can_load_grammar() {
|
||||
let mut parser = tree_sitter::Parser::new();
|
||||
parser
|
||||
.set_language(&super::language())
|
||||
.expect("Error loading C++ grammar");
|
||||
}
|
||||
}
|
||||
@ -1,16 +0,0 @@
|
||||
#ifndef TREE_SITTER_CPP_H_
|
||||
#define TREE_SITTER_CPP_H_
|
||||
|
||||
typedef struct TSLanguage TSLanguage;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
const TSLanguage *tree_sitter_cpp(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TREE_SITTER_CPP_H_
|
||||
@ -1,131 +0,0 @@
|
||||
#ifndef MARKER_INDEX_H_
|
||||
#define MARKER_INDEX_H_
|
||||
|
||||
#include <random>
|
||||
#include <unordered_map>
|
||||
#include "flat_set.h"
|
||||
#include "point.h"
|
||||
#include "range.h"
|
||||
|
||||
class MarkerIndex {
|
||||
public:
|
||||
using MarkerId = unsigned;
|
||||
using MarkerIdSet = flat_set<MarkerId>;
|
||||
|
||||
struct SpliceResult {
|
||||
flat_set<MarkerId> touch;
|
||||
flat_set<MarkerId> inside;
|
||||
flat_set<MarkerId> overlap;
|
||||
flat_set<MarkerId> surround;
|
||||
};
|
||||
|
||||
struct Boundary {
|
||||
Point position;
|
||||
flat_set<MarkerId> starting;
|
||||
flat_set<MarkerId> ending;
|
||||
};
|
||||
|
||||
struct BoundaryQueryResult {
|
||||
std::vector<MarkerId> containing_start;
|
||||
std::vector<Boundary> boundaries;
|
||||
};
|
||||
|
||||
MarkerIndex(unsigned seed = 0u);
|
||||
~MarkerIndex();
|
||||
int generate_random_number();
|
||||
void insert(MarkerId id, Point start, Point end);
|
||||
void set_exclusive(MarkerId id, bool exclusive);
|
||||
void remove(MarkerId id);
|
||||
bool has(MarkerId id);
|
||||
SpliceResult splice(Point start, Point old_extent, Point new_extent);
|
||||
Point get_start(MarkerId id) const;
|
||||
Point get_end(MarkerId id) const;
|
||||
Range get_range(MarkerId id) const;
|
||||
|
||||
int compare(MarkerId id1, MarkerId id2) const;
|
||||
flat_set<MarkerId> find_intersecting(Point start, Point end);
|
||||
flat_set<MarkerId> find_containing(Point start, Point end);
|
||||
flat_set<MarkerId> find_contained_in(Point start, Point end);
|
||||
flat_set<MarkerId> find_starting_in(Point start, Point end);
|
||||
flat_set<MarkerId> find_starting_at(Point position);
|
||||
flat_set<MarkerId> find_ending_in(Point start, Point end);
|
||||
flat_set<MarkerId> find_ending_at(Point position);
|
||||
BoundaryQueryResult find_boundaries_after(Point start, size_t max_count);
|
||||
|
||||
std::unordered_map<MarkerId, Range> dump();
|
||||
|
||||
private:
|
||||
friend class Iterator;
|
||||
|
||||
struct Node {
|
||||
Node *parent;
|
||||
Node *left;
|
||||
Node *right;
|
||||
Point left_extent;
|
||||
flat_set<MarkerId> left_marker_ids;
|
||||
flat_set<MarkerId> right_marker_ids;
|
||||
flat_set<MarkerId> start_marker_ids;
|
||||
flat_set<MarkerId> end_marker_ids;
|
||||
int priority;
|
||||
|
||||
Node(Node *parent, Point left_extent);
|
||||
bool is_marker_endpoint();
|
||||
};
|
||||
|
||||
class Iterator {
|
||||
public:
|
||||
Iterator(MarkerIndex *marker_index);
|
||||
void reset();
|
||||
Node* insert_marker_start(const MarkerId &id, const Point &start_position, const Point &end_position);
|
||||
Node* insert_marker_end(const MarkerId &id, const Point &start_position, const Point &end_position);
|
||||
Node* insert_splice_boundary(const Point &position, bool is_insertion_end);
|
||||
void find_intersecting(const Point &start, const Point &end, flat_set<MarkerId> *result);
|
||||
void find_contained_in(const Point &start, const Point &end, flat_set<MarkerId> *result);
|
||||
void find_starting_in(const Point &start, const Point &end, flat_set<MarkerId> *result);
|
||||
void find_ending_in(const Point &start, const Point &end, flat_set<MarkerId> *result);
|
||||
void find_boundaries_after(Point start, size_t max_count, BoundaryQueryResult *result);
|
||||
std::unordered_map<MarkerId, Range> dump();
|
||||
|
||||
private:
|
||||
void ascend();
|
||||
void descend_left();
|
||||
void descend_right();
|
||||
void move_to_successor();
|
||||
void seek_to_first_node_greater_than_or_equal_to(const Point &position);
|
||||
void mark_right(const MarkerId &id, const Point &start_position, const Point &end_position);
|
||||
void mark_left(const MarkerId &id, const Point &start_position, const Point &end_position);
|
||||
Node* insert_left_child(const Point &position);
|
||||
Node* insert_right_child(const Point &position);
|
||||
void check_intersection(const Point &start, const Point &end, flat_set<MarkerId> *results);
|
||||
void cache_node_position() const;
|
||||
|
||||
MarkerIndex *marker_index;
|
||||
Node *current_node;
|
||||
Point current_node_position;
|
||||
Point left_ancestor_position;
|
||||
Point right_ancestor_position;
|
||||
std::vector<Point> left_ancestor_position_stack;
|
||||
std::vector<Point> right_ancestor_position_stack;
|
||||
};
|
||||
|
||||
Point get_node_position(const Node *node) const;
|
||||
void delete_node(Node *node);
|
||||
void delete_subtree(Node *node);
|
||||
void bubble_node_up(Node *node);
|
||||
void bubble_node_down(Node *node);
|
||||
void rotate_node_left(Node *pivot);
|
||||
void rotate_node_right(Node *pivot);
|
||||
void get_starting_and_ending_markers_within_subtree(const Node *node, flat_set<MarkerId> *starting, flat_set<MarkerId> *ending);
|
||||
void populate_splice_invalidation_sets(SpliceResult *invalidated, const Node *start_node, const Node *end_node, const flat_set<MarkerId> &starting_inside_splice, const flat_set<MarkerId> &ending_inside_splice);
|
||||
|
||||
std::default_random_engine random_engine;
|
||||
std::uniform_int_distribution<int> random_distribution;
|
||||
Node *root;
|
||||
std::unordered_map<MarkerId, Node*> start_nodes_by_id;
|
||||
std::unordered_map<MarkerId, Node*> end_nodes_by_id;
|
||||
Iterator iterator;
|
||||
flat_set<MarkerId> exclusive_marker_ids;
|
||||
mutable std::unordered_map<const Node*, Point> node_position_cache;
|
||||
};
|
||||
|
||||
#endif // MARKER_INDEX_H_
|
||||
@ -1,287 +0,0 @@
|
||||
#include "compiler/rule.h"
|
||||
#include "compiler/util/hash_combine.h"
|
||||
|
||||
namespace tree_sitter {
|
||||
namespace rules {
|
||||
|
||||
using std::move;
|
||||
using std::vector;
|
||||
using util::hash_combine;
|
||||
|
||||
Rule::Rule(const Rule &other) : blank_(Blank{}), type(BlankType) {
|
||||
*this = other;
|
||||
}
|
||||
|
||||
Rule::Rule(Rule &&other) noexcept : blank_(Blank{}), type(BlankType) {
|
||||
*this = move(other);
|
||||
}
|
||||
|
||||
static void destroy_value(Rule *rule) {
|
||||
switch (rule->type) {
|
||||
case Rule::BlankType: return rule->blank_.~Blank();
|
||||
case Rule::CharacterSetType: return rule->character_set_.~CharacterSet();
|
||||
case Rule::StringType: return rule->string_ .~String();
|
||||
case Rule::PatternType: return rule->pattern_ .~Pattern();
|
||||
case Rule::NamedSymbolType: return rule->named_symbol_.~NamedSymbol();
|
||||
case Rule::SymbolType: return rule->symbol_ .~Symbol();
|
||||
case Rule::ChoiceType: return rule->choice_ .~Choice();
|
||||
case Rule::MetadataType: return rule->metadata_ .~Metadata();
|
||||
case Rule::RepeatType: return rule->repeat_ .~Repeat();
|
||||
case Rule::SeqType: return rule->seq_ .~Seq();
|
||||
}
|
||||
}
|
||||
|
||||
Rule &Rule::operator=(const Rule &other) {
|
||||
destroy_value(this);
|
||||
type = other.type;
|
||||
switch (type) {
|
||||
case BlankType:
|
||||
new (&blank_) Blank(other.blank_);
|
||||
break;
|
||||
case CharacterSetType:
|
||||
new (&character_set_) CharacterSet(other.character_set_);
|
||||
break;
|
||||
case StringType:
|
||||
new (&string_) String(other.string_);
|
||||
break;
|
||||
case PatternType:
|
||||
new (&pattern_) Pattern(other.pattern_);
|
||||
break;
|
||||
case NamedSymbolType:
|
||||
new (&named_symbol_) NamedSymbol(other.named_symbol_);
|
||||
break;
|
||||
case SymbolType:
|
||||
new (&symbol_) Symbol(other.symbol_);
|
||||
break;
|
||||
case ChoiceType:
|
||||
new (&choice_) Choice(other.choice_);
|
||||
break;
|
||||
case MetadataType:
|
||||
new (&metadata_) Metadata(other.metadata_);
|
||||
break;
|
||||
case RepeatType:
|
||||
new (&repeat_) Repeat(other.repeat_);
|
||||
break;
|
||||
case SeqType:
|
||||
new (&seq_) Seq(other.seq_);
|
||||
break;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Rule &Rule::operator=(Rule &&other) noexcept {
|
||||
destroy_value(this);
|
||||
type = other.type;
|
||||
switch (type) {
|
||||
case BlankType:
|
||||
new (&blank_) Blank(move(other.blank_));
|
||||
break;
|
||||
case CharacterSetType:
|
||||
new (&character_set_) CharacterSet(move(other.character_set_));
|
||||
break;
|
||||
case StringType:
|
||||
new (&string_) String(move(other.string_));
|
||||
break;
|
||||
case PatternType:
|
||||
new (&pattern_) Pattern(move(other.pattern_));
|
||||
break;
|
||||
case NamedSymbolType:
|
||||
new (&named_symbol_) NamedSymbol(move(other.named_symbol_));
|
||||
break;
|
||||
case SymbolType:
|
||||
new (&symbol_) Symbol(move(other.symbol_));
|
||||
break;
|
||||
case ChoiceType:
|
||||
new (&choice_) Choice(move(other.choice_));
|
||||
break;
|
||||
case MetadataType:
|
||||
new (&metadata_) Metadata(move(other.metadata_));
|
||||
break;
|
||||
case RepeatType:
|
||||
new (&repeat_) Repeat(move(other.repeat_));
|
||||
break;
|
||||
case SeqType:
|
||||
new (&seq_) Seq(move(other.seq_));
|
||||
break;
|
||||
}
|
||||
other.type = BlankType;
|
||||
other.blank_ = Blank{};
|
||||
return *this;
|
||||
}
|
||||
|
||||
Rule::~Rule() noexcept {
|
||||
destroy_value(this);
|
||||
}
|
||||
|
||||
bool Rule::operator==(const Rule &other) const {
|
||||
if (type != other.type) return false;
|
||||
switch (type) {
|
||||
case Rule::CharacterSetType: return character_set_ == other.character_set_;
|
||||
case Rule::StringType: return string_ == other.string_;
|
||||
case Rule::PatternType: return pattern_ == other.pattern_;
|
||||
case Rule::NamedSymbolType: return named_symbol_ == other.named_symbol_;
|
||||
case Rule::SymbolType: return symbol_ == other.symbol_;
|
||||
case Rule::ChoiceType: return choice_ == other.choice_;
|
||||
case Rule::MetadataType: return metadata_ == other.metadata_;
|
||||
case Rule::RepeatType: return repeat_ == other.repeat_;
|
||||
case Rule::SeqType: return seq_ == other.seq_;
|
||||
default: return blank_ == other.blank_;
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
bool Rule::is<Blank>() const { return type == BlankType; }
|
||||
|
||||
template <>
|
||||
bool Rule::is<Symbol>() const { return type == SymbolType; }
|
||||
|
||||
template <>
|
||||
bool Rule::is<Repeat>() const { return type == RepeatType; }
|
||||
|
||||
template <>
|
||||
const Symbol & Rule::get_unchecked<Symbol>() const { return symbol_; }
|
||||
|
||||
static inline void add_choice_element(std::vector<Rule> *elements, const Rule &new_rule) {
|
||||
new_rule.match(
|
||||
[elements](Choice choice) {
|
||||
for (auto &element : choice.elements) {
|
||||
add_choice_element(elements, element);
|
||||
}
|
||||
},
|
||||
|
||||
[elements](auto rule) {
|
||||
for (auto &element : *elements) {
|
||||
if (element == rule) return;
|
||||
}
|
||||
elements->push_back(rule);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
Rule Rule::choice(const vector<Rule> &rules) {
|
||||
vector<Rule> elements;
|
||||
for (auto &element : rules) {
|
||||
add_choice_element(&elements, element);
|
||||
}
|
||||
return (elements.size() == 1) ? elements.front() : Choice{elements};
|
||||
}
|
||||
|
||||
Rule Rule::repeat(const Rule &rule) {
|
||||
return rule.is<Repeat>() ? rule : Repeat{rule};
|
||||
}
|
||||
|
||||
Rule Rule::seq(const vector<Rule> &rules) {
|
||||
Rule result;
|
||||
for (const auto &rule : rules) {
|
||||
rule.match(
|
||||
[](Blank) {},
|
||||
[&](Metadata metadata) {
|
||||
if (!metadata.rule->is<Blank>()) {
|
||||
result = Seq{result, rule};
|
||||
}
|
||||
},
|
||||
[&](auto) {
|
||||
if (result.is<Blank>()) {
|
||||
result = rule;
|
||||
} else {
|
||||
result = Seq{result, rule};
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace rules
|
||||
} // namespace tree_sitter
|
||||
|
||||
namespace std {
|
||||
|
||||
size_t hash<Symbol>::operator()(const Symbol &symbol) const {
|
||||
auto result = hash<int>()(symbol.index);
|
||||
hash_combine(&result, hash<int>()(symbol.type));
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t hash<NamedSymbol>::operator()(const NamedSymbol &symbol) const {
|
||||
return hash<string>()(symbol.value);
|
||||
}
|
||||
|
||||
size_t hash<Pattern>::operator()(const Pattern &symbol) const {
|
||||
return hash<string>()(symbol.value);
|
||||
}
|
||||
|
||||
size_t hash<String>::operator()(const String &symbol) const {
|
||||
return hash<string>()(symbol.value);
|
||||
}
|
||||
|
||||
size_t hash<CharacterSet>::operator()(const CharacterSet &character_set) const {
|
||||
size_t result = 0;
|
||||
hash_combine(&result, character_set.includes_all);
|
||||
hash_combine(&result, character_set.included_chars.size());
|
||||
for (uint32_t c : character_set.included_chars) {
|
||||
hash_combine(&result, c);
|
||||
}
|
||||
hash_combine(&result, character_set.excluded_chars.size());
|
||||
for (uint32_t c : character_set.excluded_chars) {
|
||||
hash_combine(&result, c);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t hash<Blank>::operator()(const Blank &blank) const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t hash<Choice>::operator()(const Choice &choice) const {
|
||||
size_t result = 0;
|
||||
for (const auto &element : choice.elements) {
|
||||
symmetric_hash_combine(&result, element);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t hash<Repeat>::operator()(const Repeat &repeat) const {
|
||||
size_t result = 0;
|
||||
hash_combine(&result, *repeat.rule);
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t hash<Seq>::operator()(const Seq &seq) const {
|
||||
size_t result = 0;
|
||||
hash_combine(&result, *seq.left);
|
||||
hash_combine(&result, *seq.right);
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t hash<Metadata>::operator()(const Metadata &metadata) const {
|
||||
size_t result = 0;
|
||||
hash_combine(&result, *metadata.rule);
|
||||
hash_combine(&result, metadata.params.precedence);
|
||||
hash_combine<int>(&result, metadata.params.associativity);
|
||||
hash_combine(&result, metadata.params.has_precedence);
|
||||
hash_combine(&result, metadata.params.has_associativity);
|
||||
hash_combine(&result, metadata.params.is_token);
|
||||
hash_combine(&result, metadata.params.is_string);
|
||||
hash_combine(&result, metadata.params.is_active);
|
||||
hash_combine(&result, metadata.params.is_main_token);
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t hash<Rule>::operator()(const Rule &rule) const {
|
||||
size_t result = hash<int>()(rule.type);
|
||||
switch (rule.type) {
|
||||
case Rule::CharacterSetType: return result ^ hash<CharacterSet>()(rule.character_set_);
|
||||
case Rule::StringType: return result ^ hash<String>()(rule.string_);
|
||||
case Rule::PatternType: return result ^ hash<Pattern>()(rule.pattern_);
|
||||
case Rule::NamedSymbolType: return result ^ hash<NamedSymbol>()(rule.named_symbol_);
|
||||
case Rule::SymbolType: return result ^ hash<Symbol>()(rule.symbol_);
|
||||
case Rule::ChoiceType: return result ^ hash<Choice>()(rule.choice_);
|
||||
case Rule::MetadataType: return result ^ hash<Metadata>()(rule.metadata_);
|
||||
case Rule::RepeatType: return result ^ hash<Repeat>()(rule.repeat_);
|
||||
case Rule::SeqType: return result ^ hash<Seq>()(rule.seq_);
|
||||
default: return result ^ hash<Blank>()(rule.blank_);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace std
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue