Traversing graphs
Vladimir Sekissov
svg@REDACTED
Wed May 25 22:16:22 CEST 2005
Good day,
vlad_dumitrescu> What I want to do is process the grammar in different ways: for example,
vlad_dumitrescu> simplifying it or eliminating unreferenced productions. Most of the times,
vlad_dumitrescu> it's easy to traverse everything, but there are some special cases, where I
vlad_dumitrescu> have to propagate production attributes "upwards".
vlad_dumitrescu> I think I didn't see those before because I was locked on
vlad_dumitrescu> finding a completely functional solution. It should be possible and now it
vlad_dumitrescu> has become an intellectual chalenge.
May be it could be easier with continuation-passing style because you
don't know every time at upper level would you have some productions to
propagate later or not. Something like this(in pseudocode):
traverse_node({Node, Content}, UpperCont) ->
PartResult = make_what_I_can_at_this_moment(Node),
CurrentCont =
fun (V) ->
compute_node(V, UpperCont, PartResult)
end,
traverse_content(Content, CurrentCont, []).
traverse_content([], NodeCont, Acc) ->
NodeCont({nomore, lists:reverse(Acc)});
traverse_content([TreeNode|Rest], NodeCont, Acc) ->
Cont = fun (V) ->
compute_content_node(V, NodeCont, Rest, Acc)
end,
traverse_node(TreeNode, Cont).
%% node traversing finished
compute_content_node({nomore, Result}, UpperCont, Rest, Acc) ->
%% continue with rest of nodes
traverse_content(Rest, UpperCont, [Result|Acc]);
%% it is the intermediate result, feed it to upper level and return
%% new continuation to the current
compute_content_node(Other, UpperCont, Rest, Acc) ->
NxtUpperCont = UpperCont(Other),
fun (V) ->
compute_content_node(V, NxtUpperCont, Rest, Acc)
end.
compute_node(V, UpperCont, PartResult) ->
case V of
%% lower level finished, we too
{nomore, Result} ->
finish_computation(Result, PartResult),
UpperCont({nomore, finish_computation(Result, PartResult)});
%% do intermidiate computation, return next continuation
ForMe ->
NxtResult = part_computation(ForMe, PartResult),
fun (NxtV) ->
compute_node(NxtV, UpperCont, NxtResult)
end;
%% propogate information to upper level, return next continuation
ForYou ->
NxtUpperCont = UpperCont(ForYou),
fun (NxtV) ->
compute_node(NxtV, NxtUpperCont, PartResult)
end
end.
Best Regards,
Vladimir Sekissov
More information about the erlang-questions
mailing list