Core C++

1.3. Abstract syntax and parser🔗

Definition1.3.1
Group: Syntax, tokens and the parser. (13)
Group member previews
Preview
Definition 1.1.1
Loading preview
Group member preview content is loaded from the rendered-fragment cache.
uses 0
Used by 5
Reverse dependency previews
Preview
Definition 1.3.2
Loading preview
Reverse dependency preview content is loaded from the rendered-fragment cache.
✓L∃∀N

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
  • inductive(8 constructors)defined in CoreCpp/Syntax.lean
    complete
    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. 
    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
  • inductive(2 constructors)defined in CoreCpp/Syntax.lean
    complete
    inductive CoreCpp.UnOp : Type
    inductive CoreCpp.UnOp : Type
    CoreCpp.UnOp.not : CoreCpp.UnOp
    CoreCpp.UnOp.neg : CoreCpp.UnOp
  • inductive(13 constructors)defined in CoreCpp/Syntax.lean
    complete
    inductive CoreCpp.BinOp : Type
    inductive CoreCpp.BinOp : Type
    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
  • structure(3 fields)defined in CoreCpp/Syntax.lean
    complete
    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. 
    ty : CoreCpp.Ty
    name : String
    byRef : Bool
  • inductive(20 constructors)defined in CoreCpp/Syntax.lean
    complete
    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. 
    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
  • inductive(11 constructors)defined in CoreCpp/Syntax.lean
    complete
    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`. 
    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
  • structure(4 fields)defined in CoreCpp/Syntax.lean
    complete
    structure CoreCpp.Fun : Type
    structure CoreCpp.Fun : Type
    ret : CoreCpp.Ty
    name : String
    params : List CoreCpp.Param
    body : List CoreCpp.Cmd
  • inductive(2 constructors)defined in CoreCpp/Syntax.lean
    complete
    inductive CoreCpp.Vis : Type
    inductive CoreCpp.Vis : Type
    Visibility of a member. Members before any section label are private, as
    in C++. 
    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. 
  • structure(3 fields)defined in CoreCpp/Syntax.lean
    complete
    structure CoreCpp.Field : Type
    structure CoreCpp.Field : Type
    A field of a class. 
    ty : CoreCpp.Ty
    The type of the field. 
    name : String
    The name of the field. 
    vis : CoreCpp.Vis
    The visibility of the field. 
  • structure(8 fields)defined in CoreCpp/Syntax.lean
    complete
    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. 
    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. 
  • structure(2 fields)defined in CoreCpp/Syntax.lean
    complete
    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. 
    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. 
  • structure(2 fields)defined in CoreCpp/Syntax.lean
    complete
    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. 
    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. 
  • structure(6 fields)defined in CoreCpp/Syntax.lean
    complete
    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`. 
    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. 
  • inductive(5 constructors)defined in CoreCpp/Syntax.lean
    complete
    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. 
    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.lean
    complete
    abbrev CoreCpp.Program : Type
    abbrev CoreCpp.Program : Type
    A program is a list of declarations. There are no global variables. 
