Skip to content

Commit fa28e91

Browse files
authored
Merge pull request #19 from ARCJ137442/master
Detailed message for "rule unreachable" error
2 parents 5c85452 + 7c306a1 commit fa28e91

File tree

3 files changed

+31
-2
lines changed

3 files changed

+31
-2
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "PikaParser"
22
uuid = "3bbf5609-3e7b-44cd-8549-7c69f321e792"
33
authors = ["The developers of PikaParser.jl"]
4-
version = "0.6.0"
4+
version = "0.6.1"
55

66
[deps]
77
DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"

src/grammar.jl

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,15 @@ function make_grammar(
4242
end
4343
end
4444

45-
all(opened .> 0) || error("some grammar rules not reachable from starts")
45+
# At this point, all rules should be opened at least once. If some grammar
46+
# rules are unreachable from the starts, report them explicitly in the
47+
# error message to ease the debugging.
48+
if !all(opened .> 0)
49+
unreachable_names = map(Base.first, rules)[opened.==0]
50+
error(
51+
"grammar rules not reachable from starts: $(join(repr.(unreachable_names), ", "))",
52+
)
53+
end
4654

4755
reordered = rules[topo_order]
4856

test/clauses.jl

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,27 @@ end
9090
@test_throws DomainError P.flatten(rules, Char)
9191
end
9292

93+
@testset "Unreachable rules are reported" begin
94+
rules = Dict(:xxx => P.seq(:yyy, P.fail), :yyy => P.epsilon, :zzz => P.epsilon)
95+
96+
@test_throws ErrorException P.make_grammar([:xxx], P.flatten(rules, Char))
97+
@test begin
98+
# this should simply not throw anything
99+
P.make_grammar([:xxx, :zzz], P.flatten(rules, Char))
100+
true
101+
end
102+
103+
@test try
104+
P.make_grammar([:xxx], P.flatten(rules, Char))
105+
catch e
106+
b = IOBuffer()
107+
showerror(b, e)
108+
errorstring = String(take!(b))
109+
110+
(occursin(":zzz", errorstring) && all(!occursin(errorstring), [":xxx", ":yyy"]))
111+
end
112+
end
113+
93114
@testset "Corner-case epsilon matches" begin
94115
str = "whateveρ"
95116

0 commit comments

Comments
 (0)