mirror of https://github.com/Wilfred/difftastic/
Add 'vendor/tree-sitter-go/' from commit 'eb306e6e60f393df346cfc8cbfaf52667a37128a'
git-subtree-dir: vendor/tree-sitter-go git-subtree-mainline:ida_star26c6438fa2git-subtree-split:eb306e6e60
commit
8a6c7c8013
@ -0,0 +1,2 @@
|
||||
/src/** linguist-vendored
|
||||
/examples/* linguist-vendored
|
||||
@ -0,0 +1,8 @@
|
||||
|
||||
|
||||
Checklist:
|
||||
- [ ] All tests pass in CI.
|
||||
- [ ] There are sufficient tests for the new fix/feature.
|
||||
- [ ] Grammar rules have not been renamed unless absolutely necessary.
|
||||
- [ ] The conflicts section hasn't grown too much.
|
||||
- [ ] The parser size hasn't grown too much (check the value of STATE_COUNT in src/parser.c).
|
||||
@ -0,0 +1,28 @@
|
||||
name: Build/test
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "**"
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
os: [macos-latest, ubuntu-latest]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 14
|
||||
- run: npm install
|
||||
- run: npm test
|
||||
test_windows:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 14
|
||||
- run: npm install
|
||||
- run: npm run-script test-windows
|
||||
@ -0,0 +1,8 @@
|
||||
Cargo.lock
|
||||
node_modules
|
||||
build
|
||||
*.log
|
||||
package-lock.json
|
||||
examples/go
|
||||
examples/moby
|
||||
target
|
||||
@ -0,0 +1,7 @@
|
||||
corpus
|
||||
examples
|
||||
build
|
||||
script
|
||||
.travis.yml
|
||||
.gitattributes
|
||||
target
|
||||
@ -0,0 +1,31 @@
|
||||
[package]
|
||||
name = "tree-sitter-go"
|
||||
description = "Go grammar for the tree-sitter parsing library"
|
||||
version = "0.19.0"
|
||||
authors = [
|
||||
"Max Brunsfeld <maxbrunsfeld@gmail.com>",
|
||||
"Douglas Creager <dcreager@dcreager.net>",
|
||||
]
|
||||
license = "MIT"
|
||||
readme = "bindings/rust/README.md"
|
||||
keywords = ["incremental", "parsing", "go"]
|
||||
categories = ["parsing", "text-editors"]
|
||||
repository = "https://github.com/tree-sitter/tree-sitter-go"
|
||||
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,8 @@
|
||||
tree-sitter-go
|
||||
===========================
|
||||
|
||||
[](https://github.com/tree-sitter/tree-sitter-go/actions/workflows/ci.yml)
|
||||
|
||||
Golang grammar for [tree-sitter][].
|
||||
|
||||
[tree-sitter]: https://github.com/tree-sitter/tree-sitter
|
||||
@ -0,0 +1,18 @@
|
||||
{
|
||||
"targets": [
|
||||
{
|
||||
"target_name": "tree_sitter_go_binding",
|
||||
"include_dirs": [
|
||||
"<!(node -e \"require('nan')\")",
|
||||
"src"
|
||||
],
|
||||
"sources": [
|
||||
"src/parser.c",
|
||||
"bindings/node/binding.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_go();
|
||||
|
||||
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_go());
|
||||
|
||||
Nan::Set(instance, Nan::New("name").ToLocalChecked(), Nan::New("go").ToLocalChecked());
|
||||
Nan::Set(module, Nan::New("exports").ToLocalChecked(), instance);
|
||||
}
|
||||
|
||||
NODE_MODULE(tree_sitter_go_binding, Init)
|
||||
|
||||
} // namespace
|
||||
@ -0,0 +1,19 @@
|
||||
try {
|
||||
module.exports = require("../../build/Release/tree_sitter_go_binding");
|
||||
} catch (error1) {
|
||||
if (error1.code !== 'MODULE_NOT_FOUND') {
|
||||
throw error1;
|
||||
}
|
||||
try {
|
||||
module.exports = require("../../build/Debug/tree_sitter_go_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-go
|
||||
|
||||
This crate provides a Go 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-go = "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#"
|
||||
func double(x int) int {
|
||||
return x * 2
|
||||
}
|
||||
"#;
|
||||
let mut parser = Parser::new();
|
||||
parser.set_language(tree_sitter_go::language()).expect("Error loading Go 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-go/*/tree_sitter_go/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,13 @@
|
||||
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");
|
||||
}
|
||||
@ -0,0 +1,69 @@
|
||||
// -*- coding: utf-8 -*-
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Copyright © 2020, tree-sitter-go authors.
|
||||
// See the LICENSE file in this repo for license details.
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
//! This crate provides a Go 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#"
|
||||
//! func double(x int) int {
|
||||
//! return x * 2
|
||||
//! }
|
||||
//! "#;
|
||||
//! let mut parser = Parser::new();
|
||||
//! parser.set_language(tree_sitter_go::language()).expect("Error loading Go 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_go() -> 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_go() }
|
||||
}
|
||||
|
||||
/// The source of the Go tree-sitter grammar description.
|
||||
pub const GRAMMAR: &'static str = include_str!("../../grammar.js");
|
||||
|
||||
/// The syntax highlighting query for this language.
|
||||
pub const HIGHLIGHT_QUERY: &'static 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: &'static str = include_str!("../../src/node-types.json");
|
||||
|
||||
/// The symbol tagging query for this language.
|
||||
pub const TAGGING_QUERY: &'static str = include_str!("../../queries/tags.scm");
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn can_load_grammar() {
|
||||
let mut parser = tree_sitter::Parser::new();
|
||||
parser
|
||||
.set_language(super::language())
|
||||
.expect("Error loading Go grammar");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,361 @@
|
||||
============================================
|
||||
Single const declarations without types
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
const zero = 0
|
||||
const one, two = 1, 2
|
||||
const three, four, five = 3, 4, 5
|
||||
|
||||
----
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(const_declaration (const_spec
|
||||
(identifier)
|
||||
(expression_list (int_literal))))
|
||||
(const_declaration (const_spec
|
||||
(identifier)
|
||||
(identifier)
|
||||
(expression_list (int_literal) (int_literal))))
|
||||
(const_declaration (const_spec
|
||||
(identifier)
|
||||
(identifier)
|
||||
(identifier)
|
||||
(expression_list (int_literal) (int_literal) (int_literal)))))
|
||||
|
||||
============================================
|
||||
Single const declarations with types
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
const zero int = 0
|
||||
const one, two uint64 = 1, 2
|
||||
|
||||
----
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(const_declaration (const_spec
|
||||
(identifier)
|
||||
(type_identifier)
|
||||
(expression_list (int_literal))))
|
||||
(const_declaration (const_spec
|
||||
(identifier)
|
||||
(identifier)
|
||||
(type_identifier)
|
||||
(expression_list (int_literal) (int_literal)))))
|
||||
|
||||
============================================
|
||||
Grouped const declarations
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
const (
|
||||
zero = 0
|
||||
one = 1
|
||||
)
|
||||
|
||||
----
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(const_declaration
|
||||
(const_spec
|
||||
(identifier)
|
||||
(expression_list (int_literal)))
|
||||
(const_spec
|
||||
(identifier)
|
||||
(expression_list (int_literal)))))
|
||||
|
||||
============================================
|
||||
Const declarations with implicit values
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
const (
|
||||
zero = iota
|
||||
one
|
||||
two
|
||||
)
|
||||
|
||||
----
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(const_declaration
|
||||
(const_spec
|
||||
(identifier)
|
||||
(expression_list (identifier)))
|
||||
(const_spec
|
||||
(identifier))
|
||||
(const_spec
|
||||
(identifier))))
|
||||
|
||||
============================================
|
||||
Var declarations without types
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
var zero = 0
|
||||
var one, two = 1, 2
|
||||
var three, four, five = 3, 4, 5
|
||||
|
||||
----
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(var_declaration (var_spec
|
||||
(identifier)
|
||||
(expression_list (int_literal))))
|
||||
(var_declaration (var_spec
|
||||
(identifier)
|
||||
(identifier)
|
||||
(expression_list (int_literal) (int_literal))))
|
||||
(var_declaration (var_spec
|
||||
(identifier)
|
||||
(identifier)
|
||||
(identifier)
|
||||
(expression_list (int_literal) (int_literal) (int_literal)))))
|
||||
|
||||
============================================
|
||||
Var declarations with types
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
var zero int = 0
|
||||
var one, two uint64 = 1, 2
|
||||
|
||||
----
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(var_declaration (var_spec
|
||||
(identifier)
|
||||
(type_identifier)
|
||||
(expression_list (int_literal))))
|
||||
(var_declaration (var_spec
|
||||
(identifier)
|
||||
(identifier)
|
||||
(type_identifier)
|
||||
(expression_list (int_literal) (int_literal)))))
|
||||
|
||||
============================================
|
||||
Var declarations with no expressions
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
var zero int
|
||||
var one, two uint64
|
||||
|
||||
----
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(var_declaration (var_spec
|
||||
(identifier)
|
||||
(type_identifier)))
|
||||
(var_declaration (var_spec
|
||||
(identifier)
|
||||
(identifier)
|
||||
(type_identifier))))
|
||||
|
||||
============================================
|
||||
Grouped var declarations
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
var (
|
||||
zero = 0
|
||||
one = 1
|
||||
)
|
||||
|
||||
----
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(var_declaration
|
||||
(var_spec
|
||||
(identifier)
|
||||
(expression_list (int_literal)))
|
||||
(var_spec
|
||||
(identifier)
|
||||
(expression_list (int_literal)))))
|
||||
|
||||
============================================
|
||||
Function declarations
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
func f1() {}
|
||||
func f2(a File, b, c, d Thing) int {}
|
||||
func f2() (File, Thing) {}
|
||||
func f2() (result int, err error) {}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(function_declaration
|
||||
(identifier)
|
||||
(parameter_list)
|
||||
(block))
|
||||
(function_declaration
|
||||
(identifier)
|
||||
(parameter_list
|
||||
(parameter_declaration
|
||||
(identifier)
|
||||
(type_identifier))
|
||||
(parameter_declaration
|
||||
(identifier)
|
||||
(identifier)
|
||||
(identifier)
|
||||
(type_identifier)))
|
||||
(type_identifier)
|
||||
(block))
|
||||
(function_declaration
|
||||
(identifier)
|
||||
(parameter_list)
|
||||
(parameter_list
|
||||
(parameter_declaration (type_identifier))
|
||||
(parameter_declaration (type_identifier)))
|
||||
(block))
|
||||
(function_declaration
|
||||
(identifier)
|
||||
(parameter_list)
|
||||
(parameter_list
|
||||
(parameter_declaration (identifier) (type_identifier))
|
||||
(parameter_declaration (identifier) (type_identifier)))
|
||||
(block)))
|
||||
|
||||
============================================
|
||||
Single-line function declarations
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
func f1() { a() }
|
||||
func f2() { a(); b() }
|
||||
func f3() { a(); b(); }
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(function_declaration
|
||||
(identifier)
|
||||
(parameter_list)
|
||||
(block
|
||||
(call_expression (identifier) (argument_list))))
|
||||
(function_declaration
|
||||
(identifier)
|
||||
(parameter_list)
|
||||
(block
|
||||
(call_expression (identifier) (argument_list))
|
||||
(call_expression (identifier) (argument_list))))
|
||||
(function_declaration
|
||||
(identifier)
|
||||
(parameter_list)
|
||||
(block
|
||||
(call_expression (identifier) (argument_list))
|
||||
(call_expression (identifier) (argument_list)))))
|
||||
|
||||
============================================
|
||||
Variadic function declarations
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
func f1(a ...*int) {}
|
||||
func f2(a int, b ...int) {}
|
||||
func f3(...bool) {}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(function_declaration
|
||||
(identifier)
|
||||
(parameter_list
|
||||
(variadic_parameter_declaration
|
||||
(identifier)
|
||||
(pointer_type (type_identifier))))
|
||||
(block))
|
||||
(function_declaration
|
||||
(identifier)
|
||||
(parameter_list
|
||||
(parameter_declaration
|
||||
(identifier)
|
||||
(type_identifier))
|
||||
(variadic_parameter_declaration
|
||||
(identifier)
|
||||
(type_identifier)))
|
||||
(block))
|
||||
(function_declaration
|
||||
(identifier)
|
||||
(parameter_list
|
||||
(variadic_parameter_declaration (type_identifier)))
|
||||
(block)))
|
||||
|
||||
============================================
|
||||
Method declarations
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
func (self Person) Equals(other Person) bool {}
|
||||
func (v *Value) ObjxMap(optionalDefault ...(Map)) Map {}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(method_declaration
|
||||
(parameter_list
|
||||
(parameter_declaration (identifier) (type_identifier)))
|
||||
(field_identifier)
|
||||
(parameter_list
|
||||
(parameter_declaration (identifier) (type_identifier)))
|
||||
(type_identifier)
|
||||
(block))
|
||||
(method_declaration
|
||||
(parameter_list
|
||||
(parameter_declaration (identifier) (pointer_type (type_identifier))))
|
||||
(field_identifier)
|
||||
(parameter_list
|
||||
(variadic_parameter_declaration
|
||||
(identifier)
|
||||
(parenthesized_type (type_identifier))))
|
||||
(type_identifier)
|
||||
(block)))
|
||||
|
||||
============================================
|
||||
Type declarations
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
type a b
|
||||
type (
|
||||
a b
|
||||
c d
|
||||
)
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(type_declaration
|
||||
(type_spec (type_identifier) (type_identifier)))
|
||||
(type_declaration
|
||||
(type_spec (type_identifier) (type_identifier))
|
||||
(type_spec (type_identifier) (type_identifier))))
|
||||
@ -0,0 +1,229 @@
|
||||
============================================
|
||||
Call expressions
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
func main() {
|
||||
a(b, c...)
|
||||
|
||||
a(
|
||||
b,
|
||||
c,
|
||||
)
|
||||
|
||||
a(
|
||||
b,
|
||||
c...,
|
||||
)
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(function_declaration (identifier) (parameter_list) (block
|
||||
(call_expression
|
||||
(identifier)
|
||||
(argument_list
|
||||
(identifier)
|
||||
(variadic_argument (identifier))))
|
||||
(call_expression
|
||||
(identifier)
|
||||
(argument_list (identifier) (identifier)))
|
||||
(call_expression
|
||||
(identifier)
|
||||
(argument_list (identifier) (variadic_argument (identifier)))))))
|
||||
|
||||
============================================
|
||||
Nested call expressions
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
func main() {
|
||||
a(b(c(d)))
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(function_declaration (identifier) (parameter_list) (block
|
||||
(call_expression (identifier) (argument_list
|
||||
(call_expression (identifier) (argument_list
|
||||
(call_expression (identifier) (argument_list
|
||||
(identifier))))))))))
|
||||
|
||||
============================================
|
||||
Calls to 'make' and 'new'
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
func main() {
|
||||
make(chan<- int)
|
||||
|
||||
// `new` and `make` can also be used as variable names
|
||||
make(chan<- int, (new - old), make.stuff)
|
||||
|
||||
make(chan<- int, 5, 10)
|
||||
new(map[string]string)
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(function_declaration (identifier) (parameter_list) (block
|
||||
(call_expression
|
||||
(identifier)
|
||||
(argument_list (channel_type (type_identifier))))
|
||||
(comment)
|
||||
(call_expression
|
||||
(identifier)
|
||||
(argument_list
|
||||
(channel_type (type_identifier))
|
||||
(parenthesized_expression (binary_expression (identifier) (identifier)))
|
||||
(selector_expression (identifier) (field_identifier))))
|
||||
(call_expression
|
||||
(identifier)
|
||||
(argument_list
|
||||
(channel_type (type_identifier))
|
||||
(int_literal)
|
||||
(int_literal)))
|
||||
(call_expression
|
||||
(identifier)
|
||||
(argument_list
|
||||
(map_type (type_identifier) (type_identifier)))))))
|
||||
|
||||
============================================
|
||||
Selector expressions
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
func main() {
|
||||
a.b.c()
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(function_declaration (identifier) (parameter_list) (block
|
||||
(call_expression
|
||||
(selector_expression
|
||||
(selector_expression (identifier) (field_identifier))
|
||||
(field_identifier))
|
||||
(argument_list)))))
|
||||
|
||||
============================================
|
||||
Indexing expressions
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
func main() {
|
||||
a[1]
|
||||
b[:]
|
||||
c[1:]
|
||||
d[1:2]
|
||||
e[:2:3]
|
||||
f[1:2:3]
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(function_declaration (identifier) (parameter_list) (block
|
||||
(index_expression (identifier) (int_literal))
|
||||
(slice_expression (identifier))
|
||||
(slice_expression (identifier) (int_literal))
|
||||
(slice_expression (identifier) (int_literal) (int_literal))
|
||||
(slice_expression (identifier) (int_literal) (int_literal))
|
||||
(slice_expression (identifier) (int_literal) (int_literal) (int_literal)))))
|
||||
|
||||
============================================
|
||||
Type assertion expressions
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
func main() {
|
||||
a.(p.Person)
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(function_declaration (identifier) (parameter_list) (block
|
||||
(type_assertion_expression
|
||||
(identifier)
|
||||
(qualified_type (package_identifier) (type_identifier))))))
|
||||
|
||||
============================================
|
||||
Type conversion expressions
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
func main() {
|
||||
[]a.b(c.d)
|
||||
([]a.b)(c.d)
|
||||
<-chan int(c)
|
||||
// These type conversions cannot be distinguished from call expressions
|
||||
T(x)
|
||||
(*Point)(p)
|
||||
e.f(g)
|
||||
(e.f)(g)
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(function_declaration (identifier) (parameter_list) (block
|
||||
(type_conversion_expression
|
||||
(slice_type (qualified_type (package_identifier) (type_identifier)))
|
||||
(selector_expression (identifier) (field_identifier)))
|
||||
(type_conversion_expression
|
||||
(parenthesized_type (slice_type (qualified_type (package_identifier) (type_identifier))))
|
||||
(selector_expression (identifier) (field_identifier)))
|
||||
(type_conversion_expression
|
||||
(channel_type (type_identifier)) (identifier))
|
||||
(comment)
|
||||
(call_expression
|
||||
(identifier) (argument_list (identifier)))
|
||||
(call_expression
|
||||
(parenthesized_expression
|
||||
(unary_expression (identifier)))
|
||||
(argument_list (identifier)))
|
||||
(call_expression
|
||||
(selector_expression (identifier) (field_identifier))
|
||||
(argument_list (identifier)))
|
||||
(call_expression
|
||||
(parenthesized_expression
|
||||
(selector_expression (identifier) (field_identifier)))
|
||||
(argument_list (identifier))))))
|
||||
|
||||
============================================
|
||||
Unary expressions
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
func main() {
|
||||
!<-a
|
||||
*foo()
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(function_declaration (identifier) (parameter_list) (block
|
||||
(unary_expression (unary_expression (identifier)))
|
||||
(unary_expression (call_expression (identifier) (argument_list))))))
|
||||
@ -0,0 +1,317 @@
|
||||
============================================
|
||||
Int literals
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
const (
|
||||
i1 = 42
|
||||
i2 = 4_2
|
||||
i3 = 0600
|
||||
i4 = 0_600
|
||||
i5 = 0o600
|
||||
i6 = 0O600
|
||||
i7 = 0xBadFace
|
||||
i8 = 0xBad_Face
|
||||
i9 = 0x_67_7a_2f_cc_40_c6
|
||||
i10 = 170141183460469231731687303715884105727
|
||||
i11 = 170_141183_460469_231731_687303_715884_105727
|
||||
)
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(const_declaration
|
||||
(const_spec (identifier) (expression_list (int_literal)))
|
||||
(const_spec (identifier) (expression_list (int_literal)))
|
||||
(const_spec (identifier) (expression_list (int_literal)))
|
||||
(const_spec (identifier) (expression_list (int_literal)))
|
||||
(const_spec (identifier) (expression_list (int_literal)))
|
||||
(const_spec (identifier) (expression_list (int_literal)))
|
||||
(const_spec (identifier) (expression_list (int_literal)))
|
||||
(const_spec (identifier) (expression_list (int_literal)))
|
||||
(const_spec (identifier) (expression_list (int_literal)))
|
||||
(const_spec (identifier) (expression_list (int_literal)))
|
||||
(const_spec (identifier) (expression_list (int_literal)))))
|
||||
|
||||
============================================
|
||||
Float literals
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
const (
|
||||
f1 = 0.
|
||||
f2 = 72.40
|
||||
f3 = 072.40
|
||||
f4 = 2.71828
|
||||
f5 = 1.e+0
|
||||
f6 = 6.67428e-11
|
||||
f7 = 1E6
|
||||
f8 = .25
|
||||
f9 = .12345E+5
|
||||
f10 = 1_5.
|
||||
f11 = 0.15e+0_2
|
||||
f12 = 0x1p-2
|
||||
f13 = 0x2.p10
|
||||
f14 = 0x1.Fp+0
|
||||
f15 = 0X.8p-0
|
||||
f16 = 0X_1FFFP-16
|
||||
)
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(const_declaration
|
||||
(const_spec (identifier) (expression_list (float_literal)))
|
||||
(const_spec (identifier) (expression_list (float_literal)))
|
||||
(const_spec (identifier) (expression_list (float_literal)))
|
||||
(const_spec (identifier) (expression_list (float_literal)))
|
||||
(const_spec (identifier) (expression_list (float_literal)))
|
||||
(const_spec (identifier) (expression_list (float_literal)))
|
||||
(const_spec (identifier) (expression_list (float_literal)))
|
||||
(const_spec (identifier) (expression_list (float_literal)))
|
||||
(const_spec (identifier) (expression_list (float_literal)))
|
||||
(const_spec (identifier) (expression_list (float_literal)))
|
||||
(const_spec (identifier) (expression_list (float_literal)))
|
||||
(const_spec (identifier) (expression_list (float_literal)))
|
||||
(const_spec (identifier) (expression_list (float_literal)))
|
||||
(const_spec (identifier) (expression_list (float_literal)))
|
||||
(const_spec (identifier) (expression_list (float_literal)))
|
||||
(const_spec (identifier) (expression_list (float_literal)))))
|
||||
|
||||
============================================
|
||||
Rune literals
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
const (
|
||||
a = '0'
|
||||
b = '\''
|
||||
c = '\\'
|
||||
c = '\n'
|
||||
c = '\u0000'
|
||||
c = '\U01234567'
|
||||
)
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(const_declaration
|
||||
(const_spec (identifier) (expression_list (rune_literal)))
|
||||
(const_spec (identifier) (expression_list (rune_literal)))
|
||||
(const_spec (identifier) (expression_list (rune_literal)))
|
||||
(const_spec (identifier) (expression_list (rune_literal)))
|
||||
(const_spec (identifier) (expression_list (rune_literal)))
|
||||
(const_spec (identifier) (expression_list (rune_literal)))))
|
||||
|
||||
============================================
|
||||
Imaginary literals
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
const (
|
||||
a = 0i
|
||||
b = 0123i
|
||||
c = 0o123i
|
||||
d = 0xabci
|
||||
e = 0.i
|
||||
f = 2.71828i
|
||||
g = 1.e+0i
|
||||
h = 6.67428e-11i
|
||||
i = 1E6i
|
||||
j = .25i
|
||||
k = .12345E+5i
|
||||
l = 0x1p-2i
|
||||
)
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(const_declaration
|
||||
(const_spec (identifier) (expression_list (imaginary_literal)))
|
||||
(const_spec (identifier) (expression_list (imaginary_literal)))
|
||||
(const_spec (identifier) (expression_list (imaginary_literal)))
|
||||
(const_spec (identifier) (expression_list (imaginary_literal)))
|
||||
(const_spec (identifier) (expression_list (imaginary_literal)))
|
||||
(const_spec (identifier) (expression_list (imaginary_literal)))
|
||||
(const_spec (identifier) (expression_list (imaginary_literal)))
|
||||
(const_spec (identifier) (expression_list (imaginary_literal)))
|
||||
(const_spec (identifier) (expression_list (imaginary_literal)))
|
||||
(const_spec (identifier) (expression_list (imaginary_literal)))
|
||||
(const_spec (identifier) (expression_list (imaginary_literal)))
|
||||
(const_spec (identifier) (expression_list (imaginary_literal)))))
|
||||
|
||||
============================================
|
||||
String literals
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
const (
|
||||
a = "0"
|
||||
b = "`\"`"
|
||||
c = "\x0c"
|
||||
)
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(const_declaration
|
||||
(const_spec (identifier) (expression_list (interpreted_string_literal)))
|
||||
(const_spec (identifier) (expression_list (interpreted_string_literal (escape_sequence))))
|
||||
(const_spec (identifier) (expression_list (interpreted_string_literal (escape_sequence))))))
|
||||
|
||||
============================================
|
||||
Slice literals
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
const s1 = []string{}
|
||||
|
||||
const s2 = []string{"hi"}
|
||||
|
||||
const s3 = []string{
|
||||
"hi",
|
||||
"hello",
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(const_declaration (const_spec
|
||||
(identifier)
|
||||
(expression_list (composite_literal
|
||||
(slice_type (type_identifier))
|
||||
(literal_value)))))
|
||||
(const_declaration (const_spec
|
||||
(identifier)
|
||||
(expression_list (composite_literal
|
||||
(slice_type (type_identifier))
|
||||
(literal_value
|
||||
(element (interpreted_string_literal)))))))
|
||||
(const_declaration (const_spec
|
||||
(identifier)
|
||||
(expression_list (composite_literal
|
||||
(slice_type (type_identifier))
|
||||
(literal_value
|
||||
(element (interpreted_string_literal))
|
||||
(element (interpreted_string_literal))))))))
|
||||
|
||||
============================================
|
||||
Array literals with implicit length
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
const a1 = [...]int{1, 2, 3}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(const_declaration (const_spec
|
||||
(identifier)
|
||||
(expression_list (composite_literal
|
||||
(implicit_length_array_type (type_identifier))
|
||||
(literal_value
|
||||
(element (int_literal))
|
||||
(element (int_literal))
|
||||
(element (int_literal))))))))
|
||||
|
||||
============================================
|
||||
Map literals
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
const s = map[string]string{
|
||||
"hi": "hello",
|
||||
"bye": "goodbye",
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(const_declaration (const_spec
|
||||
(identifier)
|
||||
(expression_list (composite_literal
|
||||
(map_type (type_identifier) (type_identifier))
|
||||
(literal_value
|
||||
(keyed_element (interpreted_string_literal) (interpreted_string_literal))
|
||||
(keyed_element (interpreted_string_literal) (interpreted_string_literal))))))))
|
||||
|
||||
============================================
|
||||
Struct literals
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
const s1 = Person{
|
||||
name: "Frank",
|
||||
Age: "5 months",
|
||||
}
|
||||
|
||||
const s2 = struct{i int;}{i: 5}
|
||||
|
||||
const s3 = time.Time{}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(const_declaration (const_spec
|
||||
(identifier)
|
||||
(expression_list (composite_literal
|
||||
(type_identifier)
|
||||
(literal_value
|
||||
(keyed_element (field_identifier) (interpreted_string_literal))
|
||||
(keyed_element (field_identifier) (interpreted_string_literal)))))))
|
||||
(const_declaration (const_spec
|
||||
(identifier)
|
||||
(expression_list (composite_literal
|
||||
(struct_type (field_declaration_list
|
||||
(field_declaration (field_identifier) (type_identifier))))
|
||||
(literal_value
|
||||
(keyed_element (field_identifier) (int_literal)))))))
|
||||
(const_declaration (const_spec
|
||||
(identifier)
|
||||
(expression_list (composite_literal
|
||||
(qualified_type (package_identifier) (type_identifier))
|
||||
(literal_value))))))
|
||||
|
||||
============================================
|
||||
Function literals
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
const s1 = func(s string) (int, int) {
|
||||
return 1, 2
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(const_declaration (const_spec
|
||||
(identifier)
|
||||
(expression_list
|
||||
(func_literal
|
||||
(parameter_list
|
||||
(parameter_declaration (identifier) (type_identifier)))
|
||||
(parameter_list
|
||||
(parameter_declaration (type_identifier))
|
||||
(parameter_declaration (type_identifier)))
|
||||
(block
|
||||
(return_statement (expression_list (int_literal) (int_literal)))))))))
|
||||
@ -0,0 +1,642 @@
|
||||
============================================
|
||||
Declaration statements
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
func main() {
|
||||
var x = y
|
||||
const x = 5
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(function_declaration (identifier) (parameter_list) (block
|
||||
(var_declaration
|
||||
(var_spec (identifier) (expression_list (identifier))))
|
||||
(const_declaration
|
||||
(const_spec (identifier) (expression_list (int_literal)))))))
|
||||
|
||||
============================================
|
||||
Expression statements
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
func main() {
|
||||
foo(5)
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(function_declaration (identifier) (parameter_list) (block
|
||||
(call_expression (identifier) (argument_list (int_literal))))))
|
||||
|
||||
============================================
|
||||
Send statements
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
func main() {
|
||||
foo <- 5
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(function_declaration (identifier) (parameter_list) (block
|
||||
(send_statement (identifier) (int_literal)))))
|
||||
|
||||
============================================
|
||||
Increment/Decrement statements
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
func main() {
|
||||
i++
|
||||
j--
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(function_declaration (identifier) (parameter_list) (block
|
||||
(inc_statement (identifier))
|
||||
(dec_statement (identifier)))))
|
||||
|
||||
============================================
|
||||
Assignment statements
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
func main() {
|
||||
a = 1
|
||||
b, c += 2, 3
|
||||
d *= 3
|
||||
e += 1
|
||||
f /= 2
|
||||
g <<= 1
|
||||
h >>= 1
|
||||
i %= 1
|
||||
j &= 2
|
||||
k &^= 3
|
||||
l -= 1
|
||||
m |= 2
|
||||
n ^= 2
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(function_declaration (identifier) (parameter_list) (block
|
||||
(assignment_statement
|
||||
(expression_list (identifier))
|
||||
(expression_list (int_literal)))
|
||||
(assignment_statement
|
||||
(expression_list (identifier) (identifier))
|
||||
(expression_list (int_literal) (int_literal)))
|
||||
(assignment_statement
|
||||
(expression_list (identifier))
|
||||
(expression_list (int_literal)))
|
||||
(assignment_statement
|
||||
(expression_list (identifier))
|
||||
(expression_list (int_literal)))
|
||||
(assignment_statement
|
||||
(expression_list (identifier))
|
||||
(expression_list (int_literal)))
|
||||
(assignment_statement
|
||||
(expression_list (identifier))
|
||||
(expression_list (int_literal)))
|
||||
(assignment_statement
|
||||
(expression_list (identifier))
|
||||
(expression_list (int_literal)))
|
||||
(assignment_statement
|
||||
(expression_list (identifier))
|
||||
(expression_list (int_literal)))
|
||||
(assignment_statement
|
||||
(expression_list (identifier))
|
||||
(expression_list (int_literal)))
|
||||
(assignment_statement
|
||||
(expression_list (identifier))
|
||||
(expression_list (int_literal)))
|
||||
(assignment_statement
|
||||
(expression_list (identifier))
|
||||
(expression_list (int_literal)))
|
||||
(assignment_statement
|
||||
(expression_list (identifier))
|
||||
(expression_list (int_literal)))
|
||||
(assignment_statement
|
||||
(expression_list (identifier))
|
||||
(expression_list (int_literal))))))
|
||||
|
||||
============================================
|
||||
Short var declarations
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
func main() {
|
||||
a, b := 1, 2
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(function_declaration (identifier) (parameter_list) (block
|
||||
(short_var_declaration
|
||||
(expression_list (identifier) (identifier))
|
||||
(expression_list (int_literal) (int_literal))))))
|
||||
|
||||
============================================
|
||||
If statements
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
func main() {
|
||||
if a {
|
||||
b()
|
||||
}
|
||||
|
||||
if a := b(); c {
|
||||
d()
|
||||
}
|
||||
|
||||
if a {
|
||||
b()
|
||||
} else {
|
||||
c()
|
||||
}
|
||||
|
||||
if b {
|
||||
c()
|
||||
} else if d {
|
||||
e()
|
||||
} else {
|
||||
f()
|
||||
}
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(function_declaration
|
||||
name: (identifier)
|
||||
parameters: (parameter_list)
|
||||
body: (block
|
||||
(if_statement
|
||||
condition: (identifier)
|
||||
consequence: (block (call_expression
|
||||
function: (identifier)
|
||||
arguments: (argument_list))))
|
||||
|
||||
(if_statement
|
||||
initializer: (short_var_declaration
|
||||
left: (expression_list (identifier))
|
||||
right: (expression_list (call_expression
|
||||
function: (identifier)
|
||||
arguments: (argument_list))))
|
||||
condition: (identifier)
|
||||
consequence: (block
|
||||
(call_expression
|
||||
function: (identifier)
|
||||
arguments: (argument_list))))
|
||||
|
||||
(if_statement
|
||||
condition: (identifier)
|
||||
consequence: (block (call_expression
|
||||
function: (identifier)
|
||||
arguments: (argument_list)))
|
||||
alternative: (block (call_expression
|
||||
function: (identifier)
|
||||
arguments: (argument_list))))
|
||||
|
||||
(if_statement
|
||||
condition: (identifier)
|
||||
consequence: (block (call_expression
|
||||
function: (identifier)
|
||||
arguments: (argument_list)))
|
||||
alternative: (if_statement
|
||||
condition: (identifier)
|
||||
consequence: (block (call_expression
|
||||
function: (identifier)
|
||||
arguments: (argument_list)))
|
||||
alternative: (block (call_expression
|
||||
function: (identifier)
|
||||
arguments: (argument_list))))))))
|
||||
|
||||
============================================
|
||||
For statements
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
func main() {
|
||||
for {
|
||||
a()
|
||||
goto loop
|
||||
}
|
||||
|
||||
loop: for i := 0; i < 5; i++ {
|
||||
a()
|
||||
break loop
|
||||
}
|
||||
|
||||
loop2:
|
||||
for ; i < 10; i++ {
|
||||
a()
|
||||
continue loop2
|
||||
}
|
||||
|
||||
for ;; {
|
||||
a()
|
||||
continue
|
||||
}
|
||||
|
||||
for x := range y {
|
||||
a(x)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(function_declaration (identifier) (parameter_list) (block
|
||||
(for_statement
|
||||
(block
|
||||
(call_expression (identifier) (argument_list))
|
||||
(goto_statement (label_name))))
|
||||
(labeled_statement (label_name)
|
||||
(for_statement
|
||||
(for_clause
|
||||
(short_var_declaration
|
||||
(expression_list (identifier))
|
||||
(expression_list (int_literal)))
|
||||
(binary_expression (identifier) (int_literal))
|
||||
(inc_statement (identifier)))
|
||||
(block
|
||||
(call_expression (identifier) (argument_list))
|
||||
(break_statement (label_name)))))
|
||||
(labeled_statement (label_name)
|
||||
(for_statement
|
||||
(for_clause
|
||||
(binary_expression (identifier) (int_literal))
|
||||
(inc_statement (identifier)))
|
||||
(block
|
||||
(call_expression (identifier) (argument_list))
|
||||
(continue_statement (label_name)))))
|
||||
(for_statement
|
||||
(for_clause)
|
||||
(block
|
||||
(call_expression (identifier) (argument_list))
|
||||
(continue_statement)))
|
||||
(for_statement
|
||||
(range_clause (expression_list (identifier)) (identifier))
|
||||
(block
|
||||
(call_expression (identifier) (argument_list (identifier)))
|
||||
(break_statement))))))
|
||||
|
||||
============================================
|
||||
Switch statements
|
||||
============================================
|
||||
|
||||
func main() {
|
||||
switch e {
|
||||
case 1, 2:
|
||||
a()
|
||||
fallthrough
|
||||
case 3:
|
||||
d()
|
||||
default:
|
||||
c()
|
||||
break
|
||||
}
|
||||
|
||||
switch {
|
||||
case true:
|
||||
return
|
||||
}
|
||||
|
||||
switch f := y(); f {
|
||||
}
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(function_declaration
|
||||
name: (identifier)
|
||||
parameters: (parameter_list)
|
||||
body: (block
|
||||
(expression_switch_statement
|
||||
value: (identifier)
|
||||
(expression_case
|
||||
value: (expression_list (int_literal) (int_literal))
|
||||
(call_expression
|
||||
function: (identifier)
|
||||
arguments: (argument_list))
|
||||
(fallthrough_statement))
|
||||
(expression_case
|
||||
value: (expression_list (int_literal))
|
||||
(call_expression
|
||||
function: (identifier)
|
||||
arguments: (argument_list)))
|
||||
(default_case
|
||||
(call_expression
|
||||
function: (identifier)
|
||||
arguments: (argument_list))
|
||||
(break_statement)))
|
||||
(expression_switch_statement
|
||||
(expression_case
|
||||
value: (expression_list (true))
|
||||
(return_statement)))
|
||||
(expression_switch_statement
|
||||
initializer: (short_var_declaration
|
||||
left: (expression_list (identifier))
|
||||
right: (expression_list (call_expression
|
||||
function: (identifier)
|
||||
arguments: (argument_list))))
|
||||
value: (identifier)))))
|
||||
|
||||
============================================
|
||||
Type switch statements
|
||||
============================================
|
||||
|
||||
func main() {
|
||||
switch e.(type) {
|
||||
case []Person:
|
||||
a()
|
||||
case *Dog:
|
||||
break
|
||||
}
|
||||
switch i := x.(type) {
|
||||
case nil:
|
||||
printString("x is nil")
|
||||
case int:
|
||||
printInt(i)
|
||||
case float64:
|
||||
printFloat64(i)
|
||||
case func(int) float64:
|
||||
printFunction(i)
|
||||
case bool, string:
|
||||
printString("type is bool or string")
|
||||
default:
|
||||
printString("don't know the type")
|
||||
}
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(function_declaration
|
||||
name: (identifier)
|
||||
parameters: (parameter_list)
|
||||
body: (block
|
||||
(type_switch_statement
|
||||
value: (identifier)
|
||||
(type_case
|
||||
type: (slice_type
|
||||
element: (type_identifier))
|
||||
(call_expression
|
||||
function: (identifier)
|
||||
arguments: (argument_list)))
|
||||
(type_case
|
||||
type: (pointer_type (type_identifier))
|
||||
(break_statement)))
|
||||
(type_switch_statement
|
||||
alias: (expression_list (identifier))
|
||||
value: (identifier)
|
||||
(type_case
|
||||
type: (type_identifier)
|
||||
(call_expression
|
||||
function: (identifier)
|
||||
arguments: (argument_list (interpreted_string_literal))))
|
||||
(type_case
|
||||
type: (type_identifier)
|
||||
(call_expression
|
||||
function: (identifier)
|
||||
arguments: (argument_list (identifier))))
|
||||
(type_case
|
||||
type: (type_identifier)
|
||||
(call_expression
|
||||
function: (identifier)
|
||||
arguments: (argument_list (identifier))))
|
||||
(type_case
|
||||
type: (function_type
|
||||
parameters: (parameter_list (parameter_declaration
|
||||
type: (type_identifier)))
|
||||
result: (type_identifier))
|
||||
(call_expression
|
||||
function: (identifier)
|
||||
arguments: (argument_list (identifier))))
|
||||
(type_case
|
||||
type: (type_identifier)
|
||||
type: (type_identifier)
|
||||
(call_expression
|
||||
function: (identifier)
|
||||
arguments: (argument_list (interpreted_string_literal))))
|
||||
(default_case
|
||||
(call_expression
|
||||
function: (identifier)
|
||||
arguments: (argument_list (interpreted_string_literal))))))))
|
||||
|
||||
============================================
|
||||
Select statements
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
func main() {
|
||||
select {
|
||||
case x := <-c:
|
||||
println(x)
|
||||
case y <- c:
|
||||
println(5)
|
||||
case <-time.After(1):
|
||||
println(6)
|
||||
default:
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(function_declaration
|
||||
name: (identifier)
|
||||
parameters: (parameter_list)
|
||||
body: (block
|
||||
(select_statement
|
||||
(communication_case
|
||||
communication: (receive_statement
|
||||
left: (expression_list (identifier))
|
||||
right: (unary_expression operand: (identifier)))
|
||||
(call_expression
|
||||
function: (identifier)
|
||||
arguments: (argument_list (identifier))))
|
||||
(communication_case
|
||||
communication: (send_statement
|
||||
channel: (identifier)
|
||||
value: (identifier))
|
||||
(call_expression
|
||||
function: (identifier)
|
||||
arguments: (argument_list (int_literal))))
|
||||
(communication_case
|
||||
communication: (receive_statement
|
||||
right: (unary_expression operand: (call_expression
|
||||
function: (selector_expression
|
||||
operand: (identifier)
|
||||
field: (field_identifier))
|
||||
arguments: (argument_list (int_literal)))))
|
||||
(call_expression
|
||||
function: (identifier)
|
||||
arguments: (argument_list (int_literal))))
|
||||
(default_case
|
||||
(return_statement))))))
|
||||
|
||||
============================================
|
||||
Go and defer statements
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
func main() {
|
||||
defer x.y()
|
||||
go x.y()
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(function_declaration (identifier) (parameter_list) (block
|
||||
(defer_statement (call_expression (selector_expression (identifier) (field_identifier)) (argument_list)))
|
||||
(go_statement (call_expression (selector_expression (identifier) (field_identifier)) (argument_list))))))
|
||||
|
||||
============================================
|
||||
Nested statement blocks
|
||||
============================================
|
||||
|
||||
func main() {
|
||||
{
|
||||
println("hi")
|
||||
}
|
||||
{
|
||||
println("bye")
|
||||
}
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(function_declaration (identifier) (parameter_list) (block
|
||||
(block (call_expression (identifier) (argument_list (interpreted_string_literal))))
|
||||
(block (call_expression (identifier) (argument_list (interpreted_string_literal)))))))
|
||||
|
||||
============================================
|
||||
Labels at the ends of statement blocks
|
||||
============================================
|
||||
|
||||
func main() {
|
||||
{
|
||||
end_of_block:
|
||||
}
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(function_declaration
|
||||
name: (identifier)
|
||||
parameters: (parameter_list)
|
||||
body: (block (block
|
||||
(labeled_statement
|
||||
label: (label_name))))))
|
||||
|
||||
============================================
|
||||
Empty statements
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
func main() {
|
||||
;
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(function_declaration (identifier) (parameter_list) (block
|
||||
(empty_statement))))
|
||||
|
||||
=============================================
|
||||
Nested control statements
|
||||
=============================================
|
||||
|
||||
package main
|
||||
|
||||
func main() {
|
||||
for i, v := range vectors {
|
||||
func() {
|
||||
if v == v {
|
||||
fmt.Println("something: %v", vectors[i])
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(function_declaration (identifier) (parameter_list) (block
|
||||
(for_statement
|
||||
(range_clause (expression_list (identifier) (identifier)) (identifier))
|
||||
(block
|
||||
(call_expression
|
||||
(func_literal
|
||||
(parameter_list)
|
||||
(block
|
||||
(if_statement
|
||||
(binary_expression (identifier) (identifier))
|
||||
(block
|
||||
(call_expression
|
||||
(selector_expression (identifier) (field_identifier))
|
||||
(argument_list
|
||||
(interpreted_string_literal)
|
||||
(index_expression (identifier) (identifier))))))))
|
||||
(argument_list)))))))
|
||||
|
||||
============================================
|
||||
Top-level statements
|
||||
============================================
|
||||
|
||||
foo(5)
|
||||
x := T { a: b }
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(call_expression (identifier) (argument_list (int_literal)))
|
||||
(short_var_declaration
|
||||
(expression_list (identifier))
|
||||
(expression_list
|
||||
(composite_literal
|
||||
(type_identifier)
|
||||
(literal_value (keyed_element (field_identifier) (identifier)))))))
|
||||
@ -0,0 +1,297 @@
|
||||
============================================
|
||||
Qualified type names
|
||||
============================================
|
||||
|
||||
type a b.c
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(type_declaration
|
||||
(type_spec
|
||||
name: (type_identifier)
|
||||
type: (qualified_type
|
||||
package: (package_identifier)
|
||||
name: (type_identifier)))))
|
||||
|
||||
============================================
|
||||
Array types
|
||||
============================================
|
||||
|
||||
type a [2+2]c
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(type_declaration
|
||||
(type_spec
|
||||
name: (type_identifier)
|
||||
type: (array_type
|
||||
length: (binary_expression
|
||||
left: (int_literal)
|
||||
right: (int_literal))
|
||||
element: (type_identifier)))))
|
||||
|
||||
============================================
|
||||
Slice types
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
type a []c
|
||||
type b [][]d
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(type_declaration
|
||||
(type_spec
|
||||
(type_identifier)
|
||||
(slice_type (type_identifier))))
|
||||
(type_declaration
|
||||
(type_spec
|
||||
(type_identifier)
|
||||
(slice_type (slice_type (type_identifier))))))
|
||||
|
||||
============================================
|
||||
Struct types
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
type s1 struct {}
|
||||
|
||||
type s2 struct { Person }
|
||||
|
||||
type s2 struct {
|
||||
f, g int
|
||||
}
|
||||
|
||||
type s3 struct {
|
||||
// an embedded struct
|
||||
p.s1
|
||||
|
||||
// a tag
|
||||
h int `json:"h"`
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(type_declaration
|
||||
(type_spec
|
||||
(type_identifier)
|
||||
(struct_type (field_declaration_list))))
|
||||
(type_declaration
|
||||
(type_spec
|
||||
(type_identifier)
|
||||
(struct_type (field_declaration_list (field_declaration (type_identifier))))))
|
||||
(type_declaration
|
||||
(type_spec
|
||||
(type_identifier)
|
||||
(struct_type (field_declaration_list
|
||||
(field_declaration
|
||||
(field_identifier)
|
||||
(field_identifier)
|
||||
(type_identifier))))))
|
||||
(type_declaration
|
||||
(type_spec
|
||||
(type_identifier)
|
||||
(struct_type (field_declaration_list
|
||||
(comment)
|
||||
(field_declaration
|
||||
(qualified_type (package_identifier) (type_identifier)))
|
||||
(comment)
|
||||
(field_declaration
|
||||
(field_identifier)
|
||||
(type_identifier)
|
||||
(raw_string_literal)))))))
|
||||
|
||||
============================================
|
||||
Interface types
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
type i1 interface {}
|
||||
|
||||
type i1 interface { io.Reader }
|
||||
|
||||
type i2 interface {
|
||||
i1
|
||||
io.Reader
|
||||
SomeMethod(s string) error
|
||||
OtherMethod(int, ...bool) bool
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(type_declaration (type_spec
|
||||
(type_identifier)
|
||||
(interface_type (method_spec_list))))
|
||||
(type_declaration (type_spec
|
||||
(type_identifier)
|
||||
(interface_type (method_spec_list
|
||||
(qualified_type (package_identifier) (type_identifier))))))
|
||||
(type_declaration (type_spec
|
||||
(type_identifier)
|
||||
(interface_type (method_spec_list
|
||||
(type_identifier)
|
||||
(qualified_type (package_identifier) (type_identifier))
|
||||
(method_spec
|
||||
(field_identifier)
|
||||
(parameter_list (parameter_declaration (identifier) (type_identifier)))
|
||||
(type_identifier))
|
||||
(method_spec
|
||||
(field_identifier)
|
||||
(parameter_list
|
||||
(parameter_declaration (type_identifier))
|
||||
(variadic_parameter_declaration (type_identifier))) (type_identifier)))))))
|
||||
|
||||
============================================
|
||||
Map types
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
type m1 map[string]error
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(type_declaration
|
||||
(type_spec
|
||||
(type_identifier)
|
||||
(map_type (type_identifier) (type_identifier)))))
|
||||
|
||||
============================================
|
||||
Pointer types
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
type (
|
||||
p1 *string
|
||||
p2 **p1
|
||||
)
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(type_declaration
|
||||
(type_spec
|
||||
(type_identifier)
|
||||
(pointer_type (type_identifier)))
|
||||
(type_spec
|
||||
(type_identifier)
|
||||
(pointer_type (pointer_type (type_identifier))))))
|
||||
|
||||
============================================
|
||||
Channel types
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
type (
|
||||
c1 chan<- chan int
|
||||
c2 chan<- chan<- struct{}
|
||||
c3 chan<- <-chan int
|
||||
)
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(type_declaration
|
||||
(type_spec
|
||||
(type_identifier)
|
||||
(channel_type (channel_type (type_identifier))))
|
||||
(type_spec
|
||||
(type_identifier)
|
||||
(channel_type (channel_type (struct_type (field_declaration_list)))))
|
||||
(type_spec
|
||||
(type_identifier)
|
||||
(channel_type (channel_type (type_identifier))))))
|
||||
|
||||
============================================
|
||||
Function types
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
type (
|
||||
a func(int) int
|
||||
b func(int, *string) (bool, error)
|
||||
c func(int, ...*string) bool
|
||||
)
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(type_declaration
|
||||
(type_spec
|
||||
(type_identifier)
|
||||
(function_type
|
||||
(parameter_list
|
||||
(parameter_declaration (type_identifier)))
|
||||
(type_identifier)))
|
||||
(type_spec
|
||||
(type_identifier)
|
||||
(function_type
|
||||
(parameter_list
|
||||
(parameter_declaration (type_identifier))
|
||||
(parameter_declaration (pointer_type (type_identifier))))
|
||||
(parameter_list
|
||||
(parameter_declaration (type_identifier))
|
||||
(parameter_declaration (type_identifier)))))
|
||||
(type_spec
|
||||
(type_identifier)
|
||||
(function_type
|
||||
(parameter_list
|
||||
(parameter_declaration (type_identifier))
|
||||
(variadic_parameter_declaration
|
||||
(pointer_type (type_identifier))))
|
||||
(type_identifier)))))
|
||||
|
||||
============================================
|
||||
Type Aliases
|
||||
============================================
|
||||
|
||||
package main
|
||||
|
||||
type H1 = G1
|
||||
type _ = G2
|
||||
type _ = struct{}
|
||||
type (
|
||||
A0 = T0
|
||||
A1 = int
|
||||
A2 = struct{}
|
||||
A3 = reflect.Value
|
||||
A4 = Value
|
||||
A5 = Value
|
||||
)
|
||||
|
||||
---
|
||||
|
||||
(source_file
|
||||
(package_clause (package_identifier))
|
||||
(type_declaration
|
||||
(type_alias (type_identifier) (type_identifier)))
|
||||
(type_declaration
|
||||
(type_alias (type_identifier) (type_identifier)))
|
||||
(type_declaration
|
||||
(type_alias (type_identifier) (struct_type (field_declaration_list))))
|
||||
(type_declaration
|
||||
(type_alias (type_identifier) (type_identifier))
|
||||
(type_alias (type_identifier) (type_identifier))
|
||||
(type_alias (type_identifier) (struct_type (field_declaration_list)))
|
||||
(type_alias (type_identifier) (qualified_type (package_identifier) (type_identifier)))
|
||||
(type_alias (type_identifier) (type_identifier))
|
||||
(type_alias (type_identifier) (type_identifier))))
|
||||
@ -0,0 +1,19 @@
|
||||
// run
|
||||
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
func main() {
|
||||
x := 0
|
||||
func() {
|
||||
x = 1
|
||||
}()
|
||||
func() {
|
||||
if x != 1 {
|
||||
panic("x != 1")
|
||||
}
|
||||
}()
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,868 @@
|
||||
const
|
||||
PREC = {
|
||||
primary: 7,
|
||||
unary: 6,
|
||||
multiplicative: 5,
|
||||
additive: 4,
|
||||
comparative: 3,
|
||||
and: 2,
|
||||
or: 1,
|
||||
composite_literal: -1,
|
||||
},
|
||||
|
||||
multiplicative_operators = ['*', '/', '%', '<<', '>>', '&', '&^'],
|
||||
additive_operators = ['+', '-', '|', '^'],
|
||||
comparative_operators = ['==', '!=', '<', '<=', '>', '>='],
|
||||
assignment_operators = multiplicative_operators.concat(additive_operators).map(operator => operator + '=').concat('='),
|
||||
|
||||
unicodeLetter = /\p{L}/,
|
||||
unicodeDigit = /[0-9]/,
|
||||
unicodeChar = /./,
|
||||
unicodeValue = unicodeChar,
|
||||
letter = choice(unicodeLetter, '_'),
|
||||
|
||||
newline = '\n',
|
||||
terminator = choice(newline, ';'),
|
||||
|
||||
hexDigit = /[0-9a-fA-F]/,
|
||||
octalDigit = /[0-7]/,
|
||||
decimalDigit = /[0-9]/,
|
||||
binaryDigit = /[01]/,
|
||||
|
||||
hexDigits = seq(hexDigit, repeat(seq(optional('_'), hexDigit))),
|
||||
octalDigits = seq(octalDigit, repeat(seq(optional('_'), octalDigit))),
|
||||
decimalDigits = seq(decimalDigit, repeat(seq(optional('_'), decimalDigit))),
|
||||
binaryDigits = seq(binaryDigit, repeat(seq(optional('_'), binaryDigit))),
|
||||
|
||||
hexLiteral = seq('0', choice('x', 'X'), optional('_'), hexDigits),
|
||||
octalLiteral = seq('0', optional(choice('o', 'O')), optional('_'), octalDigits),
|
||||
decimalLiteral = choice('0', seq(/[1-9]/, optional(seq(optional('_'), decimalDigits)))),
|
||||
binaryLiteral = seq('0', choice('b', 'B'), optional('_'), binaryDigits),
|
||||
|
||||
intLiteral = choice(binaryLiteral, decimalLiteral, octalLiteral, hexLiteral),
|
||||
|
||||
decimalExponent = seq(choice('e', 'E'), optional(choice('+', '-')), decimalDigits),
|
||||
decimalFloatLiteral = choice(
|
||||
seq(decimalDigits, '.', optional(decimalDigits), optional(decimalExponent)),
|
||||
seq(decimalDigits, decimalExponent),
|
||||
seq('.', decimalDigits, optional(decimalExponent)),
|
||||
),
|
||||
|
||||
hexExponent = seq(choice('p', 'P'), optional(choice('+', '-')), decimalDigits),
|
||||
hexMantissa = choice(
|
||||
seq(optional('_'), hexDigits, '.', optional(hexDigits)),
|
||||
seq(optional('_'), hexDigits),
|
||||
seq('.', hexDigits),
|
||||
),
|
||||
hexFloatLiteral = seq('0', choice('x', 'X'), hexMantissa, hexExponent),
|
||||
|
||||
floatLiteral = choice(decimalFloatLiteral, hexFloatLiteral),
|
||||
|
||||
imaginaryLiteral = seq(choice(decimalDigits, intLiteral, floatLiteral), 'i')
|
||||
|
||||
module.exports = grammar({
|
||||
name: 'go',
|
||||
|
||||
extras: $ => [
|
||||
$.comment,
|
||||
/\s/
|
||||
],
|
||||
|
||||
inline: $ => [
|
||||
$._type,
|
||||
$._type_identifier,
|
||||
$._field_identifier,
|
||||
$._package_identifier,
|
||||
$._top_level_declaration,
|
||||
$._string_literal,
|
||||
],
|
||||
|
||||
word: $ => $.identifier,
|
||||
|
||||
conflicts: $ => [
|
||||
[$._simple_type, $._expression],
|
||||
[$.qualified_type, $._expression],
|
||||
[$.func_literal, $.function_type],
|
||||
[$.function_type],
|
||||
[$.parameter_declaration, $._simple_type],
|
||||
],
|
||||
|
||||
supertypes: $ => [
|
||||
$._expression,
|
||||
$._type,
|
||||
$._simple_type,
|
||||
$._statement,
|
||||
$._simple_statement,
|
||||
],
|
||||
|
||||
rules: {
|
||||
source_file: $ => repeat(choice(
|
||||
seq($._statement, terminator),
|
||||
seq($._top_level_declaration, optional(terminator)),
|
||||
)),
|
||||
|
||||
_top_level_declaration: $ => choice(
|
||||
$.package_clause,
|
||||
$.function_declaration,
|
||||
$.method_declaration,
|
||||
$.import_declaration
|
||||
),
|
||||
|
||||
package_clause: $ => seq(
|
||||
'package',
|
||||
$._package_identifier
|
||||
),
|
||||
|
||||
import_declaration: $ => seq(
|
||||
'import',
|
||||
choice(
|
||||
$.import_spec,
|
||||
$.import_spec_list
|
||||
)
|
||||
),
|
||||
|
||||
import_spec: $ => seq(
|
||||
optional(field('name', choice(
|
||||
$.dot,
|
||||
$.blank_identifier,
|
||||
$._package_identifier
|
||||
))),
|
||||
field('path', $._string_literal)
|
||||
),
|
||||
dot: $ => '.',
|
||||
blank_identifier: $ => '_',
|
||||
|
||||
import_spec_list: $ => seq(
|
||||
'(',
|
||||
repeat(seq(
|
||||
$.import_spec,
|
||||
terminator
|
||||
)),
|
||||
')'
|
||||
),
|
||||
|
||||
_declaration: $ => choice(
|
||||
$.const_declaration,
|
||||
$.type_declaration,
|
||||
$.var_declaration
|
||||
),
|
||||
|
||||
const_declaration: $ => seq(
|
||||
'const',
|
||||
choice(
|
||||
$.const_spec,
|
||||
seq(
|
||||
'(',
|
||||
repeat(seq($.const_spec, terminator)),
|
||||
')'
|
||||
)
|
||||
)
|
||||
),
|
||||
|
||||
const_spec: $ => prec.left(seq(
|
||||
field('name', commaSep1($.identifier)),
|
||||
optional(seq(
|
||||
optional(field('type', $._type)),
|
||||
'=',
|
||||
field('value', $.expression_list)
|
||||
))
|
||||
)),
|
||||
|
||||
var_declaration: $ => seq(
|
||||
'var',
|
||||
choice(
|
||||
$.var_spec,
|
||||
seq(
|
||||
'(',
|
||||
repeat(seq($.var_spec, terminator)),
|
||||
')'
|
||||
)
|
||||
)
|
||||
),
|
||||
|
||||
var_spec: $ => seq(
|
||||
field('name', commaSep1($.identifier)),
|
||||
choice(
|
||||
seq(
|
||||
field('type', $._type),
|
||||
optional(seq('=', field('value', $.expression_list)))
|
||||
),
|
||||
seq('=', field('value', $.expression_list))
|
||||
)
|
||||
),
|
||||
|
||||
function_declaration: $ => prec.right(1, seq(
|
||||
'func',
|
||||
field('name', $.identifier),
|
||||
field('parameters', $.parameter_list),
|
||||
field('result', optional(choice($.parameter_list, $._simple_type))),
|
||||
field('body', optional($.block))
|
||||
)),
|
||||
|
||||
method_declaration: $ => prec.right(1, seq(
|
||||
'func',
|
||||
field('receiver', $.parameter_list),
|
||||
field('name', $._field_identifier),
|
||||
field('parameters', $.parameter_list),
|
||||
field('result', optional(choice($.parameter_list, $._simple_type))),
|
||||
field('body', optional($.block))
|
||||
)),
|
||||
|
||||
parameter_list: $ => seq(
|
||||
'(',
|
||||
optional(seq(
|
||||
commaSep(choice($.parameter_declaration, $.variadic_parameter_declaration)),
|
||||
optional(',')
|
||||
)),
|
||||
')'
|
||||
),
|
||||
|
||||
parameter_declaration: $ => seq(
|
||||
field('name', commaSep($.identifier)),
|
||||
field('type', $._type)
|
||||
),
|
||||
|
||||
variadic_parameter_declaration: $ => seq(
|
||||
field('name', optional($.identifier)),
|
||||
'...',
|
||||
field('type', $._type)
|
||||
),
|
||||
|
||||
type_alias: $ => seq(
|
||||
field('name', $._type_identifier),
|
||||
'=',
|
||||
field('type', $._type)
|
||||
),
|
||||
|
||||
type_declaration: $ => seq(
|
||||
'type',
|
||||
choice(
|
||||
$.type_spec,
|
||||
$.type_alias,
|
||||
seq(
|
||||
'(',
|
||||
repeat(seq(choice($.type_spec, $.type_alias), terminator)),
|
||||
')'
|
||||
)
|
||||
)
|
||||
),
|
||||
|
||||
type_spec: $ => seq(
|
||||
field('name', $._type_identifier),
|
||||
field('type', $._type)
|
||||
),
|
||||
|
||||
field_name_list: $ => commaSep1($._field_identifier),
|
||||
|
||||
expression_list: $ => commaSep1($._expression),
|
||||
|
||||
_type: $ => choice(
|
||||
$._simple_type,
|
||||
$.parenthesized_type
|
||||
),
|
||||
|
||||
parenthesized_type: $ => seq('(', $._type, ')'),
|
||||
|
||||
_simple_type: $ => choice(
|
||||
prec.dynamic(-1, $._type_identifier),
|
||||
$.qualified_type,
|
||||
$.pointer_type,
|
||||
$.struct_type,
|
||||
$.interface_type,
|
||||
$.array_type,
|
||||
$.slice_type,
|
||||
$.map_type,
|
||||
$.channel_type,
|
||||
$.function_type
|
||||
),
|
||||
|
||||
pointer_type: $ => prec(PREC.unary, seq('*', $._type)),
|
||||
|
||||
array_type: $ => seq(
|
||||
'[',
|
||||
field('length', $._expression),
|
||||
']',
|
||||
field('element', $._type)
|
||||
),
|
||||
|
||||
implicit_length_array_type: $ => seq(
|
||||
'[',
|
||||
'...',
|
||||
']',
|
||||
field('element', $._type)
|
||||
),
|
||||
|
||||
slice_type: $ => seq(
|
||||
'[',
|
||||
']',
|
||||
field('element', $._type)
|
||||
),
|
||||
|
||||
struct_type: $ => seq(
|
||||
'struct',
|
||||
$.field_declaration_list
|
||||
),
|
||||
|
||||
field_declaration_list: $ => seq(
|
||||
'{',
|
||||
optional(seq(
|
||||
$.field_declaration,
|
||||
repeat(seq(terminator, $.field_declaration)),
|
||||
optional(terminator)
|
||||
)),
|
||||
'}'
|
||||
),
|
||||
|
||||
field_declaration: $ => seq(
|
||||
choice(
|
||||
seq(
|
||||
field('name', commaSep1($._field_identifier)),
|
||||
field('type', $._type)
|
||||
),
|
||||
seq(
|
||||
optional('*'),
|
||||
field('type', choice(
|
||||
$._type_identifier,
|
||||
$.qualified_type
|
||||
))
|
||||
)
|
||||
),
|
||||
field('tag', optional($._string_literal))
|
||||
),
|
||||
|
||||
interface_type: $ => seq(
|
||||
'interface',
|
||||
$.method_spec_list
|
||||
),
|
||||
|
||||
method_spec_list: $ => seq(
|
||||
'{',
|
||||
optional(seq(
|
||||
choice($._type_identifier, $.qualified_type, $.method_spec),
|
||||
repeat(seq(terminator, choice($._type_identifier, $.qualified_type, $.method_spec))),
|
||||
optional(terminator)
|
||||
)),
|
||||
'}'
|
||||
),
|
||||
|
||||
method_spec: $ => seq(
|
||||
field('name', $._field_identifier),
|
||||
field('parameters', $.parameter_list),
|
||||
field('result', optional(choice($.parameter_list, $._simple_type)))
|
||||
),
|
||||
|
||||
map_type: $ => seq(
|
||||
'map',
|
||||
'[',
|
||||
field('key', $._type),
|
||||
']',
|
||||
field('value', $._type)
|
||||
),
|
||||
|
||||
channel_type: $ => choice(
|
||||
seq('chan', field('value', $._type)),
|
||||
seq('chan', '<-', field('value', $._type)),
|
||||
prec(PREC.unary, seq('<-', 'chan', field('value', $._type)))
|
||||
),
|
||||
|
||||
function_type: $ => seq(
|
||||
'func',
|
||||
field('parameters', $.parameter_list),
|
||||
field('result', optional(choice($.parameter_list, $._simple_type)))
|
||||
),
|
||||
|
||||
block: $ => seq(
|
||||
'{',
|
||||
optional($._statement_list),
|
||||
'}'
|
||||
),
|
||||
|
||||
_statement_list: $ => choice(
|
||||
seq(
|
||||
$._statement,
|
||||
repeat(seq(terminator, $._statement)),
|
||||
optional(seq(
|
||||
terminator,
|
||||
optional(alias($.empty_labeled_statement, $.labeled_statement))
|
||||
))
|
||||
),
|
||||
alias($.empty_labeled_statement, $.labeled_statement)
|
||||
),
|
||||
|
||||
_statement: $ => choice(
|
||||
$._declaration,
|
||||
$._simple_statement,
|
||||
$.return_statement,
|
||||
$.go_statement,
|
||||
$.defer_statement,
|
||||
$.if_statement,
|
||||
$.for_statement,
|
||||
$.expression_switch_statement,
|
||||
$.type_switch_statement,
|
||||
$.select_statement,
|
||||
$.labeled_statement,
|
||||
$.fallthrough_statement,
|
||||
$.break_statement,
|
||||
$.continue_statement,
|
||||
$.goto_statement,
|
||||
$.block,
|
||||
$.empty_statement
|
||||
),
|
||||
|
||||
empty_statement: $ => ';',
|
||||
|
||||
_simple_statement: $ => choice(
|
||||
$._expression,
|
||||
$.send_statement,
|
||||
$.inc_statement,
|
||||
$.dec_statement,
|
||||
$.assignment_statement,
|
||||
$.short_var_declaration
|
||||
),
|
||||
|
||||
send_statement: $ => seq(
|
||||
field('channel', $._expression),
|
||||
'<-',
|
||||
field('value', $._expression)
|
||||
),
|
||||
|
||||
receive_statement: $ => seq(
|
||||
optional(seq(
|
||||
field('left', $.expression_list),
|
||||
choice('=', ':=')
|
||||
)),
|
||||
field('right', $._expression)
|
||||
),
|
||||
|
||||
inc_statement: $ => seq(
|
||||
$._expression,
|
||||
'++'
|
||||
),
|
||||
|
||||
dec_statement: $ => seq(
|
||||
$._expression,
|
||||
'--'
|
||||
),
|
||||
|
||||
assignment_statement: $ => seq(
|
||||
field('left', $.expression_list),
|
||||
field('operator', choice(...assignment_operators)),
|
||||
field('right', $.expression_list)
|
||||
),
|
||||
|
||||
short_var_declaration: $ => seq(
|
||||
// TODO: this should really only allow identifier lists, but that causes
|
||||
// conflicts between identifiers as expressions vs identifiers here.
|
||||
field('left', $.expression_list),
|
||||
':=',
|
||||
field('right', $.expression_list)
|
||||
),
|
||||
|
||||
labeled_statement: $ => seq(
|
||||
field('label', alias($.identifier, $.label_name)),
|
||||
':',
|
||||
$._statement
|
||||
),
|
||||
|
||||
empty_labeled_statement: $ => seq(
|
||||
field('label', alias($.identifier, $.label_name)),
|
||||
':'
|
||||
),
|
||||
|
||||
// This is a hack to prevent `fallthrough_statement` from being parsed as
|
||||
// a single token. For consistency with `break_statement` etc it should
|
||||
// be parsed as a parent node that *contains* a `fallthrough` token.
|
||||
fallthrough_statement: $ => prec.left('fallthrough'),
|
||||
|
||||
break_statement: $ => seq('break', optional(alias($.identifier, $.label_name))),
|
||||
|
||||
continue_statement: $ => seq('continue', optional(alias($.identifier, $.label_name))),
|
||||
|
||||
goto_statement: $ => seq('goto', alias($.identifier, $.label_name)),
|
||||
|
||||
return_statement: $ => seq('return', optional($.expression_list)),
|
||||
|
||||
go_statement: $ => seq('go', $._expression),
|
||||
|
||||
defer_statement: $ => seq('defer', $._expression),
|
||||
|
||||
if_statement: $ => seq(
|
||||
'if',
|
||||
optional(seq(
|
||||
field('initializer', $._simple_statement),
|
||||
';'
|
||||
)),
|
||||
field('condition', $._expression),
|
||||
field('consequence', $.block),
|
||||
optional(seq(
|
||||
'else',
|
||||
field('alternative', choice($.block, $.if_statement))
|
||||
))
|
||||
),
|
||||
|
||||
for_statement: $ => seq(
|
||||
'for',
|
||||
optional(choice($._expression, $.for_clause, $.range_clause)),
|
||||
field('body', $.block)
|
||||
),
|
||||
|
||||
for_clause: $ => seq(
|
||||
field('initializer', optional($._simple_statement)),
|
||||
';',
|
||||
field('condition', optional($._expression)),
|
||||
';',
|
||||
field('update', optional($._simple_statement))
|
||||
),
|
||||
|
||||
range_clause: $ => seq(
|
||||
optional(seq(
|
||||
field('left', $.expression_list),
|
||||
choice('=', ':=')
|
||||
)),
|
||||
'range',
|
||||
field('right', $._expression)
|
||||
),
|
||||
|
||||
expression_switch_statement: $ => seq(
|
||||
'switch',
|
||||
optional(seq(
|
||||
field('initializer', $._simple_statement),
|
||||
';'
|
||||
)),
|
||||
field('value', optional($._expression)),
|
||||
'{',
|
||||
repeat(choice($.expression_case, $.default_case)),
|
||||
'}'
|
||||
),
|
||||
|
||||
expression_case: $ => seq(
|
||||
'case',
|
||||
field('value', $.expression_list),
|
||||
':',
|
||||
optional($._statement_list)
|
||||
),
|
||||
|
||||
default_case: $ => seq(
|
||||
'default',
|
||||
':',
|
||||
optional($._statement_list)
|
||||
),
|
||||
|
||||
type_switch_statement: $ => seq(
|
||||
'switch',
|
||||
$._type_switch_header,
|
||||
'{',
|
||||
repeat(choice($.type_case, $.default_case)),
|
||||
'}'
|
||||
),
|
||||
|
||||
_type_switch_header: $ => seq(
|
||||
optional(seq(
|
||||
field('initializer', $._simple_statement),
|
||||
';'
|
||||
)),
|
||||
optional(seq(field('alias', $.expression_list), ':=')),
|
||||
field('value', $._expression),
|
||||
'.',
|
||||
'(',
|
||||
'type',
|
||||
')'
|
||||
),
|
||||
|
||||
type_case: $ => seq(
|
||||
'case',
|
||||
field('type', commaSep1($._type)),
|
||||
':',
|
||||
optional($._statement_list)
|
||||
),
|
||||
|
||||
select_statement: $ => seq(
|
||||
'select',
|
||||
'{',
|
||||
repeat(choice($.communication_case, $.default_case)),
|
||||
'}'
|
||||
),
|
||||
|
||||
communication_case: $ => seq(
|
||||
'case',
|
||||
field('communication', choice($.send_statement, $.receive_statement)),
|
||||
':',
|
||||
optional($._statement_list)
|
||||
),
|
||||
|
||||
_expression: $ => choice(
|
||||
$.unary_expression,
|
||||
$.binary_expression,
|
||||
$.selector_expression,
|
||||
$.index_expression,
|
||||
$.slice_expression,
|
||||
$.call_expression,
|
||||
$.type_assertion_expression,
|
||||
$.type_conversion_expression,
|
||||
$.identifier,
|
||||
alias(choice('new', 'make'), $.identifier),
|
||||
$.composite_literal,
|
||||
$.func_literal,
|
||||
$._string_literal,
|
||||
$.int_literal,
|
||||
$.float_literal,
|
||||
$.imaginary_literal,
|
||||
$.rune_literal,
|
||||
$.nil,
|
||||
$.true,
|
||||
$.false,
|
||||
$.parenthesized_expression
|
||||
),
|
||||
|
||||
parenthesized_expression: $ => seq(
|
||||
'(',
|
||||
$._expression,
|
||||
')'
|
||||
),
|
||||
|
||||
call_expression: $ => prec(PREC.primary, choice(
|
||||
seq(
|
||||
field('function', alias(choice('new', 'make'), $.identifier)),
|
||||
field('arguments', alias($.special_argument_list, $.argument_list))
|
||||
),
|
||||
seq(
|
||||
field('function', $._expression),
|
||||
field('arguments', $.argument_list)
|
||||
)
|
||||
)),
|
||||
|
||||
variadic_argument: $ => prec.right(seq(
|
||||
$._expression,
|
||||
'...'
|
||||
)),
|
||||
|
||||
special_argument_list: $ => seq(
|
||||
'(',
|
||||
$._type,
|
||||
repeat(seq(',', $._expression)),
|
||||
optional(','),
|
||||
')'
|
||||
),
|
||||
|
||||
argument_list: $ => seq(
|
||||
'(',
|
||||
optional(seq(
|
||||
choice($._expression, $.variadic_argument),
|
||||
repeat(seq(',', choice($._expression, $.variadic_argument))),
|
||||
optional(',')
|
||||
)),
|
||||
')'
|
||||
),
|
||||
|
||||
selector_expression: $ => prec(PREC.primary, seq(
|
||||
field('operand', $._expression),
|
||||
'.',
|
||||
field('field', $._field_identifier)
|
||||
)),
|
||||
|
||||
index_expression: $ => prec(PREC.primary, seq(
|
||||
field('operand', $._expression),
|
||||
'[',
|
||||
field('index', $._expression),
|
||||
']'
|
||||
)),
|
||||
|
||||
slice_expression: $ => prec(PREC.primary, seq(
|
||||
field('operand', $._expression),
|
||||
'[',
|
||||
choice(
|
||||
seq(
|
||||
field('start', optional($._expression)),
|
||||
':',
|
||||
field('end', optional($._expression))
|
||||
),
|
||||
seq(
|
||||
field('start', optional($._expression)),
|
||||
':',
|
||||
field('end', $._expression),
|
||||
':',
|
||||
field('capacity', $._expression)
|
||||
)
|
||||
),
|
||||
']'
|
||||
)),
|
||||
|
||||
type_assertion_expression: $ => prec(PREC.primary, seq(
|
||||
field('operand', $._expression),
|
||||
'.',
|
||||
'(',
|
||||
field('type', $._type),
|
||||
')'
|
||||
)),
|
||||
|
||||
type_conversion_expression: $ => prec.dynamic(-1, seq(
|
||||
field('type', $._type),
|
||||
'(',
|
||||
field('operand', $._expression),
|
||||
optional(','),
|
||||
')'
|
||||
)),
|
||||
|
||||
composite_literal: $ => prec(PREC.composite_literal, seq(
|
||||
field('type', choice(
|
||||
$.map_type,
|
||||
$.slice_type,
|
||||
$.array_type,
|
||||
$.implicit_length_array_type,
|
||||
$.struct_type,
|
||||
$._type_identifier,
|
||||
$.qualified_type
|
||||
)),
|
||||
field('body', $.literal_value)
|
||||
)),
|
||||
|
||||
literal_value: $ => seq(
|
||||
'{',
|
||||
optional(seq(
|
||||
choice($.element, $.keyed_element),
|
||||
repeat(seq(',', choice($.element, $.keyed_element))),
|
||||
optional(',')
|
||||
)),
|
||||
'}'
|
||||
),
|
||||
|
||||
keyed_element: $ => seq(
|
||||
choice(
|
||||
seq($._expression, ':'),
|
||||
seq($.literal_value, ':'),
|
||||
prec(1, seq($._field_identifier, ':'))
|
||||
),
|
||||
choice(
|
||||
$._expression,
|
||||
$.literal_value
|
||||
)
|
||||
),
|
||||
|
||||
element: $ => choice(
|
||||
$._expression,
|
||||
$.literal_value
|
||||
),
|
||||
|
||||
func_literal: $ => seq(
|
||||
'func',
|
||||
field('parameters', $.parameter_list),
|
||||
field('result', optional(choice($.parameter_list, $._simple_type))),
|
||||
field('body', $.block)
|
||||
),
|
||||
|
||||
unary_expression: $ => prec(PREC.unary, seq(
|
||||
field('operator', choice('+', '-', '!', '^', '*', '&', '<-')),
|
||||
field('operand', $._expression)
|
||||
)),
|
||||
|
||||
binary_expression: $ => {
|
||||
const table = [
|
||||
[PREC.multiplicative, choice(...multiplicative_operators)],
|
||||
[PREC.additive, choice(...additive_operators)],
|
||||
[PREC.comparative, choice(...comparative_operators)],
|
||||
[PREC.and, '&&'],
|
||||
[PREC.or, '||'],
|
||||
];
|
||||
|
||||
return choice(...table.map(([precedence, operator]) =>
|
||||
prec.left(precedence, seq(
|
||||
field('left', $._expression),
|
||||
field('operator', operator),
|
||||
field('right', $._expression)
|
||||
))
|
||||
));
|
||||
},
|
||||
|
||||
qualified_type: $ => seq(
|
||||
field('package', $._package_identifier),
|
||||
'.',
|
||||
field('name', $._type_identifier)
|
||||
),
|
||||
|
||||
identifier: $ => token(seq(
|
||||
letter,
|
||||
repeat(choice(letter, unicodeDigit))
|
||||
)),
|
||||
|
||||
_type_identifier: $ => alias($.identifier, $.type_identifier),
|
||||
_field_identifier: $ => alias($.identifier, $.field_identifier),
|
||||
_package_identifier: $ => alias($.identifier, $.package_identifier),
|
||||
|
||||
_string_literal: $ => choice(
|
||||
$.raw_string_literal,
|
||||
$.interpreted_string_literal
|
||||
),
|
||||
|
||||
raw_string_literal: $ => token(seq(
|
||||
'`',
|
||||
repeat(/[^`]/),
|
||||
'`'
|
||||
)),
|
||||
|
||||
interpreted_string_literal: $ => seq(
|
||||
'"',
|
||||
repeat(choice(
|
||||
token.immediate(prec(1, /[^"\n\\]+/)),
|
||||
$.escape_sequence
|
||||
)),
|
||||
'"'
|
||||
),
|
||||
|
||||
escape_sequence: $ => token.immediate(seq(
|
||||
'\\',
|
||||
choice(
|
||||
/[^xuU]/,
|
||||
/\d{2,3}/,
|
||||
/x[0-9a-fA-F]{2,}/,
|
||||
/u[0-9a-fA-F]{4}/,
|
||||
/U[0-9a-fA-F]{8}/
|
||||
)
|
||||
)),
|
||||
|
||||
int_literal: $ => token(intLiteral),
|
||||
|
||||
float_literal: $ => token(floatLiteral),
|
||||
|
||||
imaginary_literal: $ => token(imaginaryLiteral),
|
||||
|
||||
rune_literal: $ => token(seq(
|
||||
"'",
|
||||
choice(
|
||||
/[^'\\]/,
|
||||
seq(
|
||||
'\\',
|
||||
choice(
|
||||
seq('x', hexDigit, hexDigit),
|
||||
seq(octalDigit, octalDigit, octalDigit),
|
||||
seq('u', hexDigit, hexDigit, hexDigit, hexDigit),
|
||||
seq('U', hexDigit, hexDigit, hexDigit, hexDigit, hexDigit, hexDigit, hexDigit, hexDigit),
|
||||
seq(choice('a', 'b', 'f', 'n', 'r', 't', 'v', '\\', "'", '"'))
|
||||
)
|
||||
)
|
||||
),
|
||||
"'"
|
||||
)),
|
||||
|
||||
nil: $ => 'nil',
|
||||
true: $ => 'true',
|
||||
false: $ => 'false',
|
||||
|
||||
// http://stackoverflow.com/questions/13014947/regex-to-match-a-c-style-multiline-comment/36328890#36328890
|
||||
comment: $ => token(choice(
|
||||
seq('//', /.*/),
|
||||
seq(
|
||||
'/*',
|
||||
/[^*]*\*+([^/*][^*]*\*+)*/,
|
||||
'/'
|
||||
)
|
||||
))
|
||||
}
|
||||
})
|
||||
|
||||
function commaSep1(rule) {
|
||||
return seq(rule, repeat(seq(',', rule)))
|
||||
}
|
||||
|
||||
function commaSep(rule) {
|
||||
return optional(commaSep1(rule))
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
{
|
||||
"name": "tree-sitter-go",
|
||||
"version": "0.19.1",
|
||||
"description": "Go grammar for tree-sitter",
|
||||
"main": "bindings/node",
|
||||
"keywords": [
|
||||
"parser",
|
||||
"go"
|
||||
],
|
||||
"author": "Max Brunsfeld",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"nan": "^2.14.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"tree-sitter-cli": "^0.19.1"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tree-sitter generate && node-gyp build",
|
||||
"test": "tree-sitter test && script/parse-examples",
|
||||
"test-windows": "tree-sitter test"
|
||||
},
|
||||
"tree-sitter": [
|
||||
{
|
||||
"scope": "source.go",
|
||||
"file-types": [
|
||||
"go"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,117 @@
|
||||
; Function calls
|
||||
|
||||
(call_expression
|
||||
function: (identifier) @function)
|
||||
|
||||
(call_expression
|
||||
function: (selector_expression
|
||||
field: (field_identifier) @function.method))
|
||||
|
||||
; Function definitions
|
||||
|
||||
(function_declaration
|
||||
name: (identifier) @function)
|
||||
|
||||
(method_declaration
|
||||
name: (field_identifier) @function.method)
|
||||
|
||||
; Identifiers
|
||||
|
||||
(type_identifier) @type
|
||||
(field_identifier) @property
|
||||
(identifier) @variable
|
||||
|
||||
; Operators
|
||||
|
||||
[
|
||||
"--"
|
||||
"-"
|
||||
"-="
|
||||
":="
|
||||
"!"
|
||||
"!="
|
||||
"..."
|
||||
"*"
|
||||
"*"
|
||||
"*="
|
||||
"/"
|
||||
"/="
|
||||
"&"
|
||||
"&&"
|
||||
"&="
|
||||
"%"
|
||||
"%="
|
||||
"^"
|
||||
"^="
|
||||
"+"
|
||||
"++"
|
||||
"+="
|
||||
"<-"
|
||||
"<"
|
||||
"<<"
|
||||
"<<="
|
||||
"<="
|
||||
"="
|
||||
"=="
|
||||
">"
|
||||
">="
|
||||
">>"
|
||||
">>="
|
||||
"|"
|
||||
"|="
|
||||
"||"
|
||||
] @operator
|
||||
|
||||
; Keywords
|
||||
|
||||
[
|
||||
"break"
|
||||
"case"
|
||||
"chan"
|
||||
"const"
|
||||
"continue"
|
||||
"default"
|
||||
"defer"
|
||||
"else"
|
||||
"fallthrough"
|
||||
"for"
|
||||
"func"
|
||||
"go"
|
||||
"goto"
|
||||
"if"
|
||||
"import"
|
||||
"interface"
|
||||
"map"
|
||||
"package"
|
||||
"range"
|
||||
"return"
|
||||
"select"
|
||||
"struct"
|
||||
"switch"
|
||||
"type"
|
||||
"var"
|
||||
] @keyword
|
||||
|
||||
; Literals
|
||||
|
||||
[
|
||||
(interpreted_string_literal)
|
||||
(raw_string_literal)
|
||||
(rune_literal)
|
||||
] @string
|
||||
|
||||
(escape_sequence) @escape
|
||||
|
||||
[
|
||||
(int_literal)
|
||||
(float_literal)
|
||||
(imaginary_literal)
|
||||
] @number
|
||||
|
||||
[
|
||||
(true)
|
||||
(false)
|
||||
(nil)
|
||||
] @constant.builtin
|
||||
|
||||
(comment) @comment
|
||||
@ -0,0 +1,30 @@
|
||||
(
|
||||
(comment)* @doc
|
||||
.
|
||||
(function_declaration
|
||||
name: (identifier) @name) @definition.function
|
||||
(#strip! @doc "^//\\s*")
|
||||
(#set-adjacent! @doc @definition.function)
|
||||
)
|
||||
|
||||
(
|
||||
(comment)* @doc
|
||||
.
|
||||
(method_declaration
|
||||
name: (field_identifier) @name) @definition.method
|
||||
(#strip! @doc "^//\\s*")
|
||||
(#set-adjacent! @doc @definition.method)
|
||||
)
|
||||
|
||||
(call_expression
|
||||
function: [
|
||||
(identifier) @name
|
||||
(parenthesized_expression (identifier) @name)
|
||||
(selector_expression field: (field_identifier) @name)
|
||||
(parenthesized_expression (selector_expression field: (field_identifier) @name))
|
||||
]) @reference.call
|
||||
|
||||
(type_spec
|
||||
name: (type_identifier) @name) @definition.type
|
||||
|
||||
(type_identifier) @name @reference.type
|
||||
@ -0,0 +1,5 @@
|
||||
# Unhandled identifier character: 'ŝ'
|
||||
examples/go/src/math/big/arith.go
|
||||
|
||||
# Unhandled identifier character: 'ƒ'
|
||||
examples/moby/vendor/github.com/beorn7/perks/quantile/stream.go
|
||||
@ -0,0 +1,36 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
function checkout_at() {
|
||||
repo=$1; url=$2; sha=$3
|
||||
if [ ! -d "$repo" ]; then
|
||||
git clone "https://github.com/$url" "$repo"
|
||||
fi
|
||||
|
||||
pushd "$repo"
|
||||
git fetch && git reset --hard "$sha"
|
||||
popd
|
||||
}
|
||||
|
||||
checkout_at "examples/go" "golang/go" "870e12d7bfaea70fb0d743842f5864eb059cb939"
|
||||
checkout_at "examples/moby" "moby/moby" "f57f260b49b6142366e6bc1274204ee0a1205945"
|
||||
|
||||
known_failures="$(cat script/known-failures.txt | egrep -v '^#')"
|
||||
|
||||
time tree-sitter parse -q \
|
||||
'examples/**/*.go' \
|
||||
'!**/testdata/**/*' \
|
||||
'!**/go/test/**/*' \
|
||||
$(for failure in $known_failures; do echo "!${failure}"; done)
|
||||
|
||||
example_count=$(find examples -name '*.go' | egrep -v 'go/test|testdata' | wc -l)
|
||||
failure_count=$(wc -w <<< "$known_failures")
|
||||
success_count=$(( $example_count - $failure_count ))
|
||||
success_percent=$(bc -l <<< "100*${success_count}/${example_count}")
|
||||
|
||||
printf \
|
||||
"Successfully parsed %d of %d example files (%.1f%%)\n" \
|
||||
$success_count $example_count $success_percent
|
||||
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,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 **symbol_names;
|
||||
const char **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_
|
||||
Loading…
Reference in New Issue