EBNF: adv [=[ escapedgarbage = "!" . garbage-elem = !(">") ( escapedgarbage~ | . ) garbage = "<" (garbage-elem* => [[ flatten ]]) ">" elem = garbage | groups nonemptygroups = elem (","~ elem)* => [[ first2 swap suffix ]] groups = "{" nonemptygroups? "}" ]=] : cost ( level node -- cost ) dup first "<" = [ 2drop 0 ] [ [ dup 1 + ] dip second [ cost ] with map-sum + ] if ; : p1 ( str -- cost ) adv 1 swap cost ; : garbage-count ( node -- count ) dup first "<" = [ second length ] [ second [ garbage-count ] map-sum ] if ; : p2 ( str -- cost ) adv garbage-count ;