Skip to content

Commit

Permalink
Fix nested look-ahead parsing.
Browse files Browse the repository at this point in the history
When parsing nested vectors all using look-ahead, we need to return
control back to upper level when an inner look-ahead isn't found.

This may change the error message for "normal" look-ahead parsing (see
test baseline), but the new one seems fine and potentially even
better.

Closes #1844.

(cherry picked from commit 2223f18)
  • Loading branch information
rsmmr authored and bbannier committed Oct 2, 2024
1 parent d923cc0 commit 5288622
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 8 deletions.
25 changes: 18 additions & 7 deletions spicy/toolchain/src/compiler/codegen/parser-builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1787,18 +1787,15 @@ struct ProductionVisitor : public production::Visitor {
}

auto builder_default = switch_.addDefault();
pushBuilder(builder_default);
pb->parseError("no expected look-ahead token found", p.location());
popBuilder();

if ( p.condition() )
popBuilder();

return std::make_pair(builder_alt1, builder_alt2);
return std::make_tuple(builder_alt1, builder_alt2, builder_default);
}

void operator()(const production::LookAhead* p) final {
auto [builder_alt1, builder_alt2] = parseLookAhead(*p);
auto [builder_alt1, builder_alt2, builder_default] = parseLookAhead(*p);

pushBuilder(builder_alt1);
parseProduction(*p->alternatives().first);
Expand All @@ -1807,6 +1804,8 @@ struct ProductionVisitor : public production::Visitor {
pushBuilder(builder_alt2);
parseProduction(*p->alternatives().second);
popBuilder();

pushBuilder(builder_default, [&]() { pb->parseError("no expected look-ahead token found", p->location()); });
}

void operator()(const production::Sequence* p) final {
Expand Down Expand Up @@ -1897,7 +1896,10 @@ struct ProductionVisitor : public production::Visitor {

std::shared_ptr<Builder> builder_alt1;
std::shared_ptr<Builder> builder_alt2;
auto parse = [&]() { std::tie(builder_alt1, builder_alt2) = parseLookAhead(*lah_prod); };
std::shared_ptr<Builder> builder_default;
auto parse = [&]() {
std::tie(builder_alt1, builder_alt2, builder_default) = parseLookAhead(*lah_prod);
};

// If the list field generating this While is a synchronization point, set up a try/catch block
// for internal list synchronization (failure to parse a list element tries to synchronize at
Expand All @@ -1920,10 +1922,19 @@ struct ProductionVisitor : public production::Visitor {

syncProductionNext(*p);
});

pushBuilder(builder_default,
[&]() { pb->parseError("no expected look-ahead token found", p->location()); });
}
else
else {
parse();

pushBuilder(builder_default, [&]() {
// Terminate loop.
builder()->addBreak();
});
}

pushBuilder(builder_alt1, [&]() {
// Terminate loop.
builder()->addBreak();
Expand Down
2 changes: 1 addition & 1 deletion tests/Baseline/spicy.types.vector.parse-lahead-int/output
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
[$a=[[$x=1, $y=2571], [$x=1, $y=3085]], $b=2, $c=3599]
[$a=[], $b=2, $c=3599]
[error] terminating with uncaught exception of type spicy::rt::ParseError: no expected look-ahead token found (<...>/parse-lahead-int.spicy:15:5-15:14)
[error] terminating with uncaught exception of type spicy::rt::ParseError: expecting uint8(2) (<...>/parse-lahead-int.spicy:16:8-16:18)
29 changes: 29 additions & 0 deletions tests/Baseline/spicy.types.vector.parse-lahead-nested/output
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
Test::X {
y: [
Test::Y {
z: [
Test::Z {
zb: 1
}
Test::Z {
zb: 2
}
Test::Z {
zb: 3
}
]
}
Test::Y {
z: []
}
Test::Y {
z: [
Test::Z {
zb: 1
}
]
}
]
x: x
}
21 changes: 21 additions & 0 deletions tests/spicy/types/vector/parse-lahead-nested.spicy
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# @TEST-EXEC: printf 'yz1z2z3yyz1x' | spicy-dump %INPUT >output
# @TEST-EXEC: btest-diff output
#
# @TEST-DOC: Parse two nested vectors each using look-ahead; regression test for #1844.

module Test;

type Z = unit {
: /z/;
zb: bytes &size=1;
};

type Y = unit {
: /y/;
z: Z[];
};

public type X = unit {
y: Y[];
x: /x/;
};

0 comments on commit 5288622

Please sign in to comment.