fix: impatient loading order

This commit is contained in:
nullchilly 2022-08-07 12:26:15 +07:00 committed by Sidhanth Rathod
parent 20f45c3962
commit aee1c8b830
67 changed files with 97276 additions and 4 deletions

View file

@ -10,6 +10,7 @@ M.lazy_load = function(tb)
callback = function() callback = function()
if tb.condition() then if tb.condition() then
vim.api.nvim_del_augroup_by_name(tb.augroup_name) vim.api.nvim_del_augroup_by_name(tb.augroup_name)
require "impatient"
-- dont defer for treesitter as it will show slow highlighting -- dont defer for treesitter as it will show slow highlighting
-- This deferring only happens only when we do "nvim filename" -- This deferring only happens only when we do "nvim filename"

View file

@ -226,10 +226,7 @@ local plugins = {
-- Speed up deffered plugins -- Speed up deffered plugins
["lewis6991/impatient.nvim"] = { ["lewis6991/impatient.nvim"] = {
event = "VimEnter", module = "impatient"
config = function()
vim.defer_fn(function() require "impatient" end, 0)
end,
}, },
} }

15
rplugin.vim Normal file
View file

@ -0,0 +1,15 @@
" perl plugins
" node plugins
" python3 plugins
" ruby plugins
" python plugins

@ -0,0 +1 @@
Subproject commit 9b76787e273567c0e3027304bd16ffedc751c04c

@ -0,0 +1 @@
Subproject commit ac27343b52796a0aa1bb3db824d16e66d1def182

@ -0,0 +1 @@
Subproject commit 62fc67a2b0205136bc3e312664624ba2ab4a9323

@ -0,0 +1 @@
Subproject commit affe808a5c56b71630f17aa7c38e15c59fd648a8

@ -0,0 +1 @@
Subproject commit d276254e7198ab7d00f117e88e223b4bd8c02d21

@ -0,0 +1 @@
Subproject commit 447c87cdd6e6d6a1d2488b1d43108bfa217f56e1

@ -0,0 +1 @@
Subproject commit a9de941bcbda508d0a45d28ae366bb3f08db2e36

@ -0,0 +1 @@
Subproject commit e82d9f5e612ade06202591ed76ecb095e946f7f8

@ -0,0 +1 @@
Subproject commit 7339def34e46237eb7c9a893cb7d42dcb90e05e6

@ -0,0 +1 @@
Subproject commit 9c3ca027661136a618c82275427746e481c84a4e

@ -0,0 +1 @@
Subproject commit 4ccbe749ce439fa25d387d459e8c339131cc5d1f

@ -0,0 +1 @@
Subproject commit c15bbe9f23d88b5c0b4ca45a446e01a0a3913707

@ -0,0 +1 @@
Subproject commit cd1af57253b3ac3652765e4d0f83b56802ec2a5f

@ -0,0 +1 @@
Subproject commit ca89ab9e7e42aa9279f1cdad15398d6e18ccee86

@ -0,0 +1 @@
Subproject commit 706371f1300e7c0acb98b346f80dad2dd9b5f679

@ -0,0 +1 @@
Subproject commit 8fe6ec269c6bcd19a7c2d69cb0bdcf8bb86a85fe

@ -0,0 +1 @@
Subproject commit 6e047f11861bfb6ec28a6ad0138a8f0a62bb8806

@ -0,0 +1 @@
Subproject commit ff6e7966f39a897ac4d1358f4d022cfecdc88ff1

@ -0,0 +1 @@
Subproject commit a9a6493b1eeba458757903352e0d3dc4b54fd4f2

@ -0,0 +1 @@
Subproject commit 2d02a56189e2bde11edd4712fea16f08a6656944

@ -0,0 +1 @@
Subproject commit 1317d6238f089e117e3ed98b3cecc37cc4364675

@ -0,0 +1 @@
Subproject commit afab89594f4f702dc3368769c95b782dbdaeaf0a

@ -0,0 +1 @@
Subproject commit 31807eef4ed574854b8a53ae40ea3292033a78ea

@ -0,0 +1 @@
Subproject commit 4725867ec66b9a0f5e5ad95a1fd94c2f97fa2d2c

@ -0,0 +1 @@
Subproject commit bca1182e872db0ea52d86b2f4cf4ee7cb092de45

@ -0,0 +1 @@
Subproject commit bd4411a2ed4dd8bb69c125e339d837028a6eea71

@ -0,0 +1 @@
Subproject commit dfdcff9c6b2bd1ad3c364973a2497bf62c6f0f20

View file

@ -0,0 +1,22 @@
image: Visual Studio 2015
environment:
nodejs_version: "8"
platform:
- x64
install:
- ps: Install-Product node $env:nodejs_version
- node --version
- npm --version
- npm install
test_script:
- npm run test-windows
build: off
branches:
only:
- master

2
tree-sitter-c/.gitattributes vendored Normal file
View file

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

6
tree-sitter-c/.gitignore vendored Normal file
View file

@ -0,0 +1,6 @@
Cargo.lock
node_modules
build
package-lock.json
/target/
.build/

6
tree-sitter-c/.npmignore Normal file
View file

