226 lines
5.5 KiB
OCaml
226 lines
5.5 KiB
OCaml
|
(*
|
||
|
Cours "Sémantique et Application à la Vérification de programmes"
|
||
|
|
||
|
Antoine Miné 2015
|
||
|
Marc Chevalier 2018
|
||
|
Josselin Giet 2021
|
||
|
Ecole normale supérieure, Paris, France / CNRS / INRIA
|
||
|
*)
|
||
|
|
||
|
(*
|
||
|
Definition of the abstract syntax trees output by the parser.
|
||
|
*)
|
||
|
|
||
|
|
||
|
(* position in the source file, we use ocamllex's default type *)
|
||
|
|
||
|
type position = Lexing.position
|
||
|
let position_unknown = Lexing.dummy_pos
|
||
|
|
||
|
|
||
|
(* extents are pairs of positions *)
|
||
|
|
||
|
type extent = position * position (* start/end *)
|
||
|
let extent_unknown = (position_unknown, position_unknown)
|
||
|
|
||
|
|
||
|
(* Many parts of the syntax are tagged with an extent indicating which
|
||
|
part of the parser-file corresponds to the sub-tree.
|
||
|
This is very useful for interesting error reporting!
|
||
|
*)
|
||
|
type 'a ext = 'a * extent
|
||
|
|
||
|
(* variable identifiers are string *)
|
||
|
type id = string
|
||
|
|
||
|
(* types of variables: only int for now *)
|
||
|
type typ =
|
||
|
(* mathematical integers, in Z *)
|
||
|
| AST_TYP_INT
|
||
|
|
||
|
|
||
|
(* unary expression operators *)
|
||
|
|
||
|
type int_unary_op =
|
||
|
| AST_UNARY_PLUS (* +e *)
|
||
|
| AST_UNARY_MINUS (* -e *)
|
||
|
|
||
|
type bool_unary_op =
|
||
|
| AST_NOT (* !e logical negation *)
|
||
|
|
||
|
|
||
|
(* binary expression operators *)
|
||
|
|
||
|
type int_binary_op =
|
||
|
| AST_PLUS (* e + e *)
|
||
|
| AST_MINUS (* e - e *)
|
||
|
| AST_MULTIPLY (* e * e *)
|
||
|
| AST_DIVIDE (* e / e *)
|
||
|
| AST_MODULO (* e % e *)
|
||
|
|
||
|
type compare_op =
|
||
|
| AST_EQUAL (* e == e *)
|
||
|
| AST_NOT_EQUAL (* e != e *)
|
||
|
| AST_LESS (* e < e *)
|
||
|
| AST_LESS_EQUAL (* e <= e *)
|
||
|
| AST_GREATER (* e > e *)
|
||
|
| AST_GREATER_EQUAL (* e >= e *)
|
||
|
|
||
|
let reverse c = match c with
|
||
|
| AST_LESS -> AST_GREATER
|
||
|
| AST_GREATER -> AST_LESS
|
||
|
| AST_LESS_EQUAL -> AST_GREATER_EQUAL
|
||
|
| AST_GREATER_EQUAL -> AST_LESS_EQUAL
|
||
|
| x -> x
|
||
|
|
||
|
let negate c = match c with
|
||
|
| AST_LESS -> AST_GREATER_EQUAL
|
||
|
| AST_GREATER -> AST_LESS_EQUAL
|
||
|
| AST_LESS_EQUAL -> AST_GREATER
|
||
|
| AST_GREATER_EQUAL -> AST_LESS
|
||
|
| AST_EQUAL -> AST_NOT_EQUAL
|
||
|
| AST_NOT_EQUAL -> AST_EQUAL
|
||
|
|
||
|
type bool_binary_op =
|
||
|
| AST_AND (* e && e *)
|
||
|
| AST_OR (* e || e *)
|
||
|
|
||
|
|
||
|
(* expressions *)
|
||
|
|
||
|
type int_expr =
|
||
|
(* unary operation *)
|
||
|
| AST_int_unary of int_unary_op * (int_expr ext)
|
||
|
|
||
|
(* binary operation *)
|
||
|
| AST_int_binary of int_binary_op * (int_expr ext) * (int_expr ext)
|
||
|
|
||
|
(* variable use *)
|
||
|
| AST_int_identifier of id ext
|
||
|
|
||
|
(* constants (integers are still in their string representation) *)
|
||
|
| AST_int_const of string ext
|
||
|
|
||
|
(* non-deterministic choice between two integers *)
|
||
|
| AST_int_rand of (string ext) (* lower bound *) *
|
||
|
(string ext) (* upper bound *)
|
||
|
|
||
|
(* calls a function with arguments and return value *)
|
||
|
| AST_expr_call of (id ext) (* function name *) *
|
||
|
(int_expr ext list) (* arguments *)
|
||
|
|
||
|
|
||
|
type bool_expr =
|
||
|
(* unary operation *)
|
||
|
| AST_bool_unary of bool_unary_op * (bool_expr ext)
|
||
|
|
||
|
(* binary operation *)
|
||
|
| AST_bool_binary of bool_binary_op * (bool_expr ext) * (bool_expr ext)
|
||
|
| AST_compare of compare_op * (int_expr ext) * (int_expr ext)
|
||
|
|
||
|
(* constants *)
|
||
|
| AST_bool_const of bool
|
||
|
|
||
|
(* non-deterministic choice *)
|
||
|
| AST_bool_rand
|
||
|
|
||
|
|
||
|
(* statements *)
|
||
|
type stat =
|
||
|
|
||
|
(* block of statements { ... } *)
|
||
|
| AST_block of stat ext list
|
||
|
|
||
|
(* assignment lvalue = expr *)
|
||
|
| AST_assign of (id ext) * (int_expr ext)
|
||
|
|
||
|
(* assignment lvalue op= expr *)
|
||
|
| AST_assign_op of (id ext) * int_binary_op * (int_expr ext)
|
||
|
|
||
|
(* increment lvalue += cst *)
|
||
|
| AST_increment of (id ext) * int
|
||
|
|
||
|
(* if-then-else; the else branch is optional *)
|
||
|
| AST_if of (bool_expr ext) (* condition *) *
|
||
|
(stat ext) (* then branch *) *
|
||
|
(stat ext option) (* optional else *)
|
||
|
|
||
|
(* while loop *)
|
||
|
| AST_while of (bool_expr ext) (* condition *) *
|
||
|
(stat ext) (* body *)
|
||
|
|
||
|
(* for loop *)
|
||
|
| AST_for of (stat ext list) (* init *) *
|
||
|
(bool_expr ext option) (* condition *) *
|
||
|
(stat ext list) (* increment *) *
|
||
|
(stat ext) (* body *)
|
||
|
|
||
|
(* assertion: fail if the boolean expression does not hold *)
|
||
|
| AST_assert of bool_expr ext
|
||
|
|
||
|
(* declaration of a local variable, live until the end of the current block *)
|
||
|
| AST_local_decl of var_decl ext
|
||
|
|
||
|
(* calls a function with arguments (no return value) *)
|
||
|
| AST_stat_call of (id ext) (* function name *) *
|
||
|
(int_expr ext list) (* arguments *)
|
||
|
|
||
|
(* exits form the function, with optional return value *)
|
||
|
| AST_return of int_expr ext option
|
||
|
|
||
|
(* exits from the innermost while loop *)
|
||
|
| AST_break of unit ext
|
||
|
|
||
|
(* empty instruction: do nothing *)
|
||
|
| AST_SKIP
|
||
|
|
||
|
(* go to a label in the function *)
|
||
|
| AST_goto of id ext
|
||
|
|
||
|
(* destination of a goto *)
|
||
|
| AST_label of id ext
|
||
|
|
||
|
|
||
|
(* declare some variables with a common type *)
|
||
|
and var_decl = (typ ext) (* type *) * (var_init list) (* variable list *)
|
||
|
|
||
|
(* each declared variable has an optional initializer *)
|
||
|
and var_init = (id ext) (* declared variable *) *
|
||
|
(int_expr ext option) (* initializer *)
|
||
|
|
||
|
|
||
|
(* function declaration
|
||
|
(no return type, all functions return void)
|
||
|
*)
|
||
|
type fun_decl =
|
||
|
{ (* function name *)
|
||
|
fun_name: id ext;
|
||
|
|
||
|
(* formal arguments, with type *)
|
||
|
fun_args: ((typ ext) * (id ext)) list;
|
||
|
|
||
|
(* type of the returned value, if any *)
|
||
|
fun_typ: typ option ext;
|
||
|
|
||
|
(* function body *)
|
||
|
fun_body: stat ext list;
|
||
|
|
||
|
(* function location *)
|
||
|
fun_ext: extent;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
(* top-level statements *)
|
||
|
type toplevel =
|
||
|
|
||
|
(* global variable declaration *)
|
||
|
| AST_global_decl of var_decl ext
|
||
|
|
||
|
(* function declaration *)
|
||
|
| AST_fun_decl of fun_decl ext
|
||
|
|
||
|
|
||
|
(* a program is a list of top-level statements *)
|
||
|
type prog = toplevel list ext
|