Merge pull request #9878 from pfgithub/patch-4

Add line numbers to langref
This commit is contained in:
Andrew Kelley 2021-10-12 14:21:28 -04:00 committed by GitHub
commit 7f006287ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 353 additions and 309 deletions

View File

@ -89,7 +89,7 @@ release/bin/zig build test-fmt -Denable-qemu -Denable-wasmtime
release/bin/zig build test-stage2 -Denable-qemu -Denable-wasmtime release/bin/zig build test-stage2 -Denable-qemu -Denable-wasmtime
# Look for HTML errors. # Look for HTML errors.
tidy -qe ../zig-cache/langref.html tidy --drop-empty-elements no -qe ../zig-cache/langref.html
if [ "${BUILD_REASON}" != "PullRequest" ]; then if [ "${BUILD_REASON}" != "PullRequest" ]; then
# Produce the experimental std lib documentation. # Produce the experimental std lib documentation.

View File

@ -313,6 +313,7 @@ const SyntaxBlock = struct {
const SourceType = enum { const SourceType = enum {
zig, zig,
c, c,
peg,
javascript, javascript,
}; };
}; };
@ -666,6 +667,8 @@ fn genToc(allocator: *Allocator, tokenizer: *Tokenizer) !Toc {
source_type = SyntaxBlock.SourceType.zig; source_type = SyntaxBlock.SourceType.zig;
} else if (mem.eql(u8, source_type_str, "c")) { } else if (mem.eql(u8, source_type_str, "c")) {
source_type = SyntaxBlock.SourceType.c; source_type = SyntaxBlock.SourceType.c;
} else if (mem.eql(u8, source_type_str, "peg")) {
source_type = SyntaxBlock.SourceType.peg;
} else if (mem.eql(u8, source_type_str, "javascript")) { } else if (mem.eql(u8, source_type_str, "javascript")) {
source_type = SyntaxBlock.SourceType.javascript; source_type = SyntaxBlock.SourceType.javascript;
} else { } else {
@ -864,6 +867,21 @@ fn isType(name: []const u8) bool {
return false; return false;
} }
const start_line = "<span class=\"line\">";
const end_line = "</span>";
fn writeEscapedLines(out: anytype, text: []const u8) !void {
for (text) |char| {
if (char == '\n') {
try out.writeAll(end_line);
try out.writeAll("\n");
try out.writeAll(start_line);
} else {
try writeEscaped(out, &[_]u8{char});
}
}
}
fn tokenizeAndPrintRaw( fn tokenizeAndPrintRaw(
allocator: *Allocator, allocator: *Allocator,
docgen_tokenizer: *Tokenizer, docgen_tokenizer: *Tokenizer,
@ -873,7 +891,8 @@ fn tokenizeAndPrintRaw(
) !void { ) !void {
const src_non_terminated = mem.trim(u8, raw_src, " \n"); const src_non_terminated = mem.trim(u8, raw_src, " \n");
const src = try allocator.dupeZ(u8, src_non_terminated); const src = try allocator.dupeZ(u8, src_non_terminated);
try out.writeAll("<code>");
try out.writeAll("<code>" ++ start_line);
var tokenizer = std.zig.Tokenizer.init(src); var tokenizer = std.zig.Tokenizer.init(src);
var index: usize = 0; var index: usize = 0;
var next_tok_is_fn = false; var next_tok_is_fn = false;
@ -888,7 +907,7 @@ fn tokenizeAndPrintRaw(
const comment_end_off = mem.indexOf(u8, src[comment_start..token.loc.start], "\n"); const comment_end_off = mem.indexOf(u8, src[comment_start..token.loc.start], "\n");
const comment_end = if (comment_end_off) |o| comment_start + o else token.loc.start; const comment_end = if (comment_end_off) |o| comment_start + o else token.loc.start;
try writeEscaped(out, src[index..comment_start]); try writeEscapedLines(out, src[index..comment_start]);
try out.writeAll("<span class=\"tok-comment\">"); try out.writeAll("<span class=\"tok-comment\">");
try writeEscaped(out, src[comment_start..comment_end]); try writeEscaped(out, src[comment_start..comment_end]);
try out.writeAll("</span>"); try out.writeAll("</span>");
@ -897,7 +916,7 @@ fn tokenizeAndPrintRaw(
continue; continue;
} }
try writeEscaped(out, src[index..token.loc.start]); try writeEscapedLines(out, src[index..token.loc.start]);
switch (token.tag) { switch (token.tag) {
.eof => break, .eof => break,
@ -963,7 +982,6 @@ fn tokenizeAndPrintRaw(
}, },
.string_literal, .string_literal,
.multiline_string_literal_line,
.char_literal, .char_literal,
=> { => {
try out.writeAll("<span class=\"tok-str\">"); try out.writeAll("<span class=\"tok-str\">");
@ -971,6 +989,18 @@ fn tokenizeAndPrintRaw(
try out.writeAll("</span>"); try out.writeAll("</span>");
}, },
.multiline_string_literal_line => {
if (src[token.loc.end - 1] == '\n') {
try out.writeAll("<span class=\"tok-str\">");
try writeEscaped(out, src[token.loc.start .. token.loc.end - 1]);
try out.writeAll("</span>" ++ end_line ++ "\n" ++ start_line);
} else {
try out.writeAll("<span class=\"tok-str\">");
try writeEscaped(out, src[token.loc.start..token.loc.end]);
try out.writeAll("</span>");
}
},
.builtin => { .builtin => {
try out.writeAll("<span class=\"tok-builtin\">"); try out.writeAll("<span class=\"tok-builtin\">");
try writeEscaped(out, src[token.loc.start..token.loc.end]); try writeEscaped(out, src[token.loc.start..token.loc.end]);
@ -1103,7 +1133,7 @@ fn tokenizeAndPrintRaw(
} }
index = token.loc.end; index = token.loc.end;
} }
try out.writeAll("</code>"); try out.writeAll(end_line ++ "</code>");
} }
fn tokenizeAndPrint( fn tokenizeAndPrint(
@ -1126,9 +1156,9 @@ fn printSourceBlock(allocator: *Allocator, docgen_tokenizer: *Tokenizer, out: an
const raw_source = docgen_tokenizer.buffer[syntax_block.source_token.start..syntax_block.source_token.end]; const raw_source = docgen_tokenizer.buffer[syntax_block.source_token.start..syntax_block.source_token.end];
const trimmed_raw_source = mem.trim(u8, raw_source, " \n"); const trimmed_raw_source = mem.trim(u8, raw_source, " \n");
try out.writeAll("<code>"); try out.writeAll("<code>" ++ start_line);
try writeEscaped(out, trimmed_raw_source); try writeEscapedLines(out, trimmed_raw_source);
try out.writeAll("</code>"); try out.writeAll(end_line ++ "</code>");
}, },
} }
try out.writeAll("</pre></figure>"); try out.writeAll("</pre></figure>");
@ -1142,15 +1172,15 @@ fn printShell(out: anytype, shell_content: []const u8) !void {
while (iter.next()) |orig_line| { while (iter.next()) |orig_line| {
const line = mem.trimRight(u8, orig_line, " "); const line = mem.trimRight(u8, orig_line, " ");
if (!cmd_cont and line.len > 1 and mem.eql(u8, line[0..2], "$ ") and line[line.len - 1] != '\\') { if (!cmd_cont and line.len > 1 and mem.eql(u8, line[0..2], "$ ") and line[line.len - 1] != '\\') {
try out.print("$ <kbd>{s}</kbd>\n", .{std.mem.trimLeft(u8, line[1..], " ")}); try out.print(start_line ++ "$ <kbd>{s}</kbd>" ++ end_line ++ "\n", .{std.mem.trimLeft(u8, line[1..], " ")});
} else if (!cmd_cont and line.len > 1 and mem.eql(u8, line[0..2], "$ ") and line[line.len - 1] == '\\') { } else if (!cmd_cont and line.len > 1 and mem.eql(u8, line[0..2], "$ ") and line[line.len - 1] == '\\') {
try out.print("$ <kbd>{s}\n", .{std.mem.trimLeft(u8, line[1..], " ")}); try out.print(start_line ++ "$ <kbd>{s}" ++ end_line ++ "\n", .{std.mem.trimLeft(u8, line[1..], " ")});
cmd_cont = true; cmd_cont = true;
} else if (line.len > 0 and line[line.len - 1] != '\\' and cmd_cont) { } else if (line.len > 0 and line[line.len - 1] != '\\' and cmd_cont) {
try out.print("{s}</kbd>\n", .{line}); try out.print(start_line ++ "{s}</kbd>" ++ end_line ++ "\n", .{line});
cmd_cont = false; cmd_cont = false;
} else { } else {
try out.print("{s}\n", .{line}); try out.print(start_line ++ "{s}" ++ end_line ++ "\n", .{line});
} }
} }
@ -1701,7 +1731,7 @@ test "shell parsed" {
\\$ zig build test.zig \\$ zig build test.zig
; ;
const expected = const expected =
\\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig</kbd> \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp><span class="line">$ <kbd>zig build test.zig</kbd></span>
\\</samp></pre></figure> \\</samp></pre></figure>
; ;
@ -1709,6 +1739,7 @@ test "shell parsed" {
defer buffer.deinit(); defer buffer.deinit();
try printShell(buffer.writer(), shell_out); try printShell(buffer.writer(), shell_out);
std.log.emerg("{s}", .{buffer.items});
try testing.expectEqualSlices(u8, expected, buffer.items); try testing.expectEqualSlices(u8, expected, buffer.items);
} }
{ {
@ -1717,8 +1748,8 @@ test "shell parsed" {
\\build output \\build output
; ;
const expected = const expected =
\\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig</kbd> \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp><span class="line">$ <kbd>zig build test.zig</kbd></span>
\\build output \\<span class="line">build output</span>
\\</samp></pre></figure> \\</samp></pre></figure>
; ;
@ -1735,9 +1766,9 @@ test "shell parsed" {
\\$ ./test \\$ ./test
; ;
const expected = const expected =
\\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig</kbd> \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp><span class="line">$ <kbd>zig build test.zig</kbd></span>
\\build output \\<span class="line">build output</span>
\\$ <kbd>./test</kbd> \\<span class="line">$ <kbd>./test</kbd></span>
\\</samp></pre></figure> \\</samp></pre></figure>
; ;
@ -1755,10 +1786,10 @@ test "shell parsed" {
\\output \\output
; ;
const expected = const expected =
\\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig</kbd> \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp><span class="line">$ <kbd>zig build test.zig</kbd></span>
\\ \\<span class="line"></span>
\\$ <kbd>./test</kbd> \\<span class="line">$ <kbd>./test</kbd></span>
\\output \\<span class="line">output</span>
\\</samp></pre></figure> \\</samp></pre></figure>
; ;
@ -1775,9 +1806,9 @@ test "shell parsed" {
\\output \\output
; ;
const expected = const expected =
\\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig</kbd> \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp><span class="line">$ <kbd>zig build test.zig</kbd></span>
\\$ <kbd>./test</kbd> \\<span class="line">$ <kbd>./test</kbd></span>
\\output \\<span class="line">output</span>
\\</samp></pre></figure> \\</samp></pre></figure>
; ;
@ -1796,11 +1827,11 @@ test "shell parsed" {
\\output \\output
; ;
const expected = const expected =
\\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig \ \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp><span class="line">$ <kbd>zig build test.zig \</span>
\\ --build-option</kbd> \\<span class="line"> --build-option</kbd></span>
\\build output \\<span class="line">build output</span>
\\$ <kbd>./test</kbd> \\<span class="line">$ <kbd>./test</kbd></span>
\\output \\<span class="line">output</span>
\\</samp></pre></figure> \\</samp></pre></figure>
; ;
@ -1819,10 +1850,10 @@ test "shell parsed" {
\\$ ./test \\$ ./test
; ;
const expected = const expected =
\\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig \ \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp><span class="line">$ <kbd>zig build test.zig \</span>
\\ --build-option1 \ \\<span class="line"> --build-option1 \</span>
\\ --build-option2</kbd> \\<span class="line"> --build-option2</kbd></span>
\\$ <kbd>./test</kbd> \\<span class="line">$ <kbd>./test</kbd></span>
\\</samp></pre></figure> \\</samp></pre></figure>
; ;
@ -1838,8 +1869,8 @@ test "shell parsed" {
\\$ ./test \\$ ./test
; ;
const expected = const expected =
\\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig \ \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp><span class="line">$ <kbd>zig build test.zig \</span>
\\$ ./test</kbd> \\<span class="line">$ ./test</kbd></span>
\\</samp></pre></figure> \\</samp></pre></figure>
; ;
@ -1856,9 +1887,9 @@ test "shell parsed" {
\\$1 \\$1
; ;
const expected = const expected =
\\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig</kbd> \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp><span class="line">$ <kbd>zig build test.zig</kbd></span>
\\$ <kbd>./test</kbd> \\<span class="line">$ <kbd>./test</kbd></span>
\\$1 \\<span class="line">$1</span>
\\</samp></pre></figure> \\</samp></pre></figure>
; ;
@ -1873,7 +1904,7 @@ test "shell parsed" {
\\$zig build test.zig \\$zig build test.zig
; ;
const expected = const expected =
\\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$zig build test.zig \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp><span class="line">$zig build test.zig</span>
\\</samp></pre></figure> \\</samp></pre></figure>
; ;

View File

@ -170,6 +170,9 @@
background: #a8b9cc; background: #a8b9cc;
color: #000; color: #000;
} }
figcaption.peg-cap {
background: #fcdba5;
}
figcaption.javascript-cap { figcaption.javascript-cap {
background: #365d95; background: #365d95;
color: #fff; color: #fff;
@ -196,6 +199,25 @@
visibility: visible; visibility: visible;
} }
pre {
counter-reset: line;
}
pre .line:before {
counter-increment: line;
content: counter(line);
display: inline-block;
padding-right: 1em;
width: 2em;
text-align: right;
color: #999;
}
th pre code {
background: none;
}
th .line:before {
display: none;
}
@media (prefers-color-scheme: dark) { @media (prefers-color-scheme: dark) {
body{ body{
background:#121212; background:#121212;
@ -269,6 +291,10 @@
background-color: #b27306; background-color: #b27306;
color: #000; color: #000;
} }
figcaption.peg-cap {
background-color: #b27306;
color: #000;
}
figcaption.shell-cap { figcaption.shell-cap {
background: #2a2a2a; background: #2a2a2a;
color: #fff; color: #fff;
@ -11844,35 +11870,35 @@ fn readU32Be() u32 {}
{#header_close#} {#header_close#}
{#header_open|Grammar#} {#header_open|Grammar#}
<pre><code>Root &lt;- skip container_doc_comment? ContainerMembers eof {#syntax_block|peg|grammar.y#}Root <- skip container_doc_comment? ContainerMembers eof
# *** Top level *** # *** Top level ***
ContainerMembers &lt;- ContainerDeclarations (ContainerField COMMA)* (ContainerField / ContainerDeclarations) ContainerMembers <- ContainerDeclarations (ContainerField COMMA)* (ContainerField / ContainerDeclarations)
ContainerDeclarations ContainerDeclarations
&lt;- TestDecl ContainerDeclarations <- TestDecl ContainerDeclarations
/ TopLevelComptime ContainerDeclarations / TopLevelComptime ContainerDeclarations
/ doc_comment? KEYWORD_pub? TopLevelDecl ContainerDeclarations / doc_comment? KEYWORD_pub? TopLevelDecl ContainerDeclarations
/ /
TestDecl &lt;- doc_comment? KEYWORD_test STRINGLITERALSINGLE? Block TestDecl <- doc_comment? KEYWORD_test STRINGLITERALSINGLE? Block
TopLevelComptime &lt;- doc_comment? KEYWORD_comptime BlockExpr TopLevelComptime <- doc_comment? KEYWORD_comptime BlockExpr
TopLevelDecl TopLevelDecl
&lt;- (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE? / (KEYWORD_inline / KEYWORD_noinline))? FnProto (SEMICOLON / Block) <- (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE? / (KEYWORD_inline / KEYWORD_noinline))? FnProto (SEMICOLON / Block)
/ (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE?)? KEYWORD_threadlocal? VarDecl / (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE?)? KEYWORD_threadlocal? VarDecl
/ KEYWORD_usingnamespace Expr SEMICOLON / KEYWORD_usingnamespace Expr SEMICOLON
FnProto &lt;- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? CallConv? EXCLAMATIONMARK? TypeExpr FnProto <- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? CallConv? EXCLAMATIONMARK? TypeExpr
VarDecl &lt;- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? LinkSection? (EQUAL Expr)? SEMICOLON VarDecl <- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? LinkSection? (EQUAL Expr)? SEMICOLON
ContainerField &lt;- doc_comment? KEYWORD_comptime? IDENTIFIER (COLON (KEYWORD_anytype / TypeExpr) ByteAlign?)? (EQUAL Expr)? ContainerField <- doc_comment? KEYWORD_comptime? IDENTIFIER (COLON (KEYWORD_anytype / TypeExpr) ByteAlign?)? (EQUAL Expr)?
# *** Block Level *** # *** Block Level ***
Statement Statement
&lt;- KEYWORD_comptime? VarDecl <- KEYWORD_comptime? VarDecl
/ KEYWORD_comptime BlockExprStatement / KEYWORD_comptime BlockExprStatement
/ KEYWORD_nosuspend BlockExprStatement / KEYWORD_nosuspend BlockExprStatement
/ KEYWORD_suspend BlockExprStatement / KEYWORD_suspend BlockExprStatement
@ -11884,50 +11910,50 @@ Statement
/ AssignExpr SEMICOLON / AssignExpr SEMICOLON
IfStatement IfStatement
&lt;- IfPrefix BlockExpr ( KEYWORD_else Payload? Statement )? <- IfPrefix BlockExpr ( KEYWORD_else Payload? Statement )?
/ IfPrefix AssignExpr ( SEMICOLON / KEYWORD_else Payload? Statement ) / IfPrefix AssignExpr ( SEMICOLON / KEYWORD_else Payload? Statement )
LabeledStatement &lt;- BlockLabel? (Block / LoopStatement) LabeledStatement <- BlockLabel? (Block / LoopStatement)
LoopStatement &lt;- KEYWORD_inline? (ForStatement / WhileStatement) LoopStatement <- KEYWORD_inline? (ForStatement / WhileStatement)
ForStatement ForStatement
&lt;- ForPrefix BlockExpr ( KEYWORD_else Statement )? <- ForPrefix BlockExpr ( KEYWORD_else Statement )?
/ ForPrefix AssignExpr ( SEMICOLON / KEYWORD_else Statement ) / ForPrefix AssignExpr ( SEMICOLON / KEYWORD_else Statement )
WhileStatement WhileStatement
&lt;- WhilePrefix BlockExpr ( KEYWORD_else Payload? Statement )? <- WhilePrefix BlockExpr ( KEYWORD_else Payload? Statement )?
/ WhilePrefix AssignExpr ( SEMICOLON / KEYWORD_else Payload? Statement ) / WhilePrefix AssignExpr ( SEMICOLON / KEYWORD_else Payload? Statement )
BlockExprStatement BlockExprStatement
&lt;- BlockExpr <- BlockExpr
/ AssignExpr SEMICOLON / AssignExpr SEMICOLON
BlockExpr &lt;- BlockLabel? Block BlockExpr <- BlockLabel? Block
# *** Expression Level *** # *** Expression Level ***
AssignExpr &lt;- Expr (AssignOp Expr)? AssignExpr <- Expr (AssignOp Expr)?
Expr &lt;- BoolOrExpr Expr <- BoolOrExpr
BoolOrExpr &lt;- BoolAndExpr (KEYWORD_or BoolAndExpr)* BoolOrExpr <- BoolAndExpr (KEYWORD_or BoolAndExpr)*
BoolAndExpr &lt;- CompareExpr (KEYWORD_and CompareExpr)* BoolAndExpr <- CompareExpr (KEYWORD_and CompareExpr)*
CompareExpr &lt;- BitwiseExpr (CompareOp BitwiseExpr)? CompareExpr <- BitwiseExpr (CompareOp BitwiseExpr)?
BitwiseExpr &lt;- BitShiftExpr (BitwiseOp BitShiftExpr)* BitwiseExpr <- BitShiftExpr (BitwiseOp BitShiftExpr)*
BitShiftExpr &lt;- AdditionExpr (BitShiftOp AdditionExpr)* BitShiftExpr <- AdditionExpr (BitShiftOp AdditionExpr)*
AdditionExpr &lt;- MultiplyExpr (AdditionOp MultiplyExpr)* AdditionExpr <- MultiplyExpr (AdditionOp MultiplyExpr)*
MultiplyExpr &lt;- PrefixExpr (MultiplyOp PrefixExpr)* MultiplyExpr <- PrefixExpr (MultiplyOp PrefixExpr)*
PrefixExpr &lt;- PrefixOp* PrimaryExpr PrefixExpr <- PrefixOp* PrimaryExpr
PrimaryExpr PrimaryExpr
&lt;- AsmExpr <- AsmExpr
/ IfExpr / IfExpr
/ KEYWORD_break BreakLabel? Expr? / KEYWORD_break BreakLabel? Expr?
/ KEYWORD_comptime Expr / KEYWORD_comptime Expr
@ -11939,33 +11965,33 @@ PrimaryExpr
/ Block / Block
/ CurlySuffixExpr / CurlySuffixExpr
IfExpr &lt;- IfPrefix Expr (KEYWORD_else Payload? Expr)? IfExpr <- IfPrefix Expr (KEYWORD_else Payload? Expr)?
Block &lt;- LBRACE Statement* RBRACE Block <- LBRACE Statement* RBRACE
LoopExpr &lt;- KEYWORD_inline? (ForExpr / WhileExpr) LoopExpr <- KEYWORD_inline? (ForExpr / WhileExpr)
ForExpr &lt;- ForPrefix Expr (KEYWORD_else Expr)? ForExpr <- ForPrefix Expr (KEYWORD_else Expr)?
WhileExpr &lt;- WhilePrefix Expr (KEYWORD_else Payload? Expr)? WhileExpr <- WhilePrefix Expr (KEYWORD_else Payload? Expr)?
CurlySuffixExpr &lt;- TypeExpr InitList? CurlySuffixExpr <- TypeExpr InitList?
InitList InitList
&lt;- LBRACE FieldInit (COMMA FieldInit)* COMMA? RBRACE <- LBRACE FieldInit (COMMA FieldInit)* COMMA? RBRACE
/ LBRACE Expr (COMMA Expr)* COMMA? RBRACE / LBRACE Expr (COMMA Expr)* COMMA? RBRACE
/ LBRACE RBRACE / LBRACE RBRACE
TypeExpr &lt;- PrefixTypeOp* ErrorUnionExpr TypeExpr <- PrefixTypeOp* ErrorUnionExpr
ErrorUnionExpr &lt;- SuffixExpr (EXCLAMATIONMARK TypeExpr)? ErrorUnionExpr <- SuffixExpr (EXCLAMATIONMARK TypeExpr)?
SuffixExpr SuffixExpr
&lt;- KEYWORD_async PrimaryTypeExpr SuffixOp* FnCallArguments <- KEYWORD_async PrimaryTypeExpr SuffixOp* FnCallArguments
/ PrimaryTypeExpr (SuffixOp / FnCallArguments)* / PrimaryTypeExpr (SuffixOp / FnCallArguments)*
PrimaryTypeExpr PrimaryTypeExpr
&lt;- BUILTINIDENTIFIER FnCallArguments <- BUILTINIDENTIFIER FnCallArguments
/ CHAR_LITERAL / CHAR_LITERAL
/ ContainerDecl / ContainerDecl
/ DOT IDENTIFIER / DOT IDENTIFIER
@ -11985,94 +12011,93 @@ PrimaryTypeExpr
/ STRINGLITERAL / STRINGLITERAL
/ SwitchExpr / SwitchExpr
ContainerDecl &lt;- (KEYWORD_extern / KEYWORD_packed)? ContainerDeclAuto ContainerDecl <- (KEYWORD_extern / KEYWORD_packed)? ContainerDeclAuto
ErrorSetDecl &lt;- KEYWORD_error LBRACE IdentifierList RBRACE ErrorSetDecl <- KEYWORD_error LBRACE IdentifierList RBRACE
GroupedExpr &lt;- LPAREN Expr RPAREN GroupedExpr <- LPAREN Expr RPAREN
IfTypeExpr &lt;- IfPrefix TypeExpr (KEYWORD_else Payload? TypeExpr)? IfTypeExpr <- IfPrefix TypeExpr (KEYWORD_else Payload? TypeExpr)?
LabeledTypeExpr LabeledTypeExpr
&lt;- BlockLabel Block <- BlockLabel Block
/ BlockLabel? LoopTypeExpr / BlockLabel? LoopTypeExpr
LoopTypeExpr &lt;- KEYWORD_inline? (ForTypeExpr / WhileTypeExpr) LoopTypeExpr <- KEYWORD_inline? (ForTypeExpr / WhileTypeExpr)
ForTypeExpr &lt;- ForPrefix TypeExpr (KEYWORD_else TypeExpr)? ForTypeExpr <- ForPrefix TypeExpr (KEYWORD_else TypeExpr)?
WhileTypeExpr &lt;- WhilePrefix TypeExpr (KEYWORD_else Payload? TypeExpr)? WhileTypeExpr <- WhilePrefix TypeExpr (KEYWORD_else Payload? TypeExpr)?
SwitchExpr &lt;- KEYWORD_switch LPAREN Expr RPAREN LBRACE SwitchProngList RBRACE SwitchExpr <- KEYWORD_switch LPAREN Expr RPAREN LBRACE SwitchProngList RBRACE
# *** Assembly *** # *** Assembly ***
AsmExpr &lt;- KEYWORD_asm KEYWORD_volatile? LPAREN Expr AsmOutput? RPAREN AsmExpr <- KEYWORD_asm KEYWORD_volatile? LPAREN Expr AsmOutput? RPAREN
AsmOutput &lt;- COLON AsmOutputList AsmInput? AsmOutput <- COLON AsmOutputList AsmInput?
AsmOutputItem &lt;- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN (MINUSRARROW TypeExpr / IDENTIFIER) RPAREN AsmOutputItem <- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN (MINUSRARROW TypeExpr / IDENTIFIER) RPAREN
AsmInput &lt;- COLON AsmInputList AsmClobbers? AsmInput <- COLON AsmInputList AsmClobbers?
AsmInputItem &lt;- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN Expr RPAREN AsmInputItem <- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN Expr RPAREN
AsmClobbers &lt;- COLON StringList AsmClobbers <- COLON StringList
# *** Helper grammar *** # *** Helper grammar ***
BreakLabel &lt;- COLON IDENTIFIER BreakLabel <- COLON IDENTIFIER
BlockLabel &lt;- IDENTIFIER COLON BlockLabel <- IDENTIFIER COLON
FieldInit &lt;- DOT IDENTIFIER EQUAL Expr FieldInit <- DOT IDENTIFIER EQUAL Expr
WhileContinueExpr &lt;- COLON LPAREN AssignExpr RPAREN WhileContinueExpr <- COLON LPAREN AssignExpr RPAREN
LinkSection &lt;- KEYWORD_linksection LPAREN Expr RPAREN LinkSection <- KEYWORD_linksection LPAREN Expr RPAREN
# Fn specific # Fn specific
CallConv &lt;- KEYWORD_callconv LPAREN Expr RPAREN CallConv <- KEYWORD_callconv LPAREN Expr RPAREN
ParamDecl ParamDecl
&lt;- doc_comment? (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType <- doc_comment? (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType
/ DOT3 / DOT3
ParamType ParamType
&lt;- KEYWORD_anytype <- KEYWORD_anytype
/ TypeExpr / TypeExpr
# Control flow prefixes # Control flow prefixes
IfPrefix &lt;- KEYWORD_if LPAREN Expr RPAREN PtrPayload? IfPrefix <- KEYWORD_if LPAREN Expr RPAREN PtrPayload?
WhilePrefix &lt;- KEYWORD_while LPAREN Expr RPAREN PtrPayload? WhileContinueExpr? WhilePrefix <- KEYWORD_while LPAREN Expr RPAREN PtrPayload? WhileContinueExpr?
ForPrefix &lt;- KEYWORD_for LPAREN Expr RPAREN PtrIndexPayload ForPrefix <- KEYWORD_for LPAREN Expr RPAREN PtrIndexPayload
# Payloads # Payloads
Payload &lt;- PIPE IDENTIFIER PIPE Payload <- PIPE IDENTIFIER PIPE
PtrPayload &lt;- PIPE ASTERISK? IDENTIFIER PIPE PtrPayload <- PIPE ASTERISK? IDENTIFIER PIPE
PtrIndexPayload &lt;- PIPE ASTERISK? IDENTIFIER (COMMA IDENTIFIER)? PIPE PtrIndexPayload <- PIPE ASTERISK? IDENTIFIER (COMMA IDENTIFIER)? PIPE
# Switch specific # Switch specific
SwitchProng &lt;- SwitchCase EQUALRARROW PtrPayload? AssignExpr SwitchProng <- SwitchCase EQUALRARROW PtrPayload? AssignExpr
SwitchCase SwitchCase
&lt;- SwitchItem (COMMA SwitchItem)* COMMA? <- SwitchItem (COMMA SwitchItem)* COMMA?
/ KEYWORD_else / KEYWORD_else
SwitchItem &lt;- Expr (DOT3 Expr)? SwitchItem <- Expr (DOT3 Expr)?
# Operators # Operators
AssignOp AssignOp
&lt;- ASTERISKEQUAL <- ASTERISKEQUAL
/ SLASHEQUAL / SLASHEQUAL
/ PERCENTEQUAL / PERCENTEQUAL
/ PLUSEQUAL / PLUSEQUAL
/ MINUSEQUAL / MINUSEQUAL
/ LARROW2EQUAL / LARROW2EQUAL
/ LARROW2PIPEEQUAL
/ RARROW2EQUAL / RARROW2EQUAL
/ AMPERSANDEQUAL / AMPERSANDEQUAL
/ CARETEQUAL / CARETEQUAL
@ -12083,7 +12108,7 @@ AssignOp
/ EQUAL / EQUAL
CompareOp CompareOp
&lt;- EQUALEQUAL <- EQUALEQUAL
/ EXCLAMATIONMARKEQUAL / EXCLAMATIONMARKEQUAL
/ LARROW / LARROW
/ RARROW / RARROW
@ -12091,36 +12116,33 @@ CompareOp
/ RARROWEQUAL / RARROWEQUAL
BitwiseOp BitwiseOp
&lt;- AMPERSAND <- AMPERSAND
/ CARET / CARET
/ PIPE / PIPE
/ KEYWORD_orelse / KEYWORD_orelse
/ KEYWORD_catch Payload? / KEYWORD_catch Payload?
BitShiftOp BitShiftOp
&lt;- LARROW2 <- LARROW2
/ RARROW2 / RARROW2
AdditionOp AdditionOp
&lt;- PLUS <- PLUS
/ MINUS / MINUS
/ PLUS2 / PLUS2
/ PLUSPERCENT / PLUSPERCENT
/ MINUSPERCENT / MINUSPERCENT
/ PLUSPIPE
/ MINUSPIPE
MultiplyOp MultiplyOp
&lt;- PIPE2 <- PIPE2
/ ASTERISK / ASTERISK
/ SLASH / SLASH
/ PERCENT / PERCENT
/ ASTERISK2 / ASTERISK2
/ ASTERISKPERCENT / ASTERISKPERCENT
/ ASTERISKPIPE
PrefixOp PrefixOp
&lt;- EXCLAMATIONMARK <- EXCLAMATIONMARK
/ MINUS / MINUS
/ TILDE / TILDE
/ MINUSPERCENT / MINUSPERCENT
@ -12129,86 +12151,86 @@ PrefixOp
/ KEYWORD_await / KEYWORD_await
PrefixTypeOp PrefixTypeOp
&lt;- QUESTIONMARK <- QUESTIONMARK
/ KEYWORD_anyframe MINUSRARROW / KEYWORD_anyframe MINUSRARROW
/ SliceTypeStart (ByteAlign / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)* / SliceTypeStart (ByteAlign / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)*
/ PtrTypeStart (KEYWORD_align LPAREN Expr (COLON INTEGER COLON INTEGER)? RPAREN / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)* / PtrTypeStart (KEYWORD_align LPAREN Expr (COLON INTEGER COLON INTEGER)? RPAREN / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)*
/ ArrayTypeStart / ArrayTypeStart
SuffixOp SuffixOp
&lt;- LBRACKET Expr (DOT2 (Expr? (COLON Expr)?)?)? RBRACKET <- LBRACKET Expr (DOT2 (Expr? (COLON Expr)?)?)? RBRACKET
/ DOT IDENTIFIER / DOT IDENTIFIER
/ DOTASTERISK / DOTASTERISK
/ DOTQUESTIONMARK / DOTQUESTIONMARK
FnCallArguments &lt;- LPAREN ExprList RPAREN FnCallArguments <- LPAREN ExprList RPAREN
# Ptr specific # Ptr specific
SliceTypeStart &lt;- LBRACKET (COLON Expr)? RBRACKET SliceTypeStart <- LBRACKET (COLON Expr)? RBRACKET
PtrTypeStart PtrTypeStart
&lt;- ASTERISK <- ASTERISK
/ ASTERISK2 / ASTERISK2
/ LBRACKET ASTERISK (LETTERC / COLON Expr)? RBRACKET / LBRACKET ASTERISK (LETTERC / COLON Expr)? RBRACKET
ArrayTypeStart &lt;- LBRACKET Expr (COLON Expr)? RBRACKET ArrayTypeStart <- LBRACKET Expr (COLON Expr)? RBRACKET
# ContainerDecl specific # ContainerDecl specific
ContainerDeclAuto &lt;- ContainerDeclType LBRACE container_doc_comment? ContainerMembers RBRACE ContainerDeclAuto <- ContainerDeclType LBRACE container_doc_comment? ContainerMembers RBRACE
ContainerDeclType ContainerDeclType
&lt;- KEYWORD_struct <- KEYWORD_struct
/ KEYWORD_opaque / KEYWORD_opaque
/ KEYWORD_enum (LPAREN Expr RPAREN)? / KEYWORD_enum (LPAREN Expr RPAREN)?
/ KEYWORD_union (LPAREN (KEYWORD_enum (LPAREN Expr RPAREN)? / Expr) RPAREN)? / KEYWORD_union (LPAREN (KEYWORD_enum (LPAREN Expr RPAREN)? / Expr) RPAREN)?
# Alignment # Alignment
ByteAlign &lt;- KEYWORD_align LPAREN Expr RPAREN ByteAlign <- KEYWORD_align LPAREN Expr RPAREN
# Lists # Lists
IdentifierList &lt;- (doc_comment? IDENTIFIER COMMA)* (doc_comment? IDENTIFIER)? IdentifierList <- (doc_comment? IDENTIFIER COMMA)* (doc_comment? IDENTIFIER)?
SwitchProngList &lt;- (SwitchProng COMMA)* SwitchProng? SwitchProngList <- (SwitchProng COMMA)* SwitchProng?
AsmOutputList &lt;- (AsmOutputItem COMMA)* AsmOutputItem? AsmOutputList <- (AsmOutputItem COMMA)* AsmOutputItem?
AsmInputList &lt;- (AsmInputItem COMMA)* AsmInputItem? AsmInputList <- (AsmInputItem COMMA)* AsmInputItem?
StringList &lt;- (STRINGLITERAL COMMA)* STRINGLITERAL? StringList <- (STRINGLITERAL COMMA)* STRINGLITERAL?
ParamDeclList &lt;- (ParamDecl COMMA)* ParamDecl? ParamDeclList <- (ParamDecl COMMA)* ParamDecl?
ExprList &lt;- (Expr COMMA)* Expr? ExprList <- (Expr COMMA)* Expr?
# *** Tokens *** # *** Tokens ***
eof &lt;- !. eof <- !.
bin &lt;- [01] bin <- [01]
bin_ &lt;- '_'? bin bin_ <- '_'? bin
oct &lt;- [0-7] oct <- [0-7]
oct_ &lt;- '_'? oct oct_ <- '_'? oct
hex &lt;- [0-9a-fA-F] hex <- [0-9a-fA-F]
hex_ &lt;- '_'? hex hex_ <- '_'? hex
dec &lt;- [0-9] dec <- [0-9]
dec_ &lt;- '_'? dec dec_ <- '_'? dec
bin_int &lt;- bin bin_* bin_int <- bin bin_*
oct_int &lt;- oct oct_* oct_int <- oct oct_*
dec_int &lt;- dec dec_* dec_int <- dec dec_*
hex_int &lt;- hex hex_* hex_int <- hex hex_*
ox80_oxBF &lt;- [\200-\277] ox80_oxBF <- [\200-\277]
oxF4 &lt;- '\364' oxF4 <- '\364'
ox80_ox8F &lt;- [\200-\217] ox80_ox8F <- [\200-\217]
oxF1_oxF3 &lt;- [\361-\363] oxF1_oxF3 <- [\361-\363]
oxF0 &lt;- '\360' oxF0 <- '\360'
ox90_0xBF &lt;- [\220-\277] ox90_0xBF <- [\220-\277]
oxEE_oxEF &lt;- [\356-\357] oxEE_oxEF <- [\356-\357]
oxED &lt;- '\355' oxED <- '\355'
ox80_ox9F &lt;- [\200-\237] ox80_ox9F <- [\200-\237]
oxE1_oxEC &lt;- [\341-\354] oxE1_oxEC <- [\341-\354]
oxE0 &lt;- '\340' oxE0 <- '\340'
oxA0_oxBF &lt;- [\240-\277] oxA0_oxBF <- [\240-\277]
oxC2_oxDF &lt;- [\302-\337] 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/ # 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 # First Byte Second Byte Third Byte Fourth Byte
@ -12222,7 +12244,7 @@ oxC2_oxDF &lt;- [\302-\337]
# [0xF1,0xF3] [0x80,0xBF] [0x80,0xBF] [0x80,0xBF] # [0xF1,0xF3] [0x80,0xBF] [0x80,0xBF] [0x80,0xBF]
# 0xF4 [0x80,0x8F] [0x80,0xBF] [0x80,0xBF] # 0xF4 [0x80,0x8F] [0x80,0xBF] [0x80,0xBF]
mb_utf8_literal &lt;- mb_utf8_literal <-
oxF4 ox80_ox8F ox80_oxBF ox80_oxBF oxF4 ox80_ox8F ox80_oxBF ox80_oxBF
/ oxF1_oxF3 ox80_oxBF ox80_oxBF ox80_oxBF / oxF1_oxF3 ox80_oxBF ox80_oxBF ox80_oxBF
/ oxF0 ox90_0xBF ox80_oxBF ox80_oxBF / oxF0 ox90_0xBF ox80_oxBF ox80_oxBF
@ -12232,164 +12254,156 @@ mb_utf8_literal &lt;-
/ oxE0 oxA0_oxBF ox80_oxBF / oxE0 oxA0_oxBF ox80_oxBF
/ oxC2_oxDF ox80_oxBF / oxC2_oxDF ox80_oxBF
ascii_char_not_nl_slash_squote &lt;- [\000-\011\013-\046-\050-\133\135-\177] ascii_char_not_nl_slash_squote <- [\000-\011\013-\046-\050-\133\135-\177]
char_escape char_escape
&lt;- &quot;\\x&quot; hex hex <- "\\x" hex hex
/ &quot;\\u{&quot; hex+ &quot;}&quot; / "\\u{" hex+ "}"
/ &quot;\\&quot; [nr\\t'&quot;] / "\\" [nr\\t'"]
char_char char_char
&lt;- mb_utf8_literal <- mb_utf8_literal
/ char_escape / char_escape
/ ascii_char_not_nl_slash_squote / ascii_char_not_nl_slash_squote
string_char string_char
&lt;- char_escape <- char_escape
/ [^\\&quot;\n] / [^\\"\n]
container_doc_comment &lt;- ('//!' [^\n]* [ \n]*)+ container_doc_comment <- ('//!' [^\n]* [ \n]*)+
doc_comment &lt;- ('///' [^\n]* [ \n]*)+ doc_comment <- ('///' [^\n]* [ \n]*)+
line_comment &lt;- '//' ![!/][^\n]* / '////' [^\n]* line_comment <- '//' ![!/][^\n]* / '////' [^\n]*
line_string &lt;- (&quot;\\\\&quot; [^\n]* [ \n]*)+ line_string <- ("\\\\" [^\n]* [ \n]*)+
skip &lt;- ([ \n] / line_comment)* skip <- ([ \n] / line_comment)*
CHAR_LITERAL &lt;- &quot;'&quot; char_char &quot;'&quot; skip CHAR_LITERAL <- "'" char_char "'" skip
FLOAT FLOAT
&lt;- &quot;0x&quot; hex_int &quot;.&quot; hex_int ([pP] [-+]? dec_int)? skip <- "0x" hex_int "." hex_int ([pP] [-+]? dec_int)? skip
/ dec_int &quot;.&quot; dec_int ([eE] [-+]? dec_int)? skip / dec_int "." dec_int ([eE] [-+]? dec_int)? skip
/ &quot;0x&quot; hex_int &quot;.&quot;? [pP] [-+]? dec_int skip / "0x" hex_int [pP] [-+]? dec_int skip
/ dec_int &quot;.&quot;? [eE] [-+]? dec_int skip / dec_int [eE] [-+]? dec_int skip
INTEGER INTEGER
&lt;- &quot;0b&quot; bin_int skip <- "0b" bin_int skip
/ &quot;0o&quot; oct_int skip / "0o" oct_int skip
/ &quot;0x&quot; hex_int skip / "0x" hex_int skip
/ dec_int skip / dec_int skip
STRINGLITERALSINGLE &lt;- &quot;\&quot;&quot; string_char* &quot;\&quot;&quot; skip STRINGLITERALSINGLE <- "\"" string_char* "\"" skip
STRINGLITERAL STRINGLITERAL
&lt;- STRINGLITERALSINGLE <- STRINGLITERALSINGLE
/ (line_string skip)+ / (line_string skip)+
IDENTIFIER IDENTIFIER
&lt;- !keyword [A-Za-z_] [A-Za-z0-9_]* skip <- !keyword [A-Za-z_] [A-Za-z0-9_]* skip
/ &quot;@\&quot;&quot; string_char* &quot;\&quot;&quot; skip / "@\"" string_char* "\"" skip
BUILTINIDENTIFIER &lt;- &quot;@&quot;[A-Za-z_][A-Za-z0-9_]* skip BUILTINIDENTIFIER <- "@"[A-Za-z_][A-Za-z0-9_]* skip
AMPERSAND &lt;- '&amp;' ![=] skip AMPERSAND <- '&' ![=] skip
AMPERSANDEQUAL &lt;- '&amp;=' skip AMPERSANDEQUAL <- '&=' skip
ASTERISK &lt;- '*' ![*%=] skip ASTERISK <- '*' ![*%=] skip
ASTERISK2 &lt;- '**' skip ASTERISK2 <- '**' skip
ASTERISKEQUAL &lt;- '*=' skip ASTERISKEQUAL <- '*=' skip
ASTERISKPERCENT &lt;- '*%' ![=] skip ASTERISKPERCENT <- '*%' ![=] skip
ASTERISKPERCENTEQUAL &lt;- '*%=' skip ASTERISKPERCENTEQUAL <- '*%=' skip
ASTERISKPIPE &lt;- '*|' ![=] skip CARET <- '^' ![=] skip
ASTERISKPIPEEQUAL &lt;- '*|=' skip CARETEQUAL <- '^=' skip
CARET &lt;- '^' ![=] skip COLON <- ':' skip
CARETEQUAL &lt;- '^=' skip COMMA <- ',' skip
COLON &lt;- ':' skip DOT <- '.' ![*.?] skip
COMMA &lt;- ',' skip DOT2 <- '..' ![.] skip
DOT &lt;- '.' ![*.?] skip DOT3 <- '...' skip
DOT2 &lt;- '..' ![.] skip DOTASTERISK <- '.*' skip
DOT3 &lt;- '...' skip DOTQUESTIONMARK <- '.?' skip
DOTASTERISK &lt;- '.*' skip EQUAL <- '=' ![>=] skip
DOTQUESTIONMARK &lt;- '.?' skip EQUALEQUAL <- '==' skip
EQUAL &lt;- '=' ![&gt;=] skip EQUALRARROW <- '=>' skip
EQUALEQUAL &lt;- '==' skip EXCLAMATIONMARK <- '!' ![=] skip
EQUALRARROW &lt;- '=&gt;' skip EXCLAMATIONMARKEQUAL <- '!=' skip
EXCLAMATIONMARK &lt;- '!' ![=] skip LARROW <- '<' ![<=] skip
EXCLAMATIONMARKEQUAL &lt;- '!=' skip LARROW2 <- '<<' ![=] skip
LARROW &lt;- '&lt;' ![&lt;=] skip LARROW2EQUAL <- '<<=' skip
LARROW2 &lt;- '&lt;&lt;' ![=] skip LARROWEQUAL <- '<=' skip
LARROW2PIPE &lt;- '&lt;&lt;|' ![=] skip LBRACE <- '{' skip
LARROW2PIPEEQUAL &lt;- '&lt;&lt;|=' ![=] skip LBRACKET <- '[' skip
LARROW2EQUAL &lt;- '&lt;&lt;=' skip LPAREN <- '(' skip
LARROWEQUAL &lt;- '&lt;=' skip MINUS <- '-' ![%=>] skip
LBRACE &lt;- '{' skip MINUSEQUAL <- '-=' skip
LBRACKET &lt;- '[' skip MINUSPERCENT <- '-%' ![=] skip
LPAREN &lt;- '(' skip MINUSPERCENTEQUAL <- '-%=' skip
MINUS &lt;- '-' ![%=&gt;] skip MINUSRARROW <- '->' skip
MINUSEQUAL &lt;- '-=' skip PERCENT <- '%' ![=] skip
MINUSPERCENT &lt;- '-%' ![=] skip PERCENTEQUAL <- '%=' skip
MINUSPERCENTEQUAL &lt;- '-%=' skip PIPE <- '|' ![|=] skip
MINUSPIPE &lt;- '-|' ![=] skip PIPE2 <- '||' skip
MINUSPIPEEQUAL &lt;- '-|=' skip PIPEEQUAL <- '|=' skip
MINUSRARROW &lt;- '-&gt;' skip PLUS <- '+' ![%+=] skip
PERCENT &lt;- '%' ![=] skip PLUS2 <- '++' skip
PERCENTEQUAL &lt;- '%=' skip PLUSEQUAL <- '+=' skip
PIPE &lt;- '|' ![|=] skip PLUSPERCENT <- '+%' ![=] skip
PIPE2 &lt;- '||' skip PLUSPERCENTEQUAL <- '+%=' skip
PIPEEQUAL &lt;- '|=' skip LETTERC <- 'c' skip
PLUS &lt;- '+' ![%+=] skip QUESTIONMARK <- '?' skip
PLUS2 &lt;- '++' skip RARROW <- '>' ![>=] skip
PLUSEQUAL &lt;- '+=' skip RARROW2 <- '>>' ![=] skip
PLUSPERCENT &lt;- '+%' ![=] skip RARROW2EQUAL <- '>>=' skip
PLUSPERCENTEQUAL &lt;- '+%=' skip RARROWEQUAL <- '>=' skip
PLUSPIPE &lt;- '+|' ![=] skip RBRACE <- '}' skip
PLUSPIPEEQUAL &lt;- '+|=' skip RBRACKET <- ']' skip
LETTERC &lt;- 'c' skip RPAREN <- ')' skip
QUESTIONMARK &lt;- '?' skip SEMICOLON <- ';' skip
RARROW &lt;- '&gt;' ![&gt;=] skip SLASH <- '/' ![=] skip
RARROW2 &lt;- '&gt;&gt;' ![=] skip SLASHEQUAL <- '/=' skip
RARROW2EQUAL &lt;- '&gt;&gt;=' skip TILDE <- '~' skip
RARROWEQUAL &lt;- '&gt;=' skip
RBRACE &lt;- '}' skip
RBRACKET &lt;- ']' skip
RPAREN &lt;- ')' skip
SEMICOLON &lt;- ';' skip
SLASH &lt;- '/' ![=] skip
SLASHEQUAL &lt;- '/=' skip
TILDE &lt;- '~' skip
end_of_word &lt;- ![a-zA-Z0-9_] skip end_of_word <- ![a-zA-Z0-9_] skip
KEYWORD_align &lt;- 'align' end_of_word KEYWORD_align <- 'align' end_of_word
KEYWORD_allowzero &lt;- 'allowzero' end_of_word KEYWORD_allowzero <- 'allowzero' end_of_word
KEYWORD_and &lt;- 'and' end_of_word KEYWORD_and <- 'and' end_of_word
KEYWORD_anyframe &lt;- 'anyframe' end_of_word KEYWORD_anyframe <- 'anyframe' end_of_word
KEYWORD_anytype &lt;- 'anytype' end_of_word KEYWORD_anytype <- 'anytype' end_of_word
KEYWORD_asm &lt;- 'asm' end_of_word KEYWORD_asm <- 'asm' end_of_word
KEYWORD_async &lt;- 'async' end_of_word KEYWORD_async <- 'async' end_of_word
KEYWORD_await &lt;- 'await' end_of_word KEYWORD_await <- 'await' end_of_word
KEYWORD_break &lt;- 'break' end_of_word KEYWORD_break <- 'break' end_of_word
KEYWORD_callconv &lt;- 'callconv' end_of_word KEYWORD_callconv <- 'callconv' end_of_word
KEYWORD_catch &lt;- 'catch' end_of_word KEYWORD_catch <- 'catch' end_of_word
KEYWORD_comptime &lt;- 'comptime' end_of_word KEYWORD_comptime <- 'comptime' end_of_word
KEYWORD_const &lt;- 'const' end_of_word KEYWORD_const <- 'const' end_of_word
KEYWORD_continue &lt;- 'continue' end_of_word KEYWORD_continue <- 'continue' end_of_word
KEYWORD_defer &lt;- 'defer' end_of_word KEYWORD_defer <- 'defer' end_of_word
KEYWORD_else &lt;- 'else' end_of_word KEYWORD_else <- 'else' end_of_word
KEYWORD_enum &lt;- 'enum' end_of_word KEYWORD_enum <- 'enum' end_of_word
KEYWORD_errdefer &lt;- 'errdefer' end_of_word KEYWORD_errdefer <- 'errdefer' end_of_word
KEYWORD_error &lt;- 'error' end_of_word KEYWORD_error <- 'error' end_of_word
KEYWORD_export &lt;- 'export' end_of_word KEYWORD_export <- 'export' end_of_word
KEYWORD_extern &lt;- 'extern' end_of_word KEYWORD_extern <- 'extern' end_of_word
KEYWORD_fn &lt;- 'fn' end_of_word KEYWORD_fn <- 'fn' end_of_word
KEYWORD_for &lt;- 'for' end_of_word KEYWORD_for <- 'for' end_of_word
KEYWORD_if &lt;- 'if' end_of_word KEYWORD_if <- 'if' end_of_word
KEYWORD_inline &lt;- 'inline' end_of_word KEYWORD_inline <- 'inline' end_of_word
KEYWORD_noalias &lt;- 'noalias' end_of_word KEYWORD_noalias <- 'noalias' end_of_word
KEYWORD_nosuspend &lt;- 'nosuspend' end_of_word KEYWORD_nosuspend <- 'nosuspend' end_of_word
KEYWORD_noinline &lt;- 'noinline' end_of_word KEYWORD_noinline <- 'noinline' end_of_word
KEYWORD_opaque &lt;- 'opaque' end_of_word KEYWORD_opaque <- 'opaque' end_of_word
KEYWORD_or &lt;- 'or' end_of_word KEYWORD_or <- 'or' end_of_word
KEYWORD_orelse &lt;- 'orelse' end_of_word KEYWORD_orelse <- 'orelse' end_of_word
KEYWORD_packed &lt;- 'packed' end_of_word KEYWORD_packed <- 'packed' end_of_word
KEYWORD_pub &lt;- 'pub' end_of_word KEYWORD_pub <- 'pub' end_of_word
KEYWORD_resume &lt;- 'resume' end_of_word KEYWORD_resume <- 'resume' end_of_word
KEYWORD_return &lt;- 'return' end_of_word KEYWORD_return <- 'return' end_of_word
KEYWORD_linksection &lt;- 'linksection' end_of_word KEYWORD_linksection <- 'linksection' end_of_word
KEYWORD_struct &lt;- 'struct' end_of_word KEYWORD_struct <- 'struct' end_of_word
KEYWORD_suspend &lt;- 'suspend' end_of_word KEYWORD_suspend <- 'suspend' end_of_word
KEYWORD_switch &lt;- 'switch' end_of_word KEYWORD_switch <- 'switch' end_of_word
KEYWORD_test &lt;- 'test' end_of_word KEYWORD_test <- 'test' end_of_word
KEYWORD_threadlocal &lt;- 'threadlocal' end_of_word KEYWORD_threadlocal <- 'threadlocal' end_of_word
KEYWORD_try &lt;- 'try' end_of_word KEYWORD_try <- 'try' end_of_word
KEYWORD_union &lt;- 'union' end_of_word KEYWORD_union <- 'union' end_of_word
KEYWORD_unreachable &lt;- 'unreachable' end_of_word KEYWORD_unreachable <- 'unreachable' end_of_word
KEYWORD_usingnamespace &lt;- 'usingnamespace' end_of_word KEYWORD_usingnamespace <- 'usingnamespace' end_of_word
KEYWORD_var &lt;- 'var' end_of_word KEYWORD_var <- 'var' end_of_word
KEYWORD_volatile &lt;- 'volatile' end_of_word KEYWORD_volatile <- 'volatile' end_of_word
KEYWORD_while &lt;- 'while' end_of_word KEYWORD_while <- 'while' end_of_word
keyword &lt;- KEYWORD_align / KEYWORD_allowzero / KEYWORD_and / KEYWORD_anyframe keyword <- KEYWORD_align / KEYWORD_allowzero / KEYWORD_and / KEYWORD_anyframe
/ KEYWORD_anytype / KEYWORD_asm / KEYWORD_async / KEYWORD_await / KEYWORD_anytype / KEYWORD_asm / KEYWORD_async / KEYWORD_await
/ KEYWORD_break / KEYWORD_callconv / KEYWORD_catch / KEYWORD_comptime / KEYWORD_break / KEYWORD_callconv / KEYWORD_catch / KEYWORD_comptime
/ KEYWORD_const / KEYWORD_continue / KEYWORD_defer / KEYWORD_else / KEYWORD_const / KEYWORD_continue / KEYWORD_defer / KEYWORD_else
@ -12398,11 +12412,10 @@ keyword &lt;- KEYWORD_align / KEYWORD_allowzero / KEYWORD_and / KEYWORD_anyframe
/ KEYWORD_inline / KEYWORD_noalias / KEYWORD_nosuspend / KEYWORD_noinline / KEYWORD_inline / KEYWORD_noalias / KEYWORD_nosuspend / KEYWORD_noinline
/ KEYWORD_opaque / KEYWORD_or / KEYWORD_orelse / KEYWORD_packed / KEYWORD_opaque / KEYWORD_or / KEYWORD_orelse / KEYWORD_packed
/ KEYWORD_pub / KEYWORD_resume / KEYWORD_return / KEYWORD_linksection / KEYWORD_pub / KEYWORD_resume / KEYWORD_return / KEYWORD_linksection
/ KEYWORD_struct / KEYWORD_suspend / KEYWORD_switch / KEYWORD_struct / KEYWORD_suspend / KEYWORD_switch / KEYWORD_test
/ KEYWORD_test / KEYWORD_threadlocal / KEYWORD_try / KEYWORD_threadlocal / KEYWORD_try / KEYWORD_union / KEYWORD_unreachable
/ KEYWORD_union / KEYWORD_unreachable
/ KEYWORD_usingnamespace / KEYWORD_var / KEYWORD_volatile / KEYWORD_while / KEYWORD_usingnamespace / KEYWORD_var / KEYWORD_volatile / KEYWORD_while
</code></pre> {#end_syntax_block#}
{#header_close#} {#header_close#}
{#header_open|Zen#} {#header_open|Zen#}
<ul> <ul>