@ -0,0 +1,6 @@
/test
/examples
/build
/script
/target

View file

@ -0,0 +1,5 @@
language: node_js
sudo: false
node_js: 10

23
tree-sitter-c/Cargo.toml Normal file
View file

@ -0,0 +1,23 @@
[package]
name = "tree-sitter-c"
description = "C grammar for the tree-sitter parsing library"
version = "0.20.2"
authors = ["Max Brunsfeld <maxbrunsfeld@gmail.com>"]
license = "MIT"
readme = "bindings/rust/README.md"
keywords = ["incremental", "parsing", "c"]
categories = ["parsing", "text-editors"]
repository = "https://github.com/tree-sitter/tree-sitter-c"
edition = "2018"
build = "bindings/rust/build.rs"
include = ["bindings/rust/*", "grammar.js", "queries/*", "src/*"]
[lib]
path = "bindings/rust/lib.rs"
[dependencies]
tree-sitter = "0.20"
[build-dependencies]
cc = "1.0"

21
tree-sitter-c/LICENSE Normal file
View file

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

View file

@ -0,0 +1,36 @@
// swift-tools-version:5.3
import PackageDescription
let package = Package(
name: "TreeSitterC",
platforms: [.macOS(.v10_13), .iOS(.v11)],
products: [
.library(name: "TreeSitterC", targets: ["TreeSitterC"]),
],
dependencies: [],
targets: [
.target(name: "TreeSitterC",
path: ".",
exclude: [
"binding.gyp",
"bindings",
"Cargo.toml",
"examples",
"grammar.js",
"LICENSE",
"Makefile",
"package.json",
"README.md",
"src/grammar.json",
"src/node-types.json",
],
sources: [
"src/parser.c",
],
resources: [
.copy("queries")
],
publicHeadersPath: "bindings/swift",
cSettings: [.headerSearchPath("src")])
]
)

7
tree-sitter-c/README.md Normal file
View file

@ -0,0 +1,7 @@
tree-sitter-c
==================
[![Build Status](https://travis-ci.org/tree-sitter/tree-sitter-c.svg?branch=master)](https://travis-ci.org/tree-sitter/tree-sitter-c)
[![Build status](https://ci.appveyor.com/api/projects/status/7u0sy6ajmxro4wfh/branch/master?svg=true)](https://ci.appveyor.com/project/maxbrunsfeld/tree-sitter-c/branch/master)
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).

18
tree-sitter-c/binding.gyp Normal file
View file

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

View file

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

View file

@ -0,0 +1,19 @@
try {
module.exports = require("../../build/Release/tree_sitter_c_binding");
} catch (error1) {
if (error1.code !== 'MODULE_NOT_FOUND') {
throw error1;
}
try {
module.exports = require("../../build/Debug/tree_sitter_c_binding");
} catch (error2) {
if (error2.code !== 'MODULE_NOT_FOUND') {
throw error2;
}
throw error1
}
}
try {
module.exports.nodeTypeInfo = require("../../src/node-types.json");
} catch (_) {}

View file

@ -0,0 +1,37 @@
# tree-sitter-c
This crate provides a C grammar for the [tree-sitter][] parsing library. To
use this crate, add it to the `[dependencies]` section of your `Cargo.toml`
file. (Note that you will probably also need to depend on the
[`tree-sitter`][tree-sitter crate] crate to use the parsed result in any useful
way.)
``` toml
[dependencies]
tree-sitter = "0.17"
tree-sitter-c = "0.16"
```
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:
``` rust
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 parsed = parser.parse(code, None);
```
If you have any questions, please reach out to us in the [tree-sitter
discussions] page.
[Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html
[language func]: https://docs.rs/tree-sitter-c/*/tree_sitter_c/fn.language.html
[Parser]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Parser.html
[tree-sitter]: https://tree-sitter.github.io/
[tree-sitter crate]: https://crates.io/crates/tree-sitter
[tree-sitter discussions]: https://github.com/tree-sitter/tree-sitter/discussions

View file

@ -0,0 +1,17 @@
use std::path::Path;
extern crate cc;
fn main() {
let src_dir = Path::new("src");
let mut c_config = cc::Build::new();
c_config.include(&src_dir);
c_config
.flag_if_supported("-Wno-unused-parameter")
.flag_if_supported("-Wno-unused-but-set-variable")
.flag_if_supported("-Wno-trigraphs");
let parser_path = src_dir.join("parser.c");
c_config.file(&parser_path);
println!("cargo:rerun-if-changed={}", parser_path.to_str().unwrap());
c_config.compile("parser");
}

View file

@ -0,0 +1,66 @@
// -*- coding: utf-8 -*-
// ------------------------------------------------------------------------------------------------
// Copyright © 2021, tree-sitter-c authors.
// See the LICENSE file in this repo for license details.
// ------------------------------------------------------------------------------------------------
//! 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_c::language()).expect("Error loading C grammar");
//! let parsed = parser.parse(code, None);
//! # let parsed = parsed.unwrap();
//! # let root = parsed.root_node();
//! # assert!(!root.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;
}
/// 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_c() }
}
/// The source of the C tree-sitter grammar description.
pub const GRAMMAR: &str = include_str!("../../grammar.js");
/// The syntax highlighting query for this language.
pub const HIGHLIGHT_QUERY: &str = include_str!("../../queries/highlights.scm");
/// 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");
#[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");
}
}

