95 lines
1.8 KiB
Erlang
95 lines
1.8 KiB
Erlang
-module(gsc_ntree).
|
|
|
|
-export_type([
|
|
ntree/2, ntree/0,
|
|
nforest/2, nforest/0,
|
|
nt/2, nt/0,
|
|
nf/2, nf/0
|
|
]).
|
|
|
|
-export([
|
|
nstem/2, meta/1, kids/1,
|
|
flatten_tree/1, flatten_forest/1
|
|
]).
|
|
|
|
|
|
-include("$gsc_include/gsc.hrl").
|
|
|
|
%%=====================================================
|
|
%% API: types
|
|
%%=====================================================
|
|
|
|
% @doc stem record
|
|
-record(ns, {meta :: any(),
|
|
kids :: list(any())}).
|
|
|
|
% @doc `ntree(S, L)' is a "node tree" (meaning stems
|
|
% have values and children)
|
|
%
|
|
% for the purposes of the compiler, the key observation
|
|
% is that a flat list of tokens is already a forest
|
|
-type ntree(S, L) :: #ns{meta :: S, kids :: [ntree(S, L)]}
|
|
| L.
|
|
|
|
% @doc forest is just a list of trees
|
|
-type nforest(S, L) :: [ntree(S, L)].
|
|
|
|
|
|
% aliases
|
|
|
|
-type nt(S, L) :: ntree(S, L).
|
|
-type nf(S, L) :: nforest(S, L).
|
|
|
|
-type ntree() :: ntree(any(), any()).
|
|
-type nforest() :: [ntree()].
|
|
|
|
-type nt() :: ntree().
|
|
-type nf() :: nforest().
|
|
|
|
|
|
%%=====================================================
|
|
%% API: functions
|
|
%%=====================================================
|
|
|
|
-spec nstem(Root, Forest) -> Tree when
|
|
Root :: S,
|
|
Forest :: nforest(S, L),
|
|
Tree :: ntree(S, L),
|
|
S :: any(),
|
|
L :: any().
|
|
|
|
nstem(Root, List) ->
|
|
{ns, Root, List}.
|
|
|
|
|
|
meta(#ns{meta = M}) -> M.
|
|
kids(#ns{kids = K}) -> K.
|
|
|
|
|
|
|
|
-spec flatten_tree(Tree) -> Leafs when
|
|
Tree :: ntree(_, L),
|
|
Leafs :: [L],
|
|
L :: any().
|
|
|
|
flatten_tree(T) ->
|
|
lists:flatten(ft(T)).
|
|
|
|
|
|
|
|
-spec flatten_forest(Forest) -> Leafs when
|
|
Forest :: nforest(_, L),
|
|
Leafs :: [L],
|
|
L :: any().
|
|
|
|
flatten_forest(F) ->
|
|
lists:flatten(ff(F)).
|
|
|
|
|
|
ft(#ns{kids = F}) -> ff(F);
|
|
ft(Leaf) -> [Leaf].
|
|
|
|
ff(F) ->
|
|
[ft(T) || T <- F].
|
|
|