rtk-0.11: test-grammars/haskell.pg
grammar 'Haskell';
Haskell = Module ;
Module = 'module' ModId ExportsOpt 'where' Body | Body;
ExportsOpt = ( '(' ExportsList (',')?')' )?;
ExportsList = Export * ',' ;
Export = 'module' ModId | QVar | QTyCon ( '(' '..' ')' | '(' CNameList ')')? | QTyCls ( '(' '..' ')' | '(' QVarList ')')?;
Body = '{' (ImpDeclList (';' TopDecls)? | ImpDeclList) '}' ;
ImpDeclList = ImpDecl + ';';
ImportList = Import * ',' ;
Var = varid;
Con = conid;
ModIdList = (ModId '.')*;
QVarId = ModIdList varid;
QVar = QVarId;
QTyCls = ModIdList TyCls;
QTyCon = ModIdList TyCon;
CName = Var | Con ;
CNameList = CName * ',' ;
QVarList = QVar * ',' ;
Import = Var | TyCon ( '(' '..' ')' | '(' CNameList ')' )? ;
OptQualified = ('qualified')?;
OptQualifiedAs = ('as' ModId)?;
OptImpSpec = '(' ImportList (',')? ')' ;
ImpDecl = 'import' OptQualified ModId OptQualifiedAs OptImpSpec? ;
TopDecls = TopDecl * ';';
TopDecl = 'type' SimpleType '=' Type
| 'data' OptContext SimpleType '=' Constrs OptDeriving
| Decl;
Decl = GenDecl |
(FunLhs | Pat) Rhs ;
OptContext = (Context '=>')? ;
GenDecl = Vars '::' OptContext Type
| Fixity OptInteger Ops;
OptInteger = (integer)? ;
Ops = Op * ',' ;
Fixity = 'infixl' | 'infixr' | 'infix' ;
FunLhs = Var ;
# TODO: incomplete (issue #30) -- only constructor patterns over plain
# variables; the variable-only case is already covered by FunLhs
Pat = Con (Var)* ;
OptWhere = ('where' Decls) ;
DeclList = Decl * ';' ;
Decls = '{' DeclList '}' ;
Rhs = '=' Exp OptWhere
| GdRhs OptWhere;
OptGdRhs = (GdRhs)? ;
# An optional guard expression. (Formerly written with an empty first
# alternative 'Gd = | ExpI ;', hand-parser-only syntax that grammar.pg cannot
# derive; a top-level option normalizes to exactly the same empty-or-present
# alternatives.)
Gd = ExpI? ;
OptExpTypeSignature = ('::' OptContext Type)?;
Exp = ExpI OptExpTypeSignature ;
ExpI = ExpI (QOp ExpI)*;
GdRhs = Gd '=' Exp OptGdRhs ;
Constrs = Constr * '|' ;
Constr = Con '{' FieldDeclList '}';
FieldDeclList = FieldDecl * ',' ;
FieldDecl = Vars '::' (Type | '!' AType) ;
Vars = Var * ',' ;
OptDeriving = (Deriving)? ;
Deriving = 'deriving' (DClass | '(' DClassList ')' ) ;
DClassList = DClass * ',' ;
DClass = QTyCls ;
Context = Class | '(' ClassList ')' ;
ClassList = Class * ',' ;
Class = QTyCls TyVar | QTyCls '(' TyVar ATypeList ')';
Type = BType ('->' Type)? ;
BType = (BType)? AType ;
ATypeList = AType * ;
AType = TyVar
| GTyCon
| '(' (TypeList /*| ',' +*/) ')' # TODO: this should be fixed
| '[' (Type)? ']';
GTyCon = QTyCon
| '(' '->' ')' ;
TypeList = Type * ',' ;
SimpleType = TyCon TyVars ;
TyVars = TyVar * ;
conid = [A-Z] [a-zA-Z_0-9]* ;
varid = [a-zA-Z_] [a-zA-Z_0-9]* ;
TyVar = varid ;
TyCon = conid ;
ModId = conid ;
TyCls = conid ;
Op = varid | conid ;
# TODO: incomplete (issue #30) -- symbolic and backtick-quoted operators are
# not covered; an optionally qualified Op, mirroring QVarId
QOp = ModIdList Op ;
decimal = [0-9]+ ;
octal = [0-7]+ ;
hexadecimal = [0-9A-Fa-f]+ ;
integer = decimal
| ('0o' | '0O') octal
| ('0x' | '0X') hexadecimal ;
whitespace = [ \t\n] ;
Ignore: comment = '--' .* [\n] ;
ncomment = '{-' (.|[\n])* '-}' ;
th = '$(' ([^\)]|[\n])* ')' ;