open Genlex

type instr = S of string | C of string * instr list

let lexer = make_lexer [ "i"; "n"; "["; "]" ]

let rec build_instr = 
  let rec parse_comp s = parser
    | [< 'Kwd "["; (b, il) = build_ilist; 'Kwd "]" >]
      -> (b, C(s, if b then il else []))
  and parse_optbrack s = parser
    | [< p = parse_comp s >] -> p
    | [< >] -> (s = "i", S s)
  in parser
      | [< 'Kwd "i" ; p = parse_optbrack "i" >] -> p
      | [< 'Kwd "n" ; p = parse_optbrack "n" >] -> p
      | [< 'Ident s; p = parse_comp s >] -> p
and build_ilist = parser
  | [< (b1, h) = build_instr; (b2, t) = build_ilist >] -> (b1 || b2, h :: t)
  | [< >] -> (false, [])

let rec print = function
  | C (name, il) ->
    print_string name; print_string " [ "; List.iter print il; print_string "] "
  | S s -> print_string s; print_char ' '

let () = List.iter print (snd (build_ilist (lexer (Stream.of_channel stdin))))

This document was generated using caml2html