type token = LPAR | RPAR | LAPAR | RAPAR | LSPAR | RSPAR | PLUS | MID | PARAM of char list | NONTERM of char list | TERM of char list let rec spaces = parser [< ' (' ' | '\t' | '\n'); _ = spaces >] -> () | [< >] -> () let nonterm c = let rec nonterm_rec l = parser [< ' ('a'..'z' | 'A'..'Z' | '0'..'9' | '-' | '_') as c; s = nonterm_rec (c :: l) >] -> s | [< >] -> NONTERM l in nonterm_rec [c] let term = let rec term_rec l = parser [< ' ('\033'..'\038' | '\040'..'\091' | '\093'..'\126') as c; s = term_rec (c :: l) >] -> s | [< ' ('\\'); 'c; s = term_rec (c::l) >] -> s | [< >] -> TERM l in term_rec [] let param = let rec param_rec l = parser [< ' ('\033'..'\061' | '\063'..'\091' | '\093'..'\126') as c; s = param_rec (c :: l) >] -> s | [< ' ('\\'); 'c; s = param_rec (c :: l) >] -> s | [< >] -> PARAM l in param_rec [] let rec lexer str = (spaces str; match str with parser [< ' ('('); _ = spaces >] -> [< 'LPAR; lexer str >] | [< ' (')'); _ = spaces >] -> [< 'RPAR; lexer str >] | [< ' ('{'); _ = spaces >] -> [< 'LAPAR; lexer str >] | [< ' ('}'); _ = spaces >] -> [< 'RAPAR; lexer str >] | [< ' ('['); _ = spaces >] -> [< 'LSPAR; lexer str >] | [< ' (']'); _ = spaces >] -> [< 'RSPAR; lexer str >] | [< ' ('+'); _ = spaces >] -> [< 'PLUS; lexer str >] | [< ' ('|'); _ = spaces >] -> [< 'MID; lexer str >] | [< ' ('\''); tok = term; ' ('\''); _ = spaces >] -> [< 'tok; lexer str >] | [< ' ('<'); tok = param; ' ('>'); _ = spaces >] -> [< 'tok; lexer str >] | [< ' ('a'..'z' | 'A'..'Z' | '0'..'9' | '-' | '_') as c; tok = nonterm c; _ = spaces >] -> [< 'tok; lexer str >] )