| Ast.Below (p1, p2) -> aux p1 @ [NoBinding, gram_symbol "\\below"] @ aux p2
| Ast.Above (p1, p2) -> aux p1 @ [NoBinding, gram_symbol "\\above"] @ aux p2
| Ast.Frac (p1, p2) -> aux p1 @ [NoBinding, gram_symbol "\\frac"] @ aux p2
+ | Ast.InfRule (p1, p2, p3) -> [NoBinding, gram_symbol "\\infrule"] @ aux p1 @ aux p2 @ aux p3
| Ast.Atop (p1, p2) -> aux p1 @ [NoBinding, gram_symbol "\\atop"] @ aux p2
| Ast.Over (p1, p2) -> aux p1 @ [NoBinding, gram_symbol "\\over"] @ aux p2
| Ast.Root (p1, p2) ->
| Ast.Break -> []
| Ast.Box (_, pl) -> List.flatten (List.map aux pl)
| Ast.Group pl -> List.flatten (List.map aux pl)
+ | Ast.Mstyle (_,pl) -> List.flatten (List.map aux pl)
and aux_magic magic =
match magic with
| Ast.Opt p ->
type rule_id = Grammar.token Gramext.g_symbol list
+let compare_rule_id x y =
+ let rec aux = function
+ | [],[] -> 0
+ | [],_ -> ~-1
+ | _,[] -> 1
+ | ((s1::tl1) as x),((s2::tl2) as y) ->
+ if Gramext.eq_symbol s1 s2 then aux (tl1,tl2)
+ else Pervasives.compare x y
+ in
+ aux (x,y)
+
(* mapping: rule_id -> owned keywords. (rule_id, string list) Hashtbl.t *)
let owned_keywords = Hashtbl.create 23
| Ast.Below (p1, p2) -> let p1 = aux p1 in let p2 = aux p2 in Ast.Below (p1, p2)
| Ast.Above (p1, p2) -> let p1 = aux p1 in let p2 = aux p2 in Ast.Above (p1, p2)
| Ast.Frac (p1, p2) -> let p1 = aux p1 in let p2 = aux p2 in Ast.Frac (p1, p2)
+ | Ast.InfRule (p1, p2, p3) -> let p1 = aux p1 in let p2 = aux p2 in let p3 = aux p3 in Ast.InfRule (p1, p2, p3)
| Ast.Atop (p1, p2) -> let p1 = aux p1 in let p2 = aux p2 in Ast.Atop (p1, p2)
| Ast.Over (p1, p2) -> let p1 = aux p1 in let p2 = aux p2 in Ast.Over (p1, p2)
| Ast.Root (p1, p2) -> let p1 = aux p1 in let p2 = aux p2 in Ast.Root (p1, p2)
| Ast.Break as t -> t
| Ast.Box (b, pl) -> Ast.Box(b, List.map aux pl)
| Ast.Group pl -> Ast.Group (List.map aux pl)
+ | Ast.Mstyle (l,pl) -> Ast.Mstyle (l, List.map aux pl)
and aux_magic magic =
match magic with
| Ast.Opt p -> Ast.Opt (aux p)
| "ident"; id = IDENT -> Ast.IdentVar id
]
];
+ mstyle: [
+ [ id = IDENT;
+ v = [ IDENT | NUMBER | COLOR | FLOATWITHUNIT ] -> id, v]];
l1_simple_pattern:
[ "layout" LEFTA
[ p1 = SELF; SYMBOL "\\sub"; p2 = SELF ->
| p1 = SELF; SYMBOL "\\atop"; p2 = SELF ->
return_term_of_level loc
(fun l -> Ast.Layout (Ast.Atop (p1 l, p2 l)))
- | SYMBOL "\\frac"; p1 = SELF; p2 = SELF ->
+ | p1 = SELF; SYMBOL "\\frac"; p2 = SELF ->
return_term_of_level loc
(fun l -> Ast.Layout (Ast.Frac (p1 l, p2 l)))
+ | SYMBOL "\\infrule"; p1 = SELF; p2 = SELF; p3 = SELF ->
+ return_term_of_level loc
+ (fun l -> Ast.Layout (Ast.InfRule (p1 l, p2 l, p3 l)))
| SYMBOL "\\sqrt"; p = SELF ->
return_term_of_level loc (fun l -> Ast.Layout (Ast.Sqrt p l))
| SYMBOL "\\root"; index = SELF; SYMBOL "\\of"; arg = SELF ->
return_term_of_level loc
(fun l -> Ast.Layout (Ast.Box ((Ast.HOV, false, false), p l)))
| "break" -> return_term_of_level loc (fun _ -> Ast.Layout Ast.Break)
+ | "mstyle"; m = LIST1 mstyle ; LPAREN; t = l1_pattern; RPAREN ->
+ return_term_of_level loc
+ (fun l ->
+ Ast.Layout (Ast.Mstyle (m, t l)))
| LPAREN; p = l1_pattern; RPAREN ->
return_term_of_level loc (fun l -> CicNotationUtil.group (p l))
]
];
binder: [
[ SYMBOL <:unicode<Pi>> (* Π *) -> `Pi
-(* | SYMBOL <:unicode<exists>> |+ ∃ +| -> `Exists *)
| SYMBOL <:unicode<forall>> (* ∀ *) -> `Forall
| SYMBOL <:unicode<lambda>> (* λ *) -> `Lambda
]
[
[ b = binder; (vars, typ) = maybe_protected_binder_vars; SYMBOL "."; body = term LEVEL "19" ->
return_term loc (fold_cluster b vars typ body)
- | SYMBOL <:unicode<exists>> (* ∃ *);
- (vars, typ) = maybe_protected_binder_vars; SYMBOL "."; body = term LEVEL "19"->
- return_term loc (fold_exists vars typ body)
]
];
term: LEVEL "70"