Add 'vendor/tree-sitter-cpp/' from commit '9a3f2509fe5ba5a0310b5ec5aa1a7f0b595520a9'

git-subtree-dir: vendor/tree-sitter-cpp
git-subtree-mainline: 3d5bd4069f
git-subtree-split: 9a3f2509fe
edge_only_predecessors
Wilfred Hughes 2021-09-17 22:12:45 +07:00
commit 3068ad64a9
34 changed files with 297153 additions and 0 deletions

@ -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

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

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

@ -0,0 +1,4 @@
corpus
examples
build
target

@ -0,0 +1,9 @@
language: node_js
sudo: false
node_js: 10
branches:
only:
- master

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

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

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

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

@ -0,0 +1,28 @@
#include "tree_sitter/parser.h"
#include <node.h>
#include "nan.h"
using namespace v8;
extern "C" TSLanguage * tree_sitter_cpp();
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_cpp());
Nan::Set(instance, Nan::New("name").ToLocalChecked(), Nan::New("cpp").ToLocalChecked());
Nan::Set(module, Nan::New("exports").ToLocalChecked(), instance);
}
NODE_MODULE(tree_sitter_cpp_binding, Init)
} // namespace

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

@ -0,0 +1,37 @@
# tree-sitter-cpp
This crate provides a CPP 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-cpp = "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_cpp::language()).expect("Error loading CPP 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-cpp/*/tree_sitter_cpp/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

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

@ -0,0 +1,66 @@
// -*- coding: utf-8 -*-
// ------------------------------------------------------------------------------------------------
// Copyright © 2021, tree-sitter-cpp authors.
// See the LICENSE file in this repo for license details.
// ------------------------------------------------------------------------------------------------
//! This crate provides a Cpp 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 Cpp 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_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 source of the Cpp 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 Cpp grammar");
}
}

@ -0,0 +1,131 @@
#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_

@ -0,0 +1,287 @@
#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

@ -0,0 +1,960 @@
const C = require("tree-sitter-c/grammar")
const PREC = Object.assign(C.PREC, {
LAMBDA: 18,
NEW: C.PREC.CALL + 1,
STRUCTURED_BINDING: -1,
})
module.exports = grammar(C, {
name: 'cpp',
externals: $ => [
$.raw_string_literal
],
conflicts: ($, original) => original.concat([
[$.template_function, $.template_type],
[$.template_function, $.template_type, $._expression],
[$.template_function, $._expression],
[$.template_method, $.template_type, $.field_expression],
[$.scoped_type_identifier, $.scoped_identifier],
[$.scoped_type_identifier, $.scoped_field_identifier],
[$.comma_expression, $.initializer_list],
[$._expression, $._declarator],
[$._expression, $.structured_binding_declarator],
[$._expression, $._declarator, $._type_specifier],
[$.parameter_list, $.argument_list],
[$._type_specifier, $.call_expression],
[$._declaration_specifiers, $._constructor_specifiers],
[$._declaration_specifiers, $.operator_cast_declaration, $.operator_cast_definition, $.constructor_or_destructor_definition],
[$._declaration_specifiers, $.attributed_statement, $.operator_cast_declaration, $.operator_cast_definition, $.constructor_or_destructor_definition],
[$.attributed_statement, $.operator_cast_declaration, $.operator_cast_definition, $.constructor_or_destructor_definition],
]),
inline: ($, original) => original.concat([
$._namespace_identifier,
]),
rules: {
_top_level_item: ($, original) => choice(
original,
$.namespace_definition,
$.using_declaration,
$.alias_declaration,
$.static_assert_declaration,
$.template_declaration,
$.template_instantiation,
alias($.constructor_or_destructor_definition, $.function_definition),
alias($.operator_cast_definition, $.function_definition),
alias($.operator_cast_declaration, $.declaration),
),
// Types
decltype: $ => seq(
'decltype',
'(',
$._expression,
')',
),
_type_specifier: $ => choice(
$.struct_specifier,
$.union_specifier,
$.enum_specifier,
$.class_specifier,
$.sized_type_specifier,
$.primitive_type,
$.template_type,
$.auto,
$.dependent_type,
$.decltype,
prec.right(choice(
$.scoped_type_identifier,
$._type_identifier
))
),
type_qualifier: ($, original) => choice(
original,
'mutable',
'constexpr'
),
// When used in a trailing return type, these specifiers can now occur immediately before
// a compound statement. This introduces a shift/reduce conflict that needs to be resolved
// with an associativity.
class_specifier: $ => prec.right(seq(
'class',
optional($.ms_declspec_modifier),
choice(
field('name', $._class_name),
seq(
optional(field('name', $._class_name)),
optional($.virtual_specifier),
optional($.base_class_clause),
field('body', $.field_declaration_list)
)
)
)),
union_specifier: $ => prec.right(seq(
'union',
optional($.ms_declspec_modifier),
choice(
field('name', $._class_name),
seq(
optional(field('name', $._class_name)),
optional($.virtual_specifier),
optional($.base_class_clause),
field('body', $.field_declaration_list)
)
)
)),
struct_specifier: $ => prec.right(seq(
'struct',
optional($.ms_declspec_modifier),
choice(
field('name', $._class_name),
seq(
optional(field('name', $._class_name)),
optional($.virtual_specifier),
optional($.base_class_clause),
field('body', $.field_declaration_list)
)
)
)),
_class_name: $ => prec.right(choice(
$._type_identifier,
$.scoped_type_identifier,
$.template_type
)),
virtual_specifier: $ => choice(
'final', // the only legal value here for classes
'override' // legal for functions in addition to final, plus permutations.
),
virtual_function_specifier: $ => choice(
'virtual'
),
explicit_function_specifier: $ => choice(
'explicit',
prec(PREC.CALL, seq(
'explicit',
'(',
$._expression,
')'
))
),
base_class_clause: $ => seq(
':',
commaSep1(seq(
optional(choice('public', 'private', 'protected')),
$._class_name,
optional('...')
))
),
enum_specifier: $ => prec.left(seq(
'enum',
optional(choice('class', 'struct')),
choice(
seq(
field('name', $._class_name),
optional($._enum_base_clause),
optional(field('body', $.enumerator_list))
),
field('body', $.enumerator_list)
)
)),
_enum_base_clause: $ => prec.left(seq(
':',
field('base', choice($.scoped_type_identifier, $._type_identifier, $.sized_type_specifier))
)),
// The `auto` storage class is removed in C++0x in order to allow for the `auto` type.
storage_class_specifier: ($, original) => choice(
...original.members.filter(member => member.value !== 'auto'),
'thread_local',
),
auto: $ => 'auto',
dependent_type: $ => prec.dynamic(-1, seq(
'typename',
$._type_specifier
)),
// Declarations
template_declaration: $ => seq(
'template',
field('parameters', $.template_parameter_list),
choice(
$._empty_declaration,
$.alias_declaration,
$.declaration,
$.template_declaration,
$.function_definition,
alias($.constructor_or_destructor_declaration, $.declaration),
alias($.constructor_or_destructor_definition, $.function_definition),
alias($.operator_cast_declaration, $.declaration),
alias($.operator_cast_definition, $.function_definition),
)
),
template_instantiation: $ => seq(
'template',
optional($._declaration_specifiers),
field('declarator', $._declarator),
';'
),
template_parameter_list: $ => seq(
'<',
commaSep(choice(
$.parameter_declaration,
$.optional_parameter_declaration,
$.type_parameter_declaration,
$.variadic_parameter_declaration,
$.variadic_type_parameter_declaration,
$.optional_type_parameter_declaration,
$.template_template_parameter_declaration
)),
alias(token(prec(1, '>')), '>')
),
type_parameter_declaration: $ => prec(1, seq(
choice('typename', 'class'),
optional($._type_identifier)
)),
variadic_type_parameter_declaration: $ => prec(1, seq(
choice('typename', 'class'),
'...',
optional($._type_identifier)
)),
optional_type_parameter_declaration: $ => seq(
choice('typename', 'class'),
optional(field('name', $._type_identifier)),
'=',
field('default_type', $._type_specifier)
),
template_template_parameter_declaration: $ => seq(
'template',
field('parameters', $.template_parameter_list),
choice(
$.type_parameter_declaration,
$.variadic_type_parameter_declaration,
$.optional_type_parameter_declaration
)
),
parameter_list: $ => seq(
'(',
commaSep(choice(
$.parameter_declaration,
$.optional_parameter_declaration,
$.variadic_parameter_declaration,
'...'
)),
')'
),
optional_parameter_declaration: $ => seq(
$._declaration_specifiers,
field('declarator', optional($._declarator)),
'=',
field('default_value', $._expression)
),
variadic_parameter_declaration: $ => seq(
$._declaration_specifiers,
field('declarator', choice(
$.variadic_declarator,
alias($.variadic_reference_declarator, $.reference_declarator)
))
),
variadic_declarator: $ => seq(
'...',
optional($.identifier)
),
variadic_reference_declarator: $ => seq(
choice('&&', '&'),
$.variadic_declarator
),
init_declarator: ($, original) => choice(
original,
seq(
field('declarator', $._declarator),
field('value', choice(
$.argument_list,
$.initializer_list
))
)
),
operator_cast: $ => prec(1, seq(
optional(seq(
field('namespace', optional(choice(
$._namespace_identifier,
$.template_type,
$.scoped_namespace_identifier
))),
'::',
)),
'operator',
$._declaration_specifiers,
field('declarator', $._abstract_declarator),
)),
// Avoid ambiguity between compound statement and initializer list in a construct like:
// A b {};
compound_statement: ($, original) => prec(-1, original),
field_initializer_list: $ => seq(
':',
commaSep1($.field_initializer)
),
field_initializer: $ => prec(1, seq(
choice($._field_identifier, $.scoped_field_identifier),
choice($.initializer_list, $.argument_list),
optional('...')
)),
_field_declaration_list_item: ($, original) => choice(
original,
$.template_declaration,
alias($.inline_method_definition, $.function_definition),
alias($.constructor_or_destructor_definition, $.function_definition),
alias($.constructor_or_destructor_declaration, $.declaration),
alias($.operator_cast_definition, $.function_definition),
alias($.operator_cast_declaration, $.declaration),
$.friend_declaration,
$.access_specifier,
$.alias_declaration,
$.using_declaration,
$.type_definition,
$.static_assert_declaration
),
field_declaration: $ => seq(
optional($.virtual_function_specifier),
$._declaration_specifiers,
commaSep(field('declarator', $._field_declarator)),
optional(choice(
$.bitfield_clause,
field('default_value', $.initializer_list),
seq('=', field('default_value', choice($._expression, $.initializer_list)))
)),
';'
),
inline_method_definition: $ => seq(
optional($.virtual_function_specifier),
$._declaration_specifiers,
field('declarator', $._field_declarator),
choice(
field('body', $.compound_statement),
$.default_method_clause,
$.delete_method_clause
)
),
_constructor_specifiers: $ => repeat1(
prec.right(choice(
$.storage_class_specifier,
$.type_qualifier,
$.attribute_specifier,
$.attribute_declaration,
$.virtual_function_specifier,
$.explicit_function_specifier
))
),
operator_cast_definition: $ => seq(
optional($._constructor_specifiers),
field('declarator', $.operator_cast),
choice(
field('body', $.compound_statement),
$.default_method_clause,
$.delete_method_clause
)
),
operator_cast_declaration: $ => prec(1, seq(
optional($._constructor_specifiers),
field('declarator', $.operator_cast),
optional(seq('=', field('default_value', $._expression))),
';'
)),
constructor_or_destructor_definition: $ => seq(
optional($._constructor_specifiers),
field('declarator', $.function_declarator),
optional($.field_initializer_list),
choice(
field('body', $.compound_statement),
$.default_method_clause,
$.delete_method_clause
)
),
constructor_or_destructor_declaration: $ => seq(
optional($._constructor_specifiers),
field('declarator', $.function_declarator),
';'
),
default_method_clause: $ => seq('=', 'default', ';'),
delete_method_clause: $ => seq('=', 'delete', ';'),
friend_declaration: $ => seq(
'friend',
choice(
$.declaration,
$.function_definition,
seq(
optional(choice(
'class',
'struct',
'union'
)),
$._class_name, ';'
)
)
),
access_specifier: $ => seq(
choice(
'public',
'private',
'protected'
),
':'
),
_declarator: ($, original) => choice(
original,
$.reference_declarator,
$.scoped_identifier,
$.template_function,
$.operator_name,
$.destructor_name,
$.structured_binding_declarator
),
_field_declarator: ($, original) => choice(
original,
alias($.reference_field_declarator, $.reference_declarator),
$.template_method,
$.operator_name
),
_abstract_declarator: ($, original) => choice(
original,
$.abstract_reference_declarator
),
reference_declarator: $ => prec.dynamic(1, prec.right(seq(choice('&', '&&'), $._declarator))),
reference_field_declarator: $ => prec.dynamic(1, prec.right(seq(choice('&', '&&'), $._field_declarator))),
abstract_reference_declarator: $ => prec.right(seq(choice('&', '&&'), optional($._abstract_declarator))),
structured_binding_declarator: $ => prec.dynamic(PREC.STRUCTURED_BINDING, seq(
'[', commaSep1($.identifier), ']'
)),
function_declarator: ($, original) => prec.dynamic(1, seq(
original,
repeat(choice(
$.type_qualifier,
$.virtual_specifier,
$.noexcept,
$.throw_specifier,
$.trailing_return_type
))
)),
function_field_declarator: ($, original) => prec.dynamic(1, seq(
original,
repeat(choice(
$.type_qualifier,
$.virtual_specifier,
$.noexcept,
$.throw_specifier,
$.trailing_return_type
))
)),
abstract_function_declarator: ($, original) => prec.right(seq(
original,
repeat(choice(
$.type_qualifier,
$.noexcept,
$.throw_specifier
)),
optional($.trailing_return_type)
)),
trailing_return_type: $ => prec.right(seq(
'->',
optional($.type_qualifier),
$._type_specifier,
optional($._abstract_declarator)
)),
noexcept: $ => prec.right(seq(
'noexcept',
optional(
seq(
'(',
optional($._expression),
')',
),
),
)),
throw_specifier: $ => seq(
'throw',
seq(
'(',
commaSep($.type_descriptor),
')',
)
),
template_type: $ => seq(
field('name', choice($._type_identifier, $.scoped_type_identifier)),
field('arguments', $.template_argument_list)
),
template_method: $ => seq(
field('name', choice($._field_identifier, $.scoped_field_identifier)),
field('arguments', $.template_argument_list)
),
template_function: $ => seq(
field('name', choice($.identifier, $.scoped_identifier)),
field('arguments', $.template_argument_list)
),
template_argument_list: $ => seq(
'<',
commaSep(choice(
prec.dynamic(3, $.type_descriptor),
prec.dynamic(2, alias($.type_parameter_pack_expansion, $.parameter_pack_expansion)),
prec.dynamic(1, $._expression)
)),
alias(token(prec(1, '>')), '>')
),
namespace_definition: $ => seq(
'namespace',
field('name', optional(
choice(
$.identifier,
$.namespace_definition_name,
))),
field('body', $.declaration_list)
),
namespace_definition_name: $ => seq(
choice(
$.identifier,
$.namespace_definition_name,
),
'::',
optional('inline'),
$.identifier,
),
using_declaration: $ => seq(
'using',
optional('namespace'),
choice(
$.identifier,
$.scoped_identifier
),
';'
),
alias_declaration: $ => seq(
'using',
field('name', $._type_identifier),
'=',
field('type', $.type_descriptor),
';'
),
static_assert_declaration: $ => seq(
'static_assert',
'(',
field('condition', $._expression),
optional(seq(
',',
field('message', choice(
$.string_literal,
$.raw_string_literal,
$.concatenated_string,
))
)),
')',
';'
),
// Statements
_non_case_statement: ($, original) => choice(
original,
$.co_return_statement,
$.co_yield_statement,
$.for_range_loop,
$.try_statement,
$.throw_statement,
),
switch_statement: $ => seq(
'switch',
field('condition', $.condition_clause),
field('body', $.compound_statement)
),
while_statement: $ => seq(
'while',
field('condition', $.condition_clause),
field('body', $._statement)
),
if_statement: $ => prec.right(seq(
'if',
optional('constexpr'),
field('condition', $.condition_clause),
field('consequence', $._statement),
optional(seq(
'else',
field('alternative', $._statement)
))
)),
condition_clause: $ => seq(
'(',
choice(
seq(
field('initializer', optional(choice(
$.declaration,
$.expression_statement
))),
field('value', choice(
$._expression,
$.comma_expression
)),
),
field('value', alias($.condition_declaration, $.declaration))
),
')',
),
condition_declaration: $ => seq(
$._declaration_specifiers,
field('declarator', $._declarator),
choice(
seq(
'=',
field('value', $._expression),
),
field('value', $.initializer_list),
)
),
for_range_loop: $ => seq(
'for',
'(',
$._declaration_specifiers,
field('declarator', $._declarator),
':',
field('right', choice(
$._expression,
$.initializer_list,
)),
')',
field('body', $._statement)
),
return_statement: ($, original) => seq(
choice(
original,
seq('return', $.initializer_list, ';')
)
),
co_return_statement: $ => seq(
'co_return',
optional($._expression),
';'
),
co_yield_statement: $ => seq(
'co_yield',
$._expression,
';'
),
throw_statement: $ => seq(
'throw',
optional($._expression),
';'
),
try_statement: $ => seq(
'try',
field('body', $.compound_statement),
repeat1($.catch_clause)
),
catch_clause: $ => seq(
'catch',
field('parameters', $.parameter_list),
field('body', $.compound_statement)
),
// Expressions
_expression: ($, original) => choice(
original,
$.co_await_expression,
$.template_function,
$.scoped_identifier,
$.new_expression,
$.delete_expression,
$.lambda_expression,
$.parameter_pack_expansion,
$.nullptr,
$.this,
$.raw_string_literal
),
subscript_expression: $ => prec(PREC.SUBSCRIPT, seq(
field('argument', $._expression),
'[',
field('index', choice($._expression, $.initializer_list)),
']'
)),
call_expression: ($, original) => choice(original, seq(
field('function', $.primitive_type),
field('arguments', $.argument_list)
)),
co_await_expression: $ => prec.left(PREC.UNARY, seq(
field('operator', 'co_await'),
field('argument', $._expression)
)),
new_expression: $ => prec.right(PREC.NEW, seq(
optional('::'),
'new',
field('placement', optional($.argument_list)),
field('type', $._type_specifier),
field('declarator', optional($.new_declarator)),
field('arguments', optional(choice(
$.argument_list,
$.initializer_list
)))
)),
new_declarator: $ => prec.right(seq(
'[',
field('length', $._expression),
']',
optional($.new_declarator)
)),
delete_expression: $ => seq(
optional('::'),
'delete',
optional(seq('[', ']')),
$._expression
),
field_expression: ($, original) => choice(
original,
seq(
prec(PREC.FIELD, seq(
field('argument', $._expression),
choice('.', '->')
)),
field('field', choice(
$.destructor_name,
$.template_method
))
)
),
lambda_expression: $ => seq(
field('captures', $.lambda_capture_specifier),
optional(field('declarator', $.abstract_function_declarator)),
field('body', $.compound_statement)
),
lambda_capture_specifier: $ => prec(PREC.LAMBDA, seq(
'[',
choice(
$.lambda_default_capture,
commaSep($._expression),
seq(
$.lambda_default_capture,
',', commaSep1($._expression)
)
),
']'
)),
lambda_default_capture: $ => choice('=', '&'),
parameter_pack_expansion: $ => prec(-1, seq(
field('pattern', $._expression),
'...'
)),
type_parameter_pack_expansion: $ => seq(
field('pattern', $.type_descriptor),
'...'
),
sizeof_expression: ($, original) => choice(
original,
seq(
'sizeof', '...',
'(',
field('value', $.identifier),
')'
),
),
argument_list: $ => seq(
'(',
commaSep(choice($._expression, $.initializer_list)),
')'
),
destructor_name: $ => prec(1, seq('~', $.identifier)),
compound_literal_expression: ($, original) => choice(
original,
seq(
field('type', choice(
$._type_identifier,
$.template_type,
$.scoped_type_identifier
)),
field('value', $.initializer_list)
)
),
scoped_field_identifier: $ => prec(1, seq(
field('namespace', optional(choice(
$._namespace_identifier,
$.template_type,
$.scoped_namespace_identifier
))),
'::',
field('name', choice(
$._field_identifier,
$.operator_name,
$.destructor_name
))
)),
scoped_identifier: $ => prec(1, seq(
field('namespace', optional(choice(
$._namespace_identifier,
$.template_type,
$.scoped_namespace_identifier
))),
'::',
field('name', choice(
$.identifier,
$.operator_name,
$.destructor_name
))
)),
scoped_type_identifier: $ => prec(1, seq(
field('namespace', optional(choice(
$._namespace_identifier,
$.template_type,
$.scoped_namespace_identifier
))),
'::',
field('name', $._type_identifier)
)),
scoped_namespace_identifier: $ => prec(2, seq(
field('namespace', optional(choice(
$._namespace_identifier,
$.template_type,
$.scoped_namespace_identifier
))),
'::',
field('name', $._namespace_identifier)
)),
_assignment_left_expression: ($, original) => choice(
original,
$.scoped_namespace_identifier,
),
operator_name: $ => token(seq(
'operator',
/\s*/,
choice(
'co_await',
'+', '-', '*', '/', '%',
'^', '&', '|', '~',
'!', '=', '<', '>',
'+=', '-=', '*=', '/=', '%=', '^=', '&=', '|=',
'<<', '>>', '>>=', '<<=',
'==', '!=', '<=', '>=',
'&&', '||',
'++', '--',
',',
'->*',
'->',
'()', '[]',
seq(choice('new', 'delete'), /\s*/, optional('[]')),
)
)),
this: $ => 'this',
nullptr: $ => 'nullptr',
concatenated_string: $ => seq(
choice($.raw_string_literal, $.string_literal),
repeat1(choice($.raw_string_literal, $.string_literal))
),
_namespace_identifier: $ => alias($.identifier, $.namespace_identifier)
}
});
function commaSep(rule) {
return optional(commaSep1(rule));
}
function commaSep1(rule) {
return seq(rule, repeat(seq(',', rule)));
}

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