View file

@ -0,0 +1,16 @@
#ifndef TREE_SITTER_C_H_
#define TREE_SITTER_C_H_
typedef struct TSLanguage TSLanguage;
#ifdef __cplusplus
extern "C" {
#endif
extern TSLanguage *tree_sitter_c();
#ifdef __cplusplus
}
#endif
#endif // TREE_SITTER_C_H_

5446
tree-sitter-c/examples/cluster.c vendored Normal file

File diff suppressed because it is too large Load diff

532
tree-sitter-c/examples/malloc.c vendored Normal file
View file

@ -0,0 +1,532 @@
#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);
}

1283
tree-sitter-c/examples/parser.c vendored Normal file

File diff suppressed because it is too large Load diff

1082
tree-sitter-c/grammar.js Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,36 @@
{
"name": "tree-sitter-c",
"version": "0.20.2",
"description": "C grammar for node-tree-sitter",
"main": "bindings/node",
"keywords": [
"parser",
"lexer"
],
"repository": {
"type": "git",
"url": "https://github.com/tree-sitter/tree-sitter-c.git"
},
"author": "Max Brunsfeld",
"license": "MIT",
"dependencies": {
"nan": "^2.14.0"
},
"devDependencies": {
"tree-sitter-cli": "^0.20.0"
},
"scripts": {
"build": "tree-sitter generate && node-gyp build",
"test": "tree-sitter test && tree-sitter parse examples/* --quiet --time",
"test-windows": "tree-sitter test"
},
"tree-sitter": [
{
"scope": "source.c",
"file-types": [
"c",
"h"
]
}
]
}

BIN
tree-sitter-c/parser.so Executable file

Binary file not shown.

View file

@ -0,0 +1,81 @@
"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
(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)
(field_identifier) @property
(statement_identifier) @label
(type_identifier) @type
(primitive_type) @type
(sized_type_specifier) @type
((identifier) @constant
(#match? @constant "^[A-Z][A-Z\\d_]*$"))
(identifier) @variable
(comment) @comment

6629
tree-sitter-c/src/grammar.json vendored Normal file

File diff suppressed because it is too large Load diff

3664
tree-sitter-c/src/node-types.json vendored Normal file

File diff suppressed because it is too large Load diff

75781
tree-sitter-c/src/parser.c vendored Normal file

File diff suppressed because it is too large Load diff

224
tree-sitter-c/src/tree_sitter/parser.h vendored Normal file
View file

@ -0,0 +1,224 @@
#ifndef TREE_SITTER_PARSER_H_
#define TREE_SITTER_PARSER_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#define ts_builtin_sym_error ((TSSymbol)-1)
#define ts_builtin_sym_end 0
#define TREE_SITTER_SERIALIZATION_BUFFER_SIZE 1024
typedef uint16_t TSStateId;
#ifndef TREE_SITTER_API_H_
typedef uint16_t TSSymbol;
typedef uint16_t TSFieldId;
typedef struct TSLanguage TSLanguage;
#endif
typedef struct {
TSFieldId field_id;
uint8_t child_index;
bool inherited;
} TSFieldMapEntry;
typedef struct {
uint16_t index;
uint16_t length;
} TSFieldMapSlice;
typedef struct {
bool visible;
bool named;
bool supertype;
} TSSymbolMetadata;
typedef struct TSLexer TSLexer;
struct TSLexer {
int32_t lookahead;
TSSymbol result_symbol;
void (*advance)(TSLexer *, bool);
void (*mark_end)(TSLexer *);
uint32_t (*get_column)(TSLexer *);
bool (*is_at_included_range_start)(const TSLexer *);
bool (*eof)(const TSLexer *);
};
typedef enum {
TSParseActionTypeShift,
TSParseActionTypeReduce,
TSParseActionTypeAccept,
TSParseActionTypeRecover,
} TSParseActionType;
typedef union {
struct {
uint8_t type;
TSStateId state;
bool extra;
bool repetition;
} shift;
struct {
uint8_t type;
uint8_t child_count;
TSSymbol symbol;
int16_t dynamic_precedence;
uint16_t production_id;
} reduce;
uint8_t type;
} TSParseAction;
typedef struct {
uint16_t lex_state;
uint16_t external_lex_state;
} TSLexMode;
typedef union {
TSParseAction action;
struct {
uint8_t count;
bool reusable;
} entry;
} TSParseActionEntry;
struct TSLanguage {
uint32_t version;
uint32_t symbol_count;
uint32_t alias_count;
uint32_t token_count;
uint32_t external_token_count;
uint32_t state_count;
uint32_t large_state_count;
uint32_t production_id_count;
uint32_t field_count;
uint16_t max_alias_sequence_length;
const uint16_t *parse_table;
const uint16_t *small_parse_table;
const uint32_t *small_parse_table_map;
const TSParseActionEntry *parse_actions;
const char * const *symbol_names;
const char * const *field_names;
const TSFieldMapSlice *field_map_slices;
const TSFieldMapEntry *field_map_entries;
const TSSymbolMetadata *symbol_metadata;
const TSSymbol *public_symbol_map;
const uint16_t *alias_map;
const TSSymbol *alias_sequences;
const TSLexMode *lex_modes;
bool (*lex_fn)(TSLexer *, TSStateId);
bool (*keyword_lex_fn)(TSLexer *, TSStateId);
TSSymbol keyword_capture_token;
struct {
const bool *states;
const TSSymbol *symbol_map;
void *(*create)(void);
void (*destroy)(void *);
bool (*scan)(void *, TSLexer *, const bool *symbol_whitelist);
unsigned (*serialize)(void *, char *);
void (*deserialize)(void *, const char *, unsigned);
} external_scanner;
const TSStateId *primary_state_ids;
};
/*
* Lexer Macros
*/
#define START_LEXER() \
bool result = false; \
bool skip = false; \
bool eof = false; \
int32_t lookahead; \
goto start; \
next_state: \
lexer->advance(lexer, skip); \
start: \
skip = false; \
lookahead = lexer->lookahead;
#define ADVANCE(state_value) \
{ \
state = state_value; \
goto next_state; \
}
#define SKIP(state_value) \
{ \
skip = true; \
state = state_value; \
goto next_state; \
}
#define ACCEPT_TOKEN(symbol_value) \
result = true; \
lexer->result_symbol = symbol_value; \
lexer->mark_end(lexer);
#define END_STATE() return result;
/*
* Parse Table Macros
*/
#define SMALL_STATE(id) id - LARGE_STATE_COUNT
#define STATE(id) id
#define ACTIONS(id) id
#define SHIFT(state_value) \
{{ \
.shift = { \
.type = TSParseActionTypeShift, \
.state = state_value \
} \
}}
#define SHIFT_REPEAT(state_value) \
{{ \
.shift = { \
.type = TSParseActionTypeShift, \
.state = state_value, \
.repetition = true \
} \
}}
#define SHIFT_EXTRA() \
{{ \
.shift = { \
.type = TSParseActionTypeShift, \
.extra = true \
} \
}}
#define REDUCE(symbol_val, child_count_val, ...) \
{{ \
.reduce = { \
.type = TSParseActionTypeReduce, \
.symbol = symbol_val, \
.child_count = child_count_val, \
__VA_ARGS__ \
}, \
}}
#define RECOVER() \
{{ \
.type = TSParseActionTypeRecover \
}}
#define ACCEPT_INPUT() \
{{ \
.type = TSParseActionTypeAccept \
}}
#ifdef __cplusplus
}
#endif
#endif // TREE_SITTER_PARSER_H_

View file

@ -0,0 +1,178 @@
========================================================================
pointer declarations vs multiplications
========================================================================
int main() {
// declare a function pointer
T1 * b(T2 a);
// evaluate expressions
c * d(5);
e(f * g);
}
---
(translation_unit (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))))
(expression_statement (call_expression (identifier) (argument_list (identifier) (string_literal) (string_literal)))))

