127 lines
3.3 KiB
OCaml
127 lines
3.3 KiB
OCaml
|
|
||
|
|
||
|
module K = Constant
|
||
|
open Common
|
||
|
|
||
|
(* This pretty-printer based on: http:/ /en.cppreference.com/w/c/language/declarations
|
||
|
* Many cases are omitted from this bare-bones C grammar; hopefully, to be extended. *)
|
||
|
type type_spec =
|
||
|
| Int of Constant.width
|
||
|
| Void
|
||
|
| Named of ident
|
||
|
| Struct of ident option * declaration list option
|
||
|
(** Note: the option allows for zero-sized structs (GCC's C, C++) but as
|
||
|
* of 2017/05/14 we never generate these. *)
|
||
|
| Union of ident option * declaration list
|
||
|
| Enum of ident option * ident list
|
||
|
(** not encoding all the invariants here *)
|
||
|
[@@deriving show { with_path = false }]
|
||
|
|
||
|
and storage_spec =
|
||
|
| Typedef
|
||
|
| Extern
|
||
|
| Static
|
||
|
|
||
|
and declarator_and_init =
|
||
|
declarator * init option
|
||
|
|
||
|
and declarator_and_inits =
|
||
|
declarator_and_init list
|
||
|
|
||
|
and declarator =
|
||
|
| Ident of ident
|
||
|
| Pointer of declarator
|
||
|
| Array of declarator * expr
|
||
|
| Function of calling_convention option * declarator * params
|
||
|
|
||
|
and expr =
|
||
|
| Op1 of K.op * expr
|
||
|
| Op2 of K.op * expr * expr
|
||
|
| Index of expr * expr
|
||
|
| Deref of expr
|
||
|
| Address of expr
|
||
|
| Member of expr * expr
|
||
|
| MemberP of expr * expr
|
||
|
| Assign of expr * expr
|
||
|
(** not covering *=, +=, etc. *)
|
||
|
| Call of expr * expr list
|
||
|
| Name of ident
|
||
|
| Cast of type_name * expr
|
||
|
| Literal of string
|
||
|
| Constant of K.t
|
||
|
| Bool of bool
|
||
|
| Sizeof of expr
|
||
|
| SizeofType of type_spec
|
||
|
| CompoundLiteral of type_name * init list
|
||
|
| MemberAccess of expr * ident
|
||
|
| MemberAccessPointer of expr * ident
|
||
|
| InlineComment of string * expr * string
|
||
|
| Type of type_name
|
||
|
(** note: these two not in the C grammar *)
|
||
|
|
||
|
(** this is a WILD approximation of the notion of "type name" in C _and_ a hack
|
||
|
* because there's the invariant that the ident found at the bottom of the
|
||
|
* [declarator] is irrelevant... *)
|
||
|
and type_name =
|
||
|
type_spec * declarator
|
||
|
|
||
|
and params =
|
||
|
(* No support for old syntax, e.g. K&R, or [void f(void)]. *)
|
||
|
param list
|
||
|
|
||
|
and param =
|
||
|
(** Also approximate. *)
|
||
|
type_spec * declarator
|
||
|
|
||
|
and declaration =
|
||
|
type_spec * storage_spec option * declarator_and_inits
|
||
|
|
||
|
and ident =
|
||
|
string
|
||
|
|
||
|
and init =
|
||
|
| InitExpr of expr
|
||
|
| Designated of designator * init
|
||
|
| Initializer of init list
|
||
|
|
||
|
and designator =
|
||
|
| Dot of ident
|
||
|
| Bracket of int
|
||
|
|
||
|
(** Note: according to http:/ /en.cppreference.com/w/c/language/statements,
|
||
|
* declarations can only be part of a compound statement... we do not enforce
|
||
|
* this invariant via the type [stmt], but rather check it at runtime (see
|
||
|
* [mk_compound_if]), as the risk of messing things up, naturally. *)
|
||
|
type stmt =
|
||
|
| Compound of stmt list
|
||
|
| DeclStmt of declaration
|
||
|
| Expr of expr
|
||
|
| If of expr * stmt
|
||
|
| IfElse of expr * stmt * stmt
|
||
|
| While of expr * stmt
|
||
|
| For of declaration_or_expr * expr * expr * stmt
|
||
|
| Return of expr option
|
||
|
| Switch of expr * (expr * stmt) list * stmt
|
||
|
(** the last component is the default statement *)
|
||
|
| Break
|
||
|
| Comment of string
|
||
|
(** note: this is not in the C grammar *)
|
||
|
|
||
|
and program =
|
||
|
declaration_or_function list
|
||
|
|
||
|
and comment =
|
||
|
string
|
||
|
|
||
|
and declaration_or_function =
|
||
|
| Decl of comment list * declaration
|
||
|
| Function of comment list * bool * declaration * stmt
|
||
|
(** [stmt] _must_ be a compound statement; boolean is inline *)
|
||
|
|
||
|
and declaration_or_expr = [
|
||
|
| `Decl of declaration
|
||
|
| `Expr of expr
|
||
|
| `Skip
|
||
|
]
|
||
|
[@@deriving show { with_path = false }]
|