Skip to content

Commit

Permalink
Fix EBNF to BNF conversion bug.
Browse files Browse the repository at this point in the history
Expression trees with identical contents were not hashed identically.
This meant that dictionary keyed by Tree did not recognise when
a tree was already present.
  • Loading branch information
James.Hester committed May 1, 2023
1 parent 924c18e commit 4b34e1c
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 5 deletions.
7 changes: 5 additions & 2 deletions src/load_grammar.jl
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ const RULES = Dict(

mutable struct EBNF_to_BNF <: Transformer_InPlace
new_rules::Array{Tuple{String,Tree,Any}}
rules_by_expr::Dict{Union{String,LarkSymbol,Tree},NonTerminal}
rules_by_expr::Dict{Union{String,LarkSymbol,Tree}, NonTerminal}
prefix::String
i::Int
rule_options::Union{Nothing,RuleOptions}
Expand Down Expand Up @@ -640,7 +640,10 @@ compile(g::Grammar, start, terminals_to_keep) = begin
ebnf_to_bnf.prefix = name
anon_tokens_transf.rule_options = rule_options
tree = transform(transformer,rule_tree)
push!(rules,(name, transform(ebnf_to_bnf,tree), options))
@debug "After anon transf" name tree
res = transform(ebnf_to_bnf,tree)
@debug "After bnf transf" res
push!(rules,(name, res, options))
end

append!(rules, ebnf_to_bnf.new_rules)
Expand Down
3 changes: 3 additions & 0 deletions src/parsers/grammar_analysis.jl
Original file line number Diff line number Diff line change
Expand Up @@ -218,9 +218,11 @@ expand_rule(g::GrammarAnalyzer,source_rule, rules_by_origin=nothing) = begin
_expand_rule(_rule) = begin
Channel() do rule_chan
#@assert !_rule.is_term _rule
@debug "Expanding" _rule
for r in rules_by_origin[_rule]
init_ptr = RulePtr(r,0)
push!(init_ptrs,init_ptr)
@debug "Added rule" init_ptr

if !isempty(r.expansion)
# Next symbol from this
Expand All @@ -236,5 +238,6 @@ expand_rule(g::GrammarAnalyzer,source_rule, rules_by_origin=nothing) = begin

_ = collect(bfs([source_rule], _expand_rule))

@debug "Final rules after expansion" init_ptrs
return init_ptrs
end
9 changes: 8 additions & 1 deletion src/parsers/lalr_analysis.jl
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,11 @@ compute_lr0_states(l::LALR_Analyzer) = begin
end
push!(l.lr0_states,state)
end
@debug "Number of lr0 start states" length(l.lr0_start_states)
@debug "Start states: $(l.lr0_start_states)"
collect(bfs(values(l.lr0_start_states),step))
#println("lr0_states after: $(l.lr0_states)")
@debug "Number of lr0 states" length(l.lr0_states)
@debug "lr0_states after:" l.lr0_states
end

compute_reads_relations(l::LALR_Analyzer) = begin
Expand Down Expand Up @@ -294,22 +297,26 @@ end
compute_lalr1_states(l::LALR_Analyzer) = begin
m = IdDict{LR0ItemSet,IdDict{String,Tuple{Symbol,Union{Set{RulePtr},Rule}}}}()
reduce_reduce = []
@debug "Have $(length(l.lr0_states)) states"
for state in l.lr0_states
actions = IdDict{LarkSymbol,Tuple{Symbol,Union{Set{RulePtr},Rule}}}()
for (la, next_state) in state.transitions
actions[la] = (:shift, next_state.closure)
end

for (la, rules) in state.lookaheads
@debug "State" state
if length(rules) > 1
# Try to resolve conflict based on priority
p = [(r.options.priority !== nothing ? r.options.priority : 0, r) for r in rules]
sort!(p,by=r -> r[1], rev=true)
best, second_best = p[1:2]
@debug "Conflict:" state la p
if best[1] > second_best[1]
rules = [best[2]]
else
push!(reduce_reduce,(state, la, rules))
@debug "Reduce/reduce conflict" reduce_reduce[end]
end
end
if la in keys(actions)
Expand Down
8 changes: 6 additions & 2 deletions src/tree.jl
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,12 @@ end
end
==#

Base.hash(t1::Tree) = begin
return hash(t1.data,hash(t1.children))
Base.hash(t1::Tree,h::UInt) = begin
h = hash(t1.data,h)
for t in t1.children
h = hash(t, h)
end
return h
end

find_pred(t::Tree,pred) = begin
Expand Down

0 comments on commit 4b34e1c

Please sign in to comment.