Skip to content

Commit

Permalink
Fix parsing for Sentinel-Terminated Exprs (#32)
Browse files Browse the repository at this point in the history
* fix parsing for some files

* tweak parsing script

* more explicit message

* fix parsing for for sentinel-terminated exprs

* simplify implementation
  • Loading branch information
resolritter authored Apr 24, 2023
1 parent 8feed70 commit d1df473
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 12 deletions.
30 changes: 28 additions & 2 deletions grammar.js
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ module.exports = grammar({
// *** Helper grammar ***
BreakLabel: ($) => seq(COLON, $.IDENTIFIER),

BlockLabel: ($) => prec.left(seq($.IDENTIFIER, COLON)),
BlockLabel: ($) => prec.left(seq(...blockLabel($))),

FieldInit: ($) =>
seq(DOT, field("field_member", $.IDENTIFIER), EQUAL, $._Expr),
Expand Down Expand Up @@ -710,12 +710,29 @@ module.exports = grammar({
$.ArrayTypeStart
),

/*
Given a sentinel-terminated expression, e.g. `foo[bar..bar: 0]`, note
how "bar: " resembles the opening of a labeled block; due to that
label-like syntax, Tree-sitter would try to parse what comes after the
COLON as a block, which would obviously fail in this case. To work
around that problem, we'll create a SentinelTerminatedExpr rule which
starts like the the BlockLabel rule (hence why they share a common
definition), but ends with an arbitrary Expr instead of a block.
BlockLabel should have preferential precedence based on its usage sites
throughout the rest of the grammar, thus this rule effectively serves
as a fallback for the former.
*/
_SentinelTerminatedExpr: ($) => choice(
seq(...blockLabel($), $._Expr),
seq($._Expr, optional(seq(COLON, $._Expr)))
),

SuffixOp: ($) =>
choice(
seq(
LBRACKET,
$._Expr,
optional(seq(DOT2, optional($._Expr), optional(seq(COLON, $._Expr)))),
optional(seq(DOT2, optional($._SentinelTerminatedExpr))),
RBRACKET
),
DOTASTERISK,
Expand Down Expand Up @@ -869,3 +886,12 @@ function keyword(rule, _) {
function sepBy(sep, rule) {
return optional(sepBy1(sep, rule));
}

/*
This rule was extracted as a function for the sake of making
_SentinelTerminatedExpr and BlockLabel share the same definition. Please check
the comment of _SentinelTerminatedExpr for more context.
*/
function blockLabel($) {
return [$.IDENTIFIER, COLON]
}
10 changes: 0 additions & 10 deletions scripts/known-parsing-failures.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
zig/test/cases/safety/slice with sentinel out of bounds - runtime len.zig
zig/test/behavior/struct.zig
zig/test/behavior/slice.zig
zig/test/behavior/array.zig
Expand All @@ -10,7 +9,6 @@ zig/lib/std/os.zig
zig/lib/std/fs.zig
zig/lib/std/mem.zig
zig/lib/std/zig/c_translation.zig
zig/lib/std/zig/system/windows.zig
zig/lib/std/os/test.zig
zig/lib/std/os/linux/bpf/btf.zig
zig/lib/std/os/linux/bpf.zig
Expand All @@ -24,19 +22,11 @@ zig/lib/std/os/uefi/protocols/edid_override_protocol.zig
zig/lib/std/os/uefi/tables/boot_services.zig
zig/lib/std/unicode.zig
zig/lib/std/Thread.zig
zig/lib/std/mem/Allocator.zig
zig/lib/std/json/test.zig
zig/lib/std/child_process.zig
zig/lib/std/macho.zig
zig/lib/std/process.zig
zig/lib/std/dwarf.zig
zig/lib/std/json.zig
zig/lib/std/c/openbsd.zig
zig/src/main.zig
zig/src/link/Wasm/Object.zig
zig/src/link/Wasm/Archive.zig
zig/src/link/MachO/Archive.zig
zig/src/Air.zig
zig/src/codegen/llvm/bindings.zig
zig/src/Autodoc.zig
zig/src/Zir.zig

0 comments on commit d1df473

Please sign in to comment.