Package: A Lustre package is a sequence (semantically a set) of declarations of constants, types, functions or nodes.

\underline{LusPack} ⟶ \{\underline{OneDecl} \}^{∗}
\underline{OneDecl} ⟶ \underline{ConstDecl} | \underline{TypeDecl} | \underline{FuncDecl} | \underline{NodeDecl}

Constant Declarations: A constant can be declared with its type and/or value. If no value is given, the constant is considered as imported. Imported constants of a same type can be given as a list. The type of defined constant can be given for more precision.

\underline{ConstDecl} ⟶ const \{\underline{OneConstDecl} \}^{+} ;

OneConstDecl ⟶

\{\underline{Idf} , \}^{∗} \underline{Idf} : \underline{Type}
| \underline{Idf} = \underline{Exp} [: \underline{Type} ]

Type Declarations: A declared type can be external (just a name) or declared. Declared types are either aliases on type expressions, or built types (structured or enumerated).

\underline{TypeDecl} ⟶ type \{\underline{OneTypeDecl} ; \}^{+}
\underline{OneTypeDecl} ⟶ \{\underline{Idf} , \}^{∗} \underline{Idf} | \underline{Idf} = \underline{Type}
| \underline{Idf} = \underline{TypeBuilder}
\underline{TypeBuilder} ⟶ enum \{ \{\underline{Idf} , \}^{∗} \underline{Idf} \}
| struct \{ \{\underline{Fields} ; \}^{∗} \underline{Fields} \}
\underline{Fields} ⟶ \{\underline{Idf} , \}^{∗} \underline{Idf} : \underline{Type}

Type Expression: Those expressions are used to specify the type of a variable, a field, etc. We also talk about immediate type, to outline the difference with built types. Immediate types are predefined types, type identifiers (references to declared types) or static arrays.

\underline{Type} ⟶ \underline{PredefType} | \underline{Idf} | \underline{Type} ˆ \underline{Exp}
\underline{PredefType} ⟶ bool | int | real

Function Declarations: A function is declared with the names and types of its formal parameters.

\underline{FuncDecl} ⟶ function \underline{Idf} ( \underline{VarDeclList} ) returns ( \underline{VarDeclList} )
\underline{VarDeclList} ⟶ \{\underline{VarDecl} ; \}^{∗} \underline{VarDecl}
\underline{VarDecl} ⟶ \{\underline{Idf} , \}^{∗} \underline{Idf} : \underline{Type}

Node Declaration: A node can be declared with a complete description of its dynamic behaviour, or by implicitely reusing the dynamic behaviour of another node. A node can have static parameters (we also talk about template node, or no (in which case we also talk about actual node).

\underline{NodeDecl} ⟶ node \underline{Idf} [\underline{StaticProto} ] \underline{NodeProto} \underline{NodeBody}
| node \underline{Idf} [\underline{StaticProto} ] = \underline{Idf} [\underline{StaticArgList} ] ;

Static parameters are constants and abstract types, or nodes.

\underline{StaticProto} ⟶ << \{\underline{StaticParam} ; \}^{∗} \underline{StaticParam} >>
\underline{StaticParam} ⟶ type \underline{Idf} | const \underline{Idf} : \underline{Type}
| node \underline{Idf} \underline{NodeProto}

A node prototype defines the formal inputs/outputs of a node (in some sence the ”type” of the node). Formal node parameters are typed identifiers with an optionnal formal clock).

\underline{NodeProto} ⟶ ( \underline{ClockedVarDeclList} ) returns ( \underline{ClockedVarDeclList} )

ClockedVarDeclList ⟶

\{\underline{ClockedVarDecl} ; \}^{∗} \underline{ClockedVarDecl}
ClockedVarDecl ⟶ \underline{VarDecl} when \underline{Idf} | ( \underline{VarDeclList} ) when \underline{Idf}

Node Body: It contains an optionnal set of local variable definitions and a sequence (semantically a set) of equations.

\underline{NodeBody} ⟶ [var \underline{ClockedVarDeclList} ; ] let \{\underline{Equation} ; \}^{+} tel

An equation is either an assertion or a ”real” equation.

\underline{Equation} ⟶ assert \underline{Exp} | \underline{LeftPart} = \underline{Exp}

A left part is a non-empty list of left item. A left item denotes a variable ”piece”: a full variable, the field of a structured left item, an element or a slice of an array left item.

\underline{LeftPart} ⟶ [( ] \{\underline{LeftItem} , \}^{∗} \underline{LeftItem} [) ]
\underline{LeftItem} ⟶ \underline{Idf} | \underline{LeftItem} . \underline{Idf} | \underline{LeftItem} [ \underline{Exp} ]
| \underline{LeftItem} [ \underline{Exp} .. \underline{Exp} [step \underline{Exp} ] ]

Expressions:

\underline{Exp} ⟶ \underline{PredefConst} | \underline{Idf} | \underline{UnOp} \underline{Exp} | \underline{Exp} \underline{BinOp} \underline{Exp}
| if \underline{Exp} then \underline{Exp} else \underline{Exp} | with \underline{Exp} then \underline{Exp} else \underline{Exp}
| \underline{Exp} .\underline{Idf} | \underline{Exp} [ \underline{Exp} ] | \underline{Exp} [ \underline{Exp} .. \underline{Exp} [step \underline{Exp} ] ]
| \underline{NaryOp} ( \{\underline{Exp} , \}^{∗} \underline{Exp} )
| ( \{\underline{Exp} , \}^{∗} \underline{Exp} )
| \underline{Idf} \{ \{\underline{Idf} = \underline{Exp} ; \}^{∗} \underline{Idf} = \underline{Exp} \}
| \underline{NodeExpression} ( \{\underline{Exp} , \}^{∗} \underline{Exp} )

Integer and floating point notations are following the ansi-c syntax.

\underline{PredefConst} ⟶ \underline{Integer} | \underline{Real} | true | false

Operator denotations: The effective node construction denotes an actual operation wich can be a predifined operation, or a user defined operation, in which case a list of effective static parameters can be given. NodeExpression ⟶

operator \underline{PredefOp}
| \underline{Idf} [\underline{StaticArgList} ]

The keyword if is denoting the ternary operation if ...then ...else ...

\underline{PredefOp} ⟶ \underline{Unop} | \underline{BinOp} | if
\underline{Unop} ⟶ not | - | pre | current
\underline{BinOp} ⟶ -> | when | or | xor | and | => | = | <> | < | >
| <= | >= | + | - | * | / | div | mod | ^| |
\underline{NaryOp} ⟶ # | nor

Static arguments: The strict way is to specify the nature (const, type or node) of a effective static; however, the nature can be avoided when the parameter is: a simple arithmetic and logic expression (typically n-1), a predifined type or constant (or an array of), a predifined operator, or even a single identifier (in this case, the compiler will try to compute the nature according to its naming environment).

StaticArgList ⟶ << \{\underline{StaticArg} , \}^{∗} \underline{StaticArg} >>

\underline{StaticArg} ⟶ type \underline{Type} | const \underline{Exp} | node \underline{NodeExpression}
| \underline{PredefType} \{ˆ \underline{Expression} \}^{∗} | \underline{PredefConst} \{ˆ \underline{Expression} \}^{∗}
| \underline{SimpleExpression} | operator \underline{PredefOp} | \underline{idf}