Definition1.3.2
Group: Syntax, tokens and the parser. (13)
Group member previews
Preview
Definition 1.1.1
Loading preview
Group member preview content is loaded from the rendered-fragment cache.
Statement uses 2
Statement dependency previews
Preview
Definition 1.1.3
Loading preview
Statement dependency preview content is loaded from the rendered-fragment cache.
used by 1✓L∃∀N

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
  • abbrevdefined in CoreCpp/Parser.lean
    complete
    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. 
  • structure(4 fields)defined in CoreCpp/Parser.lean
    complete
    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. 
    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.lean
    complete
    opaque CoreCpp.expr : CoreCpp.P CoreCpp.Expr
    opaque CoreCpp.expr : CoreCpp.P CoreCpp.Expr
    ```
    Expr = OrExpr [ "?" Expr ":" Expr ] ;
    ```
    
  • opaquedefined in CoreCpp/Parser.lean
    complete
    opaque CoreCpp.orExpr : CoreCpp.P CoreCpp.Expr
    opaque CoreCpp.orExpr : CoreCpp.P CoreCpp.Expr
    ```
    OrExpr = AndExpr { "||" AndExpr } ;
    ```
    
  • opaquedefined in CoreCpp/Parser.lean
    complete
    opaque CoreCpp.andExpr : CoreCpp.P CoreCpp.Expr
    opaque CoreCpp.andExpr : CoreCpp.P CoreCpp.Expr
    ```
    AndExpr = EqExpr { "&&" EqExpr } ;
    ```
    
  • opaquedefined in CoreCpp/Parser.lean
    complete
    opaque CoreCpp.eqExpr : CoreCpp.P CoreCpp.Expr
    opaque CoreCpp.eqExpr : CoreCpp.P CoreCpp.Expr
    ```
    EqExpr = RelExpr { ( "==" | "!=" ) RelExpr } ;
    ```
    
  • opaquedefined in CoreCpp/Parser.lean
    complete
    opaque CoreCpp.relExpr : CoreCpp.P CoreCpp.Expr
    opaque CoreCpp.relExpr : CoreCpp.P CoreCpp.Expr
    ```
    RelExpr = AddExpr { ( "<" | "<=" | ">" | ">=" ) AddExpr } ;
    ```
    
  • opaquedefined in CoreCpp/Parser.lean
    complete
    opaque CoreCpp.addExpr : CoreCpp.P CoreCpp.Expr
    opaque CoreCpp.addExpr : CoreCpp.P CoreCpp.Expr
    ```
    AddExpr = MulExpr { ( "+" | "-" ) MulExpr } ;
    ```
    
  • opaquedefined in CoreCpp/Parser.lean
    complete
    opaque CoreCpp.mulExpr : CoreCpp.P CoreCpp.Expr
    opaque CoreCpp.mulExpr : CoreCpp.P CoreCpp.Expr
    ```
    MulExpr = UnaryExpr { ( "*" | "/" | "%" ) UnaryExpr } ;
    ```
    
  • opaquedefined in CoreCpp/Parser.lean
    complete
    opaque CoreCpp.unaryExpr : CoreCpp.P CoreCpp.Expr
    opaque CoreCpp.unaryExpr : CoreCpp.P CoreCpp.Expr
    ```
    UnaryExpr = ( "!" | "-" | "*" ) UnaryExpr | PostfixExpr ;
    ```
    
  • opaquedefined in CoreCpp/Parser.lean
    complete
    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.lean
    complete
    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.lean
    complete
    opaque CoreCpp.args : CoreCpp.P (List CoreCpp.Expr)
    opaque CoreCpp.args :
      CoreCpp.P (List CoreCpp.Expr)
    ```
    Args = "(" [ ArgExpr { "," ArgExpr } ] ")" ;
    ```
    
  • opaquedefined in CoreCpp/Parser.lean
    complete
    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.lean
    complete
    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 ;
    ```
    
Definition1.3.3
Group: Syntax, tokens and the parser. (13)
Group member previews
Preview
Definition 1.1.1
Loading preview
Group member preview content is loaded from the rendered-fragment cache.
Statement uses 2
Statement dependency previews
Preview
Definition 1.3.1
Loading preview
Statement dependency preview content is loaded from the rendered-fragment cache.
used by 1✓L∃∀N

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
  • opaquedefined in CoreCpp/Parser.lean
    complete
    opaque CoreCpp.block : CoreCpp.P (List CoreCpp.Cmd)
    opaque CoreCpp.block :
      CoreCpp.P (List CoreCpp.Cmd)
    ```
    Block = "{" { Statement } "}" ;
    ```
    
  • opaquedefined in CoreCpp/Parser.lean
    complete
    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.lean
    complete
    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.lean
    complete
    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.lean
    complete
    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.lean
    complete
    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.lean
    complete
    opaque CoreCpp.type : CoreCpp.P CoreCpp.Ty
    opaque CoreCpp.type : CoreCpp.P CoreCpp.Ty
    ```
    Type = BasicType | ClassType [ "*" ] ;
    ```
    
  • defdefined in CoreCpp/Parser.lean
    complete
    def CoreCpp.basicType : CoreCpp.P CoreCpp.Ty
    def CoreCpp.basicType : CoreCpp.P CoreCpp.Ty
    ```
    BasicType = "int" | "bool" | "void" ;
    ```
    
  • opaquedefined in CoreCpp/Parser.lean
    complete
    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.lean
    complete
    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.lean
    complete
    opaque CoreCpp.templateArgs : CoreCpp.P (List CoreCpp.Ty)
    opaque CoreCpp.templateArgs :
      CoreCpp.P (List CoreCpp.Ty)
    ```
    TemplateArgs = "<" TemplateArg { "," TemplateArg } ">" ;
    ```
    
  • opaquedefined in CoreCpp/Parser.lean
    complete
    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 } ] ")" ] ;
    ```
    
Definition1.3.4
Group: Syntax, tokens and the parser. (13)
Group member previews
Preview
Definition 1.1.1
Loading preview
Group member preview content is loaded from the rendered-fragment cache.
Statement uses 2
Statement dependency previews
Preview
Definition 1.3.1
Loading preview
Statement dependency preview content is loaded from the rendered-fragment cache.
used by 1✓L∃∀N

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
  • defdefined in CoreCpp/Parser.lean
    complete
    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.lean
    complete
    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.lean
    complete
    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.lean
    complete
    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.lean
    complete
    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.lean
    complete
    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.lean
    complete
    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.lean
    complete
    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.lean
    complete
    def CoreCpp.params : CoreCpp.P (List CoreCpp.Param)
    def CoreCpp.params :
      CoreCpp.P (List CoreCpp.Param)
    ```
    Params = "(" [ Param { "," Param } ] ")" ;
    ```
    
  • defdefined in CoreCpp/Parser.lean
    complete
    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.lean
    complete
    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.lean
    complete
    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.lean
    complete
    def CoreCpp.parseProgram : String → Except String CoreCpp.Program
    def CoreCpp.parseProgram :
      String → Except String CoreCpp.Program
  • defdefined in CoreCpp/Parser.lean
    complete
    def CoreCpp.parseExpr : String → Except String CoreCpp.Expr
    def CoreCpp.parseExpr :
      String → Except String CoreCpp.Expr
  • defdefined in CoreCpp/Parser.lean
    complete
    def CoreCpp.parseStatement : String → Except String CoreCpp.Cmd
    def CoreCpp.parseStatement :
      String → Except String CoreCpp.Cmd
  • defdefined in CoreCpp/Parser.lean
    complete
    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.