The Language Pec

BNF Converter

This document was automatically generated by the BNF-Converter. It was generated together with the lexer, the parser, and the abstract syntax module, which guarantees that the document matches with the implementation of the language (provided no hand-hacking has taken place).

The lexical structure of Pec

Literals

String literals String have the form "x", where x is any sequence of any characters except " unless preceded by \.

Character literals Char have the form 'c', where c is any single character.

Frac literals are recognized by the regular expression `'-'? digit+ '.' digit+ ('e' '-'? digit+)?`

Uident literals are recognized by the regular expression `upper (letter | digit | '_')*`

Lident literals are recognized by the regular expression `(lower | '_') (letter | digit | '_')*`

USym literals are recognized by the regular expression `('!' | '#' | '$' | '%' | '&' | '*' | '+' | '-' | '.' | '/' | ':' | '<' | '=' | '>' | '?' | '@' | '\' | '^' | '|' | '~')+`

Number literals are recognized by the regular expression `'-'? digit+`

Count literals are recognized by the regular expression `'#' digit+`

Reserved words and symbols

The set of reserved words is the set of terminals appearing in the grammar. Those reserved words that consist of non-letter characters are called symbols, and they are treated in a different way from those that are similar to identifiers. The lexer follows rules familiar from languages like Haskell, C, and Java, including longest match and spacing conventions.

The reserved words used in Pec are the following:

Array all as branch
case do exports extern
import in let module
of type where

The symbols used in Pec are the following:

{ } ( )
. .. :: =
<- [ ] @
-> | # ,
;

Comments

Single-line comments begin with //.Multiple-line comments are enclosed with /* and */.

The syntactic structure of Pec

Non-terminals are enclosed between < and >. The symbols -> (production), | (union) and eps (empty rule) belong to the BNF notation. All other symbols are terminals.

Module -> module Modid exports ExportDecl where { [TopDecl] }
ExportDecl -> all
| ( [Export] )
Export -> Con Spec
| Var
Spec -> eps
| ( . )
| ( .. )
TopDecl -> import Modid AsSpec
| extern ExtNm Var :: Type
| type Con [TyVar] = TyDecl
| Var :: Type
| Var = Exp
| Var [Exp0] = Exp
AsSpec -> as Con
| eps
ExtNm -> String
| eps
Exp -> do { [Exp5] }
| Exp5
Exp5 -> Exp4 = Exp
| let Exp4 = Exp in Exp
| Exp4 <- Exp
| case Exp of { [CaseAlt] }
| branch of { [BranchAlt] }
| Exp4
Exp4 -> Exp3 USym Exp3
| Exp3
Exp3 -> Exp3 Exp2
| Exp2
Exp2 -> UnOp Exp1
| Exp1
Exp1 -> Exp1 [ Exp ]
| Exp1 . Field
| Exp0
Exp0 -> Array [ [Exp] ]
| { [FieldD] }
| ( [Exp] )
| ( Exp :: Type )
| Count
| Var
| Lit
UnOp -> @
CaseAlt -> CasePat -> Exp
CasePat -> Con Var
| Lit
| Var
BranchAlt -> | BranchPat -> Exp
BranchPat -> Exp4
| eps
Type -> Type2 -> Type
| Type2
Type2 -> Array Type1 Type1
| Con [Type1]
| Type1
Type1 -> Type0
Type0 -> ( [Type] )
| Count
| TyVar
| Con
TyDecl -> { [FieldT] }
| | [ConC]
| Type
ConC -> Con [Type0]
FieldT -> Field :: Type
Lit -> Char
| String
| Number
| Frac
| Con
FieldD -> Field = Exp
Var -> Lident
Con -> Uident
Modid -> Uident
Field -> Lident
TyVar -> Lident
| # Lident
[Exp] -> eps
| Exp
| Exp , [Exp]
[FieldT] -> eps
| FieldT
| FieldT , [FieldT]
[TyVar] -> eps
| TyVar [TyVar]
[Type] -> eps
| Type
| Type , [Type]
[Export] -> eps
| Export
| Export , [Export]
[Type0] -> eps
| Type0 [Type0]
[ConC] -> ConC
| ConC | [ConC]
[Exp0] -> Exp0
| Exp0 [Exp0]
[FieldD] -> FieldD
| FieldD , [FieldD]
[Type1] -> Type1
| Type1 [Type1]
[TopDecl] -> eps
| TopDecl
| TopDecl ; [TopDecl]
[CaseAlt] -> CaseAlt
| CaseAlt ; [CaseAlt]
[BranchAlt] -> BranchAlt
| BranchAlt ; [BranchAlt]
[Exp5] -> Exp5
| Exp5 ; [Exp5]