/**
 * Implosion of lexical syntax.
 */
module stratego/asfix/implode/lexical
strategies

  ImplodeLexical =
    ?appl(prod([lex(_)],cf(_),_), _)
    ; asfix-yield-appl

  ImplodeLexical =
    ?appl(prod(_,lex(_),_), _)
    ; asfix-yield-appl

  ImplodeLexical =
    ?appl(prod(_,lit(_),_),_)
    ; asfix-yield-appl

  ImplodeLexical =
    ?appl(prod(_,cilit(_),_),_)
    ; asfix-yield-appl

  ImplodeLexical =
    ImplodeLexicalListVar <+ ImplodeLexicalVar
    
  ImplodeLexicalListVar =
    ?appl(prod(_,varsym(cf(iter-star(_))),_),_)
    ; !meta-listvar(<asfix-yield-appl>)

  ImplodeLexicalListVar =
    ?appl(prod(_,varsym(cf(iter-star-sep(_,_))),_),_)
    ; !meta-listvar(<asfix-yield-appl>)

  ImplodeLexicalListVar =
    ?appl(prod(_,varsym(cf(iter(_))),_),_)
    ; !meta-listvar(<asfix-yield-appl>)

  ImplodeLexicalListVar =
    ?appl(prod(_,varsym(cf(iter-sep(_,_))),_),_)
    ; !meta-listvar(<asfix-yield-appl>)

  ImplodeLexicalVar =
    ?appl(prod(_,varsym(_),_),_)
    ; !meta-var(<asfix-yield-appl>)

strategies

  /**
   * The yield of an AsFixTerm is the string consisting of the
   * characters at the leaves of the tree.
   */
  asfix-yield-appl =
    let yield(|chars) =
            asfix-yield-acc(yield | chars)

     in ?appl(_, <id>){anno*}
      ; yield(|[])
      ; implode-string
      ; ?s
      ; !s{anno*}
    end

  asfix-yield-acc(rec : b * c -> d | acc) :
    appl(_, ts) -> acc'
    where
      acc' := <rec(|acc)> ts

  asfix-yield-acc(rec : b * c -> d |acc) :
    [] -> acc

  asfix-yield-acc(rec : b * c -> d | acc) :
    [x | xs] -> acc''
    where
      acc' := <rec(|acc)> xs
    ; acc'' := <rec(|acc')> x

  asfix-yield-acc(rec : b * c -> d | acc) :
    i -> [i | acc]
    where
      is-int