@ -0,0 +1,69 @@
; Functions
(call_expression
function: (scoped_identifier
name: (identifier) @function))
(template_function
name: (identifier) @function)
(template_method
name: (field_identifier) @function)
(template_function
name: (scoped_identifier
name: (identifier) @function))
(function_declarator
declarator: (scoped_identifier
name: (identifier) @function))
(function_declarator
declarator: (scoped_identifier
name: (identifier) @function))
(function_declarator
declarator: (field_identifier) @function)
; Types
((namespace_identifier) @type
(#match? @type "^[A-Z]"))
(auto) @type
; Constants
(this) @variable.builtin
(nullptr) @constant
; Keywords
"catch" @keyword
"class" @keyword
"co_await" @keyword
"co_return" @keyword
"co_yield" @keyword
"constexpr" @keyword
"delete" @keyword
"explicit" @keyword
"final" @keyword
"friend" @keyword
"mutable" @keyword
"namespace" @keyword
"noexcept" @keyword
"new" @keyword
"override" @keyword
"private" @keyword
"protected" @keyword
"public" @keyword
"template" @keyword
"throw" @keyword
"try" @keyword
"typename" @keyword
"using" @keyword
"virtual" @keyword
; Strings
(raw_string_literal) @string

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

@ -0,0 +1,119 @@
#include <tree_sitter/parser.h>
#include <string>
#include <cwctype>
namespace {
using std::wstring;
using std::iswspace;
enum TokenType {
RAW_STRING_LITERAL,
};
struct Scanner {
bool scan(TSLexer *lexer, const bool *valid_symbols) {
while (iswspace(lexer->lookahead)) {
lexer->advance(lexer, true);
}
lexer->result_symbol = RAW_STRING_LITERAL;
// Raw string literals can start with: R, LR, uR, UR, u8R
// Consume 'R'
if (lexer->lookahead == 'L' || lexer->lookahead == 'U') {
lexer->advance(lexer, false);
if (lexer->lookahead != 'R') {
return false;
}
} else if (lexer->lookahead == 'u') {
lexer->advance(lexer, false);
if (lexer->lookahead == '8') {
lexer->advance(lexer, false);
if (lexer->lookahead != 'R') {
return false;
}
} else if (lexer->lookahead != 'R') {
return false;
}
} else if (lexer->lookahead != 'R') {
return false;
}
lexer->advance(lexer, false);
// Consume '"'
if (lexer->lookahead != '"') return false;
lexer->advance(lexer, false);
// Consume '(', delimiter
wstring delimiter;
for (;;) {
if (lexer->lookahead == 0 || lexer->lookahead == '\\' || iswspace(lexer->lookahead)) {
return false;
}
if (lexer->lookahead == '(') {
lexer->advance(lexer, false);
break;
}
delimiter += lexer->lookahead;
lexer->advance(lexer, false);
}
// Consume content, delimiter, ')', '"'
int delimiter_index = -1;
for (;;) {
if (lexer->lookahead == 0) return false;
if (delimiter_index >= 0) {
if (static_cast<unsigned>(delimiter_index) == delimiter.size()) {
if (lexer->lookahead == '"') {
lexer->advance(lexer, false);
return true;
} else {
delimiter_index = -1;
}
} else {
if (lexer->lookahead == delimiter[delimiter_index]) {
delimiter_index++;
} else {
delimiter_index = -1;
}
}
}
if (delimiter_index == -1 && lexer->lookahead == ')') {
delimiter_index = 0;
}
lexer->advance(lexer, false);
}
}
};
}
extern "C" {
void *tree_sitter_cpp_external_scanner_create() {
return new Scanner();
}
bool tree_sitter_cpp_external_scanner_scan(void *payload, TSLexer *lexer,
const bool *valid_symbols) {
Scanner *scanner = static_cast<Scanner *>(payload);
return scanner->scan(lexer, valid_symbols);
}
unsigned tree_sitter_cpp_external_scanner_serialize(void *payload, char *buffer) {
return 0;
}
void tree_sitter_cpp_external_scanner_deserialize(void *payload, const char *buffer, unsigned length) {
}
void tree_sitter_cpp_external_scanner_destroy(void *payload) {
Scanner *scanner = static_cast<Scanner *>(payload);
delete scanner;
}
}

@ -0,0 +1,223 @@
#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;
};
/*
* 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_

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

@ -0,0 +1,100 @@
================================================
template functions vs relational expressions
================================================
T1 a = b < c > d;
T2 e = f<T3>(g);
int a = std::get<0>(t);
---
(translation_unit
(declaration
(type_identifier)
(init_declarator
(identifier)
(binary_expression
(binary_expression (identifier) (identifier))
(identifier))))
(declaration
(type_identifier)
(init_declarator
(identifier)
(call_expression
(template_function (identifier) (template_argument_list
(type_descriptor (type_identifier))))
(argument_list (identifier)))))
(declaration
(primitive_type)
(init_declarator
(identifier)
(call_expression
(template_function
(scoped_identifier (namespace_identifier) (identifier))
(template_argument_list (number_literal)))
(argument_list (identifier))))))
=================================================
function declarations vs variable initializations
=================================================
// Function declarations
T1 a(T2 *b);
T3 c(T4 &d, T5 &&e);
// Variable declarations with initializers
T7 f(g.h);
T6 i{j};
---
(translation_unit
(comment)
(declaration
(type_identifier)
(function_declarator
(identifier)
(parameter_list (parameter_declaration (type_identifier) (pointer_declarator (identifier))))))
(declaration
(type_identifier)
(function_declarator
(identifier)
(parameter_list
(parameter_declaration (type_identifier) (reference_declarator (identifier)))
(parameter_declaration (type_identifier) (reference_declarator (identifier))))))
(comment)
(declaration
(type_identifier)
(init_declarator
(identifier)
(argument_list (field_expression (identifier) (field_identifier)))))
(declaration
(type_identifier)
(init_declarator
(identifier)
(initializer_list (identifier)))))
================================================
template classes vs relational expressions
================================================
int main() {
T1<T2> v1;
T1<T2> v2 = v3;
}
---
(translation_unit (function_definition
(primitive_type)
(function_declarator (identifier) (parameter_list))
(compound_statement
(declaration
(template_type (type_identifier)
(template_argument_list (type_descriptor (type_identifier))))
(identifier))
(declaration
(template_type (type_identifier)
(template_argument_list (type_descriptor (type_identifier))))
(init_declarator (identifier) (identifier))))))

File diff suppressed because it is too large Load Diff

@ -0,0 +1,164 @@
=====================================
Scoped function definitions
=====================================
int T::foo() { return 1; }
int T::foo() const { return 0; }
---
(translation_unit
(function_definition
(primitive_type)
(function_declarator
(scoped_identifier (namespace_identifier) (identifier))
(parameter_list))
(compound_statement (return_statement (number_literal))))
(function_definition
(primitive_type)
(function_declarator
(scoped_identifier (namespace_identifier) (identifier))
(parameter_list)
(type_qualifier))
(compound_statement (return_statement (number_literal)))))
=====================================
Constructor definitions
=====================================
T::T() {}
T::T() : f1(0), f2(1, 2) {
puts("HI");
}
---
(translation_unit
(function_definition
(function_declarator
(scoped_identifier (namespace_identifier) (identifier))
(parameter_list))
(compound_statement))
(function_definition
(function_declarator
(scoped_identifier (namespace_identifier) (identifier))
(parameter_list))
(field_initializer_list
(field_initializer (field_identifier) (argument_list (number_literal)))
(field_initializer (field_identifier) (argument_list (number_literal) (number_literal))))
(compound_statement
(expression_statement (call_expression (identifier) (argument_list (string_literal)))))))
=====================================
Explicit constructor definitions
=====================================
class C {
explicit C(int f) : f_(f) {}
private:
int f_;
};
---
(translation_unit
(class_specifier
(type_identifier)
(field_declaration_list
(function_definition
(explicit_function_specifier)
(function_declarator
(identifier)
(parameter_list (parameter_declaration (primitive_type) (identifier))))
(field_initializer_list
(field_initializer (field_identifier) (argument_list (identifier))))
(compound_statement))
(access_specifier)
(field_declaration (primitive_type) (field_identifier)))))
=====================================
Explicit constructor declaration
=====================================
class C {
explicit C(int f);
explicit(true) C(long f);
};
---
(translation_unit
(class_specifier
(type_identifier)
(field_declaration_list
(declaration
(explicit_function_specifier)
(function_declarator (identifier) (parameter_list (parameter_declaration (primitive_type) (identifier)))))
(declaration
(explicit_function_specifier (true))
(function_declarator (identifier) (parameter_list (parameter_declaration (sized_type_specifier) (identifier))))))))
=====================================
Default and deleted methods
=====================================
class A : public B {
A() = default;
A(A &&) = delete;
void f() = delete;
A& operator=(const A&) = default;
A& operator=(A&&) = delete;
};
---
(translation_unit
(class_specifier
(type_identifier)
(base_class_clause (type_identifier))
(field_declaration_list
(function_definition
(function_declarator (identifier) (parameter_list))
(default_method_clause))
(function_definition
(function_declarator
(identifier)
(parameter_list (parameter_declaration (type_identifier) (abstract_reference_declarator))))
(delete_method_clause))
(function_definition
(primitive_type)
(function_declarator (field_identifier) (parameter_list)) (delete_method_clause))
(function_definition
(type_identifier)
(reference_declarator
(function_declarator
(operator_name)
(parameter_list (parameter_declaration (type_qualifier) (type_identifier) (abstract_reference_declarator)))))
(default_method_clause))
(function_definition
(type_identifier)
(reference_declarator
(function_declarator
(operator_name)
(parameter_list (parameter_declaration (type_identifier) (abstract_reference_declarator)))))
(delete_method_clause)))))
=====================================
Destructor definitions
=====================================
~T() {}
T::~T() {}
---
(translation_unit
(function_definition
(function_declarator (destructor_name (identifier)) (parameter_list))
(compound_statement))
(function_definition
(function_declarator
(scoped_identifier (namespace_identifier) (destructor_name (identifier))) (parameter_list))
(compound_statement)))

@ -0,0 +1,703 @@
================================================
Scoped function calls
================================================
int main() {
abc::def("hello", "world");
}
---
(translation_unit (function_definition
(primitive_type)
(function_declarator (identifier) (parameter_list))
(compound_statement
(expression_statement (call_expression
(scoped_identifier (namespace_identifier) (identifier))
(argument_list
(string_literal)
(string_literal)))))))
=================================================
Compound literals without parentheses
=================================================
T x = T{0};
U<V> y = U<V>{0};
---
(translation_unit
(declaration
(type_identifier)
(init_declarator
(identifier)
(compound_literal_expression
(type_identifier)
(initializer_list (number_literal)))))
(declaration
(template_type (type_identifier) (template_argument_list (type_descriptor (type_identifier))))
(init_declarator
(identifier)
(compound_literal_expression
(template_type (type_identifier) (template_argument_list (type_descriptor (type_identifier))))
(initializer_list (number_literal))))))
=================================================
Explicit destructor calls
=================================================
int main() {
foo.~Foo();
bar->~Bar();
}
---
(translation_unit
(function_definition
(primitive_type)
(function_declarator (identifier) (parameter_list))
(compound_statement
(expression_statement (call_expression
(field_expression (identifier) (destructor_name (identifier)))
(argument_list)))
(expression_statement (call_expression
(field_expression (identifier) (destructor_name (identifier)))
(argument_list))))))
=================================================
New and Delete expressions
=================================================
int main() {
auto a = new T();
auto b = new U::V<W, X>{};
auto c = new (&d) T;
auto d = new T[5][3]();
auto e = new int[5];
d = new(2, f) T;
delete a;
::delete[] c;
::new (foo(x)) T(this, x);
}
---
(translation_unit
(function_definition
(primitive_type)
(function_declarator (identifier) (parameter_list))
(compound_statement
(declaration
(auto)
(init_declarator
(identifier)
(new_expression (type_identifier) (argument_list))))
(declaration
(auto)
(init_declarator
(identifier)
(new_expression
(template_type
(scoped_type_identifier (namespace_identifier) (type_identifier))
(template_argument_list
(type_descriptor (type_identifier))
(type_descriptor (type_identifier))))
(initializer_list))))
(declaration
(auto)
(init_declarator
(identifier)
(new_expression
(argument_list (pointer_expression (identifier)))
(type_identifier))))
(declaration
(auto)
(init_declarator
(identifier)
(new_expression
(type_identifier)
(new_declarator (number_literal) (new_declarator (number_literal)))
(argument_list))))
(declaration
(auto)
(init_declarator
(identifier)
(new_expression (primitive_type) (new_declarator (number_literal)))))
(expression_statement (assignment_expression
(identifier)
(new_expression
(argument_list (number_literal) (identifier))
(type_identifier))))
(expression_statement (delete_expression (identifier)))
(expression_statement (delete_expression (identifier)))
(expression_statement (new_expression
(argument_list (call_expression (identifier) (argument_list (identifier))))
(type_identifier) (argument_list (this) (identifier)))))))
====================================================
Initializer lists as arguments
====================================================
int main() {
pairs.push_back({true, false});
}
---
(translation_unit
(function_definition
(primitive_type)
(function_declarator (identifier) (parameter_list))
(compound_statement
(expression_statement (call_expression
(field_expression (identifier) (field_identifier))
(argument_list (initializer_list (true) (false))))))))
====================================================
Lambda expressions
====================================================
auto f = [&](int x) -> bool {
return true;
};
auto g = [x, y](int z) {
return false;
};
auto h = [] {
return false;
};
---
(translation_unit
(declaration
(auto)
(init_declarator
(identifier)
(lambda_expression
(lambda_capture_specifier (lambda_default_capture))
(abstract_function_declarator
(parameter_list (parameter_declaration (primitive_type) (identifier)))
(trailing_return_type (primitive_type)))
(compound_statement (return_statement (true))))))
(declaration
(auto)
(init_declarator
(identifier)
(lambda_expression
(lambda_capture_specifier (identifier) (identifier))
(abstract_function_declarator
(parameter_list (parameter_declaration (primitive_type) (identifier))))
(compound_statement (return_statement (false))))))
(declaration
(auto)
(init_declarator
(identifier)
(lambda_expression
(lambda_capture_specifier)
(compound_statement (return_statement (false)))))))
====================================================
Nested template calls
====================================================
class A {
B<C::D<E, F>>::G field;
H<I<J>> method() {
K::L<M<N>> variable1 = K::L<M<N>>{};
}
};
---
(translation_unit
(class_specifier (type_identifier) (field_declaration_list
(field_declaration
(scoped_type_identifier
(template_type
(type_identifier)
(template_argument_list
(type_descriptor (template_type
(scoped_type_identifier (namespace_identifier) (type_identifier))
(template_argument_list
(type_descriptor (type_identifier)) (type_descriptor (type_identifier)))))))
(type_identifier))
(field_identifier))
(function_definition
(template_type
(type_identifier)
(template_argument_list (type_descriptor
(template_type
(type_identifier)
(template_argument_list (type_descriptor (type_identifier)))))))
(function_declarator (field_identifier) (parameter_list))
(compound_statement
(declaration
(template_type
(scoped_type_identifier (namespace_identifier) (type_identifier))
(template_argument_list (type_descriptor
(template_type (type_identifier) (template_argument_list (type_descriptor (type_identifier)))))))
(init_declarator
(identifier)
(compound_literal_expression
(template_type
(scoped_type_identifier (namespace_identifier) (type_identifier))
(template_argument_list (type_descriptor
(template_type
(type_identifier)
(template_argument_list (type_descriptor (type_identifier)))))))
(initializer_list)))))))))
====================================================
Comma expressions at the start of blocks
====================================================
int main() { a(), b(); }
---
(translation_unit
(function_definition
(primitive_type)
(function_declarator (identifier) (parameter_list))
(compound_statement
(expression_statement (comma_expression
(call_expression (identifier) (argument_list))
(call_expression (identifier) (argument_list)))))))
====================================================
Nullptr
====================================================
void *x = nullptr;
---
(translation_unit
(declaration (primitive_type) (init_declarator (pointer_declarator (identifier)) (nullptr))))
====================================================
Raw string literals
====================================================
const char *s1 = R"(
This is a string. It ends with ')' and a quote.
)";
const char *s2 = R"FOO(
This is a string. It ends with ')FOO' and a quote.
)FOO";
const char *s3 = uR"FOO(
This is a string. It ends with ')FOO' and a quote.
)FOO";
const char *s4 = UR"FOO(
This is a string. It ends with ')FOO' and a quote.
)FOO";
const char *s5 = u8R"FOO(
This is a string. It ends with ')FOO' and a quote.
)FOO";
const char *s6 = LR"FOO(
This is a string. It ends with ')FOO' and a quote.
)FOO";
---
(translation_unit
(declaration
(type_qualifier)
(primitive_type)
(init_declarator
(pointer_declarator (identifier))
(raw_string_literal)))
(declaration
(type_qualifier)
(primitive_type)
(init_declarator
(pointer_declarator (identifier))
(raw_string_literal)))
(declaration
(type_qualifier)
(primitive_type)
(init_declarator
(pointer_declarator (identifier))
(raw_string_literal)))
(declaration
(type_qualifier)
(primitive_type)
(init_declarator
(pointer_declarator (identifier))
(raw_string_literal)))
(declaration
(type_qualifier)
(primitive_type)
(init_declarator
(pointer_declarator (identifier))
(raw_string_literal)))
(declaration
(type_qualifier)
(primitive_type)
(init_declarator
(pointer_declarator (identifier))
(raw_string_literal))))
====================================================
Template calls
====================================================
int main() {
// '<' and '>' as template argument list delimiters
if (a<b && c>()) {}
// '<' and '>' as binary operators
if (a < b && c >= d) {}
}
---
(translation_unit
(function_definition
(primitive_type)
(function_declarator (identifier) (parameter_list))
(compound_statement
(comment)
(if_statement
(condition_clause
(call_expression
(template_function
(identifier)
(template_argument_list (binary_expression (identifier) (identifier))))
(argument_list)))
(compound_statement))
(comment)
(if_statement
(condition_clause
(binary_expression
(binary_expression (identifier) (identifier))
(binary_expression (identifier) (identifier))))
(compound_statement)))))
====================================================
Parameter pack expansions
====================================================
container<A,B,C...> t1;
container<C...,A,B> t2;
typedef Tuple<Pair<Args1, Args2>...> type;
f(&args...); // expands to f(&E1, &E2, &E3)
f(n, ++args...); // expands to f(n, ++E1, ++E2, ++E3);
f(++args..., n); // expands to f(++E1, ++E2, ++E3, n);
f(const_cast<const Args*>(&args)...); // f(const_cast<const E1*>(&X1), const_cast<const E2*>(&X2), const_cast<const E3*>(&X3))
f(h(args...) + args...); // expands to f(h(E1,E2,E3) + E1, h(E1,E2,E3) + E2, h(E1,E2,E3) + E3)
const int size = sizeof...(args) + 2;
int res[size] = {1,args...,2};
int dummy[sizeof...(Ts)] = { (std::cout << args, 0)... };
auto lm = [&, args...] { return g(args...); };
class X : public Mixins... {
public:
X(const Mixins&... mixins) : Mixins(mixins)... { }
};
template <typename... Args>
void wrap(Args&&... args) {
f(forward<Args>(args)...);
}
void f(T...) {}
---
(translation_unit
(declaration
type: (template_type
name: (type_identifier)
arguments: (template_argument_list
(type_descriptor
type: (type_identifier))
(type_descriptor
type: (type_identifier))
(parameter_pack_expansion
pattern: (type_descriptor
type: (type_identifier)))))
declarator: (identifier))
(declaration
type: (template_type
name: (type_identifier)
arguments: (template_argument_list
(parameter_pack_expansion
pattern: (type_descriptor
type: (type_identifier)))
(type_descriptor
type: (type_identifier))
(type_descriptor
type: (type_identifier))))
declarator: (identifier))
(type_definition
type: (template_type
name: (type_identifier)
arguments: (template_argument_list
(parameter_pack_expansion
pattern: (type_descriptor
type: (template_type
name: (type_identifier)
arguments: (template_argument_list
(type_descriptor
type: (type_identifier))
(type_descriptor
type: (type_identifier))))))))
declarator: (type_identifier))
(expression_statement
(call_expression
function: (identifier)
arguments: (argument_list
(parameter_pack_expansion
pattern: (pointer_expression
argument: (identifier))))))
(comment)
(expression_statement
(call_expression
function: (identifier)
arguments: (argument_list
(identifier)
(parameter_pack_expansion
pattern: (update_expression
argument: (identifier))))))
(comment)
(expression_statement
(call_expression
function: (identifier)
arguments: (argument_list
(parameter_pack_expansion
pattern: (update_expression
argument: (identifier)))
(identifier))))
(comment)
(expression_statement
(call_expression
function: (identifier)
arguments: (argument_list
(parameter_pack_expansion
pattern: (call_expression
function: (template_function
name: (identifier)
arguments: (template_argument_list
(type_descriptor
(type_qualifier)
type: (type_identifier)
declarator: (abstract_pointer_declarator))))
arguments: (argument_list
(pointer_expression argument: (identifier))))))))
(comment)
(expression_statement
(call_expression
function: (identifier)
arguments: (argument_list
(parameter_pack_expansion
pattern: (binary_expression
left: (call_expression
function: (identifier)
arguments: (argument_list
(parameter_pack_expansion pattern: (identifier))))
right: (identifier))))))
(comment)
(declaration
(type_qualifier)
type: (primitive_type)
declarator: (init_declarator
declarator: (identifier)
value: (binary_expression
left: (sizeof_expression value: (identifier))
right: (number_literal))))
(declaration
type: (primitive_type)
declarator: (init_declarator
declarator: (array_declarator
declarator: (identifier)
size: (identifier))
value: (initializer_list
(number_literal)
(parameter_pack_expansion pattern: (identifier))
(number_literal))))
(declaration
type: (primitive_type)
declarator: (init_declarator
declarator: (array_declarator
declarator: (identifier)
size: (sizeof_expression value: (identifier)))
value: (initializer_list
(parameter_pack_expansion
pattern: (parenthesized_expression
(comma_expression
left: (binary_expression
left: (scoped_identifier
namespace: (namespace_identifier)
name: (identifier))
right: (identifier))
right: (number_literal)))))))
(declaration
type: (auto)
declarator: (init_declarator
declarator: (identifier)
value: (lambda_expression
captures: (lambda_capture_specifier
(lambda_default_capture)
(parameter_pack_expansion pattern: (identifier)))
body: (compound_statement
(return_statement
(call_expression
function: (identifier)
arguments: (argument_list
(parameter_pack_expansion pattern: (identifier)))))))))
(class_specifier
name: (type_identifier)
(base_class_clause
(type_identifier))
body: (field_declaration_list
(access_specifier)
(function_definition
declarator: (function_declarator
declarator: (identifier)
parameters: (parameter_list
(variadic_parameter_declaration
(type_qualifier)
type: (type_identifier)
declarator: (reference_declarator
(variadic_declarator (identifier))))))
(field_initializer_list
(field_initializer
(field_identifier)
(argument_list (identifier))))
body: (compound_statement))))
(template_declaration
parameters: (template_parameter_list (variadic_type_parameter_declaration (type_identifier)))
(function_definition
type: (primitive_type)
declarator: (function_declarator
declarator: (identifier)
parameters: (parameter_list
(variadic_parameter_declaration
type: (type_identifier)
declarator: (reference_declarator (variadic_declarator (identifier))))))
body: (compound_statement
(expression_statement
(call_expression
function: (identifier)
arguments: (argument_list
(parameter_pack_expansion
pattern: (call_expression
function: (template_function
name: (identifier)
arguments: (template_argument_list
(type_descriptor type: (type_identifier))))
arguments: (argument_list (identifier))))))))))
(function_definition
type: (primitive_type)
declarator: (function_declarator
declarator: (identifier)
parameters: (parameter_list
(variadic_parameter_declaration
type: (type_identifier)
declarator: (variadic_declarator))))
body: (compound_statement)))
============================================
Concatenated string literals
============================================
"a" "b" "c";
R"(a)" R"(b)" R"(c)";
"a" R"(b)" L"c" R"FOO(d)FOO";
---
(translation_unit
(expression_statement (concatenated_string (string_literal) (string_literal) (string_literal)))
(expression_statement (concatenated_string (raw_string_literal) (raw_string_literal) (raw_string_literal)))
(expression_statement (concatenated_string (string_literal) (raw_string_literal) (string_literal) (raw_string_literal))))
====================================================
Primitive types ctor
====================================================
x = int(1);
x = new int(1);
x = (int(1) + float(2));
---
(translation_unit
(expression_statement
(assignment_expression
(identifier)
(call_expression (primitive_type) (argument_list (number_literal)))))
(expression_statement
(assignment_expression
(identifier)
(new_expression (primitive_type) (argument_list (number_literal)))))
(expression_statement
(assignment_expression
(identifier)
(parenthesized_expression
(binary_expression
(call_expression (primitive_type) (argument_list (number_literal)))
(call_expression (primitive_type) (argument_list (number_literal))))))))
============================================
Array assignment expression
============================================
array_[i] = s[i];
array_[{i}] = s[{1,2,3}];
---
(translation_unit
(expression_statement
(assignment_expression
(subscript_expression
(identifier)
(identifier))
(subscript_expression
(identifier)
(identifier))))
(expression_statement
(assignment_expression
(subscript_expression
(identifier)
(initializer_list
(identifier)))
(subscript_expression
(identifier)
(initializer_list
(number_literal)
(number_literal)
(number_literal))))))
============================================
Coroutines
============================================
co_await fn() || co_await var;
---
(translation_unit
(expression_statement
(binary_expression
(co_await_expression
(call_expression
(identifier)
(argument_list)))
(co_await_expression
(identifier)))))

@ -0,0 +1,32 @@
================================
declaration specs
================================
struct __declspec(dllexport) s2
{
};
union __declspec(noinline) u2 {
};
class __declspec(uuid) 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))
(class_specifier
(ms_declspec_modifier
(identifier))
name: (type_identifier)
body: (field_declaration_list)))

@ -0,0 +1,377 @@
===========================================
Returning braced initializer lists
===========================================
T main() {
return {0, 5};
}
---
(translation_unit
(function_definition
(type_identifier)
(function_declarator (identifier) (parameter_list))
(compound_statement
(return_statement (initializer_list (number_literal) (number_literal))))))
===========================================
Range-based for loops
===========================================
T main() {
for (Value &value : values) {
cout << value;
}
for (const auto &value : values) {
cout << value;
}
for (const auto &value : {1, 2, 3}) {
cout << value;
}
}
---
(translation_unit
(function_definition
type: (type_identifier)
declarator: (function_declarator
declarator: (identifier)
parameters: (parameter_list))
body: (compound_statement
(for_range_loop
type: (type_identifier)
declarator: (reference_declarator (identifier))
right: (identifier)
body: (compound_statement
(expression_statement (binary_expression
left: (identifier)
right: (identifier)))))
(for_range_loop
(type_qualifier)
type: (auto)
declarator: (reference_declarator (identifier))
right: (identifier)
body: (compound_statement
(expression_statement (binary_expression
left: (identifier)
right: (identifier)))))
(for_range_loop
(type_qualifier)
type: (auto)
declarator: (reference_declarator (identifier))
right: (initializer_list (number_literal) (number_literal) (number_literal))
body: (compound_statement
(expression_statement (binary_expression
left: (identifier)
right: (identifier))))))))
===========================================
Constexpr if statements
===========================================
T f() {
if constexpr (std::is_pointer_v<T>)
return *t;
else
return t;
}
---
(translation_unit
(function_definition
type: (type_identifier)
declarator: (function_declarator
declarator: (identifier)
parameters: (parameter_list))
body: (compound_statement
(if_statement
condition: (condition_clause
value: (template_function
name: (scoped_identifier
namespace: (namespace_identifier)
name: (identifier))
arguments: (template_argument_list
(type_descriptor type: (type_identifier)))))
consequence: (return_statement
(pointer_expression argument: (identifier)))
alternative: (return_statement (identifier))))))
=====================================
If statements with declarations
====================================
void f() {
if (const int x = foo()) { }
if (const int x { foo() }) { }
if (const int x = foo(); x != 0) { }
}
---
(translation_unit
(function_definition
type: (primitive_type)
declarator: (function_declarator
declarator: (identifier)
parameters: (parameter_list))
body: (compound_statement
(if_statement
condition: (condition_clause
value: (declaration
(type_qualifier)
type: (primitive_type)
declarator: (identifier)
value: (call_expression
function: (identifier)
arguments: (argument_list))))
consequence: (compound_statement))
(if_statement
condition: (condition_clause
value: (declaration
(type_qualifier)
type: (primitive_type)
declarator: (identifier)
value: (initializer_list (call_expression function: (identifier) arguments: (argument_list)))))
consequence: (compound_statement))
(if_statement
condition: (condition_clause
initializer: (declaration
(type_qualifier)
type: (primitive_type)
declarator: (init_declarator
declarator: (identifier)
value: (call_expression function: (identifier) arguments: (argument_list))))
value: (binary_expression left: (identifier) right: (number_literal)))
consequence: (compound_statement)))))
===========================================
Try/catch statements
===========================================
void main() {
try {
f();
} catch (const std::overflow_error) {
// f() throws std::overflow_error (same type rule)
} catch (const exception &e) {
// f() throws std::logic_error (base class rule)
} catch (...) {
// f() throws std::string or int or any other unrelated type
}
}
---
(translation_unit
(function_definition
(primitive_type)
(function_declarator (identifier) (parameter_list))
(compound_statement
(try_statement
(compound_statement
(expression_statement (call_expression (identifier) (argument_list))))
(catch_clause
(parameter_list (parameter_declaration (type_qualifier) (scoped_type_identifier (namespace_identifier) (type_identifier))))
(compound_statement (comment)))
(catch_clause
(parameter_list (parameter_declaration (type_qualifier) (type_identifier) (reference_declarator (identifier))))
(compound_statement (comment)))
(catch_clause
(parameter_list)
(compound_statement (comment)))))))
===========================================
Throw statements
===========================================
void main() {
throw e;
throw x + 1;
throw "exception";
}
---
(translation_unit
(function_definition
(primitive_type)
(function_declarator
(identifier)
(parameter_list))
(compound_statement
(throw_statement (identifier))
(throw_statement (binary_expression (identifier) (number_literal)))
(throw_statement (string_literal)))))
===========================================
Noexcept specifier
===========================================
void foo() noexcept;
void foo() noexcept(true);
template<class T> T foo() noexcept(sizeof(T) < 4);
---
(translation_unit
(declaration
(primitive_type)
(function_declarator (identifier) (parameter_list)
(noexcept)))
(declaration
(primitive_type)
(function_declarator (identifier) (parameter_list)
(noexcept (true))))
(template_declaration
(template_parameter_list
(type_parameter_declaration (type_identifier)))
(declaration
(type_identifier)
(function_declarator (identifier) (parameter_list)
(noexcept
(binary_expression (sizeof_expression (parenthesized_expression (identifier))) (number_literal)))))))
===========================================
Throw specifier
===========================================
void foo() throw();
void foo() throw(int);
void foo() throw(std::string, char *);
void foo() throw(float) { }
---
(translation_unit
(declaration
(primitive_type)
(function_declarator (identifier) (parameter_list)
(throw_specifier)))
(declaration
(primitive_type)
(function_declarator (identifier) (parameter_list)
(throw_specifier (type_descriptor (primitive_type)))))
(declaration
(primitive_type)
(function_declarator (identifier) (parameter_list)
(throw_specifier
(type_descriptor (scoped_type_identifier (namespace_identifier) (type_identifier)))
(type_descriptor (primitive_type) (abstract_pointer_declarator)))))
(function_definition
(primitive_type)
(function_declarator (identifier) (parameter_list)
(throw_specifier (type_descriptor (primitive_type))))
(compound_statement)))
===========================================
Assignment
===========================================
a::b::c = 1;
---
(translation_unit
(expression_statement
(assignment_expression
(scoped_namespace_identifier
(scoped_namespace_identifier (namespace_identifier) (namespace_identifier))
(namespace_identifier))
(number_literal))))
=========================================
Attributes
=========================================
void f() {
[[a]] switch (b) {
[[c]] case 1: {}
}
[[a]] while (true) {}
[[a]] if (true) {}
[[a]] for (auto x : y) {}
[[a]] for (;;) {}
[[a]] return;
[[a]] a;
[[a]];
[[a]] label: {}
[[a]] goto label;
}
---
(translation_unit
(function_definition (primitive_type)
(function_declarator (identifier) (parameter_list))
(compound_statement
(attributed_statement (attribute_declaration (attribute (identifier)))
(switch_statement
(condition_clause (identifier))
(compound_statement
(attributed_statement (attribute_declaration (attribute (identifier)))
(case_statement (number_literal) (compound_statement))))))
(attributed_statement (attribute_declaration (attribute (identifier))) (while_statement (condition_clause (true)) (compound_statement)))
(attributed_statement (attribute_declaration (attribute (identifier))) (if_statement (condition_clause (true)) (compound_statement)))
(attributed_statement (attribute_declaration (attribute (identifier))) (for_range_loop (auto) (identifier) (identifier) (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))))))
===========================================
Coroutines
===========================================
co_return 1;
co_return;
co_yield 1;
---
(translation_unit
(co_return_statement
(number_literal))
(co_return_statement)
(co_yield_statement
(number_literal)))
===========================================
Switch statements
===========================================
void foo(int a) {
switch (a) {
case 1:
for (auto i : vec) {}
case 2:
try {
// do something
} catch(...) {}
throw 1;
case 3:
co_return;
default:
co_yield a;
}
}
---
(translation_unit
(function_definition (primitive_type)
(function_declarator (identifier) (parameter_list (parameter_declaration (primitive_type) (identifier))))
(compound_statement
(switch_statement (condition_clause (identifier))
(compound_statement
(case_statement (number_literal) (for_range_loop (auto) (identifier) (identifier) (compound_statement)))
(case_statement (number_literal) (try_statement (compound_statement (comment)) (catch_clause (parameter_list) (compound_statement))) (throw_statement (number_literal)))
(case_statement (number_literal) (co_return_statement))
(case_statement (co_yield_statement (identifier))))))))

@ -0,0 +1,155 @@
==========================================
The auto type
==========================================
void foo() {
auto x = 1;
}
---
(translation_unit
(function_definition
(primitive_type)
(function_declarator (identifier) (parameter_list))
(compound_statement
(declaration (auto) (init_declarator (identifier) (number_literal))))))
==========================================
Namespaced types
==========================================
std::string my_string;
std::vector<int>::size_typ my_string;
---
(translation_unit
(declaration
(scoped_type_identifier (namespace_identifier) (type_identifier))
(identifier))
(declaration
(scoped_type_identifier
(template_type
(scoped_type_identifier (namespace_identifier) (type_identifier))
(template_argument_list (type_descriptor (primitive_type))))
(type_identifier))
(identifier)))
==========================================
Dependent type names
==========================================
template<typename T>
struct X : B<T>
{
typename T::A* pa;
};
---
(translation_unit
(template_declaration
(template_parameter_list (type_parameter_declaration (type_identifier)))
(struct_specifier
(type_identifier)
(base_class_clause
(template_type (type_identifier) (template_argument_list (type_descriptor (type_identifier)))))
(field_declaration_list
(field_declaration
(dependent_type (scoped_type_identifier (namespace_identifier) (type_identifier)))
(pointer_declarator (field_identifier)))))))
==========================================
Template types with empty argument lists
==========================================
use_future_t<> use_future;
---
(translation_unit
(declaration (template_type (type_identifier) (template_argument_list)) (identifier)))
================================
Function types as template arguments
================================
typedef std::function<T(int)> MyFunc;
typedef std::function<void(int)> b;
---
(translation_unit
(type_definition
(template_type
(scoped_type_identifier (namespace_identifier) (type_identifier))
(template_argument_list
(type_descriptor
(type_identifier)
(abstract_function_declarator (parameter_list
(parameter_declaration (primitive_type)))))))
(type_identifier))
(type_definition
(template_type
(scoped_type_identifier (namespace_identifier) (type_identifier))
(template_argument_list
(type_descriptor
(primitive_type)
(abstract_function_declarator (parameter_list
(parameter_declaration (primitive_type)))))))
(type_identifier)))
====================================================
Decltype
====================================================
decltype(A) x;
decltype(B) foo(void x, decltype(C) y);
template<typename T, typename U> auto add(T t, U u) -> decltype(t + u);
---
(translation_unit
(declaration
(decltype (identifier))
(identifier))
(declaration
(decltype (identifier))
(function_declarator (identifier)
(parameter_list
(parameter_declaration (primitive_type) (identifier))
(parameter_declaration (decltype (identifier)) (identifier)))))
(template_declaration
(template_parameter_list
(type_parameter_declaration (type_identifier)) (type_parameter_declaration (type_identifier)))
(declaration
(auto)
(function_declarator
(identifier)
(parameter_list
(parameter_declaration (type_identifier) (identifier))
(parameter_declaration (type_identifier) (identifier)))
(trailing_return_type
(decltype (binary_expression (identifier) (identifier))))))))
====================================================
Trailing return type
====================================================
auto a::foo() const -> const A<B>& {}
---
(translation_unit
(function_definition
(auto)
(function_declarator
(scoped_identifier (namespace_identifier) (identifier))
(parameter_list)
(type_qualifier)
(trailing_return_type
(type_qualifier)
(template_type (type_identifier) (template_argument_list (type_descriptor (type_identifier))))
(abstract_reference_declarator)))
(compound_statement)))

@ -0,0 +1,34 @@
using namespace std;
// ^ keyword
namespace foo {}
// ^ keyword
template <typename T>
// ^ keyword
// ^ keyword
class A {
// <- keyword
public:
// <- keyword
private:
// <- keyword
protected:
// <- keyword
virtual ~A() = 0;
// <- keyword
};
int main() {
throw new Error();
// ^ keyword
// ^ keyword
try {
// <- keyword
} catch (e) {
// <- keyword
}
}

@ -0,0 +1,35 @@
int main() {
a<T>();
// <- function
a::b();
// ^ function
a::b<C, D>();
// ^ function
this->b<C, D>();
// ^ function
auto x = y;
// <- type
vector<T> a;
// <- type
std::vector<T> a;
// ^ type
}
class C : D{
A();
// <- function
void efg() {
// ^ function
}
}
void A::b() {
// ^ function
}