View file

@ -0,0 +1,13 @@
============================================
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)))

View file

@ -0,0 +1,530 @@
============================================
Struct declarations
============================================
struct s1;
struct s2 {
int x;
float y : 5;
};
---
(translation_unit
(struct_specifier
name: (type_identifier))
(struct_specifier
name: (type_identifier)
body: (field_declaration_list
(field_declaration
type: (primitive_type)
declarator: (field_identifier))
(field_declaration
type: (primitive_type)
declarator: (field_identifier)
(bitfield_clause (number_literal))))))
============================================
Union declarations
============================================
union u1;
union s2 {
int x;
float y;
};
---
(translation_unit
(union_specifier
name: (type_identifier))
(union_specifier
name: (type_identifier)
body: (field_declaration_list
(field_declaration
type: (primitive_type)
declarator: (field_identifier))
(field_declaration
type: (primitive_type)
declarator: (field_identifier)))))
============================================
Enum declarations
============================================
enum e1;
enum e2 {
val1,
val2 = 5,
val3
};
enum e3 {
val1,
};
---
(translation_unit
(enum_specifier
name: (type_identifier))
(enum_specifier
name: (type_identifier)
body: (enumerator_list
(enumerator name: (identifier))
(enumerator name: (identifier) value: (number_literal))
(enumerator name: (identifier))))
(enum_specifier
name: (type_identifier)
body: (enumerator_list
(enumerator name: (identifier)))))
======================================================
Struct declarations containing preprocessor directives
======================================================
struct s {
#define A 5
int b[a];
#undef A
};
---
(translation_unit
(struct_specifier
(type_identifier)
(field_declaration_list
(preproc_def (identifier) (preproc_arg))
(field_declaration (primitive_type) (array_declarator (field_identifier) (identifier)))
(preproc_call (preproc_directive) (preproc_arg)))))
============================================
Primitive-typed variable declarations
============================================
unsigned short int a;
long int b, c = 5, d;
float d, e;
unsigned f;
short g, h;
---
(translation_unit
(declaration
type: (sized_type_specifier type: (primitive_type))
declarator: (identifier))
(declaration
type: (sized_type_specifier type: (primitive_type))
declarator: (identifier)
declarator: (init_declarator
declarator: (identifier)
value: (number_literal))
declarator: (identifier))
(declaration
type: (primitive_type)
declarator: (identifier)
declarator: (identifier))
(declaration
type: (sized_type_specifier)
declarator: (identifier))
(declaration
type: (sized_type_specifier)
declarator: (identifier)
declarator: (identifier)))
============================================
Variable storage classes
============================================
int a;
extern int b, c;
auto int d;
register int e;
static int f;
---
(translation_unit
(declaration (primitive_type) (identifier))
(declaration (storage_class_specifier) (primitive_type) (identifier) (identifier))
(declaration (storage_class_specifier) (primitive_type) (identifier))
(declaration (storage_class_specifier) (primitive_type) (identifier))
(declaration (storage_class_specifier) (primitive_type) (identifier)))
============================================
Composite-typed variable declarations
============================================
struct b c;
union { int e; } f;
enum { g, h } i;
---
(translation_unit
(declaration
type: (struct_specifier name: (type_identifier))
declarator: (identifier))
(declaration
type: (union_specifier
body: (field_declaration_list
(field_declaration
type: (primitive_type)
declarator: (field_identifier))))
declarator: (identifier))
(declaration
type: (enum_specifier body: (enumerator_list
(enumerator name: (identifier))
(enumerator name: (identifier))))
declarator: (identifier)))
============================================
Pointer variable declarations
============================================
char *the_string;
const char **the_strings;
int const * const restrict x;
---
(translation_unit
(declaration
type: (primitive_type)
declarator: (pointer_declarator
declarator: (identifier)))
(declaration
(type_qualifier)
type: (primitive_type)
declarator: (pointer_declarator
declarator: (pointer_declarator
declarator: (identifier))))
(declaration
type: (primitive_type)
(type_qualifier)
declarator: (pointer_declarator
(type_qualifier)
(type_qualifier)
declarator: (identifier))))
============================================
Typedefs
============================================
typedef int my_int;
typedef struct {
int x;
} *a;
typedef void my_callback(void *, size_t);
typedef struct A {
int i;
} a, b;
---
(translation_unit
(type_definition
type: (primitive_type)
declarator: (type_identifier))
(type_definition
type: (struct_specifier
body: (field_declaration_list
(field_declaration
type: (primitive_type)
declarator: (field_identifier))))
declarator: (pointer_declarator
declarator: (type_identifier)))
(type_definition
type: (primitive_type)
declarator: (function_declarator
declarator: (type_identifier)
parameters: (parameter_list
(parameter_declaration
type: (primitive_type)
declarator: (abstract_pointer_declarator))
(parameter_declaration
type: (primitive_type)))))
(type_definition
type: (struct_specifier
name: (type_identifier)
body: (field_declaration_list
(field_declaration
type: (primitive_type)
declarator: (field_identifier))))
declarator: (type_identifier)
declarator: (type_identifier)))
============================================
Function declarations
============================================
int main(int argc, const char **argv);
static foo bar();
static baz quux(...);
---
(translation_unit
(declaration
(primitive_type)
(function_declarator
(identifier)
(parameter_list
(parameter_declaration
(primitive_type)
(identifier))
(parameter_declaration
(type_qualifier)
(primitive_type)
(pointer_declarator (pointer_declarator (identifier)))))))
(declaration
(storage_class_specifier)
(type_identifier)
(function_declarator (identifier) (parameter_list)))
(declaration
(storage_class_specifier)
(type_identifier)
(function_declarator (identifier) (parameter_list (variadic_parameter)))))
============================================
Function definitions
============================================
void * do_stuff(int arg1) {
return 5;
}
---
(translation_unit
(function_definition
type: (primitive_type)
declarator: (pointer_declarator
declarator: (function_declarator
declarator: (identifier)
parameters: (parameter_list
(parameter_declaration
type: (primitive_type)
declarator: (identifier)))))
body: (compound_statement
(return_statement (number_literal)))))
============================================
Function specifiers after types
============================================
int static inline do_stuff(int arg1) {
return 5;
}
---
(translation_unit
(function_definition
(primitive_type)
(storage_class_specifier)
(storage_class_specifier)
(function_declarator
(identifier)
(parameter_list (parameter_declaration (primitive_type) (identifier))))
(compound_statement (return_statement (number_literal)))))
============================================
Linkage specifications
============================================
extern "C" int foo();
extern "C" int foo() { return 0; }
extern "C" {
int bar();
int baz();
}
---
(translation_unit
(linkage_specification
(string_literal)
(declaration
(primitive_type)
(function_declarator (identifier) (parameter_list))))
(linkage_specification
(string_literal)
(function_definition
(primitive_type)
(function_declarator (identifier) (parameter_list))
(compound_statement (return_statement (number_literal)))))
(linkage_specification
(string_literal)
(declaration_list
(declaration
(primitive_type)
(function_declarator (identifier) (parameter_list)))
(declaration
(primitive_type)
(function_declarator (identifier) (parameter_list))))))
==========================
Type qualifiers
==========================
const _Atomic unsigned long int x = 5;
restrict int y = 6;
volatile int z = 7;
---
(translation_unit
(declaration
(type_qualifier)
(type_qualifier)
(sized_type_specifier (primitive_type))
(init_declarator (identifier) (number_literal)))
(declaration
(type_qualifier)
(primitive_type)
(init_declarator (identifier) (number_literal)))
(declaration
(type_qualifier)
(primitive_type)
(init_declarator (identifier) (number_literal))))
================================
Local array declarations
================================
int main() {
char the_buffer[the_size];
char the_other_buffer[*];
}
---
(translation_unit
(function_definition
(primitive_type)
(function_declarator (identifier) (parameter_list))
(compound_statement
(declaration (primitive_type) (array_declarator (identifier) (identifier)))
(declaration (primitive_type) (array_declarator (identifier))))))
================================
Attributes
================================
extern __attribute__((visibility("hidden"))) int foo();
extern int bar() __attribute__((const));
void die(const char *format, ...) __attribute__((noreturn))
__attribute__((format(printf,1,2)));
extern __attribute__((visibility("default"), weak)) int print_status();
int f([[a::b(c), d]] int x) {}
[[gnu::always_inline]] [[gnu::hot]] [[gnu::const]] [[nodiscard]]
int g(void);
[[gnu::always_inline, gnu::hot, gnu::const, nodiscard]]
int g(void);
int i [[maybe_unused]];
void f[[gnu::always_inline]]();
[[nodiscard("reason")]] int foo;
[[fallthrough]];
struct S {
int a [[deprecated]];
};
typedef int MyInt [[deprecated]];
---
(translation_unit
(declaration
(storage_class_specifier)
(attribute_specifier
(argument_list
(call_expression
(identifier) (argument_list (string_literal)))))
(primitive_type)
(function_declarator (identifier) (parameter_list)))
(declaration
(storage_class_specifier)
(primitive_type)
(function_declarator (identifier) (parameter_list) (attribute_specifier (argument_list (identifier)))))
(declaration
(primitive_type)
(function_declarator (identifier)
(parameter_list (parameter_declaration (type_qualifier) (primitive_type) (pointer_declarator (identifier))) (variadic_parameter))
(attribute_specifier (argument_list (identifier)))
(attribute_specifier
(argument_list (call_expression (identifier) (argument_list (identifier) (number_literal) (number_literal)))))))
(declaration
(storage_class_specifier)
(attribute_specifier
(argument_list (call_expression (identifier) (argument_list (string_literal))) (identifier)))
(primitive_type) (function_declarator (identifier) (parameter_list)))
(function_definition (primitive_type)
(function_declarator (identifier) (parameter_list (parameter_declaration
(attribute_declaration
(attribute (identifier) (identifier) (argument_list (identifier)))
(attribute (identifier)))
(primitive_type) (identifier)))) (compound_statement))
(declaration
(attribute_declaration (attribute (identifier) (identifier)))
(attribute_declaration (attribute (identifier) (identifier)))
(attribute_declaration (attribute (identifier) (identifier)))
(attribute_declaration (attribute (identifier)))
(primitive_type)
(function_declarator (identifier) (parameter_list (parameter_declaration (primitive_type)))))
(declaration
(attribute_declaration
(attribute (identifier) (identifier))
(attribute (identifier) (identifier))
(attribute (identifier) (identifier))
(attribute (identifier)))
(primitive_type)
(function_declarator (identifier) (parameter_list (parameter_declaration (primitive_type)))))
(declaration
(primitive_type)
(attributed_declarator
(identifier)
(attribute_declaration (attribute (identifier)))))
(declaration
(primitive_type)
(function_declarator
(attributed_declarator
(identifier)
(attribute_declaration (attribute (identifier) (identifier))))
(parameter_list)))
(declaration
(attribute_declaration (attribute (identifier) (argument_list (string_literal))))
(primitive_type) (identifier))
(attributed_statement
(attribute_declaration (attribute (identifier)))
(expression_statement))
(struct_specifier
(type_identifier)
(field_declaration_list (field_declaration (primitive_type)
(attributed_declarator
(field_identifier)
(attribute_declaration (attribute (identifier)))))))
(type_definition (primitive_type)
(attributed_declarator
(type_identifier)
(attribute_declaration (attribute (identifier))))))

