mirror of https://github.com/Wilfred/difftastic/
parent
62752b6ab6
commit
b3995cd967
@ -1 +0,0 @@
|
||||
../tree-sitter-zig/queries/highlights.scm
|
||||
@ -1 +0,0 @@
|
||||
tree-sitter-zig/src
|
||||
@ -1,26 +0,0 @@
|
||||
[package]
|
||||
name = "tree-sitter-zig"
|
||||
description = "zig grammar for the tree-sitter parsing library"
|
||||
version = "0.0.1"
|
||||
keywords = ["incremental", "parsing", "zig"]
|
||||
categories = ["parsing", "text-editors"]
|
||||
repository = "https://github.com/tree-sitter/tree-sitter-zig"
|
||||
edition = "2018"
|
||||
license = "MIT"
|
||||
|
||||
build = "bindings/rust/build.rs"
|
||||
include = [
|
||||
"bindings/rust/*",
|
||||
"grammar.js",
|
||||
"queries/*",
|
||||
"src/*",
|
||||
]
|
||||
|
||||
[lib]
|
||||
path = "bindings/rust/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
tree-sitter = "~0.20"
|
||||
|
||||
[build-dependencies]
|
||||
cc = "1.0"
|
||||
@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 maxxnino
|
||||
|
||||
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.
|
||||
@ -1,20 +0,0 @@
|
||||
<div align="center">
|
||||
<h1>Tree Sitter For Zig</h1>
|
||||
</div>
|
||||
|
||||
<div align="center">
|
||||
<p>
|
||||
<a href="https://github.com/maxxnino/tree-sitter-zig">Zig's Tree Sitter</a>
|
||||
based on
|
||||
<a href="https://github.com/ziglang/zig-spec">Zig Spec</a> Official.
|
||||
</p>
|
||||
<p>
|
||||
<i>
|
||||
Made by Zig's enthusiasts
|
||||
</i>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
>Check [Gallery](https://github.com/maxxnino/tree-sitter-zig/wiki/Gallery) for more images
|
||||
>
|
||||

|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 269 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 224 KiB |
@ -1,19 +0,0 @@
|
||||
{
|
||||
"targets": [
|
||||
{
|
||||
"target_name": "tree_sitter_zig_binding",
|
||||
"include_dirs": [
|
||||
"<!(node -e \"require('nan')\")",
|
||||
"src"
|
||||
],
|
||||
"sources": [
|
||||
"bindings/node/binding.cc",
|
||||
"src/parser.c",
|
||||
# If your language uses an external scanner, add it here.
|
||||
],
|
||||
"cflags_c": [
|
||||
"-std=c99",
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -1,28 +0,0 @@
|
||||
#include "tree_sitter/parser.h"
|
||||
#include <node.h>
|
||||
#include "nan.h"
|
||||
|
||||
using namespace v8;
|
||||
|
||||
extern "C" TSLanguage * tree_sitter_zig();
|
||||
|
||||
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_zig());
|
||||
|
||||
Nan::Set(instance, Nan::New("name").ToLocalChecked(), Nan::New("zig").ToLocalChecked());
|
||||
Nan::Set(module, Nan::New("exports").ToLocalChecked(), instance);
|
||||
}
|
||||
|
||||
NODE_MODULE(tree_sitter_zig_binding, Init)
|
||||
|
||||
} // namespace
|
||||
@ -1,19 +0,0 @@
|
||||
try {
|
||||
module.exports = require("../../build/Release/tree_sitter_zig_binding");
|
||||
} catch (error1) {
|
||||
if (error1.code !== 'MODULE_NOT_FOUND') {
|
||||
throw error1;
|
||||
}
|
||||
try {
|
||||
module.exports = require("../../build/Debug/tree_sitter_zig_binding");
|
||||
} catch (error2) {
|
||||
if (error2.code !== 'MODULE_NOT_FOUND') {
|
||||
throw error2;
|
||||
}
|
||||
throw error1
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
module.exports.nodeTypeInfo = require("../../src/node-types.json");
|
||||
} catch (_) {}
|
||||
@ -1,40 +0,0 @@
|
||||
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);
|
||||
|
||||
// If your language uses an external scanner written in C,
|
||||
// then include this block of code:
|
||||
|
||||
/*
|
||||
let scanner_path = src_dir.join("scanner.c");
|
||||
c_config.file(&scanner_path);
|
||||
println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap());
|
||||
*/
|
||||
|
||||
c_config.compile("parser");
|
||||
println!("cargo:rerun-if-changed={}", parser_path.to_str().unwrap());
|
||||
|
||||
// If your language uses an external scanner written in C++,
|
||||
// then include this block of code:
|
||||
|
||||
/*
|
||||
let mut cpp_config = cc::Build::new();
|
||||
cpp_config.cpp(true);
|
||||
cpp_config.include(&src_dir);
|
||||
cpp_config
|
||||
.flag_if_supported("-Wno-unused-parameter")
|
||||
.flag_if_supported("-Wno-unused-but-set-variable");
|
||||
let scanner_path = src_dir.join("scanner.cc");
|
||||
cpp_config.file(&scanner_path);
|
||||
cpp_config.compile("scanner");
|
||||
println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap());
|
||||
*/
|
||||
}
|
||||
@ -1,52 +0,0 @@
|
||||
//! This crate provides zig language support for the [tree-sitter][] parsing library.
|
||||
//!
|
||||
//! Typically, you will use the [language][language func] function to add this language to a
|
||||
//! tree-sitter [Parser][], and then use the parser to parse some code:
|
||||
//!
|
||||
//! ```
|
||||
//! let code = "";
|
||||
//! let mut parser = tree_sitter::Parser::new();
|
||||
//! parser.set_language(tree_sitter_zig::language()).expect("Error loading zig grammar");
|
||||
//! let tree = parser.parse(code, None).unwrap();
|
||||
//! ```
|
||||
//!
|
||||
//! [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_zig() -> Language;
|
||||
}
|
||||
|
||||
/// Get 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_zig() }
|
||||
}
|
||||
|
||||
/// 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");
|
||||
|
||||
// Uncomment these to include any queries that this grammar contains
|
||||
|
||||
// pub const HIGHLIGHTS_QUERY: &'static str = include_str!("../../queries/highlights.scm");
|
||||
// pub const INJECTIONS_QUERY: &'static str = include_str!("../../queries/injections.scm");
|
||||
// pub const LOCALS_QUERY: &'static str = include_str!("../../queries/locals.scm");
|
||||
// pub const TAGS_QUERY: &'static str = include_str!("../../queries/tags.scm");
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn test_can_load_grammar() {
|
||||
let mut parser = tree_sitter::Parser::new();
|
||||
parser
|
||||
.set_language(super::language())
|
||||
.expect("Error loading zig language");
|
||||
}
|
||||
}
|
||||
@ -1,867 +0,0 @@
|
||||
const AMPERSAND = "&",
|
||||
AMPERSANDEQUAL = "&=",
|
||||
ASTERISK = "*",
|
||||
ASTERISK2 = "**",
|
||||
ASTERISKEQUAL = "*=",
|
||||
ASTERISKPERCENT = "*%",
|
||||
ASTERISKPERCENTEQUAL = "*%=",
|
||||
ASTERISKPIPE = "*|",
|
||||
ASTERISKPIPEEQUAL = "*|=",
|
||||
CARET = "^",
|
||||
CARETEQUAL = "^=",
|
||||
COLON = ":",
|
||||
COMMA = ",",
|
||||
DOT = ".",
|
||||
DOT2 = "..",
|
||||
DOT3 = "...",
|
||||
DOTASTERISK = ".*",
|
||||
DOTQUESTIONMARK = ".?",
|
||||
EQUAL = "=",
|
||||
EQUALEQUAL = "==",
|
||||
EQUALRARROW = "=>",
|
||||
EXCLAMATIONMARK = "!",
|
||||
EXCLAMATIONMARKEQUAL = "!=",
|
||||
LARROW = "<",
|
||||
LARROW2 = "<<",
|
||||
LARROW2PIPE = "<<|",
|
||||
LARROW2PIPEEQUAL = "<<|=",
|
||||
LARROW2EQUAL = "<<=",
|
||||
LARROWEQUAL = "<=",
|
||||
LBRACE = "{",
|
||||
LBRACKET = "[",
|
||||
LPAREN = "(",
|
||||
MINUS = "-",
|
||||
MINUSEQUAL = "-=",
|
||||
MINUSPERCENT = "-%",
|
||||
MINUSPERCENTEQUAL = "-%=",
|
||||
MINUSPIPE = "-|",
|
||||
MINUSPIPEEQUAL = "-|=",
|
||||
MINUSRARROW = "->",
|
||||
PERCENT = "%",
|
||||
PERCENTEQUAL = "%=",
|
||||
PIPE = "|",
|
||||
PIPE2 = "||",
|
||||
PIPEEQUAL = "|=",
|
||||
PLUS = "+",
|
||||
PLUS2 = "++",
|
||||
PLUSEQUAL = "+=",
|
||||
PLUSPERCENT = "+%",
|
||||
PLUSPERCENTEQUAL = "+%=",
|
||||
PLUSPIPE = "+|",
|
||||
PLUSPIPEEQUAL = "+|=",
|
||||
LETTERC = "c",
|
||||
QUESTIONMARK = "?",
|
||||
RARROW = ">",
|
||||
RARROW2 = ">>",
|
||||
RARROW2EQUAL = ">>=",
|
||||
RARROWEQUAL = ">=",
|
||||
RBRACE = "}",
|
||||
RBRACKET = "]",
|
||||
RPAREN = ")",
|
||||
SEMICOLON = ";",
|
||||
SLASH = "/",
|
||||
SLASHEQUAL = "/=",
|
||||
TILDE = "~",
|
||||
PREC = {
|
||||
label: -1,
|
||||
curly: 1,
|
||||
assign: 2,
|
||||
primary: 3,
|
||||
statement: 4,
|
||||
paramType: 5,
|
||||
or: 6,
|
||||
and: 7,
|
||||
comparative: 8,
|
||||
bitwise: 9,
|
||||
bitshift: 10,
|
||||
addition: 11,
|
||||
multiply: 12,
|
||||
prefix: 13,
|
||||
},
|
||||
buildin_type = [
|
||||
"bool",
|
||||
"f16",
|
||||
"f32",
|
||||
"f64",
|
||||
"f128",
|
||||
"void",
|
||||
"type",
|
||||
"anyerror",
|
||||
"anyframe",
|
||||
"anyopaque",
|
||||
"noreturn",
|
||||
"isize",
|
||||
"usize",
|
||||
"comptime_int",
|
||||
"comptime_float",
|
||||
"c_short",
|
||||
"c_ushort",
|
||||
"c_int",
|
||||
"c_uint",
|
||||
"c_long",
|
||||
"c_ulong",
|
||||
"c_longlong",
|
||||
"c_ulonglong",
|
||||
"c_longdouble",
|
||||
/(i|u)[0-9]+/,
|
||||
],
|
||||
bin = /[01]/,
|
||||
bin_ = seq(optional("_"), bin),
|
||||
oct = /[0-7]/,
|
||||
oct_ = seq(optional("_"), oct),
|
||||
hex = /[0-9a-fA-F]/,
|
||||
hex_ = seq(optional("_"), hex),
|
||||
dec = /[0-9]/,
|
||||
dec_ = seq(optional("_"), dec),
|
||||
bin_int = seq(bin, repeat(bin_)),
|
||||
oct_int = seq(oct, repeat(oct_)),
|
||||
dec_int = seq(dec, repeat(dec_)),
|
||||
hex_int = seq(hex, repeat(hex_)),
|
||||
unescaped_string_fragment = token.immediate(prec(1, /[^"\\\{\}]+/)),
|
||||
unescaped_char_fragment = token.immediate(prec(1, /[^'\\]/));
|
||||
|
||||
module.exports = grammar({
|
||||
name: "zig",
|
||||
|
||||
externals: (_) => [],
|
||||
inline: ($) => [$.Variable],
|
||||
extras: ($) => [/\s/, $.line_comment],
|
||||
rules: {
|
||||
source_file: ($) =>
|
||||
seq(optional($.container_doc_comment), optional($._ContainerMembers)),
|
||||
|
||||
// *** Top level ***
|
||||
_ContainerMembers: ($) =>
|
||||
repeat1(
|
||||
choice($._ContainerDeclarations, seq($.ContainerField, optional(COMMA)))
|
||||
),
|
||||
|
||||
_ContainerDeclarations: ($) =>
|
||||
choice(
|
||||
$.TestDecl,
|
||||
$.TopLevelComptime,
|
||||
seq(
|
||||
optional($.doc_comment),
|
||||
optional(keyword("pub", $)),
|
||||
$.TopLevelDecl
|
||||
)
|
||||
),
|
||||
|
||||
TestDecl: ($) =>
|
||||
seq(
|
||||
optional($.doc_comment),
|
||||
keyword("test", $),
|
||||
optional($.STRINGLITERALSINGLE),
|
||||
$.Block
|
||||
),
|
||||
|
||||
TopLevelComptime: ($) =>
|
||||
seq(optional($.doc_comment), keyword("comptime", $), $.BlockExpr),
|
||||
|
||||
TopLevelDecl: ($) =>
|
||||
// INFO: left and right doesn't matter?
|
||||
prec.left(
|
||||
choice(
|
||||
keyword("export", $),
|
||||
seq(keyword("extern", $), optional($.STRINGLITERALSINGLE)),
|
||||
seq(
|
||||
optional(keyword(choice("inline", "noinline"), $)),
|
||||
$.FnProto,
|
||||
choice(SEMICOLON, $.Block)
|
||||
),
|
||||
seq(
|
||||
optional(
|
||||
choice(
|
||||
keyword("export", $),
|
||||
seq(keyword("extern", $), optional($.STRINGLITERALSINGLE))
|
||||
)
|
||||
),
|
||||
optional(keyword("threadlocal", $)),
|
||||
$.VarDecl
|
||||
),
|
||||
seq(keyword("usingnamespace", $), $._Expr, SEMICOLON)
|
||||
)
|
||||
),
|
||||
|
||||
FnProto: ($) =>
|
||||
seq(
|
||||
keyword("fn", $),
|
||||
optional(field("function", $.IDENTIFIER)),
|
||||
$.ParamDeclList,
|
||||
optional($.ByteAlign),
|
||||
optional($.LinkSection),
|
||||
optional($.CallConv),
|
||||
optional(field("exception", EXCLAMATIONMARK)),
|
||||
$._TypeExpr
|
||||
),
|
||||
|
||||
VarDecl: ($) =>
|
||||
seq(
|
||||
keyword(choice("const", "var"), $),
|
||||
field("variable_type_function", $.IDENTIFIER),
|
||||
optional(seq(COLON, $._TypeExpr)),
|
||||
optional($.ByteAlign),
|
||||
optional($.LinkSection),
|
||||
optional(seq(EQUAL, $._Expr)),
|
||||
SEMICOLON
|
||||
),
|
||||
|
||||
ContainerField: ($) =>
|
||||
seq(
|
||||
optional($.doc_comment),
|
||||
optional(keyword("comptime", $)),
|
||||
field("field_member", $.IDENTIFIER),
|
||||
optional(
|
||||
seq(
|
||||
COLON,
|
||||
choice(keyword("anytype", $), $._TypeExpr),
|
||||
optional($.ByteAlign)
|
||||
)
|
||||
),
|
||||
optional(seq(EQUAL, $._Expr))
|
||||
),
|
||||
|
||||
// *** Block Level ***
|
||||
|
||||
Statement: ($) =>
|
||||
prec(
|
||||
PREC.statement,
|
||||
choice(
|
||||
seq(optional(keyword("comptime", $)), $.VarDecl),
|
||||
seq(
|
||||
choice(
|
||||
keyword(choice("comptime", "nosuspend", "defer", "suspend"), $),
|
||||
seq(keyword("errdefer", $), optional($.Payload))
|
||||
),
|
||||
$.BlockExprStatement
|
||||
),
|
||||
$.IfStatement,
|
||||
$.LabeledStatement,
|
||||
$.SwitchExpr,
|
||||
seq($.AssignExpr, SEMICOLON)
|
||||
)
|
||||
),
|
||||
|
||||
IfStatement: ($) =>
|
||||
choice(
|
||||
seq($.IfPrefix, $.BlockExpr, optional($._ElseStatementTail)),
|
||||
seq($.IfPrefix, $.AssignExpr, choice(SEMICOLON, $._ElseStatementTail))
|
||||
),
|
||||
_ElseStatementTail: ($) =>
|
||||
seq(keyword("else", $), optional($.Payload), $.Statement),
|
||||
|
||||
LabeledStatement: ($) =>
|
||||
prec(
|
||||
PREC.statement,
|
||||
seq(optional($.BlockLabel), choice($.Block, $.LoopStatement))
|
||||
),
|
||||
|
||||
LoopStatement: ($) =>
|
||||
seq(
|
||||
optional(keyword("inline", $)),
|
||||
choice($.ForStatement, $.WhileStatement)
|
||||
),
|
||||
|
||||
ForStatement: ($) =>
|
||||
choice(
|
||||
seq($.ForPrefix, $.BlockExpr, optional($._ElseStatementTail)),
|
||||
seq($.ForPrefix, $.AssignExpr, choice(SEMICOLON, $._ElseStatementTail))
|
||||
),
|
||||
|
||||
WhileStatement: ($) =>
|
||||
choice(
|
||||
seq($.WhilePrefix, $.BlockExpr, optional($._ElseStatementTail)),
|
||||
seq(
|
||||
$.WhilePrefix,
|
||||
$.AssignExpr,
|
||||
choice(SEMICOLON, $._ElseStatementTail)
|
||||
)
|
||||
),
|
||||
|
||||
BlockExprStatement: ($) =>
|
||||
choice($.BlockExpr, seq($.AssignExpr, SEMICOLON)),
|
||||
|
||||
BlockExpr: ($) => prec(PREC.curly, seq(optional($.BlockLabel), $.Block)),
|
||||
|
||||
// *** Expression Level ***
|
||||
|
||||
AssignExpr: ($) =>
|
||||
prec(PREC.assign, seq($._Expr, optional(seq($.AssignOp, $._Expr)))),
|
||||
|
||||
_Expr: ($) => choice($.BinaryExpr, $.UnaryExpr, $._PrimaryExpr),
|
||||
|
||||
BinaryExpr: ($) => {
|
||||
const table = [
|
||||
[PREC.or, "or"],
|
||||
[PREC.and, "and"],
|
||||
[PREC.comparative, $.CompareOp],
|
||||
[PREC.bitwise, $.BitwiseOp],
|
||||
[PREC.bitshift, $.BitShiftOp],
|
||||
[PREC.addition, $.AdditionOp],
|
||||
[PREC.multiply, $.MultiplyOp],
|
||||
];
|
||||
|
||||
return choice(
|
||||
...table.map(([precedence, operator]) =>
|
||||
prec.left(
|
||||
precedence,
|
||||
seq(
|
||||
field("left", $._Expr),
|
||||
field("operator", operator),
|
||||
field("right", $._Expr)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
},
|
||||
|
||||
UnaryExpr: ($) =>
|
||||
prec.left(
|
||||
PREC.prefix,
|
||||
seq(field("operator", $.PrefixOp), field("left", $._Expr))
|
||||
),
|
||||
|
||||
_PrimaryExpr: ($) =>
|
||||
// INFO: left/right doesn't matter?
|
||||
prec.left(
|
||||
PREC.primary,
|
||||
choice(
|
||||
$.AsmExpr,
|
||||
$.IfExpr,
|
||||
seq(keyword("break", $), optional($.BreakLabel), optional($._Expr)),
|
||||
seq(keyword("continue", $), optional($.BreakLabel)),
|
||||
seq(keyword(choice("comptime", "nosuspend", "resume"), $), $._Expr),
|
||||
seq(keyword("return", $), optional($._Expr)),
|
||||
seq(optional($.BlockLabel), $.LoopExpr),
|
||||
$.Block,
|
||||
$._CurlySuffixExpr
|
||||
)
|
||||
),
|
||||
|
||||
IfExpr: ($) =>
|
||||
prec.left(seq($.IfPrefix, $._Expr, optional($._ElseExprTail))),
|
||||
|
||||
_ElseExprTail: ($) => seq(keyword("else", $), optional($.Payload), $._Expr),
|
||||
|
||||
Block: ($) => seq(LBRACE, repeat($.Statement), RBRACE),
|
||||
|
||||
LoopExpr: ($) =>
|
||||
seq(optional(keyword("inline", $)), choice($.ForExpr, $.WhileExpr)),
|
||||
|
||||
ForExpr: ($) =>
|
||||
prec.left(seq($.ForPrefix, $._Expr, optional($._ElseExprTail))),
|
||||
|
||||
WhileExpr: ($) =>
|
||||
prec.left(seq($.WhilePrefix, $._Expr, optional($._ElseExprTail))),
|
||||
|
||||
_CurlySuffixExpr: ($) =>
|
||||
// INFO: solve #1 issue
|
||||
prec(PREC.curly, seq($._TypeExpr, optional($.InitList))),
|
||||
|
||||
InitList: ($) =>
|
||||
choice(
|
||||
seq(LBRACE, sepBy1(COMMA, $.FieldInit), RBRACE),
|
||||
seq(LBRACE, sepBy1(COMMA, $._Expr), RBRACE),
|
||||
seq(LBRACE, RBRACE)
|
||||
),
|
||||
|
||||
_TypeExpr: ($) => seq(repeat($.PrefixTypeOp), $.ErrorUnionExpr),
|
||||
|
||||
ErrorUnionExpr: ($) =>
|
||||
// INFO: left and right doesn't matter?
|
||||
prec.left(
|
||||
seq(
|
||||
$.SuffixExpr,
|
||||
optional(seq(field("exception", EXCLAMATIONMARK), $._TypeExpr))
|
||||
)
|
||||
),
|
||||
|
||||
SuffixExpr: ($) =>
|
||||
// INFO: solve #1 issue
|
||||
prec.right(
|
||||
seq(
|
||||
optional(keyword("async", $)),
|
||||
choice(
|
||||
$._PrimaryTypeExpr,
|
||||
seq($._PrimaryTypeExpr, $.FnCallArguments),
|
||||
field("variable_type_function", $.IDENTIFIER),
|
||||
seq(field("function_call", $.IDENTIFIER), $.FnCallArguments)
|
||||
),
|
||||
repeat(
|
||||
choice(
|
||||
$.SuffixOp,
|
||||
seq($.SuffixOp, $.FnCallArguments),
|
||||
$.FieldOrFnCall
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
|
||||
FieldOrFnCall: ($) =>
|
||||
prec.right(
|
||||
choice(
|
||||
seq(DOT, field("field_access", $.IDENTIFIER)),
|
||||
seq(DOT, field("function_call", $.IDENTIFIER), $.FnCallArguments)
|
||||
)
|
||||
),
|
||||
|
||||
_PrimaryTypeExpr: ($) =>
|
||||
choice(
|
||||
seq($.BUILTINIDENTIFIER, $.FnCallArguments),
|
||||
$.CHAR_LITERAL,
|
||||
$.ContainerDecl,
|
||||
seq(DOT, field("field_constant", $.IDENTIFIER)),
|
||||
seq(DOT, $.InitList),
|
||||
$.ErrorSetDecl,
|
||||
$.FLOAT,
|
||||
$.FnProto,
|
||||
$.GroupedExpr,
|
||||
$.LabeledTypeExpr,
|
||||
$.IfTypeExpr,
|
||||
$.INTEGER,
|
||||
seq(keyword("comptime", $), $._TypeExpr),
|
||||
seq(keyword("error", $), DOT, field("field_constant", $.IDENTIFIER)),
|
||||
keyword("false", $),
|
||||
keyword("null", $),
|
||||
keyword("anyframe", $),
|
||||
keyword("true", $),
|
||||
keyword("undefined", $),
|
||||
keyword("unreachable", $),
|
||||
$._STRINGLITERAL,
|
||||
$.SwitchExpr,
|
||||
$.BuildinTypeExpr
|
||||
),
|
||||
|
||||
BuildinTypeExpr: (_) => token(choice(...buildin_type)),
|
||||
ContainerDecl: ($) =>
|
||||
seq(
|
||||
optional(keyword(choice("extern", "packed"), $)),
|
||||
$._ContainerDeclAuto
|
||||
),
|
||||
|
||||
ErrorSetDecl: ($) =>
|
||||
seq(
|
||||
keyword("error", $),
|
||||
LBRACE,
|
||||
sepBy(
|
||||
COMMA,
|
||||
seq(optional($.doc_comment), field("field_constant", $.IDENTIFIER))
|
||||
),
|
||||
RBRACE
|
||||
),
|
||||
|
||||
GroupedExpr: ($) => seq(LPAREN, $._Expr, RPAREN),
|
||||
|
||||
IfTypeExpr: ($) =>
|
||||
prec.left(seq($.IfPrefix, $._TypeExpr, optional($._ElseTypeExprTail))),
|
||||
|
||||
_ElseTypeExprTail: ($) =>
|
||||
seq(keyword("else", $), optional($.Payload), $._TypeExpr),
|
||||
|
||||
LabeledTypeExpr: ($) =>
|
||||
choice(
|
||||
seq($.BlockLabel, $.Block),
|
||||
seq(optional($.BlockLabel), $.LoopTypeExpr)
|
||||
),
|
||||
|
||||
LoopTypeExpr: ($) =>
|
||||
seq(
|
||||
optional(keyword("inline", $)),
|
||||
choice($.ForTypeExpr, $.WhileTypeExpr)
|
||||
),
|
||||
|
||||
ForTypeExpr: ($) =>
|
||||
prec.left(seq($.ForPrefix, $._TypeExpr, optional($._ElseTypeExprTail))),
|
||||
|
||||
WhileTypeExpr: ($) =>
|
||||
prec.left(seq($.WhilePrefix, $._TypeExpr, optional($._ElseTypeExprTail))),
|
||||
|
||||
SwitchExpr: ($) =>
|
||||
seq(
|
||||
keyword("switch", $),
|
||||
LPAREN,
|
||||
$._Expr,
|
||||
RPAREN,
|
||||
LBRACE,
|
||||
sepBy(COMMA, $.SwitchProng),
|
||||
RBRACE
|
||||
),
|
||||
|
||||
// *** Assembly ***
|
||||
|
||||
AsmExpr: ($) =>
|
||||
seq(
|
||||
keyword("asm", $),
|
||||
optional(keyword("volatile", $)),
|
||||
LPAREN,
|
||||
$._Expr,
|
||||
optional($.AsmOutput),
|
||||
RPAREN
|
||||
),
|
||||
|
||||
AsmOutput: ($) =>
|
||||
seq(COLON, sepBy(COMMA, $.AsmOutputItem), optional($.AsmInput)),
|
||||
|
||||
AsmOutputItem: ($) =>
|
||||
seq(
|
||||
LBRACKET,
|
||||
$.Variable,
|
||||
RBRACKET,
|
||||
$._STRINGLITERAL,
|
||||
LPAREN,
|
||||
choice(seq("->", $._TypeExpr), $.Variable),
|
||||
RPAREN
|
||||
),
|
||||
|
||||
AsmInput: ($) =>
|
||||
seq(COLON, sepBy(COMMA, $.AsmInputItem), optional($.AsmClobbers)),
|
||||
|
||||
AsmInputItem: ($) =>
|
||||
seq(
|
||||
LBRACKET,
|
||||
$.Variable,
|
||||
RBRACKET,
|
||||
$._STRINGLITERAL,
|
||||
LPAREN,
|
||||
$._Expr,
|
||||
RPAREN
|
||||
),
|
||||
|
||||
AsmClobbers: ($) => seq(COLON, sepBy(COMMA, $._STRINGLITERAL)),
|
||||
|
||||
// *** Helper grammar ***
|
||||
BreakLabel: ($) => seq(COLON, $.IDENTIFIER),
|
||||
|
||||
BlockLabel: ($) => prec(PREC.label, seq($.IDENTIFIER, COLON)),
|
||||
|
||||
FieldInit: ($) =>
|
||||
seq(DOT, field("field_member", $.IDENTIFIER), EQUAL, $._Expr),
|
||||
|
||||
WhileContinueExpr: ($) => seq(COLON, LPAREN, $.AssignExpr, RPAREN),
|
||||
|
||||
LinkSection: ($) => seq(keyword("linksection", $), LPAREN, $._Expr, RPAREN),
|
||||
|
||||
// Fn specific
|
||||
CallConv: ($) => seq(keyword("callconv", $), LPAREN, $._Expr, RPAREN),
|
||||
|
||||
ParamDecl: ($) =>
|
||||
choice(
|
||||
seq(
|
||||
optional($.doc_comment),
|
||||
optional(keyword(choice("noalias", "comptime"), $)),
|
||||
optional(seq(field("parameter", $.IDENTIFIER), COLON)),
|
||||
$.ParamType
|
||||
),
|
||||
DOT3
|
||||
),
|
||||
|
||||
ParamType: ($) =>
|
||||
prec(PREC.paramType, choice(keyword("anytype", $), $._TypeExpr)),
|
||||
|
||||
// Control flow prefixes
|
||||
IfPrefix: ($) =>
|
||||
seq(keyword("if", $), LPAREN, $._Expr, RPAREN, optional($.PtrPayload)),
|
||||
|
||||
WhilePrefix: ($) =>
|
||||
seq(
|
||||
keyword("while", $),
|
||||
LPAREN,
|
||||
$._Expr,
|
||||
RPAREN,
|
||||
optional($.PtrPayload),
|
||||
optional($.WhileContinueExpr)
|
||||
),
|
||||
|
||||
ForPrefix: ($) =>
|
||||
seq(keyword("for", $), LPAREN, $._Expr, RPAREN, $.PtrIndexPayload),
|
||||
|
||||
// Payloads
|
||||
Payload: ($) => seq(PIPE, $.Variable, PIPE),
|
||||
|
||||
PtrPayload: ($) => seq(PIPE, optional(ASTERISK), $.Variable, PIPE),
|
||||
|
||||
PtrIndexPayload: ($) =>
|
||||
seq(
|
||||
PIPE,
|
||||
optional(ASTERISK),
|
||||
$.Variable,
|
||||
optional(seq(COMMA, $.Variable)),
|
||||
PIPE
|
||||
),
|
||||
|
||||
// Switch specific
|
||||
SwitchProng: ($) =>
|
||||
seq($.SwitchCase, EQUALRARROW, optional($.PtrPayload), $.AssignExpr),
|
||||
|
||||
SwitchCase: ($) => choice(sepBy1(COMMA, $.SwitchItem), keyword("else", $)),
|
||||
|
||||
SwitchItem: ($) => seq($._Expr, optional(seq(DOT3, $._Expr))),
|
||||
AssignOp: (_) =>
|
||||
choice(
|
||||
ASTERISKEQUAL,
|
||||
ASTERISKPIPEEQUAL,
|
||||
SLASHEQUAL,
|
||||
PERCENTEQUAL,
|
||||
PLUSEQUAL,
|
||||
PLUSPIPEEQUAL,
|
||||
MINUSEQUAL,
|
||||
MINUSPIPEEQUAL,
|
||||
LARROW2EQUAL,
|
||||
LARROW2PIPEEQUAL,
|
||||
RARROW2EQUAL,
|
||||
AMPERSANDEQUAL,
|
||||
CARETEQUAL,
|
||||
PIPEEQUAL,
|
||||
ASTERISKPERCENTEQUAL,
|
||||
PLUSPERCENTEQUAL,
|
||||
MINUSPERCENTEQUAL,
|
||||
EQUAL
|
||||
),
|
||||
CompareOp: (_) =>
|
||||
choice(
|
||||
EQUALEQUAL,
|
||||
EXCLAMATIONMARKEQUAL,
|
||||
LARROW,
|
||||
RARROW,
|
||||
LARROWEQUAL,
|
||||
RARROWEQUAL
|
||||
),
|
||||
BitwiseOp: ($) =>
|
||||
choice(
|
||||
AMPERSAND,
|
||||
CARET,
|
||||
PIPE,
|
||||
keyword("orelse", $),
|
||||
seq(keyword("catch", $), optional($.Payload))
|
||||
),
|
||||
|
||||
BitShiftOp: (_) => choice(LARROW2, RARROW2, LARROW2PIPE),
|
||||
|
||||
AdditionOp: (_) =>
|
||||
choice(
|
||||
PLUS,
|
||||
MINUS,
|
||||
PLUS2,
|
||||
PLUSPERCENT,
|
||||
MINUSPERCENT,
|
||||
PLUSPIPE,
|
||||
MINUSPIPE
|
||||
),
|
||||
|
||||
MultiplyOp: (_) =>
|
||||
choice(
|
||||
PIPE2,
|
||||
ASTERISK,
|
||||
SLASH,
|
||||
PERCENT,
|
||||
ASTERISK2,
|
||||
ASTERISKPERCENT,
|
||||
ASTERISKPIPE
|
||||
),
|
||||
|
||||
PrefixOp: ($) =>
|
||||
choice(
|
||||
EXCLAMATIONMARK,
|
||||
MINUS,
|
||||
TILDE,
|
||||
MINUSPERCENT,
|
||||
AMPERSAND,
|
||||
keyword("try", $),
|
||||
keyword("await", $)
|
||||
),
|
||||
|
||||
PrefixTypeOp: ($) =>
|
||||
choice(
|
||||
QUESTIONMARK,
|
||||
seq(keyword("anyframe", $), MINUSRARROW),
|
||||
seq(
|
||||
$.SliceTypeStart,
|
||||
repeat(
|
||||
choice(
|
||||
$.ByteAlign,
|
||||
keyword(choice("const", "volatile", "allowzero"), $)
|
||||
)
|
||||
)
|
||||
),
|
||||
|
||||
seq(
|
||||
$.PtrTypeStart,
|
||||
repeat(
|
||||
choice(
|
||||
seq(
|
||||
keyword("align", $),
|
||||
LPAREN,
|
||||
$._Expr,
|
||||
optional(seq(COLON, $.INTEGER, COLON, $.INTEGER)),
|
||||
RPAREN
|
||||
),
|
||||
keyword(choice("const", "volatile", "allowzero"), $)
|
||||
)
|
||||
)
|
||||
),
|
||||
$.ArrayTypeStart
|
||||
),
|
||||
|
||||
SuffixOp: ($) =>
|
||||
choice(
|
||||
seq(
|
||||
LBRACKET,
|
||||
$._Expr,
|
||||
optional(seq(DOT2, optional($._Expr), optional(seq(COLON, $._Expr)))),
|
||||
RBRACKET
|
||||
),
|
||||
DOTASTERISK,
|
||||
DOTQUESTIONMARK
|
||||
),
|
||||
|
||||
FnCallArguments: ($) => seq(LPAREN, sepBy(COMMA, $._Expr), RPAREN),
|
||||
|
||||
// Ptr specific
|
||||
SliceTypeStart: ($) =>
|
||||
seq(LBRACKET, optional(seq(COLON, $._Expr)), RBRACKET),
|
||||
|
||||
PtrTypeStart: ($) =>
|
||||
choice(
|
||||
ASTERISK,
|
||||
ASTERISK2,
|
||||
seq(
|
||||
LBRACKET,
|
||||
ASTERISK,
|
||||
optional(choice(LETTERC, seq(COLON, $._Expr))),
|
||||
RBRACKET
|
||||
)
|
||||
),
|
||||
|
||||
ArrayTypeStart: ($) =>
|
||||
seq(LBRACKET, $._Expr, optional(seq(COLON, $._Expr)), RBRACKET),
|
||||
|
||||
// ContainerDecl specific
|
||||
_ContainerDeclAuto: ($) =>
|
||||
seq(
|
||||
$.ContainerDeclType,
|
||||
LBRACE,
|
||||
optional($.container_doc_comment),
|
||||
optional($._ContainerMembers),
|
||||
RBRACE
|
||||
),
|
||||
|
||||
ContainerDeclType: ($) =>
|
||||
choice(
|
||||
keyword("struct", $),
|
||||
keyword("opaque", $),
|
||||
seq(keyword("enum", $), optional(seq(LPAREN, $._Expr, RPAREN))),
|
||||
seq(
|
||||
keyword("union", $),
|
||||
optional(
|
||||
seq(
|
||||
LPAREN,
|
||||
choice(
|
||||
seq(keyword("enum", $), optional(seq(LPAREN, $._Expr, RPAREN))),
|
||||
$._Expr
|
||||
),
|
||||
RPAREN
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
|
||||
// Alignment
|
||||
ByteAlign: ($) => seq(keyword("align", $), LPAREN, $._Expr, RPAREN),
|
||||
|
||||
// Lists
|
||||
ParamDeclList: ($) => seq(LPAREN, sepBy(COMMA, $.ParamDecl), RPAREN),
|
||||
|
||||
// *** Tokens ***
|
||||
container_doc_comment: (_) =>
|
||||
token(repeat1(seq("//!", /[^\n]*/, /[ \n]*/))),
|
||||
doc_comment: (_) => token(repeat1(seq("///", /[^\n]*/, /[ \n]*/))),
|
||||
line_comment: (_) => token(seq("//", /.*/)),
|
||||
|
||||
CHAR_LITERAL: ($) =>
|
||||
seq("'", choice(unescaped_char_fragment, $.EscapeSequence), "'"),
|
||||
|
||||
FLOAT: (_) =>
|
||||
choice(
|
||||
token(
|
||||
seq("0x", hex_int, ".", hex_int, optional(seq(/[pP][-+]?/, dec_int)))
|
||||
),
|
||||
token(seq(dec_int, ".", dec_int, optional(seq(/[eE][-+]?/, dec_int)))),
|
||||
token(seq("0x", hex_int, /[pP][-+]?/, dec_int)),
|
||||
token(seq(dec_int, /[eE][-+]?/, dec_int))
|
||||
),
|
||||
|
||||
INTEGER: (_) =>
|
||||
choice(
|
||||
token(seq("0b", bin_int)),
|
||||
token(seq("0o", oct_int)),
|
||||
token(seq("0x", hex_int)),
|
||||
token(dec_int)
|
||||
),
|
||||
|
||||
EscapeSequence: (_) =>
|
||||
token.immediate(
|
||||
choice(
|
||||
seq(
|
||||
"\\",
|
||||
choice(/x[0-9a-fA-f]{2}/, /u\{[0-9a-fA-F]+\}/, /[nr\\t'"]/)
|
||||
),
|
||||
"{{",
|
||||
"}}"
|
||||
)
|
||||
),
|
||||
|
||||
FormatSequence: (_) =>
|
||||
token.immediate(
|
||||
seq(
|
||||
"{",
|
||||
/[0-9]*/,
|
||||
optional(choice(/[xXsedbocu*]{1}/, "any")),
|
||||
optional(
|
||||
seq(
|
||||
":",
|
||||
optional(seq(/[^"\\\{\}]{1}/, /[<^>]{1}/, /[0-9]+/)),
|
||||
/.{0,1}/,
|
||||
/[0-9]*/
|
||||
)
|
||||
),
|
||||
"}"
|
||||
)
|
||||
),
|
||||
|
||||
STRINGLITERALSINGLE: ($) =>
|
||||
seq(
|
||||
'"',
|
||||
repeat(
|
||||
choice(
|
||||
unescaped_string_fragment,
|
||||
$.EscapeSequence,
|
||||
$.FormatSequence,
|
||||
token.immediate(choice("{", "}"))
|
||||
)
|
||||
),
|
||||
'"'
|
||||
),
|
||||
|
||||
LINESTRING: (_) => seq("\\\\", /[^\n]*/),
|
||||
|
||||
_STRINGLITERAL: ($) => choice($.STRINGLITERALSINGLE, repeat1($.LINESTRING)),
|
||||
|
||||
Variable: ($) => field("variable", $.IDENTIFIER),
|
||||
|
||||
IDENTIFIER: ($) =>
|
||||
choice(/[A-Za-z_][A-Za-z0-9_]*/, seq("@", $.STRINGLITERALSINGLE)),
|
||||
|
||||
BUILTINIDENTIFIER: (_) => seq("@", /[A-Za-z_][A-Za-z0-9_]*/),
|
||||
},
|
||||
});
|
||||
|
||||
function sepBy1(sep, rule) {
|
||||
return seq(rule, repeat(seq(sep, rule)), optional(sep));
|
||||
}
|
||||
function keyword(rule, _) {
|
||||
return rule;
|
||||
// return alias(rule, $.keyword);
|
||||
}
|
||||
function sepBy(sep, rule) {
|
||||
return optional(sepBy1(sep, rule));
|
||||
}
|
||||
@ -1,557 +0,0 @@
|
||||
Root <- skip container_doc_comment? ContainerMembers eof
|
||||
|
||||
# *** Top level ***
|
||||
ContainerMembers <- ContainerDeclarations (ContainerField COMMA)* (ContainerField / ContainerDeclarations)
|
||||
|
||||
ContainerDeclarations
|
||||
<- TestDecl ContainerDeclarations
|
||||
/ TopLevelComptime ContainerDeclarations
|
||||
/ doc_comment? KEYWORD_pub? TopLevelDecl ContainerDeclarations
|
||||
/
|
||||
|
||||
TestDecl <- doc_comment? KEYWORD_test STRINGLITERALSINGLE? Block
|
||||
|
||||
TopLevelComptime <- doc_comment? KEYWORD_comptime BlockExpr
|
||||
|
||||
TopLevelDecl
|
||||
<- (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE? / (KEYWORD_inline / KEYWORD_noinline))? FnProto (SEMICOLON / Block)
|
||||
/ (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE?)? KEYWORD_threadlocal? VarDecl
|
||||
/ KEYWORD_usingnamespace Expr SEMICOLON
|
||||
|
||||
FnProto <- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? CallConv? EXCLAMATIONMARK? TypeExpr
|
||||
|
||||
VarDecl <- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? LinkSection? (EQUAL Expr)? SEMICOLON
|
||||
|
||||
ContainerField <- doc_comment? KEYWORD_comptime? IDENTIFIER (COLON (KEYWORD_anytype / TypeExpr) ByteAlign?)? (EQUAL Expr)?
|
||||
|
||||
# *** Block Level ***
|
||||
Statement
|
||||
<- KEYWORD_comptime? VarDecl
|
||||
/ KEYWORD_comptime BlockExprStatement
|
||||
/ KEYWORD_nosuspend BlockExprStatement
|
||||
/ KEYWORD_suspend BlockExprStatement
|
||||
/ KEYWORD_defer BlockExprStatement
|
||||
/ KEYWORD_errdefer Payload? BlockExprStatement
|
||||
/ IfStatement
|
||||
/ LabeledStatement
|
||||
/ SwitchExpr
|
||||
/ AssignExpr SEMICOLON
|
||||
|
||||
IfStatement
|
||||
<- IfPrefix BlockExpr ( KEYWORD_else Payload? Statement )?
|
||||
/ IfPrefix AssignExpr ( SEMICOLON / KEYWORD_else Payload? Statement )
|
||||
|
||||
LabeledStatement <- BlockLabel? (Block / LoopStatement)
|
||||
|
||||
LoopStatement <- KEYWORD_inline? (ForStatement / WhileStatement)
|
||||
|
||||
ForStatement
|
||||
<- ForPrefix BlockExpr ( KEYWORD_else Statement )?
|
||||
/ ForPrefix AssignExpr ( SEMICOLON / KEYWORD_else Statement )
|
||||
|
||||
WhileStatement
|
||||
<- WhilePrefix BlockExpr ( KEYWORD_else Payload? Statement )?
|
||||
/ WhilePrefix AssignExpr ( SEMICOLON / KEYWORD_else Payload? Statement )
|
||||
|
||||
BlockExprStatement
|
||||
<- BlockExpr
|
||||
/ AssignExpr SEMICOLON
|
||||
|
||||
BlockExpr <- BlockLabel? Block
|
||||
|
||||
# *** Expression Level ***
|
||||
AssignExpr <- Expr (AssignOp Expr)?
|
||||
|
||||
Expr <- BoolOrExpr
|
||||
|
||||
BoolOrExpr <- BoolAndExpr (KEYWORD_or BoolAndExpr)*
|
||||
|
||||
BoolAndExpr <- CompareExpr (KEYWORD_and CompareExpr)*
|
||||
|
||||
CompareExpr <- BitwiseExpr (CompareOp BitwiseExpr)?
|
||||
|
||||
BitwiseExpr <- BitShiftExpr (BitwiseOp BitShiftExpr)*
|
||||
|
||||
BitShiftExpr <- AdditionExpr (BitShiftOp AdditionExpr)*
|
||||
|
||||
AdditionExpr <- MultiplyExpr (AdditionOp MultiplyExpr)*
|
||||
|
||||
MultiplyExpr <- PrefixExpr (MultiplyOp PrefixExpr)*
|
||||
|
||||
PrefixExpr <- PrefixOp* PrimaryExpr
|
||||
|
||||
PrimaryExpr
|
||||
<- AsmExpr
|
||||
/ IfExpr
|
||||
/ KEYWORD_break BreakLabel? Expr?
|
||||
/ KEYWORD_comptime Expr
|
||||
/ KEYWORD_nosuspend Expr
|
||||
/ KEYWORD_continue BreakLabel?
|
||||
/ KEYWORD_resume Expr
|
||||
/ KEYWORD_return Expr?
|
||||
/ BlockLabel? LoopExpr
|
||||
/ Block
|
||||
/ CurlySuffixExpr
|
||||
|
||||
IfExpr <- IfPrefix Expr (KEYWORD_else Payload? Expr)?
|
||||
|
||||
Block <- LBRACE Statement* RBRACE
|
||||
|
||||
LoopExpr <- KEYWORD_inline? (ForExpr / WhileExpr)
|
||||
|
||||
ForExpr <- ForPrefix Expr (KEYWORD_else Expr)?
|
||||
|
||||
WhileExpr <- WhilePrefix Expr (KEYWORD_else Payload? Expr)?
|
||||
|
||||
CurlySuffixExpr <- TypeExpr InitList?
|
||||
|
||||
InitList
|
||||
<- LBRACE FieldInit (COMMA FieldInit)* COMMA? RBRACE
|
||||
/ LBRACE Expr (COMMA Expr)* COMMA? RBRACE
|
||||
/ LBRACE RBRACE
|
||||
|
||||
TypeExpr <- PrefixTypeOp* ErrorUnionExpr
|
||||
|
||||
ErrorUnionExpr <- SuffixExpr (EXCLAMATIONMARK TypeExpr)?
|
||||
|
||||
SuffixExpr
|
||||
<- KEYWORD_async PrimaryTypeExpr SuffixOp* FnCallArguments
|
||||
/ PrimaryTypeExpr (SuffixOp / FnCallArguments)*
|
||||
|
||||
PrimaryTypeExpr
|
||||
<- BUILTINIDENTIFIER FnCallArguments
|
||||
/ CHAR_LITERAL
|
||||
/ ContainerDecl
|
||||
/ DOT IDENTIFIER
|
||||
/ DOT InitList
|
||||
/ ErrorSetDecl
|
||||
/ FLOAT
|
||||
/ FnProto
|
||||
/ GroupedExpr
|
||||
/ LabeledTypeExpr
|
||||
/ IDENTIFIER
|
||||
/ IfTypeExpr
|
||||
/ INTEGER
|
||||
/ KEYWORD_comptime TypeExpr
|
||||
/ KEYWORD_error DOT IDENTIFIER
|
||||
/ KEYWORD_anyframe
|
||||
/ KEYWORD_unreachable
|
||||
/ STRINGLITERAL
|
||||
/ SwitchExpr
|
||||
|
||||
ContainerDecl <- (KEYWORD_extern / KEYWORD_packed)? ContainerDeclAuto
|
||||
|
||||
ErrorSetDecl <- KEYWORD_error LBRACE IdentifierList RBRACE
|
||||
|
||||
GroupedExpr <- LPAREN Expr RPAREN
|
||||
|
||||
IfTypeExpr <- IfPrefix TypeExpr (KEYWORD_else Payload? TypeExpr)?
|
||||
|
||||
LabeledTypeExpr
|
||||
<- BlockLabel Block
|
||||
/ BlockLabel? LoopTypeExpr
|
||||
|
||||
LoopTypeExpr <- KEYWORD_inline? (ForTypeExpr / WhileTypeExpr)
|
||||
|
||||
ForTypeExpr <- ForPrefix TypeExpr (KEYWORD_else TypeExpr)?
|
||||
|
||||
WhileTypeExpr <- WhilePrefix TypeExpr (KEYWORD_else Payload? TypeExpr)?
|
||||
|
||||
SwitchExpr <- KEYWORD_switch LPAREN Expr RPAREN LBRACE SwitchProngList RBRACE
|
||||
|
||||
# *** Assembly ***
|
||||
AsmExpr <- KEYWORD_asm KEYWORD_volatile? LPAREN Expr AsmOutput? RPAREN
|
||||
|
||||
AsmOutput <- COLON AsmOutputList AsmInput?
|
||||
|
||||
AsmOutputItem <- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN (MINUSRARROW TypeExpr / IDENTIFIER) RPAREN
|
||||
|
||||
AsmInput <- COLON AsmInputList AsmClobbers?
|
||||
|
||||
AsmInputItem <- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN Expr RPAREN
|
||||
|
||||
AsmClobbers <- COLON StringList
|
||||
|
||||
# *** Helper grammar ***
|
||||
BreakLabel <- COLON IDENTIFIER
|
||||
|
||||
BlockLabel <- IDENTIFIER COLON
|
||||
|
||||
FieldInit <- DOT IDENTIFIER EQUAL Expr
|
||||
|
||||
WhileContinueExpr <- COLON LPAREN AssignExpr RPAREN
|
||||
|
||||
LinkSection <- KEYWORD_linksection LPAREN Expr RPAREN
|
||||
|
||||
# Fn specific
|
||||
CallConv <- KEYWORD_callconv LPAREN Expr RPAREN
|
||||
|
||||
ParamDecl
|
||||
<- doc_comment? (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType
|
||||
/ DOT3
|
||||
|
||||
ParamType
|
||||
<- KEYWORD_anytype
|
||||
/ TypeExpr
|
||||
|
||||
# Control flow prefixes
|
||||
IfPrefix <- KEYWORD_if LPAREN Expr RPAREN PtrPayload?
|
||||
|
||||
WhilePrefix <- KEYWORD_while LPAREN Expr RPAREN PtrPayload? WhileContinueExpr?
|
||||
|
||||
ForPrefix <- KEYWORD_for LPAREN Expr RPAREN PtrIndexPayload
|
||||
|
||||
# Payloads
|
||||
Payload <- PIPE IDENTIFIER PIPE
|
||||
|
||||
PtrPayload <- PIPE ASTERISK? IDENTIFIER PIPE
|
||||
|
||||
PtrIndexPayload <- PIPE ASTERISK? IDENTIFIER (COMMA IDENTIFIER)? PIPE
|
||||
|
||||
|
||||
# Switch specific
|
||||
SwitchProng <- SwitchCase EQUALRARROW PtrPayload? AssignExpr
|
||||
|
||||
SwitchCase
|
||||
<- SwitchItem (COMMA SwitchItem)* COMMA?
|
||||
/ KEYWORD_else
|
||||
|
||||
SwitchItem <- Expr (DOT3 Expr)?
|
||||
|
||||
# Operators
|
||||
AssignOp
|
||||
<- ASTERISKEQUAL
|
||||
/ SLASHEQUAL
|
||||
/ PERCENTEQUAL
|
||||
/ PLUSEQUAL
|
||||
/ MINUSEQUAL
|
||||
/ LARROW2EQUAL
|
||||
/ LARROW2PIPEEQUAL
|
||||
/ RARROW2EQUAL
|
||||
/ AMPERSANDEQUAL
|
||||
/ CARETEQUAL
|
||||
/ PIPEEQUAL
|
||||
/ ASTERISKPERCENTEQUAL
|
||||
/ PLUSPERCENTEQUAL
|
||||
/ MINUSPERCENTEQUAL
|
||||
/ EQUAL
|
||||
|
||||
CompareOp
|
||||
<- EQUALEQUAL
|
||||
/ EXCLAMATIONMARKEQUAL
|
||||
/ LARROW
|
||||
/ RARROW
|
||||
/ LARROWEQUAL
|
||||
/ RARROWEQUAL
|
||||
|
||||
BitwiseOp
|
||||
<- AMPERSAND
|
||||
/ CARET
|
||||
/ PIPE
|
||||
/ KEYWORD_orelse
|
||||
/ KEYWORD_catch Payload?
|
||||
|
||||
BitShiftOp
|
||||
<- LARROW2
|
||||
/ RARROW2
|
||||
|
||||
AdditionOp
|
||||
<- PLUS
|
||||
/ MINUS
|
||||
/ PLUS2
|
||||
/ PLUSPERCENT
|
||||
/ MINUSPERCENT
|
||||
/ PLUSPIPE
|
||||
/ MINUSPIPE
|
||||
|
||||
MultiplyOp
|
||||
<- PIPE2
|
||||
/ ASTERISK
|
||||
/ SLASH
|
||||
/ PERCENT
|
||||
/ ASTERISK2
|
||||
/ ASTERISKPERCENT
|
||||
/ ASTERISKPIPE
|
||||
|
||||
PrefixOp
|
||||
<- EXCLAMATIONMARK
|
||||
/ MINUS
|
||||
/ TILDE
|
||||
/ MINUSPERCENT
|
||||
/ AMPERSAND
|
||||
/ KEYWORD_try
|
||||
/ KEYWORD_await
|
||||
|
||||
PrefixTypeOp
|
||||
<- QUESTIONMARK
|
||||
/ KEYWORD_anyframe MINUSRARROW
|
||||
/ SliceTypeStart (ByteAlign / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)*
|
||||
/ PtrTypeStart (KEYWORD_align LPAREN Expr (COLON INTEGER COLON INTEGER)? RPAREN / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)*
|
||||
/ ArrayTypeStart
|
||||
|
||||
SuffixOp
|
||||
<- LBRACKET Expr (DOT2 (Expr? (COLON Expr)?)?)? RBRACKET
|
||||
/ DOT IDENTIFIER
|
||||
/ DOTASTERISK
|
||||
/ DOTQUESTIONMARK
|
||||
|
||||
FnCallArguments <- LPAREN ExprList RPAREN
|
||||
|
||||
# Ptr specific
|
||||
SliceTypeStart <- LBRACKET (COLON Expr)? RBRACKET
|
||||
|
||||
PtrTypeStart
|
||||
<- ASTERISK
|
||||
/ ASTERISK2
|
||||
/ LBRACKET ASTERISK (LETTERC / COLON Expr)? RBRACKET
|
||||
|
||||
ArrayTypeStart <- LBRACKET Expr (COLON Expr)? RBRACKET
|
||||
|
||||
# ContainerDecl specific
|
||||
ContainerDeclAuto <- ContainerDeclType LBRACE container_doc_comment? ContainerMembers RBRACE
|
||||
|
||||
ContainerDeclType
|
||||
<- KEYWORD_struct
|
||||
/ KEYWORD_opaque
|
||||
/ KEYWORD_enum (LPAREN Expr RPAREN)?
|
||||
/ KEYWORD_union (LPAREN (KEYWORD_enum (LPAREN Expr RPAREN)? / Expr) RPAREN)?
|
||||
|
||||
# Alignment
|
||||
ByteAlign <- KEYWORD_align LPAREN Expr RPAREN
|
||||
|
||||
# Lists
|
||||
IdentifierList <- (doc_comment? IDENTIFIER COMMA)* (doc_comment? IDENTIFIER)?
|
||||
|
||||
SwitchProngList <- (SwitchProng COMMA)* SwitchProng?
|
||||
|
||||
AsmOutputList <- (AsmOutputItem COMMA)* AsmOutputItem?
|
||||
|
||||
AsmInputList <- (AsmInputItem COMMA)* AsmInputItem?
|
||||
|
||||
StringList <- (STRINGLITERAL COMMA)* STRINGLITERAL?
|
||||
|
||||
ParamDeclList <- (ParamDecl COMMA)* ParamDecl?
|
||||
|
||||
ExprList <- (Expr COMMA)* Expr?
|
||||
|
||||
# *** Tokens ***
|
||||
eof <- !.
|
||||
bin <- [01]
|
||||
bin_ <- '_'? bin
|
||||
oct <- [0-7]
|
||||
oct_ <- '_'? oct
|
||||
hex <- [0-9a-fA-F]
|
||||
hex_ <- '_'? hex
|
||||
dec <- [0-9]
|
||||
dec_ <- '_'? dec
|
||||
|
||||
bin_int <- bin bin_*
|
||||
oct_int <- oct oct_*
|
||||
dec_int <- dec dec_*
|
||||
hex_int <- hex hex_*
|
||||
|
||||
ox80_oxBF <- [\200-\277]
|
||||
oxF4 <- '\364'
|
||||
ox80_ox8F <- [\200-\217]
|
||||
oxF1_oxF3 <- [\361-\363]
|
||||
oxF0 <- '\360'
|
||||
ox90_0xBF <- [\220-\277]
|
||||
oxEE_oxEF <- [\356-\357]
|
||||
oxED <- '\355'
|
||||
ox80_ox9F <- [\200-\237]
|
||||
oxE1_oxEC <- [\341-\354]
|
||||
oxE0 <- '\340'
|
||||
oxA0_oxBF <- [\240-\277]
|
||||
oxC2_oxDF <- [\302-\337]
|
||||
|
||||
# From https://lemire.me/blog/2018/05/09/how-quickly-can-you-check-that-a-string-is-valid-unicode-utf-8/
|
||||
# First Byte Second Byte Third Byte Fourth Byte
|
||||
# [0x00,0x7F]
|
||||
# [0xC2,0xDF] [0x80,0xBF]
|
||||
# 0xE0 [0xA0,0xBF] [0x80,0xBF]
|
||||
# [0xE1,0xEC] [0x80,0xBF] [0x80,0xBF]
|
||||
# 0xED [0x80,0x9F] [0x80,0xBF]
|
||||
# [0xEE,0xEF] [0x80,0xBF] [0x80,0xBF]
|
||||
# 0xF0 [0x90,0xBF] [0x80,0xBF] [0x80,0xBF]
|
||||
# [0xF1,0xF3] [0x80,0xBF] [0x80,0xBF] [0x80,0xBF]
|
||||
# 0xF4 [0x80,0x8F] [0x80,0xBF] [0x80,0xBF]
|
||||
|
||||
mb_utf8_literal <-
|
||||
oxF4 ox80_ox8F ox80_oxBF ox80_oxBF
|
||||
/ oxF1_oxF3 ox80_oxBF ox80_oxBF ox80_oxBF
|
||||
/ oxF0 ox90_0xBF ox80_oxBF ox80_oxBF
|
||||
/ oxEE_oxEF ox80_oxBF ox80_oxBF
|
||||
/ oxED ox80_ox9F ox80_oxBF
|
||||
/ oxE1_oxEC ox80_oxBF ox80_oxBF
|
||||
/ oxE0 oxA0_oxBF ox80_oxBF
|
||||
/ oxC2_oxDF ox80_oxBF
|
||||
|
||||
ascii_char_not_nl_slash_squote <- [\000-\011\013-\046-\050-\133\135-\177]
|
||||
|
||||
char_escape
|
||||
<- "\\x" hex hex
|
||||
/ "\\u{" hex+ "}"
|
||||
/ "\\" [nr\\t'"]
|
||||
char_char
|
||||
<- mb_utf8_literal
|
||||
/ char_escape
|
||||
/ ascii_char_not_nl_slash_squote
|
||||
|
||||
string_char
|
||||
<- char_escape
|
||||
/ [^\\"\n]
|
||||
|
||||
container_doc_comment <- ('//!' [^\n]* [ \n]*)+
|
||||
doc_comment <- ('///' [^\n]* [ \n]*)+
|
||||
line_comment <- '//' ![!/][^\n]* / '////' [^\n]*
|
||||
line_string <- ("\\\\" [^\n]* [ \n]*)+
|
||||
skip <- ([ \n] / line_comment)*
|
||||
|
||||
CHAR_LITERAL <- "'" char_char "'" skip
|
||||
FLOAT
|
||||
<- "0x" hex_int "." hex_int ([pP] [-+]? dec_int)? skip
|
||||
/ dec_int "." dec_int ([eE] [-+]? dec_int)? skip
|
||||
/ "0x" hex_int "."? [pP] [-+]? dec_int skip
|
||||
/ dec_int "."? [eE] [-+]? dec_int skip
|
||||
INTEGER
|
||||
<- "0b" bin_int skip
|
||||
/ "0o" oct_int skip
|
||||
/ "0x" hex_int skip
|
||||
/ dec_int skip
|
||||
STRINGLITERALSINGLE <- "\"" string_char* "\"" skip
|
||||
STRINGLITERAL
|
||||
<- STRINGLITERALSINGLE
|
||||
/ (line_string skip)+
|
||||
IDENTIFIER
|
||||
<- !keyword [A-Za-z_] [A-Za-z0-9_]* skip
|
||||
/ "@\"" string_char* "\"" skip
|
||||
BUILTINIDENTIFIER <- "@"[A-Za-z_][A-Za-z0-9_]* skip
|
||||
|
||||
|
||||
AMPERSAND <- '&' ![=] skip
|
||||
AMPERSANDEQUAL <- '&=' skip
|
||||
ASTERISK <- '*' ![*%=] skip
|
||||
ASTERISK2 <- '**' skip
|
||||
ASTERISKEQUAL <- '*=' skip
|
||||
ASTERISKPERCENT <- '*%' ![=] skip
|
||||
ASTERISKPERCENTEQUAL <- '*%=' skip
|
||||
ASTERISKPIPE <- '*|' ![=] skip
|
||||
ASTERISKPIPEEQUAL <- '*|=' skip
|
||||
CARET <- '^' ![=] skip
|
||||
CARETEQUAL <- '^=' skip
|
||||
COLON <- ':' skip
|
||||
COMMA <- ',' skip
|
||||
DOT <- '.' ![*.?] skip
|
||||
DOT2 <- '..' ![.] skip
|
||||
DOT3 <- '...' skip
|
||||
DOTASTERISK <- '.*' skip
|
||||
DOTQUESTIONMARK <- '.?' skip
|
||||
EQUAL <- '=' ![>=] skip
|
||||
EQUALEQUAL <- '==' skip
|
||||
EQUALRARROW <- '=>' skip
|
||||
EXCLAMATIONMARK <- '!' ![=] skip
|
||||
EXCLAMATIONMARKEQUAL <- '!=' skip
|
||||
LARROW <- '<' ![<=] skip
|
||||
LARROW2 <- '<<' ![=] skip
|
||||
LARROW2PIPE <- '<<|' ![=] skip
|
||||
LARROW2PIPEEQUAL <- '<<|=' ![=] skip
|
||||
LARROW2EQUAL <- '<<=' skip
|
||||
LARROWEQUAL <- '<=' skip
|
||||
LBRACE <- '{' skip
|
||||
LBRACKET <- '[' skip
|
||||
LPAREN <- '(' skip
|
||||
MINUS <- '-' ![%=>] skip
|
||||
MINUSEQUAL <- '-=' skip
|
||||
MINUSPERCENT <- '-%' ![=] skip
|
||||
MINUSPERCENTEQUAL <- '-%=' skip
|
||||
MINUSPIPE <- '-|' ![=] skip
|
||||
MINUSPIPEEQUAL <- '-|=' skip
|
||||
MINUSRARROW <- '->' skip
|
||||
PERCENT <- '%' ![=] skip
|
||||
PERCENTEQUAL <- '%=' skip
|
||||
PIPE <- '|' ![|=] skip
|
||||
PIPE2 <- '||' skip
|
||||
PIPEEQUAL <- '|=' skip
|
||||
PLUS <- '+' ![%+=] skip
|
||||
PLUS2 <- '++' skip
|
||||
PLUSEQUAL <- '+=' skip
|
||||
PLUSPERCENT <- '+%' ![=] skip
|
||||
PLUSPERCENTEQUAL <- '+%=' skip
|
||||
PLUSPIPE <- '+|' ![=] skip
|
||||
PLUSPIPEEQUAL <- '+|=' skip
|
||||
LETTERC <- 'c' skip
|
||||
QUESTIONMARK <- '?' skip
|
||||
RARROW <- '>' ![>=] skip
|
||||
RARROW2 <- '>>' ![=] skip
|
||||
RARROW2EQUAL <- '>>=' skip
|
||||
RARROWEQUAL <- '>=' skip
|
||||
RBRACE <- '}' skip
|
||||
RBRACKET <- ']' skip
|
||||
RPAREN <- ')' skip
|
||||
SEMICOLON <- ';' skip
|
||||
SLASH <- '/' ![=] skip
|
||||
SLASHEQUAL <- '/=' skip
|
||||
TILDE <- '~' skip
|
||||
|
||||
end_of_word <- ![a-zA-Z0-9_] skip
|
||||
KEYWORD_align <- 'align' end_of_word
|
||||
KEYWORD_allowzero <- 'allowzero' end_of_word
|
||||
KEYWORD_and <- 'and' end_of_word
|
||||
KEYWORD_anyframe <- 'anyframe' end_of_word
|
||||
KEYWORD_anytype <- 'anytype' end_of_word
|
||||
KEYWORD_asm <- 'asm' end_of_word
|
||||
KEYWORD_async <- 'async' end_of_word
|
||||
KEYWORD_await <- 'await' end_of_word
|
||||
KEYWORD_break <- 'break' end_of_word
|
||||
KEYWORD_callconv <- 'callconv' end_of_word
|
||||
KEYWORD_catch <- 'catch' end_of_word
|
||||
KEYWORD_comptime <- 'comptime' end_of_word
|
||||
KEYWORD_const <- 'const' end_of_word
|
||||
KEYWORD_continue <- 'continue' end_of_word
|
||||
KEYWORD_defer <- 'defer' end_of_word
|
||||
KEYWORD_else <- 'else' end_of_word
|
||||
KEYWORD_enum <- 'enum' end_of_word
|
||||
KEYWORD_errdefer <- 'errdefer' end_of_word
|
||||
KEYWORD_error <- 'error' end_of_word
|
||||
KEYWORD_export <- 'export' end_of_word
|
||||
KEYWORD_extern <- 'extern' end_of_word
|
||||
KEYWORD_fn <- 'fn' end_of_word
|
||||
KEYWORD_for <- 'for' end_of_word
|
||||
KEYWORD_if <- 'if' end_of_word
|
||||
KEYWORD_inline <- 'inline' end_of_word
|
||||
KEYWORD_noalias <- 'noalias' end_of_word
|
||||
KEYWORD_nosuspend <- 'nosuspend' end_of_word
|
||||
KEYWORD_noinline <- 'noinline' end_of_word
|
||||
KEYWORD_opaque <- 'opaque' end_of_word
|
||||
KEYWORD_or <- 'or' end_of_word
|
||||
KEYWORD_orelse <- 'orelse' end_of_word
|
||||
KEYWORD_packed <- 'packed' end_of_word
|
||||
KEYWORD_pub <- 'pub' end_of_word
|
||||
KEYWORD_resume <- 'resume' end_of_word
|
||||
KEYWORD_return <- 'return' end_of_word
|
||||
KEYWORD_linksection <- 'linksection' end_of_word
|
||||
KEYWORD_struct <- 'struct' end_of_word
|
||||
KEYWORD_suspend <- 'suspend' end_of_word
|
||||
KEYWORD_switch <- 'switch' end_of_word
|
||||
KEYWORD_test <- 'test' end_of_word
|
||||
KEYWORD_threadlocal <- 'threadlocal' end_of_word
|
||||
KEYWORD_try <- 'try' end_of_word
|
||||
KEYWORD_union <- 'union' end_of_word
|
||||
KEYWORD_unreachable <- 'unreachable' end_of_word
|
||||
KEYWORD_usingnamespace <- 'usingnamespace' end_of_word
|
||||
KEYWORD_var <- 'var' end_of_word
|
||||
KEYWORD_volatile <- 'volatile' end_of_word
|
||||
KEYWORD_while <- 'while' end_of_word
|
||||
|
||||
keyword <- KEYWORD_align / KEYWORD_allowzero / KEYWORD_and / KEYWORD_anyframe
|
||||
/ KEYWORD_anytype / KEYWORD_asm / KEYWORD_async / KEYWORD_await
|
||||
/ KEYWORD_break / KEYWORD_callconv / KEYWORD_catch / KEYWORD_comptime
|
||||
/ KEYWORD_const / KEYWORD_continue / KEYWORD_defer / KEYWORD_else
|
||||
/ KEYWORD_enum / KEYWORD_errdefer / KEYWORD_error / KEYWORD_export
|
||||
/ KEYWORD_extern / KEYWORD_fn / KEYWORD_for / KEYWORD_if
|
||||
/ KEYWORD_inline / KEYWORD_noalias / KEYWORD_nosuspend / KEYWORD_noinline
|
||||
/ KEYWORD_opaque / KEYWORD_or / KEYWORD_orelse / KEYWORD_packed
|
||||
/ KEYWORD_pub / KEYWORD_resume / KEYWORD_return / KEYWORD_linksection
|
||||
/ KEYWORD_struct / KEYWORD_suspend / KEYWORD_switch / KEYWORD_test
|
||||
/ KEYWORD_threadlocal / KEYWORD_try / KEYWORD_union / KEYWORD_unreachable
|
||||
/ KEYWORD_usingnamespace / KEYWORD_var / KEYWORD_volatile / KEYWORD_while
|
||||
@ -1,29 +0,0 @@
|
||||
{
|
||||
"name": "tree-sitter-zig",
|
||||
"version": "0.0.1",
|
||||
"description": "zig grammar for tree-sitter",
|
||||
"main": "bindings/node",
|
||||
"keywords": [
|
||||
"parsing",
|
||||
"incremental"
|
||||
],
|
||||
"dependencies": {
|
||||
"nan": "^2.12.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"tree-sitter-cli": "^0.20.1"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "tree-sitter test"
|
||||
}
|
||||
,
|
||||
"tree-sitter": [
|
||||
{
|
||||
"scope": "source.zig",
|
||||
"injection-regex": "zig",
|
||||
"file-types": [
|
||||
"zig"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -1,16 +0,0 @@
|
||||
[
|
||||
(Block)
|
||||
(ContainerDecl)
|
||||
(SwitchExpr)
|
||||
(InitList)
|
||||
(AsmExpr)
|
||||
(ErrorSetDecl)
|
||||
(LINESTRING)
|
||||
(
|
||||
[
|
||||
(IfPrefix)
|
||||
(WhilePrefix)
|
||||
(ForPrefix)
|
||||
]
|
||||
)
|
||||
] @fold
|
||||
@ -1,234 +0,0 @@
|
||||
[
|
||||
(container_doc_comment)
|
||||
(doc_comment)
|
||||
(line_comment)
|
||||
] @comment
|
||||
|
||||
[
|
||||
variable: (IDENTIFIER)
|
||||
variable_type_function: (IDENTIFIER)
|
||||
] @variable
|
||||
|
||||
parameter: (IDENTIFIER) @parameter
|
||||
|
||||
[
|
||||
field_member: (IDENTIFIER)
|
||||
field_access: (IDENTIFIER)
|
||||
] @field
|
||||
|
||||
;; assume TitleCase is a type
|
||||
(
|
||||
[
|
||||
variable_type_function: (IDENTIFIER)
|
||||
field_access: (IDENTIFIER)
|
||||
parameter: (IDENTIFIER)
|
||||
] @type
|
||||
(#match? @type "^[A-Z]([a-z]+[A-Za-z0-9]*)*$")
|
||||
)
|
||||
;; assume camelCase is a function
|
||||
(
|
||||
[
|
||||
variable_type_function: (IDENTIFIER)
|
||||
field_access: (IDENTIFIER)
|
||||
parameter: (IDENTIFIER)
|
||||
] @function
|
||||
(#match? @function "^[a-z]+([A-Z][a-z0-9]*)+$")
|
||||
)
|
||||
|
||||
;; assume all CAPS_1 is a constant
|
||||
(
|
||||
[
|
||||
variable_type_function: (IDENTIFIER)
|
||||
field_access: (IDENTIFIER)
|
||||
] @constant
|
||||
(#match? @constant "^[A-Z][A-Z_0-9]+$")
|
||||
)
|
||||
|
||||
[
|
||||
function_call: (IDENTIFIER)
|
||||
function: (IDENTIFIER)
|
||||
] @function
|
||||
|
||||
exception: "!" @exception
|
||||
|
||||
(
|
||||
(IDENTIFIER) @variable.builtin
|
||||
(#eq? @variable.builtin "_")
|
||||
)
|
||||
|
||||
(PtrTypeStart "c" @variable.builtin)
|
||||
|
||||
(
|
||||
(ContainerDeclType
|
||||
[
|
||||
(ErrorUnionExpr)
|
||||
"enum"
|
||||
]
|
||||
)
|
||||
(ContainerField (IDENTIFIER) @constant)
|
||||
)
|
||||
|
||||
field_constant: (IDENTIFIER) @constant
|
||||
|
||||
(BUILTINIDENTIFIER) @function.builtin
|
||||
|
||||
((BUILTINIDENTIFIER) @include
|
||||
(#any-of? @include "@import" "@cImport"))
|
||||
|
||||
(INTEGER) @number
|
||||
|
||||
(FLOAT) @float
|
||||
|
||||
[
|
||||
(LINESTRING)
|
||||
(STRINGLITERALSINGLE)
|
||||
] @string
|
||||
|
||||
(CHAR_LITERAL) @character
|
||||
(EscapeSequence) @string.escape
|
||||
(FormatSequence) @string.special
|
||||
|
||||
[
|
||||
"allowzero"
|
||||
"volatile"
|
||||
"anytype"
|
||||
"anyframe"
|
||||
(BuildinTypeExpr)
|
||||
] @type.builtin
|
||||
|
||||
(BreakLabel (IDENTIFIER) @label)
|
||||
(BlockLabel (IDENTIFIER) @label)
|
||||
|
||||
[
|
||||
"true"
|
||||
"false"
|
||||
] @boolean
|
||||
|
||||
[
|
||||
"undefined"
|
||||
"unreachable"
|
||||
"null"
|
||||
] @constant.builtin
|
||||
|
||||
[
|
||||
"else"
|
||||
"if"
|
||||
"switch"
|
||||
] @conditional
|
||||
|
||||
[
|
||||
"for"
|
||||
"while"
|
||||
] @repeat
|
||||
|
||||
[
|
||||
"or"
|
||||
"and"
|
||||
"orelse"
|
||||
] @keyword.operator
|
||||
|
||||
[
|
||||
"struct"
|
||||
"enum"
|
||||
"union"
|
||||
"error"
|
||||
"packed"
|
||||
"opaque"
|
||||
] @keyword
|
||||
|
||||
[
|
||||
"try"
|
||||
"error"
|
||||
"catch"
|
||||
] @exception
|
||||
|
||||
; VarDecl
|
||||
[
|
||||
"const"
|
||||
"var"
|
||||
"comptime"
|
||||
"threadlocal"
|
||||
"fn"
|
||||
] @keyword.function
|
||||
|
||||
[
|
||||
"test"
|
||||
"pub"
|
||||
"usingnamespace"
|
||||
] @keyword
|
||||
|
||||
[
|
||||
"return"
|
||||
"break"
|
||||
"continue"
|
||||
] @keyword.return
|
||||
|
||||
; Macro
|
||||
[
|
||||
"defer"
|
||||
"errdefer"
|
||||
"async"
|
||||
"nosuspend"
|
||||
"await"
|
||||
"suspend"
|
||||
"resume"
|
||||
"export"
|
||||
"extern"
|
||||
] @function.macro
|
||||
|
||||
; PrecProc
|
||||
[
|
||||
"inline"
|
||||
"noinline"
|
||||
"asm"
|
||||
"callconv"
|
||||
"noalias"
|
||||
] @attribute
|
||||
|
||||
[
|
||||
"linksection"
|
||||
"align"
|
||||
] @function.builtin
|
||||
|
||||
[
|
||||
(CompareOp)
|
||||
(BitwiseOp)
|
||||
(BitShiftOp)
|
||||
(AdditionOp)
|
||||
(AssignOp)
|
||||
(MultiplyOp)
|
||||
(PrefixOp)
|
||||
"*"
|
||||
"**"
|
||||
"->"
|
||||
".?"
|
||||
".*"
|
||||
"?"
|
||||
] @operator
|
||||
|
||||
[
|
||||
";"
|
||||
"."
|
||||
","
|
||||
":"
|
||||
] @punctuation.delimiter
|
||||
|
||||
[
|
||||
".."
|
||||
"..."
|
||||
] @punctuation.special
|
||||
|
||||
[
|
||||
"["
|
||||
"]"
|
||||
"("
|
||||
")"
|
||||
"{"
|
||||
"}"
|
||||
(Payload "|")
|
||||
(PtrPayload "|")
|
||||
(PtrIndexPayload "|")
|
||||
] @punctuation.bracket
|
||||
|
||||
; Error
|
||||
(ERROR) @error
|
||||
@ -1,22 +0,0 @@
|
||||
[
|
||||
(Block)
|
||||
(ContainerDecl)
|
||||
(SwitchExpr)
|
||||
(InitList)
|
||||
] @indent
|
||||
|
||||
[
|
||||
"("
|
||||
")"
|
||||
"["
|
||||
"]"
|
||||
"{"
|
||||
"}"
|
||||
] @branch
|
||||
|
||||
[
|
||||
(line_comment)
|
||||
(container_doc_comment)
|
||||
(doc_comment)
|
||||
(LINESTRING)
|
||||
] @ignore
|
||||
@ -1,5 +0,0 @@
|
||||
[
|
||||
(container_doc_comment)
|
||||
(doc_comment)
|
||||
(line_comment)
|
||||
] @comment
|
||||
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
@ -1,224 +0,0 @@
|
||||
#ifndef TREE_SITTER_PARSER_H_
|
||||
#define TREE_SITTER_PARSER_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define ts_builtin_sym_error ((TSSymbol)-1)
|
||||
#define ts_builtin_sym_end 0
|
||||
#define TREE_SITTER_SERIALIZATION_BUFFER_SIZE 1024
|
||||
|
||||
typedef uint16_t TSStateId;
|
||||
|
||||
#ifndef TREE_SITTER_API_H_
|
||||
typedef uint16_t TSSymbol;
|
||||
typedef uint16_t TSFieldId;
|
||||
typedef struct TSLanguage TSLanguage;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
TSFieldId field_id;
|
||||
uint8_t child_index;
|
||||
bool inherited;
|
||||
} TSFieldMapEntry;
|
||||
|
||||
typedef struct {
|
||||
uint16_t index;
|
||||
uint16_t length;
|
||||
} TSFieldMapSlice;
|
||||
|
||||
typedef struct {
|
||||
bool visible;
|
||||
bool named;
|
||||
bool supertype;
|
||||
} TSSymbolMetadata;
|
||||
|
||||
typedef struct TSLexer TSLexer;
|
||||
|
||||
struct TSLexer {
|
||||
int32_t lookahead;
|
||||
TSSymbol result_symbol;
|
||||
void (*advance)(TSLexer *, bool);
|
||||
void (*mark_end)(TSLexer *);
|
||||
uint32_t (*get_column)(TSLexer *);
|
||||
bool (*is_at_included_range_start)(const TSLexer *);
|
||||
bool (*eof)(const TSLexer *);
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
TSParseActionTypeShift,
|
||||
TSParseActionTypeReduce,
|
||||
TSParseActionTypeAccept,
|
||||
TSParseActionTypeRecover,
|
||||
} TSParseActionType;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t type;
|
||||
TSStateId state;
|
||||
bool extra;
|
||||
bool repetition;
|
||||
} shift;
|
||||
struct {
|
||||
uint8_t type;
|
||||
uint8_t child_count;
|
||||
TSSymbol symbol;
|
||||
int16_t dynamic_precedence;
|
||||
uint16_t production_id;
|
||||
} reduce;
|
||||
uint8_t type;
|
||||
} TSParseAction;
|
||||
|
||||
typedef struct {
|
||||
uint16_t lex_state;
|
||||
uint16_t external_lex_state;
|
||||
} TSLexMode;
|
||||
|
||||
typedef union {
|
||||
TSParseAction action;
|
||||
struct {
|
||||
uint8_t count;
|
||||
bool reusable;
|
||||
} entry;
|
||||
} TSParseActionEntry;
|
||||
|
||||
struct TSLanguage {
|
||||
uint32_t version;
|
||||
uint32_t symbol_count;
|
||||
uint32_t alias_count;
|
||||
uint32_t token_count;
|
||||
uint32_t external_token_count;
|
||||
uint32_t state_count;
|
||||
uint32_t large_state_count;
|
||||
uint32_t production_id_count;
|
||||
uint32_t field_count;
|
||||
uint16_t max_alias_sequence_length;
|
||||
const uint16_t *parse_table;
|
||||
const uint16_t *small_parse_table;
|
||||
const uint32_t *small_parse_table_map;
|
||||
const TSParseActionEntry *parse_actions;
|
||||
const char * const *symbol_names;
|
||||
const char * const *field_names;
|
||||
const TSFieldMapSlice *field_map_slices;
|
||||
const TSFieldMapEntry *field_map_entries;
|
||||
const TSSymbolMetadata *symbol_metadata;
|
||||
const TSSymbol *public_symbol_map;
|
||||
const uint16_t *alias_map;
|
||||
const TSSymbol *alias_sequences;
|
||||
const TSLexMode *lex_modes;
|
||||
bool (*lex_fn)(TSLexer *, TSStateId);
|
||||
bool (*keyword_lex_fn)(TSLexer *, TSStateId);
|
||||
TSSymbol keyword_capture_token;
|
||||
struct {
|
||||
const bool *states;
|
||||
const TSSymbol *symbol_map;
|
||||
void *(*create)(void);
|
||||
void (*destroy)(void *);
|
||||
bool (*scan)(void *, TSLexer *, const bool *symbol_whitelist);
|
||||
unsigned (*serialize)(void *, char *);
|
||||
void (*deserialize)(void *, const char *, unsigned);
|
||||
} external_scanner;
|
||||
const TSStateId *primary_state_ids;
|
||||
};
|
||||
|
||||
/*
|
||||
* 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