Add 'vendor/tree-sitter-go/' from commit 'eb306e6e60f393df346cfc8cbfaf52667a37128a'

git-subtree-dir: vendor/tree-sitter-go
git-subtree-mainline: 26c6438fa2
git-subtree-split: eb306e6e60
ida_star
Wilfred Hughes 2021-08-15 16:42:25 +07:00
commit 8a6c7c8013
35 changed files with 71799 additions and 0 deletions

@ -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
===========================
[![Build/test](https://github.com/tree-sitter/tree-sitter-go/actions/workflows/ci.yml/badge.svg)](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,130 @@
============================================
Package clauses
============================================
package main
----
(source_file
(package_clause (package_identifier)))
============================================
Single import declarations
============================================
package a
import "net/http"
import . "some/dsl"
import _ "os"
import alias "some/package"
----
(source_file
(package_clause (package_identifier))
(import_declaration (import_spec (interpreted_string_literal)))
(import_declaration (import_spec (dot) (interpreted_string_literal)))
(import_declaration (import_spec (blank_identifier) (interpreted_string_literal)))
(import_declaration (import_spec (package_identifier) (interpreted_string_literal))))
============================================
Grouped import declarations
============================================
package a
import (
"net/http"
. "some/dsl"
_ "os"
alias "some/package"
)
----
(source_file
(package_clause (package_identifier))
(import_declaration (import_spec_list
(import_spec (interpreted_string_literal))
(import_spec (dot) (interpreted_string_literal))
(import_spec (blank_identifier) (interpreted_string_literal))
(import_spec (package_identifier) (interpreted_string_literal)))))
============================================
Block comments
============================================
/*
* This is a great package
*/
package a
----
(source_file
(comment)
(package_clause (package_identifier)))
============================================
Comments with asterisks
============================================
package main
/* a */
const a
/* b **/
const b
/* c ***/
const c
/* d
***/
const d
---
(source_file
(package_clause (package_identifier))
(comment)
(const_declaration (const_spec (identifier)))
(comment)
(const_declaration (const_spec (identifier)))
(comment)
(const_declaration (const_spec (identifier)))
(comment)
(const_declaration (const_spec (identifier))))
============================================
Non-ascii variable names
============================================
package main
const (
α
Α
µs // micro sign (not mu)
δ1
ΔΔΔ
ω_omega
Ω_OMEGA
)
---
(source_file
(package_clause (package_identifier))
(const_declaration
(const_spec (identifier))
(const_spec (identifier))
(const_spec (identifier)) (comment)
(const_spec (identifier))
(const_spec (identifier))
(const_spec (identifier))
(const_spec (identifier))))

@ -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,549 @@
// Copyright 2009 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 unicode_test
import (
"flag"
"fmt"
"runtime"
"sort"
"testing"
. "unicode"
)
var upperTest = []rune{
0x41,
0xc0,
0xd8,
0x100,
0x139,
0x14a,
0x178,
0x181,
0x376,
0x3cf,
0x13bd,
0x1f2a,
0x2102,
0x2c00,
0x2c10,
0x2c20,
0xa650,
0xa722,
0xff3a,
0x10400,
0x1d400,
0x1d7ca,
}
var notupperTest = []rune{
0x40,
0x5b,
0x61,
0x185,
0x1b0,
0x377,
0x387,
0x2150,
0xab7d,
0xffff,
0x10000,
}
var letterTest = []rune{
0x41,
0x61,
0xaa,
0xba,
0xc8,
0xdb,
0xf9,
0x2ec,
0x535,
0x620,
0x6e6,
0x93d,
0xa15,
0xb99,
0xdc0,
0xedd,
0x1000,
0x1200,
0x1312,
0x1401,
0x1885,
0x2c00,
0xa800,
0xf900,
0xfa30,
0xffda,
0xffdc,
0x10000,
0x10300,
0x10400,
0x20000,
0x2f800,
0x2fa1d,
}
var notletterTest = []rune{
0x20,
0x35,
0x375,
0x619,
0x700,
0xfffe,
0x1ffff,
0x10ffff,
}
// Contains all the special cased Latin-1 chars.
var spaceTest = []rune{
0x09,
0x0a,
0x0b,
0x0c,
0x0d,
0x20,
0x85,
0xA0,
0x2000,
0x3000,
}
type caseT struct {
cas int
in, out rune
}
var caseTest = []caseT{
// errors
{-1, '\n', 0xFFFD},
{UpperCase, -1, -1},
{UpperCase, 1 << 30, 1 << 30},
// ASCII (special-cased so test carefully)
{UpperCase, '\n', '\n'},
{UpperCase, 'a', 'A'},
{UpperCase, 'A', 'A'},
{UpperCase, '7', '7'},
{LowerCase, '\n', '\n'},
{LowerCase, 'a', 'a'},
{LowerCase, 'A', 'a'},
{LowerCase, '7', '7'},
{TitleCase, '\n', '\n'},
{TitleCase, 'a', 'A'},
{TitleCase, 'A', 'A'},
{TitleCase, '7', '7'},
// Latin-1: easy to read the tests!
{UpperCase, 0x80, 0x80},
{UpperCase, 'Å', 'Å'},
{UpperCase, 'å', 'Å'},
{LowerCase, 0x80, 0x80},
{LowerCase, 'Å', 'å'},
{LowerCase, 'å', 'å'},
{TitleCase, 0x80, 0x80},
{TitleCase, 'Å', 'Å'},
{TitleCase, 'å', 'Å'},
// 0131;LATIN SMALL LETTER DOTLESS I;Ll;0;L;;;;;N;;;0049;;0049
{UpperCase, 0x0131, 'I'},
{LowerCase, 0x0131, 0x0131},
{TitleCase, 0x0131, 'I'},
// 0133;LATIN SMALL LIGATURE IJ;Ll;0;L;<compat> 0069 006A;;;;N;LATIN SMALL LETTER I J;;0132;;0132
{UpperCase, 0x0133, 0x0132},
{LowerCase, 0x0133, 0x0133},
{TitleCase, 0x0133, 0x0132},
// 212A;KELVIN SIGN;Lu;0;L;004B;;;;N;DEGREES KELVIN;;;006B;
{UpperCase, 0x212A, 0x212A},
{LowerCase, 0x212A, 'k'},
{TitleCase, 0x212A, 0x212A},
// From an UpperLower sequence
// A640;CYRILLIC CAPITAL LETTER ZEMLYA;Lu;0;L;;;;;N;;;;A641;
{UpperCase, 0xA640, 0xA640},
{LowerCase, 0xA640, 0xA641},
{TitleCase, 0xA640, 0xA640},
// A641;CYRILLIC SMALL LETTER ZEMLYA;Ll;0;L;;;;;N;;;A640;;A640
{UpperCase, 0xA641, 0xA640},
{LowerCase, 0xA641, 0xA641},
{TitleCase, 0xA641, 0xA640},
// A64E;CYRILLIC CAPITAL LETTER NEUTRAL YER;Lu;0;L;;;;;N;;;;A64F;
{UpperCase, 0xA64E, 0xA64E},
{LowerCase, 0xA64E, 0xA64F},
{TitleCase, 0xA64E, 0xA64E},
// A65F;CYRILLIC SMALL LETTER YN;Ll;0;L;;;;;N;;;A65E;;A65E
{UpperCase, 0xA65F, 0xA65E},
{LowerCase, 0xA65F, 0xA65F},
{TitleCase, 0xA65F, 0xA65E},
// From another UpperLower sequence
// 0139;LATIN CAPITAL LETTER L WITH ACUTE;Lu;0;L;004C 0301;;;;N;LATIN CAPITAL LETTER L ACUTE;;;013A;
{UpperCase, 0x0139, 0x0139},
{LowerCase, 0x0139, 0x013A},
{TitleCase, 0x0139, 0x0139},
// 013F;LATIN CAPITAL LETTER L WITH MIDDLE DOT;Lu;0;L;<compat> 004C 00B7;;;;N;;;;0140;
{UpperCase, 0x013f, 0x013f},
{LowerCase, 0x013f, 0x0140},
{TitleCase, 0x013f, 0x013f},
// 0148;LATIN SMALL LETTER N WITH CARON;Ll;0;L;006E 030C;;;;N;LATIN SMALL LETTER N HACEK;;0147;;0147
{UpperCase, 0x0148, 0x0147},
{LowerCase, 0x0148, 0x0148},
{TitleCase, 0x0148, 0x0147},
// Lowercase lower than uppercase.
// AB78;CHEROKEE SMALL LETTER GE;Ll;0;L;;;;;N;;;13A8;;13A8
{UpperCase, 0xab78, 0x13a8},
{LowerCase, 0xab78, 0xab78},
{TitleCase, 0xab78, 0x13a8},
{UpperCase, 0x13a8, 0x13a8},
{LowerCase, 0x13a8, 0xab78},
{TitleCase, 0x13a8, 0x13a8},
// Last block in the 5.1.0 table
// 10400;DESERET CAPITAL LETTER LONG I;Lu;0;L;;;;;N;;;;10428;
{UpperCase, 0x10400, 0x10400},
{LowerCase, 0x10400, 0x10428},
{TitleCase, 0x10400, 0x10400},
// 10427;DESERET CAPITAL LETTER EW;Lu;0;L;;;;;N;;;;1044F;
{UpperCase, 0x10427, 0x10427},
{LowerCase, 0x10427, 0x1044F},
{TitleCase, 0x10427, 0x10427},
// 10428;DESERET SMALL LETTER LONG I;Ll;0;L;;;;;N;;;10400;;10400
{UpperCase, 0x10428, 0x10400},
{LowerCase, 0x10428, 0x10428},
{TitleCase, 0x10428, 0x10400},
// 1044F;DESERET SMALL LETTER EW;Ll;0;L;;;;;N;;;10427;;10427
{UpperCase, 0x1044F, 0x10427},
{LowerCase, 0x1044F, 0x1044F},
{TitleCase, 0x1044F, 0x10427},
// First one not in the 5.1.0 table
// 10450;SHAVIAN LETTER PEEP;Lo;0;L;;;;;N;;;;;
{UpperCase, 0x10450, 0x10450},
{LowerCase, 0x10450, 0x10450},
{TitleCase, 0x10450, 0x10450},
// Non-letters with case.
{LowerCase, 0x2161, 0x2171},
{UpperCase, 0x0345, 0x0399},
}
func TestIsLetter(t *testing.T) {
for _, r := range upperTest {
if !IsLetter(r) {
t.Errorf("IsLetter(U+%04X) = false, want true", r)
}
}
for _, r := range letterTest {
if !IsLetter(r) {
t.Errorf("IsLetter(U+%04X) = false, want true", r)
}
}
for _, r := range notletterTest {
if IsLetter(r) {
t.Errorf("IsLetter(U+%04X) = true, want false", r)
}
}
}
func TestIsUpper(t *testing.T) {
for _, r := range upperTest {
if !IsUpper(r) {
t.Errorf("IsUpper(U+%04X) = false, want true", r)
}
}
for _, r := range notupperTest {
if IsUpper(r) {
t.Errorf("IsUpper(U+%04X) = true, want false", r)
}
}
for _, r := range notletterTest {
if IsUpper(r) {
t.Errorf("IsUpper(U+%04X) = true, want false", r)
}
}
}
func caseString(c int) string {
switch c {
case UpperCase:
return "UpperCase"
case LowerCase:
return "LowerCase"
case TitleCase:
return "TitleCase"
}
return "ErrorCase"
}
func TestTo(t *testing.T) {
for _, c := range caseTest {
r := To(c.cas, c.in)
if c.out != r {
t.Errorf("To(U+%04X, %s) = U+%04X want U+%04X", c.in, caseString(c.cas), r, c.out)
}
}
}
func TestToUpperCase(t *testing.T) {
for _, c := range caseTest {
if c.cas != UpperCase {
continue
}
r := ToUpper(c.in)
if c.out != r {
t.Errorf("ToUpper(U+%04X) = U+%04X want U+%04X", c.in, r, c.out)
}
}
}
func TestToLowerCase(t *testing.T) {
for _, c := range caseTest {
if c.cas != LowerCase {
continue
}
r := ToLower(c.in)
if c.out != r {
t.Errorf("ToLower(U+%04X) = U+%04X want U+%04X", c.in, r, c.out)
}
}
}
func TestToTitleCase(t *testing.T) {
for _, c := range caseTest {
if c.cas != TitleCase {
continue
}
r := ToTitle(c.in)
if c.out != r {
t.Errorf("ToTitle(U+%04X) = U+%04X want U+%04X", c.in, r, c.out)
}
}
}
func TestIsSpace(t *testing.T) {
for _, c := range spaceTest {
if !IsSpace(c) {
t.Errorf("IsSpace(U+%04X) = false; want true", c)
}
}
for _, c := range letterTest {
if IsSpace(c) {
t.Errorf("IsSpace(U+%04X) = true; want false", c)
}
}
}
// Check that the optimizations for IsLetter etc. agree with the tables.
// We only need to check the Latin-1 range.
func TestLetterOptimizations(t *testing.T) {
for i := rune(0); i <= MaxLatin1; i++ {
if Is(Letter, i) != IsLetter(i) {
t.Errorf("IsLetter(U+%04X) disagrees with Is(Letter)", i)
}
if Is(Upper, i) != IsUpper(i) {
t.Errorf("IsUpper(U+%04X) disagrees with Is(Upper)", i)
}
if Is(Lower, i) != IsLower(i) {
t.Errorf("IsLower(U+%04X) disagrees with Is(Lower)", i)
}
if Is(Title, i) != IsTitle(i) {
t.Errorf("IsTitle(U+%04X) disagrees with Is(Title)", i)
}
if Is(White_Space, i) != IsSpace(i) {
t.Errorf("IsSpace(U+%04X) disagrees with Is(White_Space)", i)
}
if To(UpperCase, i) != ToUpper(i) {
t.Errorf("ToUpper(U+%04X) disagrees with To(Upper)", i)
}
if To(LowerCase, i) != ToLower(i) {
t.Errorf("ToLower(U+%04X) disagrees with To(Lower)", i)
}
if To(TitleCase, i) != ToTitle(i) {
t.Errorf("ToTitle(U+%04X) disagrees with To(Title)", i)
}
}
}
func TestTurkishCase(t *testing.T) {
lower := []rune("abcçdefgğhıijklmnoöprsştuüvyz")
upper := []rune("ABCÇDEFGĞHIİJKLMNOÖPRSŞTUÜVYZ")
for i, l := range lower {
u := upper[i]
if TurkishCase.ToLower(l) != l {
t.Errorf("lower(U+%04X) is U+%04X not U+%04X", l, TurkishCase.ToLower(l), l)
}
if TurkishCase.ToUpper(u) != u {
t.Errorf("upper(U+%04X) is U+%04X not U+%04X", u, TurkishCase.ToUpper(u), u)
}
if TurkishCase.ToUpper(l) != u {
t.Errorf("upper(U+%04X) is U+%04X not U+%04X", l, TurkishCase.ToUpper(l), u)
}
if TurkishCase.ToLower(u) != l {
t.Errorf("lower(U+%04X) is U+%04X not U+%04X", u, TurkishCase.ToLower(l), l)
}
if TurkishCase.ToTitle(u) != u {
t.Errorf("title(U+%04X) is U+%04X not U+%04X", u, TurkishCase.ToTitle(u), u)
}
if TurkishCase.ToTitle(l) != u {
t.Errorf("title(U+%04X) is U+%04X not U+%04X", l, TurkishCase.ToTitle(l), u)
}
}
}
var simpleFoldTests = []string{
// SimpleFold(x) returns the next equivalent rune > x or wraps
// around to smaller values.
// Easy cases.
"Aa",
"δΔ",
// ASCII special cases.
"Kk",
"Ssſ",
// Non-ASCII special cases.
"ρϱΡ",
"ͅΙιι",
// Extra special cases: has lower/upper but no case fold.
"İ",
"ı",
// Upper comes before lower (Cherokee).
"\u13b0\uab80",
}
func TestSimpleFold(t *testing.T) {
for _, tt := range simpleFoldTests {
cycle := []rune(tt)
r := cycle[len(cycle)-1]
for _, out := range cycle {
if r := SimpleFold(r); r != out {
t.Errorf("SimpleFold(%#U) = %#U, want %#U", r, r, out)
}
r = out
}
}
}
// Running 'go test -calibrate' runs the calibration to find a plausible
// cutoff point for linear search of a range list vs. binary search.
// We create a fake table and then time how long it takes to do a
// sequence of searches within that table, for all possible inputs
// relative to the ranges (something before all, in each, between each, after all).
// This assumes that all possible runes are equally likely.
// In practice most runes are ASCII so this is a conservative estimate
// of an effective cutoff value. In practice we could probably set it higher
// than what this function recommends.
var calibrate = flag.Bool("calibrate", false, "compute crossover for linear vs. binary search")
func TestCalibrate(t *testing.T) {
if !*calibrate {
return
}
if runtime.GOARCH == "amd64" {
fmt.Printf("warning: running calibration on %s\n", runtime.GOARCH)
}
// Find the point where binary search wins by more than 10%.
// The 10% bias gives linear search an edge when they're close,
// because on predominantly ASCII inputs linear search is even
// better than our benchmarks measure.
n := sort.Search(64, func(n int) bool {
tab := fakeTable(n)
blinear := func(b *testing.B) {
tab := tab
max := n*5 + 20
for i := 0; i < b.N; i++ {
for j := 0; j <= max; j++ {
linear(tab, uint16(j))
}
}
}
bbinary := func(b *testing.B) {
tab := tab
max := n*5 + 20
for i := 0; i < b.N; i++ {
for j := 0; j <= max; j++ {
binary(tab, uint16(j))
}
}
}
bmlinear := testing.Benchmark(blinear)
bmbinary := testing.Benchmark(bbinary)
fmt.Printf("n=%d: linear=%d binary=%d\n", n, bmlinear.NsPerOp(), bmbinary.NsPerOp())
return bmlinear.NsPerOp()*100 > bmbinary.NsPerOp()*110
})
fmt.Printf("calibration: linear cutoff = %d\n", n)
}
func fakeTable(n int) []Range16 {
var r16 []Range16
for i := 0; i < n; i++ {
r16 = append(r16, Range16{uint16(i*5 + 10), uint16(i*5 + 12), 1})
}
return r16
}
func linear(ranges []Range16, r uint16) bool {
for i := range ranges {
range_ := &ranges[i]
if r < range_.Lo {
return false
}
if r <= range_.Hi {
return (r-range_.Lo)%range_.Stride == 0
}
}
return false
}
func binary(ranges []Range16, r uint16) bool {
// binary search over ranges
lo := 0
hi := len(ranges)
for lo < hi {
m := lo + (hi-lo)/2
range_ := &ranges[m]
if range_.Lo <= r && r <= range_.Hi {
return (r-range_.Lo)%range_.Stride == 0
}
if r < range_.Lo {
hi = m
} else {
lo = m + 1
}
}
return false
}
func TestLatinOffset(t *testing.T) {
var maps = []map[string]*RangeTable{
Categories,
FoldCategory,
FoldScript,
Properties,
Scripts,
}
for _, m := range maps {
for name, tab := range m {
i := 0
for i < len(tab.R16) && tab.R16[i].Hi <= MaxLatin1 {
i++
}
if tab.LatinOffset != i {
t.Errorf("%s: LatinOffset=%d, want %d", name, tab.LatinOffset, i)
}
}
}
}

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