expr: expr_p0 { $1 } ;; expr_p0: expr_p0 EQEQ expr_p1 { EQEQ_TREE ($1,$3) } | expr_p0 GT expr_p1 { GT_TREE ($1,$3) } | expr_p0 LT expr_p1 { GT_TREE ($3,$1) } | expr_p0 GE expr_p1 { GE_TREE ($1,$3) } | expr_p0 LE expr_p1 { GE_TREE ($3,$1) } | expr_p1 { $1 } ;; expr_p1: expr_p1 PLUS expr_p2 { PLUS_TREE ($1,$3) } | expr_p1 MINUS expr_p2 { MINUS_TREE ($1,$3) } | expr_p2 { $1 } ;; expr_p2: expr_p2 TIMES expr_p3 { TIMES_TREE ($1,$3) } | expr_p3 { $1 } ;; expr_p3: LPAREN expr_p0 RPAREN { $2 } | ID { ID_TREE $1 } | INT { INT_TREE $1 }
W tym przypadku priorytety operatorów zdefiniowano bezpośrednio na poziomie gramatyki. Można użyć zamiast tego analogicznie jak w yacc deklaracji %left, %right, %nonassoc i %prec
stmt_a1 i stmt_a2 rozwiązują interesujący dangling else problem i są warte specjalnej uwagi.
program.ml Plik program.ml zawiera wnętrzności programu. Nie są one interesujące z punktu widzenia budowy parsera, jednak należy je zamieścić ze względu na kompletność helloworlda.
Typy xtree - drzewo przedstawiające wyrażenie i stree - drzewo przedstawiające polecenie są używane przez parser.
(* autohash *) type autohash = { autohash_last: int ref; autohash_h:(string,int)Hashtbl.t;