1.3. Abstract syntax and parser
-
CoreCpp.Ty[complete] -
CoreCpp.UnOp[complete] -
CoreCpp.BinOp[complete] -
CoreCpp.Param[complete] -
CoreCpp.Expr[complete] -
CoreCpp.Cmd[complete] -
CoreCpp.Fun[complete] -
CoreCpp.Vis[complete] -
CoreCpp.Field[complete] -
CoreCpp.Method[complete] -
CoreCpp.Ctor[complete] -
CoreCpp.Dtor[complete] -
CoreCpp.ClassDecl[complete] -
CoreCpp.Decl[complete] -
CoreCpp.Program[complete]
The abstract syntax is the tree form of the grammar of Definition 1.2.1, with one inductive type or structure per class of nonterminals. It has no parentheses and no precedence, because the tree fixes the structure. The table below gives the alternatives of every constructor of Syntax.lean, in the order of the file, with the constructor in the right column.
The type Ty has the basic types int, bool and void, class types, pointer types, the types of the library such as std::vector<int>, function types, and \mathsf{nullptr\_t}, the internal type of nullptr.
The type UnOp has ! and unary -, and the type BinOp has the arithmetic, the comparison and the logical operators.
The type Expr has literals and variables, operators and the conditional, and three calls, of a named function, of a method and of a function value. It has the two forms of new, this, field access through . and ->, dereference and indexing, and the lambda.
The last two constructors, locOf and intrinsic, are forms no program writes, and the function Typing.annotate of the type checker inserts both. The form locOf e is the location of e as a value, on the return of a member that returns a reference. The form intrinsic L u args is a use u of the entity L of the library.
The type Cmd has the block, if, while, for and return, the declarations with a type, with a reference and with auto, the assignment, the expression statement and delete.
A Param may be by reference. A Fun has a return type, a name, parameters and a body. A Vis is public or private.
A member is a Field, a Method, a Ctor or a Dtor. A method also records whether it is virtual, whether it overrides and whether it returns a reference, and a destructor records whether it is virtual. A ClassDecl has a qualified name, an optional base, fields and methods with their visibility, at most one constructor and at most one destructor.
A Decl is a class, a function, a class template, or a class template or a function of the library declared without a body. A Program is a list of declarations.
\begin{array}{lcll} \textit{Ty} & ::= & \mathtt{int} \mid \mathtt{bool} \mid \mathtt{void} & \textsf{Ty.int, bool, void} \\ & \mid & C \mid \textit{Ty}\mathtt{*} & \textsf{cls, ptr} \\ & \mid & \mathtt{std{:}{:}}L\langle\textit{Ty}_1, \ldots, \textit{Ty}_k\rangle \mid \textit{Ty}(\textit{Ty}_1, \ldots, \textit{Ty}_k) & \textsf{lib, fn} \\ & \mid & \mathsf{nullptr\_t} & \textsf{nullT} \\ \textit{UnOp} & ::= & \mathtt{!} \mid \mathtt{-} & \textsf{UnOp.not, neg} \\ \textit{BinOp} & ::= & \mathtt{+} \mid \mathtt{-} \mid \mathtt{*} \mid \mathtt{/} \mid \mathtt{\%} & \textsf{BinOp.add} \ldots \textsf{mod} \\ & \mid & \mathtt{==} \mid \mathtt{!=} \mid \mathtt{<} \mid \mathtt{<=} \mid \mathtt{>} \mid \mathtt{>=} & \textsf{eq} \ldots \textsf{ge} \\ & \mid & \mathtt{\&\&} \mid \mathtt{||} & \textsf{and, or} \\ \textit{Param} & ::= & \textit{Ty}\ x \mid \textit{Ty}\mathtt{\&}\ x & \textsf{Param} \\ \textit{Expr} & ::= & n \mid b & \textsf{Expr.intLit, boolLit} \\ & \mid & \mathtt{nullptr} \mid x & \textsf{nullptr, var} \\ & \mid & \textit{UnOp}\, \textit{Expr} \mid \textit{Expr}_1 \textit{BinOp} \textit{Expr}_2 & \textsf{unop, binop} \\ & \mid & \textit{Expr}_1\ \mathtt{?}\ \textit{Expr}_2\ \mathtt{:}\ \textit{Expr}_3 & \textsf{cond} \\ & \mid & f(\textit{Expr}_1, \ldots, \textit{Expr}_k) & \textsf{call} \\ & \mid & \mathtt{new}\ C(\textit{Expr}_1, \ldots, \textit{Expr}_k) & \textsf{newObj} \\ & \mid & \mathtt{new}\ \mathtt{std{:}{:}}L\langle\textit{Ty}_1, \ldots, \textit{Ty}_k\rangle & \textsf{newLib} \\ & & \qquad (\textit{Expr}_1, \ldots, \textit{Expr}_n) & \\ & \mid & \mathtt{this} & \textsf{this} \\ & \mid & \textit{Expr}.m(\textit{Expr}_1, \ldots, \textit{Expr}_k) & \textsf{methodCall} \\ & & \qquad \mid \textit{Expr}\texttt{->}m(\textit{Expr}_1, \ldots, \textit{Expr}_k) & \\ & \mid & \textit{Expr}.f \mid \textit{Expr}\texttt{->}f & \textsf{field, arrow} \\ & \mid & \mathtt{*}\textit{Expr} \mid \textit{Expr}_1[\textit{Expr}_2] & \textsf{deref, index} \\ & \mid & \mathtt{[=]}(\textit{Param}_1, \ldots, \textit{Param}_k)\ \texttt{->}\ \textit{Ty} & \textsf{lambda} \\ & & \qquad \{\, \textit{Cmd}_1 \ldots \textit{Cmd}_n \,\} & \\ & \mid & \textit{Expr}(\textit{Expr}_1, \ldots, \textit{Expr}_k) & \textsf{callFn} \\ & \mid & \mathsf{locOf}\ \textit{Expr} & \textsf{locOf} \\ & \mid & L.u(\textit{Expr}_1, \ldots, \textit{Expr}_k) & \textsf{intrinsic} \\ \textit{Cmd} & ::= & \{\, \textit{Cmd}_1 \ldots \textit{Cmd}_n \,\} & \textsf{Cmd.block} \\ & \mid & \mathtt{if}\ (\textit{Expr})\ \{\, \textit{Cmd}_1 \ldots \textit{Cmd}_n \,\} & \textsf{ite} \\ & & \qquad \mathtt{else}\ \{\, \textit{Cmd}'_1 \ldots \textit{Cmd}'_m \,\} & \\ & \mid & \mathtt{while}\ (\textit{Expr})\ \{\, \textit{Cmd}_1 \ldots \textit{Cmd}_n \,\} & \textsf{while} \\ & \mid & \mathtt{for}\ (\textit{Cmd}_0;\ \textit{Expr};\ \textit{Cmd}_s) & \textsf{for} \\ & & \qquad \{\, \textit{Cmd}_1 \ldots \textit{Cmd}_n \,\} & \\ & \mid & \mathtt{return} \mid \mathtt{return}\ \textit{Expr} & \textsf{ret} \\ & \mid & \textit{Ty}\ x = \textit{Expr} \mid \textit{Ty}\mathtt{\&}\ x = \textit{Expr} & \textsf{decl, declRef} \\ & \mid & \mathtt{auto}\ x = \textit{Expr} & \textsf{declAuto} \\ & \mid & \textit{Expr}_1 = \textit{Expr}_2 & \textsf{assign} \\ & \mid & \textit{Expr}; & \textsf{exprStmt} \\ & \mid & \mathtt{delete}\ \textit{Expr} & \textsf{delete} \\ \textit{Fun} & ::= & \textit{Ty}\ f(\textit{Param}_1, \ldots, \textit{Param}_k) & \textsf{Fun} \\ & & \qquad \{\, \textit{Cmd}_1 \ldots \textit{Cmd}_n \,\} & \\ \textit{Vis} & ::= & \mathtt{public} \mid \mathtt{private} & \textsf{Vis.pub, priv} \\ \textit{Member} & ::= & \textit{Ty}\ f; & \textsf{Field} \\ & \mid & \textit{Ty}\ m(\textit{Param}_1, \ldots, \textit{Param}_k) & \textsf{Method} \\ & & \qquad \{\, \textit{Cmd}_1 \ldots \textit{Cmd}_n \,\} & \\ & \mid & C(\textit{Param}_1, \ldots, \textit{Param}_k)\ \{\, \textit{Cmd}_1 \ldots \textit{Cmd}_n \,\} & \textsf{Ctor} \\ & \mid & \mathtt{\sim}C()\ \{\, \textit{Cmd}_1 \ldots \textit{Cmd}_n \,\} & \textsf{Dtor} \\ \textit{ClassDecl} & ::= & \mathtt{class}\ C\ (\mathtt{:}\ \mathtt{public}\ B)^{?} & \textsf{ClassDecl} \\ & & \qquad \{\, \textit{Member}_1 \ldots \textit{Member}_n \,\} & \\ \textit{Decl} & ::= & \textit{ClassDecl} \mid \textit{Fun} & \textsf{Decl.cls, fn} \\ & \mid & \mathtt{template}\ \langle\mathtt{typename}\ T\rangle\ \textit{ClassDecl} & \textsf{tmpl} \\ & \mid & \mathtt{template}\ \langle\mathtt{typename}\ T_1, \ldots, \mathtt{typename}\ T_k\rangle & \textsf{libTmpl} \\ & & \qquad \mathtt{class}\ L; & \\ & \mid & \textit{Ty}\ f(\textit{Param}_1, \ldots, \textit{Param}_k); & \textsf{libFn} \\ \textit{Program} & ::= & \textit{Decl}_1 \ldots \textit{Decl}_n & \textsf{Program} \end{array}
The symbols on the left are the nonterminals of this grammar, each named after the type of Syntax.lean it describes. The nonterminal Member stands for the four structures Field, Method, Ctor and Dtor.
The rules of the typing and of the evaluation abbreviate them, τ for a Ty, e for an Expr, c for a Cmd and p for a Param, and a subscript tells two occurrences apart.
Inside the productions, n stands for an integer literal and b for a boolean one, x for a variable, f for a field or a function, m for a method and u for an intrinsic, all of them written as a VarId, and C for a class, B for a base, T for a template parameter and L for a library class, all of them written as a TypeId.
The right column names, for each alternative, the constructor of the inductive type of Syntax.lean that the alternative builds, Expr.intLit for a literal and Cmd.block for a block. The type is written out on the first line of a category and only the constructor afterwards.
A constructor here is a case of an inductive definition of Lean, and not the member of a class that new runs, which this table calls Ctor.
Every field and every method carries a Vis, which the parser takes from the section that holds it. The constructor and the destructor are public and carry no visibility.
Lean code for Definition1.3.1●15 definitions
Associated Lean declarations
-
CoreCpp.Ty[complete]
-
CoreCpp.UnOp[complete]
-
CoreCpp.BinOp[complete]
-
CoreCpp.Param[complete]
-
CoreCpp.Expr[complete]
-
CoreCpp.Cmd[complete]
-
CoreCpp.Fun[complete]
-
CoreCpp.Vis[complete]
-
CoreCpp.Field[complete]
-
CoreCpp.Method[complete]
-
CoreCpp.Ctor[complete]
-
CoreCpp.Dtor[complete]
-
CoreCpp.ClassDecl[complete]
-
CoreCpp.Decl[complete]
-
CoreCpp.Program[complete]
-
CoreCpp.Ty[complete] -
CoreCpp.UnOp[complete] -
CoreCpp.BinOp[complete] -
CoreCpp.Param[complete] -
CoreCpp.Expr[complete] -
CoreCpp.Cmd[complete] -
CoreCpp.Fun[complete] -
CoreCpp.Vis[complete] -
CoreCpp.Field[complete] -
CoreCpp.Method[complete] -
CoreCpp.Ctor[complete] -
CoreCpp.Dtor[complete] -
CoreCpp.ClassDecl[complete] -
CoreCpp.Decl[complete] -
CoreCpp.Program[complete]
-
inductivedefined in CoreCpp/Syntax.leancomplete
inductive CoreCpp.Ty : Type
inductive CoreCpp.Ty : Type
Types. `cls` is a class type, reached only through a pointer, `ptr` a pointer type, `lib n args` an instance of a class template `n` of the library, such as `std::vector<int>`, `fn ret params` the function type `ret(params)`, the argument of `std::function`, and `nullT` the type of `nullptr`, which converts to any pointer type and never names a variable.
Constructors
CoreCpp.Ty.int : CoreCpp.Ty
CoreCpp.Ty.bool : CoreCpp.Ty
CoreCpp.Ty.void : CoreCpp.Ty
CoreCpp.Ty.cls (name : String) : CoreCpp.Ty
CoreCpp.Ty.ptr (t : CoreCpp.Ty) : CoreCpp.Ty
CoreCpp.Ty.lib (name : String) (args : List CoreCpp.Ty) : CoreCpp.Ty
CoreCpp.Ty.fn (ret : CoreCpp.Ty) (params : List CoreCpp.Ty) : CoreCpp.Ty
CoreCpp.Ty.nullT : CoreCpp.Ty
-
inductivedefined in CoreCpp/Syntax.leancomplete
inductive CoreCpp.UnOp : Type
inductive CoreCpp.UnOp : Type
Constructors
CoreCpp.UnOp.not : CoreCpp.UnOp
CoreCpp.UnOp.neg : CoreCpp.UnOp
-
inductivedefined in CoreCpp/Syntax.leancomplete
inductive CoreCpp.BinOp : Type
inductive CoreCpp.BinOp : Type
Constructors
CoreCpp.BinOp.add : CoreCpp.BinOp
CoreCpp.BinOp.sub : CoreCpp.BinOp
CoreCpp.BinOp.mul : CoreCpp.BinOp
CoreCpp.BinOp.div : CoreCpp.BinOp
CoreCpp.BinOp.mod : CoreCpp.BinOp
CoreCpp.BinOp.eq : CoreCpp.BinOp
CoreCpp.BinOp.ne : CoreCpp.BinOp
CoreCpp.BinOp.lt : CoreCpp.BinOp
CoreCpp.BinOp.le : CoreCpp.BinOp
CoreCpp.BinOp.gt : CoreCpp.BinOp
CoreCpp.BinOp.ge : CoreCpp.BinOp
CoreCpp.BinOp.and : CoreCpp.BinOp
CoreCpp.BinOp.or : CoreCpp.BinOp
-
structuredefined in CoreCpp/Syntax.leancomplete
structure CoreCpp.Param : Type
structure CoreCpp.Param : Type
A parameter. `byRef` marks a `τ&` parameter, bound to the location of the argument instead of to a fresh copy.
Fields
ty : CoreCpp.Ty
name : String
byRef : Bool
-
inductivedefined in CoreCpp/Syntax.leancomplete
inductive CoreCpp.Expr : Type
inductive CoreCpp.Expr : Type
Expressions. The forms a program writes. `field` is `e.f`, `arrow` is `e->f`, `deref` is `*e` and `index` is `e[i]`. `newObj C args` is `new C(args)`, which allocates the object and runs the constructor, and `newLib τ args` is `new τ(args)` for a type of the library, `new std::vector<int>(3)` for instance. `this` is the location of the receiver inside a method. `call f args` calls the function named `f`, or the function value bound to `f` when `f` is a variable in scope, or the method `f` of `this` inside a class. `callFn e args` calls the function value `e`. Function call is a form of `Expr` because `Args` is part of `PostfixExpr`. `methodCall e arrow m args static sig` is `e.m(args)` when `arrow` is false and `e->m(args)` when it is true. `lambda ps τ c` is `[=](ps) -> τ { c }`, which the grammar admits only as an argument, as the initialiser of a declaration and as the expression of `return`. Two fields carry what the type checker learns and the evaluator needs. The field `static` of `methodCall` is the class of the receiver as the type checker sees it, which tells a dispatched call from a static one. The field `sig` of `call` and of `methodCall` is the parameter type list of the overload it chose, which picks one function or method out of an overload set. Both fields are `none` as the parser leaves them, and `Typing.annotate` fills them. Two forms no program writes, both introduced by `Typing.annotate`. `locOf e` is the location of `e` as a value, which it puts on the `return` of a member that returns a reference. `intrinsic L u args` is a use `u` of the entity `L` of the library, which it puts where a program indexes, calls or applies an entity of the library, the receiver of a member being the first argument.Constructors
CoreCpp.Expr.intLit (n : Int) : CoreCpp.Expr
CoreCpp.Expr.boolLit (b : Bool) : CoreCpp.Expr
CoreCpp.Expr.nullptr : CoreCpp.Expr
CoreCpp.Expr.var (x : String) : CoreCpp.Expr
CoreCpp.Expr.unop (op : CoreCpp.UnOp) (e : CoreCpp.Expr) : CoreCpp.Expr
CoreCpp.Expr.binop (op : CoreCpp.BinOp) (l r : CoreCpp.Expr) : CoreCpp.Expr
CoreCpp.Expr.cond (c t e : CoreCpp.Expr) : CoreCpp.Expr
CoreCpp.Expr.call (f : String) (args : List CoreCpp.Expr) (sig : Option (List CoreCpp.Ty)) : CoreCpp.Expr
CoreCpp.Expr.newObj (c : String) (args : List CoreCpp.Expr) : CoreCpp.Expr
CoreCpp.Expr.newLib (t : CoreCpp.Ty) (args : List CoreCpp.Expr) : CoreCpp.Expr
CoreCpp.Expr.this : CoreCpp.Expr
CoreCpp.Expr.methodCall (recv : CoreCpp.Expr) (arrow : Bool) (m : String) (args : List CoreCpp.Expr) (static : Option String) (sig : Option (List CoreCpp.Ty)) : CoreCpp.Expr
CoreCpp.Expr.field (e : CoreCpp.Expr) (f : String) : CoreCpp.Expr
CoreCpp.Expr.arrow (e : CoreCpp.Expr) (f : String) : CoreCpp.Expr
CoreCpp.Expr.deref (e : CoreCpp.Expr) : CoreCpp.Expr
CoreCpp.Expr.index (e i : CoreCpp.Expr) : CoreCpp.Expr
CoreCpp.Expr.lambda (params : List CoreCpp.Param) (ret : CoreCpp.Ty) (body : List CoreCpp.Cmd) : CoreCpp.Expr
CoreCpp.Expr.callFn (f : CoreCpp.Expr) (args : List CoreCpp.Expr) : CoreCpp.Expr
CoreCpp.Expr.locOf (e : CoreCpp.Expr) : CoreCpp.Expr
CoreCpp.Expr.intrinsic (lib use : String) (args : List CoreCpp.Expr) : CoreCpp.Expr
-
inductivedefined in CoreCpp/Syntax.leancomplete
inductive CoreCpp.Cmd : Type
inductive CoreCpp.Cmd : Type
Commands. A block is a list of commands. `exprStmt` is the statement that evaluates an expression and discards its value. `declRef` is the local reference `τ& x = e`, a second name for the location `e` denotes. `delete e static` is `delete e;`, with `static` the class of the pointer as the type checker sees it, filled by `Typing.annotate`.
Constructors
CoreCpp.Cmd.block (cs : List CoreCpp.Cmd) : CoreCpp.Cmd
CoreCpp.Cmd.ite (c : CoreCpp.Expr) (t e : List CoreCpp.Cmd) : CoreCpp.Cmd
CoreCpp.Cmd.while (c : CoreCpp.Expr) (body : List CoreCpp.Cmd) : CoreCpp.Cmd
CoreCpp.Cmd.for (init : CoreCpp.Cmd) (c : CoreCpp.Expr) (step : CoreCpp.Cmd) (body : List CoreCpp.Cmd) : CoreCpp.Cmd
CoreCpp.Cmd.ret (e : Option CoreCpp.Expr) : CoreCpp.Cmd
CoreCpp.Cmd.decl (ty : CoreCpp.Ty) (x : String) (init : CoreCpp.Expr) : CoreCpp.Cmd
CoreCpp.Cmd.declRef (ty : CoreCpp.Ty) (x : String) (init : CoreCpp.Expr) : CoreCpp.Cmd
CoreCpp.Cmd.declAuto (x : String) (init : CoreCpp.Expr) : CoreCpp.Cmd
CoreCpp.Cmd.assign (lhs rhs : CoreCpp.Expr) : CoreCpp.Cmd
CoreCpp.Cmd.exprStmt (e : CoreCpp.Expr) : CoreCpp.Cmd
CoreCpp.Cmd.delete (e : CoreCpp.Expr) (static : Option String) : CoreCpp.Cmd
-
structuredefined in CoreCpp/Syntax.leancomplete
structure CoreCpp.Fun : Type
structure CoreCpp.Fun : Type
Fields
ret : CoreCpp.Ty
name : String
params : List CoreCpp.Param
body : List CoreCpp.Cmd
-
inductivedefined in CoreCpp/Syntax.leancomplete
inductive CoreCpp.Vis : Type
inductive CoreCpp.Vis : Type
Visibility of a member. Members before any section label are private, as in C++.
Constructors
CoreCpp.Vis.pub : CoreCpp.Vis
A public member, visible to every expression.
CoreCpp.Vis.priv : CoreCpp.Vis
A private member, visible only inside a member body of the class that declares it.
-
structuredefined in CoreCpp/Syntax.leancomplete
structure CoreCpp.Field : Type
structure CoreCpp.Field : Type
A field of a class.
Fields
ty : CoreCpp.Ty
The type of the field.
name : String
The name of the field.
vis : CoreCpp.Vis
The visibility of the field.
-
structuredefined in CoreCpp/Syntax.leancomplete
structure CoreCpp.Method : Type
structure CoreCpp.Method : Type
A method, defined inside the class. `isVirtual` marks `virtual`, which makes the call dispatch by the class tag of the receiver, and `isOverride` marks `override`, required on a method that redefines a `virtual` one. An operator member is a method whose name is `operator` followed by the operator, `operator+` or `operator[]`, which the type checker reaches by rewriting the infix form.
Fields
name : String
The name of the method.
ret : CoreCpp.Ty
The result type.
params : List CoreCpp.Param
The parameters.
body : List CoreCpp.Cmd
The body, run with `this` bound to the receiver.
vis : CoreCpp.Vis
The visibility of the method.
isVirtual : Bool
Whether the method is declared `virtual`.
isOverride : Bool
Whether the method is declared `override`.
retRef : Bool
Whether the method returns a reference, `τ& m(…)`, so that a call to it denotes the location the body returns.
-
structuredefined in CoreCpp/Syntax.leancomplete
structure CoreCpp.Ctor : Type
structure CoreCpp.Ctor : Type
The constructor of a class, named after the class and run by `new` after the fields are allocated.
Fields
params : List CoreCpp.Param
The parameters of the constructor.
body : List CoreCpp.Cmd
The body, run by `new C(args)` after the fields are allocated.
-
structuredefined in CoreCpp/Syntax.leancomplete
structure CoreCpp.Dtor : Type
structure CoreCpp.Dtor : Type
The destructor of a class, `~C()`, run by `delete` before the locations of the object leave the store.
Fields
body : List CoreCpp.Cmd
The body, run by `delete` before the object leaves the store.
isVirtual : Bool
Whether the destructor is declared `virtual`, which makes `delete` through a pointer to the base well defined.
-
structuredefined in CoreCpp/Syntax.leancomplete
structure CoreCpp.ClassDecl : Type
structure CoreCpp.ClassDecl : Type
A class, with an optional base class, fields, methods, at most one constructor and at most one destructor. Names are qualified by their namespace, `N::C`.
Fields
name : String
The name of the class, qualified by its namespace when it has one.
base : Option String
The base class, when the class derives from one.
fields : List CoreCpp.Field
The fields declared by the class itself.
methods : List CoreCpp.Method
The methods declared by the class itself.
ctor : Option CoreCpp.Ctor
The constructor, when the class declares one.
dtor : Option CoreCpp.Dtor
The destructor, when the class declares one.
-
inductivedefined in CoreCpp/Syntax.leancomplete
inductive CoreCpp.Decl : Type
inductive CoreCpp.Decl : Type
Top level declarations. A `tmpl T C` is a class template, the class `C` with the type parameter `T`, which is never checked and never run. Only its instantiations are, and `Templates.instantiate` adds one class per instantiation the program mentions. A `libTmpl L Ts` is a class template of the library and a `libFn f τ ps` a function of the library, both declared without a body and implemented by an intrinsic.
Constructors
CoreCpp.Decl.cls (c : CoreCpp.ClassDecl) : CoreCpp.Decl
CoreCpp.Decl.fn (f : CoreCpp.Fun) : CoreCpp.Decl
CoreCpp.Decl.tmpl (param : String) (c : CoreCpp.ClassDecl) : CoreCpp.Decl
CoreCpp.Decl.libTmpl (name : String) (params : List String) : CoreCpp.Decl
CoreCpp.Decl.libFn (name : String) (ret : CoreCpp.Ty) (params : List CoreCpp.Param) : CoreCpp.Decl
-
abbrevdefined in CoreCpp/Syntax.leancomplete
abbrev CoreCpp.Program : Type
abbrev CoreCpp.Program : Type
A program is a list of declarations. There are no global variables.
-
CoreCpp.P[complete] -
CoreCpp.PState[complete] -
CoreCpp.expr[complete] -
CoreCpp.orExpr[complete] -
CoreCpp.andExpr[complete] -
CoreCpp.eqExpr[complete] -
CoreCpp.relExpr[complete] -
CoreCpp.addExpr[complete] -
CoreCpp.mulExpr[complete] -
CoreCpp.unaryExpr[complete] -
CoreCpp.postfixExpr[complete] -
CoreCpp.primary[complete] -
CoreCpp.args[complete] -
CoreCpp.argExpr[complete] -
CoreCpp.lambda[complete]
A parser has the type P α, a state monad over PState that gives an α or fails with a message. The state holds the tokens, the position of the next one, the prefix of the enclosing namespaces and, for each token, whether it comes from a header.
One parser function per expression nonterminal, from Expr down to Primary, named after it. Each level of the grammar is one level of precedence, and the repetition of an operator and its operand builds a left associative tree.
The function postfixExpr reads Chain, After and ChainNoCall inline. It covers the call of a named function, the call of a function value, indexing, field access through . and ->, and the method call in its two forms. The nonterminal After separates a method call from a field access.
The function unaryExpr adds the dereference, and primary covers literals, nullptr, this, variables, parenthesised expressions and the two forms of new. Lambdas are parsed as argument expressions, by argExpr, in the three positions the grammar gives them.
Lean code for Definition1.3.2●15 definitions
Associated Lean declarations
-
CoreCpp.P[complete]
-
CoreCpp.PState[complete]
-
CoreCpp.expr[complete]
-
CoreCpp.orExpr[complete]
-
CoreCpp.andExpr[complete]
-
CoreCpp.eqExpr[complete]
-
CoreCpp.relExpr[complete]
-
CoreCpp.addExpr[complete]
-
CoreCpp.mulExpr[complete]
-
CoreCpp.unaryExpr[complete]
-
CoreCpp.postfixExpr[complete]
-
CoreCpp.primary[complete]
-
CoreCpp.args[complete]
-
CoreCpp.argExpr[complete]
-
CoreCpp.lambda[complete]
-
CoreCpp.P[complete] -
CoreCpp.PState[complete] -
CoreCpp.expr[complete] -
CoreCpp.orExpr[complete] -
CoreCpp.andExpr[complete] -
CoreCpp.eqExpr[complete] -
CoreCpp.relExpr[complete] -
CoreCpp.addExpr[complete] -
CoreCpp.mulExpr[complete] -
CoreCpp.unaryExpr[complete] -
CoreCpp.postfixExpr[complete] -
CoreCpp.primary[complete] -
CoreCpp.args[complete] -
CoreCpp.argExpr[complete] -
CoreCpp.lambda[complete]
-
abbrevdefined in CoreCpp/Parser.leancomplete
abbrev CoreCpp.P (α : Type) : Type
abbrev CoreCpp.P (α : Type) : Type
The type of the parsers. A value of `P α` reads the tokens of a `PState` from its position, advances it, and gives an `α` or fails with a message.
-
structuredefined in CoreCpp/Parser.leancomplete
structure CoreCpp.PState : Type
structure CoreCpp.PState : Type
The state of a parser, the tokens, the position of the next one, the enclosing namespaces and the origin of each token.
Fields
toks : Array CoreCpp.Token
The tokens from the lexer, ending in `eof`.
pos : Nat
The index of the next token in `toks`.
ns : String
The prefix of the enclosing namespaces, `N::M::`, empty at top level.
hdr : Array Bool
Whether each token comes from a header of Core C++.
-
opaquedefined in CoreCpp/Parser.leancomplete
opaque CoreCpp.expr : CoreCpp.P CoreCpp.Expr
opaque CoreCpp.expr : CoreCpp.P CoreCpp.Expr
``` Expr = OrExpr [ "?" Expr ":" Expr ] ; ```
-
opaquedefined in CoreCpp/Parser.leancomplete
opaque CoreCpp.orExpr : CoreCpp.P CoreCpp.Expr
opaque CoreCpp.orExpr : CoreCpp.P CoreCpp.Expr
``` OrExpr = AndExpr { "||" AndExpr } ; ``` -
opaquedefined in CoreCpp/Parser.leancomplete
opaque CoreCpp.andExpr : CoreCpp.P CoreCpp.Expr
opaque CoreCpp.andExpr : CoreCpp.P CoreCpp.Expr
``` AndExpr = EqExpr { "&&" EqExpr } ; ``` -
opaquedefined in CoreCpp/Parser.leancomplete
opaque CoreCpp.eqExpr : CoreCpp.P CoreCpp.Expr
opaque CoreCpp.eqExpr : CoreCpp.P CoreCpp.Expr
``` EqExpr = RelExpr { ( "==" | "!=" ) RelExpr } ; ``` -
opaquedefined in CoreCpp/Parser.leancomplete
opaque CoreCpp.relExpr : CoreCpp.P CoreCpp.Expr
opaque CoreCpp.relExpr : CoreCpp.P CoreCpp.Expr
``` RelExpr = AddExpr { ( "<" | "<=" | ">" | ">=" ) AddExpr } ; ``` -
opaquedefined in CoreCpp/Parser.leancomplete
opaque CoreCpp.addExpr : CoreCpp.P CoreCpp.Expr
opaque CoreCpp.addExpr : CoreCpp.P CoreCpp.Expr
``` AddExpr = MulExpr { ( "+" | "-" ) MulExpr } ; ``` -
opaquedefined in CoreCpp/Parser.leancomplete
opaque CoreCpp.mulExpr : CoreCpp.P CoreCpp.Expr
opaque CoreCpp.mulExpr : CoreCpp.P CoreCpp.Expr
``` MulExpr = UnaryExpr { ( "*" | "/" | "%" ) UnaryExpr } ; ``` -
opaquedefined in CoreCpp/Parser.leancomplete
opaque CoreCpp.unaryExpr : CoreCpp.P CoreCpp.Expr
opaque CoreCpp.unaryExpr : CoreCpp.P CoreCpp.Expr
``` UnaryExpr = ( "!" | "-" | "*" ) UnaryExpr | PostfixExpr ; ```
-
opaquedefined in CoreCpp/Parser.leancomplete
opaque CoreCpp.postfixExpr : CoreCpp.P CoreCpp.Expr
opaque CoreCpp.postfixExpr : CoreCpp.P CoreCpp.Expr
A primary expression and its chain, with `Chain`, `After` and `ChainNoCall` read inline by the loop. ``` PostfixExpr = Primary Chain ; Chain = [ ( "[" Expr "]" Chain | "." VarId After | "->" VarId After | Args Chain ) ] ; After = Args Chain | ChainNoCall ; ChainNoCall = [ ( "[" Expr "]" Chain | "." VarId After | "->" VarId After ) ] ; ``` An `Args` after a variable is the call `f(…)`, of the function named `f`, of the function value bound to `f` or of the method `f` of `this`, and after any other postfix expression it is the call of a function value, `callFn`. The forms `.m(…)` and `->m(…)` are method calls, with the static class left for the type checker, and a field access never takes `Args` directly. -
opaquedefined in CoreCpp/Parser.leancomplete
opaque CoreCpp.primary : CoreCpp.P CoreCpp.Expr
opaque CoreCpp.primary : CoreCpp.P CoreCpp.Expr
A primary expression. After `new`, a class of the program gives `newObj` and a type of the library gives `newLib`. ``` Primary = IntLit | "true" | "false" | "nullptr" | "this" | VarId | "(" Expr ")" | "new" ClassType Args ; ``` -
opaquedefined in CoreCpp/Parser.leancomplete
opaque CoreCpp.args : CoreCpp.P (List CoreCpp.Expr)
opaque CoreCpp.args : CoreCpp.P (List CoreCpp.Expr)
``` Args = "(" [ ArgExpr { "," ArgExpr } ] ")" ; ``` -
opaquedefined in CoreCpp/Parser.leancomplete
opaque CoreCpp.argExpr : CoreCpp.P CoreCpp.Expr
opaque CoreCpp.argExpr : CoreCpp.P CoreCpp.Expr
The lambda is an argument expression and not a primary, so it occurs only as argument, as initialiser of a declaration with a type and as the expression of `return`. ``` ArgExpr = Lambda | Expr ; ```
-
opaquedefined in CoreCpp/Parser.leancomplete
opaque CoreCpp.lambda : CoreCpp.P CoreCpp.Expr
opaque CoreCpp.lambda : CoreCpp.P CoreCpp.Expr
The parameters of a lambda are by value. ``` Lambda = "[=]" Params "->" Type Block ; ```
-
CoreCpp.block[complete] -
CoreCpp.statement[complete] -
CoreCpp.localDecl[complete] -
CoreCpp.forInit[complete] -
CoreCpp.exprStatement[complete] -
CoreCpp.isTypeStart[complete] -
CoreCpp.type[complete] -
CoreCpp.basicType[complete] -
CoreCpp.classType[complete] -
CoreCpp.qualTail[complete] -
CoreCpp.templateArgs[complete] -
CoreCpp.templateArg[complete]
One parser function per command nonterminal and per type nonterminal, named after it. The function statement chooses the production by the first token, and a token that opens a type, by isTypeStart, opens a declaration. The function exprStatement reads an expression and then decides between assignment and expression statement by the presence of =.
A Type is a basic type or a class type, optionally followed by *. A class type is a name, qualified by namespaces or not, with template arguments or without. An unqualified name is read in the enclosing namespace. The case of the last component of a qualified name says which type it is, an uppercase one names a class of the program and a lowercase one a class of the library, whose names are lowercase, so Geometry::Shape is the first and std::vector<int> the second.
A template argument is a type, and a function type Type(Type, …) as well. A local declaration with a type may be a reference, and its initialiser may be a lambda.
Lean code for Definition1.3.3●12 definitions
Associated Lean declarations
-
CoreCpp.block[complete]
-
CoreCpp.statement[complete]
-
CoreCpp.localDecl[complete]
-
CoreCpp.forInit[complete]
-
CoreCpp.exprStatement[complete]
-
CoreCpp.isTypeStart[complete]
-
CoreCpp.type[complete]
-
CoreCpp.basicType[complete]
-
CoreCpp.classType[complete]
-
CoreCpp.qualTail[complete]
-
CoreCpp.templateArgs[complete]
-
CoreCpp.templateArg[complete]
-
CoreCpp.block[complete] -
CoreCpp.statement[complete] -
CoreCpp.localDecl[complete] -
CoreCpp.forInit[complete] -
CoreCpp.exprStatement[complete] -
CoreCpp.isTypeStart[complete] -
CoreCpp.type[complete] -
CoreCpp.basicType[complete] -
CoreCpp.classType[complete] -
CoreCpp.qualTail[complete] -
CoreCpp.templateArgs[complete] -
CoreCpp.templateArg[complete]
-
opaquedefined in CoreCpp/Parser.leancomplete
opaque CoreCpp.block : CoreCpp.P (List CoreCpp.Cmd)
opaque CoreCpp.block : CoreCpp.P (List CoreCpp.Cmd)
``` Block = "{" { Statement } "}" ; ``` -
opaquedefined in CoreCpp/Parser.leancomplete
opaque CoreCpp.statement : CoreCpp.P CoreCpp.Cmd
opaque CoreCpp.statement : CoreCpp.P CoreCpp.Cmd
A command or an expression statement, chosen by the first token. A token that opens a type, by `isTypeStart`, opens a declaration. ``` Statement = Block | "if" "(" Expr ")" Block [ "else" Block ] | "while" "(" Expr ")" Block | "for" "(" ForInit ";" Expr ";" ExprStatement ")" Block | "return" [ ArgExpr ] ";" | "delete" Expr ";" | LocalDecl ";" | ExprStatement ";" ; ``` -
opaquedefined in CoreCpp/Parser.leancomplete
opaque CoreCpp.localDecl : CoreCpp.P CoreCpp.Cmd
opaque CoreCpp.localDecl : CoreCpp.P CoreCpp.Cmd
With `&` the declaration is a local reference. A lambda initialises only a typed declaration, never an `auto` one. ``` LocalDecl = "auto" VarId "=" Expr | Type [ "&" ] VarId "=" ArgExpr ; ``` -
opaquedefined in CoreCpp/Parser.leancomplete
opaque CoreCpp.forInit : CoreCpp.P CoreCpp.Cmd
opaque CoreCpp.forInit : CoreCpp.P CoreCpp.Cmd
A declaration when the first token opens a type, by `isTypeStart`, and an expression statement otherwise. ``` ForInit = LocalDecl | ExprStatement ; ```
-
opaquedefined in CoreCpp/Parser.leancomplete
opaque CoreCpp.exprStatement : CoreCpp.P CoreCpp.Cmd
opaque CoreCpp.exprStatement : CoreCpp.P CoreCpp.Cmd
An assignment command or an expression as statement, told apart by `=`. ``` ExprStatement = Expr [ "=" Expr ] ; ```
-
defdefined in CoreCpp/Parser.leancomplete
def CoreCpp.isTypeStart : CoreCpp.Token → Bool
def CoreCpp.isTypeStart : CoreCpp.Token → Bool
The tokens that open a `Type`, and therefore a declaration. No expression starts with one of them.
-
opaquedefined in CoreCpp/Parser.leancomplete
opaque CoreCpp.type : CoreCpp.P CoreCpp.Ty
opaque CoreCpp.type : CoreCpp.P CoreCpp.Ty
``` Type = BasicType | ClassType [ "*" ] ; ```
-
defdefined in CoreCpp/Parser.leancomplete
def CoreCpp.basicType : CoreCpp.P CoreCpp.Ty
def CoreCpp.basicType : CoreCpp.P CoreCpp.Ty
``` BasicType = "int" | "bool" | "void" ; ```
-
opaquedefined in CoreCpp/Parser.leancomplete
opaque CoreCpp.classType : CoreCpp.P CoreCpp.Ty
opaque CoreCpp.classType : CoreCpp.P CoreCpp.Ty
A class name possibly qualified by namespaces and possibly instantiating a class template. ``` ClassType = NsId "::" QualTail | TypeId [ TemplateArgs ] ; ``` An unqualified name is read in the enclosing namespace, and a class template takes one template argument. The instantiation is named by the chain the design prints for the type, so `Stack<int>` in the source and the expanded class have the same name, and `Templates.instantiate` adds the class before the program is checked.
-
opaquedefined in CoreCpp/Parser.leancomplete
opaque CoreCpp.qualTail (pre : String) : CoreCpp.P CoreCpp.Ty
opaque CoreCpp.qualTail (pre : String) : CoreCpp.P CoreCpp.Ty
The rest of a qualified name after a namespace. ``` QualTail = NsId "::" QualTail | Name [ TemplateArgs ] ; ``` The case of the last component says which type it is. An uppercase one names a class of the program, so `Geometry::Shape` is a class type, and a lowercase one names a class of the library, whose names are lowercase, so `std::vector<int>` is a library type. A class of the program takes one template argument at most, and a class of the library always takes its arguments.
-
opaquedefined in CoreCpp/Parser.leancomplete
opaque CoreCpp.templateArgs : CoreCpp.P (List CoreCpp.Ty)
opaque CoreCpp.templateArgs : CoreCpp.P (List CoreCpp.Ty)
``` TemplateArgs = "<" TemplateArg { "," TemplateArg } ">" ; ``` -
opaquedefined in CoreCpp/Parser.leancomplete
opaque CoreCpp.templateArg : CoreCpp.P CoreCpp.Ty
opaque CoreCpp.templateArg : CoreCpp.P CoreCpp.Ty
A type or a function type, as `int(int)` in `std::function<int(int)>`. ``` TemplateArg = Type [ "(" [ Type { "," Type } ] ")" ] ; ```
-
CoreCpp.program[complete] -
CoreCpp.declaration[complete] -
CoreCpp.P.name[complete] -
CoreCpp.classDecl[complete] -
CoreCpp.classRest[complete] -
CoreCpp.member[complete] -
CoreCpp.operatorName[complete] -
CoreCpp.function[complete] -
CoreCpp.params[complete] -
CoreCpp.param[complete] -
CoreCpp.className[complete] -
CoreCpp.runParser[complete] -
CoreCpp.parseProgram[complete] -
CoreCpp.parseExpr[complete] -
CoreCpp.parseStatement[complete] -
CoreCpp.parseUnit[complete]
A program is a sequence of declarations up to eof. Each one is a class, a class template, a namespace, a function, or a class template or a function of the library declared without a body.
The functions carry the names of their nonterminals, with three exceptions. The function classDecl reads Class, operatorName reads Op and P.name reads Name. The function classRest reads Section inline, and member reads MemberRest.
A class carries its fields, its methods, its constructor and its destructor, under the visibility of the section that holds them. A namespace is flattened at parse time, and every class it declares carries the prefix of the enclosing namespaces, as N::C.
The function runParser runs the lexer and a parser on a string and requires the whole input to be consumed. The function parseUnit parses the output of Preproc, runs the automaton on each line alone and the pass qualifiers on all the tokens, and marks the tokens of the lines that come from a header.
Lean code for Definition1.3.4●16 definitions
Associated Lean declarations
-
CoreCpp.program[complete]
-
CoreCpp.declaration[complete]
-
CoreCpp.P.name[complete]
-
CoreCpp.classDecl[complete]
-
CoreCpp.classRest[complete]
-
CoreCpp.member[complete]
-
CoreCpp.operatorName[complete]
-
CoreCpp.function[complete]
-
CoreCpp.params[complete]
-
CoreCpp.param[complete]
-
CoreCpp.className[complete]
-
CoreCpp.runParser[complete]
-
CoreCpp.parseProgram[complete]
-
CoreCpp.parseExpr[complete]
-
CoreCpp.parseStatement[complete]
-
CoreCpp.parseUnit[complete]
-
CoreCpp.program[complete] -
CoreCpp.declaration[complete] -
CoreCpp.P.name[complete] -
CoreCpp.classDecl[complete] -
CoreCpp.classRest[complete] -
CoreCpp.member[complete] -
CoreCpp.operatorName[complete] -
CoreCpp.function[complete] -
CoreCpp.params[complete] -
CoreCpp.param[complete] -
CoreCpp.className[complete] -
CoreCpp.runParser[complete] -
CoreCpp.parseProgram[complete] -
CoreCpp.parseExpr[complete] -
CoreCpp.parseStatement[complete] -
CoreCpp.parseUnit[complete]
-
defdefined in CoreCpp/Parser.leancomplete
def CoreCpp.program : CoreCpp.P CoreCpp.Program
def CoreCpp.program : CoreCpp.P CoreCpp.Program
A sequence of declarations up to `eof`. ``` Program = { Declaration } ; ``` -
opaquedefined in CoreCpp/Parser.leancomplete
opaque CoreCpp.declaration : CoreCpp.P (List CoreCpp.Decl)
opaque CoreCpp.declaration : CoreCpp.P (List CoreCpp.Decl)
``` Declaration = "namespace" Name "{" { Declaration } "}" | "template" "<" "typename" TypeId { "," "typename" TypeId } ">" "class" ( TypeId ClassRest | VarId ";" ) | Class | Function ; ``` A namespace holds classes, templates and namespaces, and its name is of either case, since the library opens `namespace std`, which only a header of Core C++ opens. Its declarations are flattened into the program with qualified names. A class template with a body has one type parameter. A class template declared without a body is a class of the library, named in lowercase, which an intrinsic implements. -
defdefined in CoreCpp/Parser.leancomplete
def CoreCpp.P.name : CoreCpp.P String
def CoreCpp.P.name : CoreCpp.P String
A name of either case, the name of a namespace and the last component of a qualified name. ``` Name = TypeId | VarId ; ```
-
defdefined in CoreCpp/Parser.leancomplete
def CoreCpp.classDecl : CoreCpp.P CoreCpp.ClassDecl
def CoreCpp.classDecl : CoreCpp.P CoreCpp.ClassDecl
The class name is read in the enclosing namespace. ``` Class = "class" TypeId ClassRest ; ```
-
defdefined in CoreCpp/Parser.leancomplete
def CoreCpp.classRest (name : String) : CoreCpp.P CoreCpp.ClassDecl
def CoreCpp.classRest (name : String) : CoreCpp.P CoreCpp.ClassDecl
The class after its name, with `Section` read inline. ``` ClassRest = [ ":" "public" ClassType ] "{" { Member } { Section } "}" ";" ; Section = ( "public" | "private" ) ":" { Member } ; ``` Members before any section label are private, as in C++. The base is a class of the program. A class has at most one constructor and at most one destructor, both public. A field is never virtual. -
defdefined in CoreCpp/Parser.leancomplete
def CoreCpp.member (cls : String) (vis : CoreCpp.Vis) : CoreCpp.P CoreCpp.MemberItem
def CoreCpp.member (cls : String) (vis : CoreCpp.Vis) : CoreCpp.P CoreCpp.MemberItem
A member of a class, with `MemberRest` read inline by `afterType`. ``` Member = "virtual" ( Type [ "&" ] MemberRest | "~" TypeId "(" ")" Block ) | "~" TypeId "(" ")" Block | ( BasicType | NsId "::" QualTail [ "*" ] ) [ "&" ] MemberRest | TypeId ( Params Block | [ TemplateArgs ] [ "*" ] [ "&" ] MemberRest ) ; MemberRest = VarId ( ";" | Params [ "override" ] Block ) | "operator" Op Params Block ; ``` The first factoring of the grammar. A `TypeId` followed by `(` opens the constructor, which must be named after the class, and a `TypeId` followed by anything else opens a type. The `&` after the type marks a member that returns a reference, so a call to it denotes a location, and it never appears on a field. -
defdefined in CoreCpp/Parser.leancomplete
def CoreCpp.operatorName : CoreCpp.P String
def CoreCpp.operatorName : CoreCpp.P String
The operators a class may overload, the nonterminal `Op`. ``` Op = "+" | "-" | "*" | "/" | "%" | "==" | "!=" | "<" | "<=" | ">" | ">=" | "[" "]" ; ```
-
defdefined in CoreCpp/Parser.leancomplete
def CoreCpp.function : CoreCpp.P CoreCpp.Decl
def CoreCpp.function : CoreCpp.P CoreCpp.Decl
A function without a body is a declaration of the library, as `void assert(bool condition);` of `<cassert>`, and only a header holds it. ``` Function = Type VarId Params ( Block | ";" ) ; ```
-
defdefined in CoreCpp/Parser.leancomplete
def CoreCpp.params : CoreCpp.P (List CoreCpp.Param)
def CoreCpp.params : CoreCpp.P (List CoreCpp.Param)
``` Params = "(" [ Param { "," Param } ] ")" ; ``` -
defdefined in CoreCpp/Parser.leancomplete
def CoreCpp.param : CoreCpp.P CoreCpp.Param
def CoreCpp.param : CoreCpp.P CoreCpp.Param
With `&` the parameter is by reference. ``` Param = Type [ "&" ] VarId ; ```
-
defdefined in CoreCpp/Parser.leancomplete
def CoreCpp.className : CoreCpp.P String
def CoreCpp.className : CoreCpp.P String
The name of a class type, for the base of a class, which is never a type of the library.
-
defdefined in CoreCpp/Parser.leancomplete
def CoreCpp.runParser {α : Type} (p : CoreCpp.P α) (input : String) : Except String α
def CoreCpp.runParser {α : Type} (p : CoreCpp.P α) (input : String) : Except String α
Runs a parser on a string, requiring the whole input to be consumed.
-
defdefined in CoreCpp/Parser.leancomplete
def CoreCpp.parseProgram : String → Except String CoreCpp.Program
def CoreCpp.parseProgram : String → Except String CoreCpp.Program
-
defdefined in CoreCpp/Parser.leancomplete
def CoreCpp.parseExpr : String → Except String CoreCpp.Expr
def CoreCpp.parseExpr : String → Except String CoreCpp.Expr
-
defdefined in CoreCpp/Parser.leancomplete
def CoreCpp.parseStatement : String → Except String CoreCpp.Cmd
def CoreCpp.parseStatement : String → Except String CoreCpp.Cmd
-
defdefined in CoreCpp/Parser.leancomplete
def CoreCpp.parseUnit (lines : List (String × Bool)) : Except String CoreCpp.Program
def CoreCpp.parseUnit (lines : List (String × Bool)) : Except String CoreCpp.Program
Parses the output of Preproc, a list of lines each marked with whether it comes from a header. No token spans two lines, so the automaton runs on each line alone. The pass `Lexer.qualifiers` runs once on the tokens of the whole unit, so it marks `std` at the end of a line before a `::` on the next.