From ae4cdb5d27bf876a432b6c30b6a88f56c9b3e761 Mon Sep 17 00:00:00 2001 From: Mathspy Date: Wed, 5 Jan 2022 11:21:37 +0200 Subject: [PATCH] Initial Rust bindings implementation --- .gitignore | 4 +-- Cargo.lock | 59 ++++++++++++++++++++++++++++++++++ Cargo.toml | 28 +++++++++++++++++ bindings/rust/README.md | 39 +++++++++++++++++++++++ bindings/rust/build.rs | 16 ++++++++++ bindings/rust/lib.rs | 70 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 213 insertions(+), 3 deletions(-) create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 bindings/rust/README.md create mode 100644 bindings/rust/build.rs create mode 100644 bindings/rust/lib.rs diff --git a/.gitignore b/.gitignore index 39e4380..a9118c8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,3 @@ /build /node_modules - -/bindings/rust -/Cargo.toml +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..adb51b5 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,59 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + +[[package]] +name = "cc" +version = "1.0.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" + +[[package]] +name = "memchr" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" + +[[package]] +name = "regex" +version = "1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + +[[package]] +name = "tree-sitter" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c36be3222512d85a112491ae0cc280a38076022414f00b64582da1b7565ffd82" +dependencies = [ + "cc", + "regex", +] + +[[package]] +name = "tree-sitter-toml" +version = "0.20.0" +dependencies = [ + "cc", + "tree-sitter", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..1e7523a --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "tree-sitter-toml" +description = "TOML grammar for the tree-sitter parsing library" +version = "0.20.0" +license = "MIT" +readme = "bindings/rust/README.md" +keywords = ["incremental", "parsing", "toml"] +categories = ["parsing", "text-editors"] +repository = "https://github.com/Mathspy/tree-sitter-toml" +edition = "2018" + +build = "bindings/rust/build.rs" +include = [ + "bindings/rust/*", + "grammar.js", + "queries/*", + "src/*", +] +autoexamples = false + +[lib] +path = "bindings/rust/lib.rs" + +[dependencies] +tree-sitter = "0.20" + +[build-dependencies] +cc = "1.0" diff --git a/bindings/rust/README.md b/bindings/rust/README.md new file mode 100644 index 0000000..f4b62d7 --- /dev/null +++ b/bindings/rust/README.md @@ -0,0 +1,39 @@ +# tree-sitter-toml + +This crate provides TOML 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-toml = "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#" +[package] +name = "cargo" +version = "0.1.0" +edition = "2021" +"#; +let mut parser = Parser::new(); +parser.set_language(tree_sitter_toml::language()).expect("Error loading TOML grammar"); +let parsed = parser.parse(code, None); +``` + +It's based on the lovely bindings of [tree-sitter-rust][] and uses the awesome grammar +defined by [tree-sitter-toml][]. + +[Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html +[language func]: https://docs.rs/tree-sitter-toml/*/tree_sitter_rust/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-rust]: https://github.com/tree-sitter/tree-sitter-rust/tree/master/bindings/rust +[tree-sitter-toml]: https://github.com/ikatyang/tree-sitter-toml diff --git a/bindings/rust/build.rs b/bindings/rust/build.rs new file mode 100644 index 0000000..0dce566 --- /dev/null +++ b/bindings/rust/build.rs @@ -0,0 +1,16 @@ +fn main() { + let src_dir = std::path::Path::new("src"); + let mut config = cc::Build::new(); + config.include(&src_dir); + 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"); + let scanner_path = src_dir.join("scanner.c"); + println!("cargo:rerun-if-changed={}", parser_path.to_str().unwrap()); + println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap()); + config.file(&parser_path); + config.file(&scanner_path); + config.compile("parser-scanner"); +} diff --git a/bindings/rust/lib.rs b/bindings/rust/lib.rs new file mode 100644 index 0000000..49011e6 --- /dev/null +++ b/bindings/rust/lib.rs @@ -0,0 +1,70 @@ +// -*- coding: utf-8 -*- +// ------------------------------------------------------------------------------------------------ +// Modified from tree-sitter-rust under the permissive license of MIT. +// Based on the grammar of tree-sitter-toml, used under the permissive license of MIT +// Copyright © 2021, tree-sitter-toml authors. +// Copyright © 2021, tree-sitter-rust authors. +// See the LICENSE file in this repo for license details. +// ------------------------------------------------------------------------------------------------ + +//! This crate provides TOML 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#" +//! [package] +//! name = "cargo" +//! version = "0.1.0" +//! edition = "2021" +//! "#; +//! let mut parser = Parser::new(); +//! parser.set_language(tree_sitter_toml::language()).expect("Error loading TOML 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_toml() -> 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_toml() } +} + +/// The source of the TOML 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 TOML grammar"); + } +}