mirror of https://github.com/Wilfred/difftastic/
Add 'vendor/tree-sitter-cpp/' from commit '9a3f2509fe5ba5a0310b5ec5aa1a7f0b595520a9'
git-subtree-dir: vendor/tree-sitter-cpp git-subtree-mainline:edge_only_predecessors3d5bd4069fgit-subtree-split:9a3f2509fe
commit
3068ad64a9
@ -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
|
||||
==================
|
||||
|
||||
[](https://travis-ci.org/tree-sitter/tree-sitter-cpp)
|
||||
[](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
|
||||
}
|
||||
Loading…
Reference in New Issue