View file

@ -0,0 +1,518 @@
============================================
Number literals
============================================
double a = {
0xAC00,
0.123,
0b1010001,
0xabc00ull,
-0.1f,
1'000'000.000'001,
24e-5,
0.1E,
58.,
4e2,
123.456e-67,
.1E4f,
0x10.1p0,
};
---
(translation_unit
(declaration
(primitive_type)
(init_declarator
(identifier)
(initializer_list
(number_literal)
(number_literal)
(number_literal)
(number_literal)
(number_literal)
(number_literal)
(number_literal)
(number_literal)
(number_literal)
(number_literal)
(number_literal)
(number_literal)
(number_literal)
))))
============================================
Identifiers
============================================
int main() {
_abc;
d_EG123;
}
---
(translation_unit
(function_definition
(primitive_type)
(function_declarator (identifier) (parameter_list))
(compound_statement
(expression_statement (identifier))
(expression_statement (identifier)))))
============================================
Common constants
============================================
int main() {
true;
false;
NULL;
// regression test - identifiers starting w/ these strings should tokenize correctly.
true_value;
false_value;
NULL_value;
}
---
(translation_unit
(function_definition
(primitive_type)
(function_declarator (identifier) (parameter_list))
(compound_statement
(expression_statement (true))
(expression_statement (false))
(expression_statement (null))
(comment)
(expression_statement (identifier))
(expression_statement (identifier))
(expression_statement (identifier)))))
============================================
Function calls
============================================
int main() {
printf("hi! %d\n", x);
}
---
(translation_unit
(function_definition
(primitive_type)
(function_declarator (identifier) (parameter_list))
(compound_statement
(expression_statement (call_expression
(identifier)
(argument_list (string_literal (escape_sequence)) (identifier)))))))
============================================
String literals
============================================
int main() {
"a";
"b" "c" "d";
"\"hi\"";
L"bonjour";
u"guten morgen";
U"buenos dias";
u8"buongiorno";
}
---
(translation_unit
(function_definition
(primitive_type)
(function_declarator (identifier) (parameter_list))
(compound_statement
(expression_statement (string_literal))
(expression_statement (concatenated_string (string_literal) (string_literal) (string_literal)))
(expression_statement (string_literal (escape_sequence) (escape_sequence)))
(expression_statement (string_literal))
(expression_statement (string_literal))
(expression_statement (string_literal))
(expression_statement (string_literal)))))
============================================
Character literals
============================================
int main() {
'a';
'\0';
'\t';
'\'';
L'b';
u'c';
U'\xa1';
u8'\x1A';
}
---
(translation_unit
(function_definition
(primitive_type)
(function_declarator (identifier) (parameter_list))
(compound_statement
(expression_statement (char_literal))
(expression_statement (char_literal (escape_sequence)))
(expression_statement (char_literal (escape_sequence)))
(expression_statement (char_literal (escape_sequence)))
(expression_statement (char_literal))
(expression_statement (char_literal))
(expression_statement (char_literal (escape_sequence)))
(expression_statement (char_literal (escape_sequence))))))
============================================
Field access
============================================
int main() {
s.data1;
p->data2;
q[data3];
}
---
(translation_unit
(function_definition
(primitive_type)
(function_declarator (identifier) (parameter_list))
(compound_statement
(expression_statement (field_expression (identifier) (field_identifier)))
(expression_statement (field_expression (identifier) (field_identifier)))
(expression_statement (subscript_expression (identifier) (identifier))))))
============================================
Boolean operators
============================================
int main() {
!x || !y && !z;
}
---
(translation_unit
(function_definition
(primitive_type)
(function_declarator (identifier) (parameter_list))
(compound_statement
(expression_statement (binary_expression
(unary_expression (identifier))
(binary_expression
(unary_expression (identifier))
(unary_expression (identifier))))))))
============================================
Math operators
============================================
int main() {
-a / b + c * -d;
a++ - ++b + c-- + --d;
++L;
}
---
(translation_unit
(function_definition
(primitive_type)
(function_declarator (identifier) (parameter_list))
(compound_statement
(expression_statement (binary_expression
(binary_expression
(unary_expression (identifier))
(identifier))
(binary_expression
(identifier)
(unary_expression (identifier)))))
(expression_statement
(binary_expression
(binary_expression
(binary_expression
(update_expression (identifier))
(update_expression (identifier)))
(update_expression (identifier)))
(update_expression (identifier))))
(expression_statement (update_expression (identifier))))))
============================================
The comma operator
============================================
int main() {
i--, j--;
(i--, j--);
}
---
(translation_unit
(function_definition
(primitive_type)
(function_declarator (identifier) (parameter_list))
(compound_statement
(expression_statement
(comma_expression
(update_expression (identifier))
(update_expression (identifier))))
(expression_statement
(parenthesized_expression
(comma_expression
(update_expression (identifier))
(update_expression (identifier))))))))
============================================
Assignments
============================================
int main() {
static int a = 1;
b = *c = 2;
d.e = 3;
f->g = 4;
h[i] = j;
k += l;
m -= o;
n *= p;
q /= r;
*s++ = 1;
(*t) = 1;
}
---
(translation_unit
(function_definition
type: (primitive_type)
declarator: (function_declarator
declarator: (identifier)
parameters: (parameter_list))
body: (compound_statement
(declaration
(storage_class_specifier)
type: (primitive_type)
declarator: (init_declarator
declarator: (identifier)
value: (number_literal)))
(expression_statement (assignment_expression
left: (identifier)
right: (assignment_expression
left: (pointer_expression
argument: (identifier))
right: (number_literal))))
(expression_statement (assignment_expression
left: (field_expression
argument: (identifier)
field: (field_identifier))
right: (number_literal)))
(expression_statement (assignment_expression
left: (field_expression
argument: (identifier)
field: (field_identifier))
right: (number_literal)))
(expression_statement (assignment_expression
left: (subscript_expression
argument: (identifier)
index: (identifier))
right: (identifier)))
(expression_statement (assignment_expression
left: (identifier)
right: (identifier)))
(expression_statement (assignment_expression
left: (identifier)
right: (identifier)))
(expression_statement (assignment_expression
left: (identifier)
right: (identifier)))
(expression_statement (assignment_expression
left: (identifier)
right: (identifier)))
(expression_statement (assignment_expression
left: (pointer_expression
argument: (update_expression
argument: (identifier)))
right: (number_literal)))
(expression_statement (assignment_expression
left: (parenthesized_expression (pointer_expression
argument: (identifier)))
right: (number_literal))))))
============================================
Pointer operations
============================================
int main() {
doSomething(&x, *x);
}
---
(translation_unit
(function_definition
(primitive_type)
(function_declarator (identifier) (parameter_list))
(compound_statement
(expression_statement (call_expression
(identifier)
(argument_list
(pointer_expression (identifier))
(pointer_expression (identifier))))))))
============================================
Type-casts
============================================
int main() {
x = (const SomeType *)thing;
}
---
(translation_unit
(function_definition
type: (primitive_type)
declarator: (function_declarator
declarator: (identifier)
parameters: (parameter_list))
body: (compound_statement
(expression_statement (assignment_expression
left: (identifier)
right: (cast_expression
type: (type_descriptor
(type_qualifier)
type: (type_identifier)
declarator: (abstract_pointer_declarator))
value: (identifier)))))))
============================================
Sizeof expressions
============================================
int main() {
sizeof x.a;
sizeof(x.a);
sizeof(const char **);
sizeof(char * ());
}
---
(translation_unit
(function_definition
(primitive_type)
(function_declarator (identifier) (parameter_list))
(compound_statement
(expression_statement (sizeof_expression (field_expression (identifier) (field_identifier))))
(expression_statement (sizeof_expression (parenthesized_expression (field_expression (identifier) (field_identifier)))))
(expression_statement (sizeof_expression
(type_descriptor (type_qualifier) (primitive_type) (abstract_pointer_declarator (abstract_pointer_declarator)))))
(expression_statement (sizeof_expression
(type_descriptor (primitive_type) (abstract_pointer_declarator (abstract_function_declarator (parameter_list)))))))))
============================================
Compound literals
============================================
int main() {
x = (SomeType) {
.f1.f2[f3] = 5,
.f4 = {}
};
y = (struct SomeStruct) {
7,
8
};
z = (char const []) {'a', 'b'};
}
---
(translation_unit
(function_definition
(primitive_type)
(function_declarator (identifier) (parameter_list))
(compound_statement
(expression_statement (assignment_expression
(identifier)
(compound_literal_expression
(type_descriptor (type_identifier))
(initializer_list
(initializer_pair
(field_designator (field_identifier))
(field_designator (field_identifier))
(subscript_designator (identifier))
(number_literal))
(initializer_pair
(field_designator (field_identifier))
(initializer_list))))))
(expression_statement (assignment_expression
(identifier)
(compound_literal_expression
(type_descriptor (struct_specifier (type_identifier)))
(initializer_list
(number_literal)
(number_literal)))))
(expression_statement
(assignment_expression
(identifier)
(compound_literal_expression
(type_descriptor (primitive_type) (type_qualifier) (abstract_array_declarator))
(initializer_list (char_literal) (char_literal))))))))
============================================
Compound literals with trailing commas
============================================
int main() {
y = (struct SomeStruct) { 7, 8, };
}
---
(translation_unit
(function_definition
(primitive_type)
(function_declarator (identifier) (parameter_list))
(compound_statement
(expression_statement (assignment_expression
(identifier)
(compound_literal_expression
(type_descriptor (struct_specifier (type_identifier)))
(initializer_list
(number_literal)
(number_literal))))))))
====================================
Comments with escaped newlines
====================================
// one \
two
---
(translation_unit
(comment))
==============================================
Comments with escaped chars and newlines
==============================================
// one \a \b \
two
// one \c \d
---
(translation_unit
(comment)
(comment))

View file

@ -0,0 +1,187 @@
================================
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;
}
---
(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))))

View file

@ -0,0 +1,274 @@
============================================
Include directives
============================================
#include "some/path.h"
#include <stdint.h>
#include MACRO
#include MACRO(arg1, arg2)
---
(translation_unit
(preproc_include path: (string_literal))
(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
---
(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)))
============================================
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)))))
===============================================================
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))))
(preproc_else
(expression_statement (call_expression (identifier) (argument_list (string_literal))))))
(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))))

View file

@ -0,0 +1,326 @@
============================================
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)))
(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))))))))
============================================
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))))
(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)))
============================================
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))
(attributed_statement (attribute_declaration (attribute (identifier))) (compound_statement)))
(do_statement
(attributed_statement (attribute_declaration (attribute (identifier))) (compound_statement))
(parenthesized_expression (true))))))

View file

@ -0,0 +1,80 @@
========================================
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))))))

View file

@ -0,0 +1,6 @@
#include <stdlib.h>
// ^ keyword
// ^ string
#include "something.h"
// ^ string

View file

@ -0,0 +1,33 @@
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;
}