%{ open Fnlib Config Mixture Const Globals Location Types Asynt Asyntfn; fun rev acc [] = acc | rev acc (h::t) = rev (h::acc) t; val anonId = "?"; val anonQualId = {qual = "",id =[anonId]}; val mkDerivedfunbind = fn (funid,funsort,modid,sigexp,modexp) => FUNBINDfunbind(funid,(xxLR modid modexp, (FUNCTORmodexp(funsort,modid,ref VARik,sigexp,modexp),ref NONE))) local fun flattenDec (dec as (loc,dec')) acc = case dec' of SEQdec (dec1,dec2) => flattenDec dec1 (flattenDec dec2 acc) | _ => dec::acc in fun mkDerivedDecs (locmodexp as (loc,(modexp',_))) = case modexp' of DECmodexp dec => flattenDec dec [] | _ => [(loc,LOCALdec ((loc,STRUCTUREdec [MODBINDmodbind((loc,anonId),locmodexp)]), (loc,OPENdec [(mkIdInfo (loc,anonQualId) false,ref NONE)])))] end ; %} %token ABSTYPE %token AND %token ANDALSO %token ARROW %token AS %token BAR %token CASE %token CHAR %token COLON %token COLONGT %token COMMA %token DARROW %token DATATYPE %token DLBRACE %token DO %token DOTDOTDOT %token DRBRACE %token ELSE %token END %token EOF %token EQTYPE %token EQUALS %token EXCEPTION %token FN %token FUN %token FUNCTOR %token HANDLE %token HASH %token HASHLBRACKET %token ID %token IF %token IN %token INCLUDE %token INFIX %token INFIXR %token LBRACE %token LBRACKET %token LET %token LOCAL %token LPAREN %token NEGINT %token NONFIX %token NZDIGIT %token NZPOSINT2 %token OF %token OP %token OPEN %token ORELSE %token PRIM_EQTYPE %token PRIM_REFTYPE %token PRIM_TYPE %token PRIM_VAL %token QUAL_ID %token QUAL_STAR %token QUOTEL %token QUOTEM %token QUOTER %token RAISE %token RBRACE %token RBRACKET %token REAL %token REC %token RPAREN %token SEMICOLON %token SHARING %token SIG %token SIGNATURE %token STAR %token STRING %token STRUCT %token STRUCTURE %token THEN %token TYPE %token TYVAR %token UNDERBAR %token VAL %token WHERE %token WHILE %token WITH %token WITHTYPE %token WORD %token ZDIGIT %token ZPOSINT2 %right AND %nonassoc DARROW %nonassoc BAR %nonassoc ELSE %nonassoc DO %nonassoc RAISE %right HANDLE %right ORELSE %right ANDALSO %right AS /* cvr: in Mosml144, COLON was nonassociative but this conflicts with the modexp COLON SigExp production */ /* %nonassoc COLON */ %right ARROW %nonassoc ID EQUALS %right STAR %start ToplevelPhrase %type ToplevelPhrase %start SigFile %type SigFile %start StructFile %type StructFile %start TopSpecFile %type TopSpecFile %start TopDecFile %type TopDecFile %type EOPh %type Ident EqIdent %type IdentWithLoc %type OpIdent TypeIdent LongTypeIdent %type LongIdent LongOpIdent LongOpEqIdent %type TyVar %type TyCon %type ModId %type SigId %type EqIdent_seq1 %type DIGIT_opt Integer NumLabel Arity %type SemiEof %type Label %type SCon %type Dec KWDec_seq1 KWDec KWCoreDec KWModuleDec %type KWDec_seq KWCoreDec_seq %type ValBind AndValBind_opt %type PrimValBind AndPrimValBind_opt %type FnValBind AndFnValBind_opt %type TypBind AndTypBind_opt %type TypDesc AndTypDesc_opt %type DatBind AndDatBind_opt DatBind_0 DatBind_n %type ConBind BarConBind_opt %type WithType_opt %type ExBind AndExBind_opt %type ExDesc AndExDesc_opt %type OfTy_opt ColonTy_opt %type FValBind AndFValBind_opt %type FClauseWithLoc %type FClause BarFClause_opt %type VIdPathInfo %type InfixExp %type AtExp Exp %type ExpComma_seq0 ExpComma_seq1 ExpComma_seq2 QuoteTail ExpQuoteTail %type ExpSemicolon_seq2 %type AtExp_seq1 %type ExpRow_opt ExpRow CommaExpRow_opt %type Match %type MatchWithLoc %type MRule %type InfixPat %type Pat AtPat %type AtPat_seq1 %type PatComma_seq0 PatComma_seq1 PatComma_seq2 %type PatRow_opt PatRow CommaPatRow_opt %type AsPat_opt %type TyConPath %type Ty Ty_sans_STAR AtomicTy %type TupleTy TyComma_seq2 %type TyRow_opt TyRow CommaTyRow_opt %type TyVarSeq TyVarSeq1 TyVarComma_seq1 %type Spec KWSpec KWCoreSpec KWModuleSpec %type Spec_seq CoreSpec_seq %type ValDesc AndValDesc_opt %type LongModId %type LongModIdInfo_seq1 %type ModBind_seq1 AndModBind_opt %type FunBind_seq1 AndFunBind_opt %type SigBind_seq1 AndSigBind_opt %type AtModExp ModExp FunBindBody OptConEqualsModExp %type AtModExp_seq1 %type ModDesc_seq1 AndModDesc_opt %type FunDesc_seq1 AndFunDesc_opt %type SigExp FunDescBody %type SigId_seq2 %type LongTyConEqn LongTyConEqnTail %type LongModIdEqnTail LongModIdEqn %type LongModIdEqnWithLoc %type <(Location * (Asynt.TyVarSeq * Asynt.LongTyCon * Asynt.Ty)) list> WhereType AndWhereType_opt %type <(Asynt.ModId * ModExp) option> WhereModBind_opt %% Ident : ID { $1 } | STAR { "*" } ; IdentWithLoc : Ident { mkLoc($1) } ; OpIdent : Ident { mkIdInfo (mkLoc { qual="", id=[$1] }) false } | OP Ident { mkIdInfo (mkLoc { qual="", id=[$2] }) true } ; EqIdent : Ident { $1 } | EQUALS { "=" } ; ModId : IdentWithLoc { $1 } ; SigId : IdentWithLoc { $1 } ; TypeIdent : ID { mkIdInfo (mkLoc { qual="", id=[$1] }) false } ; LongTypeIdent : TypeIdent { $1 } | QUAL_ID { mkIdInfo (mkLoc $1) false } ; LongIdent : Ident { mkIdInfo (mkLoc { qual="", id=[$1] }) false } | QUAL_ID { mkIdInfo (mkLoc $1) false } | QUAL_STAR { mkIdInfo (mkLoc $1) false } ; LongOpIdent : LongIdent { $1 } | OP Ident { mkIdInfo (mkLoc { qual="", id=[$2] }) true } | OP QUAL_ID { mkIdInfo (mkLoc $2) true } | OP QUAL_STAR { mkIdInfo (mkLoc $2) true } ; LongOpEqIdent : LongOpIdent { $1 } | EQUALS { mkIdInfo (mkLoc { qual="", id=["="] }) false } | OP EQUALS { mkIdInfo (mkLoc { qual="", id=["="] }) true } ; TyVar : TYVAR { mkIdInfo (mkLoc { qual="", id=[$1] }) false } ; EqIdent_seq1 : EqIdent EqIdent_seq1 { $1 :: $2 } | EqIdent { [$1] } ; LongModId : LongOpIdent {$1} LongModIdInfo_seq1 : LongModId LongModIdInfo_seq1 { (($1,ref NONE)) :: $2 } | LongModId { [($1, ref NONE)] } ; DIGIT_opt : ZDIGIT { $1 } | NZDIGIT { $1 } | /* */ { 0 } ; Integer : ZPOSINT2 { $1 } | NZPOSINT2 { $1 } | NEGINT { $1 } | ZDIGIT { $1 } | NZDIGIT { $1 } ; NumLabel : NZPOSINT2 { $1 } | NZDIGIT { $1 } ; Label : Ident { STRINGlab $1 } | NumLabel { INTlab $1 } ; Arity : ZPOSINT2 { $1 } | NZPOSINT2 { $1 } | ZDIGIT { $1 } | NZDIGIT { $1 } ; ToplevelPhrase : Exp EOPh { (mkValIt $1, $2) } | KWDec_seq1 EOPh { ($1, $2) } | EOPh { (mkLoc(EMPTYdec), $1) } ; EOPh : SEMICOLON { false } | EOF { true } ; SemiEof : SEMICOLON SemiEof { } | EOF { } ; Dec : KWDec Dec { mkLoc(SEQdec($1, $2)) } | SEMICOLON Dec { $2 } | /* */ { mkLoc(EMPTYdec) } ; KWDec_seq1 : KWDec KWDec_seq1 { mkLoc(SEQdec($1,$2)) } | KWDec { $1 } ; TopDecFile : KWDec_seq EOF { TopDecs $1 } /* cvr: TODO allow expressions? */ ; StructFile : STRUCTURE ModId EQUALS ModExp SemiEof { NamedStruct{locstrid = $2, locsigid = NONE, decs = mkDerivedDecs $4} } | STRUCTURE ModId COLONGT SigId EQUALS ModExp SemiEof { Abstraction{locstrid = $2, locsigid = $4, decs = mkDerivedDecs $6} } | KWCoreDec_seq EOF { AnonStruct $1 } /* backwards compatability mode * */ ; KWDec_seq : KWDec KWDec_seq { $1 :: $2 } | SEMICOLON KWDec_seq { $2 } | /* */ { [] } ; KWCoreDec_seq : KWCoreDec KWCoreDec_seq { $1 :: $2 } | SEMICOLON KWCoreDec_seq { $2 } | /* */ { [] } ; KWDec : KWCoreDec {$1} | KWModuleDec {$1} ; KWModuleDec: STRUCTURE ModBind_seq1 { mkLoc(STRUCTUREdec $2)} | FUNCTOR FunBind_seq1 { mkLoc(FUNCTORdec $2)} | SIGNATURE SigBind_seq1 { mkLoc(SIGNATUREdec $2)} ; KWCoreDec : VAL ValBind { mkLoc(VALdec ([], $2)) } /* cvr: REVIEW */ | VAL TyVarSeq1 ValBind { mkLoc(VALdec ($2, $3)) } | PRIM_VAL PrimValBind { mkLoc(PRIM_VALdec ([],$2)) } /* cvr: REVIEW */ | PRIM_VAL TyVarSeq1 PrimValBind { mkLoc(PRIM_VALdec ($2,$3)) } | FUN FValBind { mkLoc(FUNdec (ref (UNRESfundec([], $2)))) } | FUN TyVarSeq1 FValBind { mkLoc(FUNdec (ref (UNRESfundec($2, $3)))) } | TYPE TypBind { mkLoc(TYPEdec $2) } | PRIM_TYPE TypDesc { mkLoc(PRIM_TYPEdec(FALSEequ, $2)) } | PRIM_EQTYPE TypDesc { mkLoc(PRIM_TYPEdec(TRUEequ, $2)) } | PRIM_REFTYPE TypDesc { mkLoc(PRIM_TYPEdec(REFequ, $2)) } | DATATYPE DatBind_0 WithType_opt { mkLoc(DATATYPEdec($2,$3)) } | DATATYPE DatBind_n WithType_opt { mkLoc(DATATYPEdec($2,$3)) } /* cvr: this simpler production cause a shift/reduce conflict with datatype replication | DATATYPE DatBind WithType_opt { mkLoc(DATATYPEdec($2,$3)) } */ | DATATYPE TyCon EQUALS DATATYPE TyConPath { mkLoc(DATATYPErepdec($2,$5))} | ABSTYPE DatBind WithType_opt WITH Dec END { mkLoc(ABSTYPEdec($2,$3,$5)) } | EXCEPTION ExBind { mkLoc(EXCEPTIONdec $2) } | LOCAL Dec IN Dec END { mkLoc(LOCALdec($2,$4)) } | OPEN LongModIdInfo_seq1 { mkLoc(OPENdec $2) } | INFIX DIGIT_opt EqIdent_seq1 { mkLoc(FIXITYdec(INFIXst $2, $3)) } | INFIXR DIGIT_opt EqIdent_seq1 { mkLoc(FIXITYdec(INFIXRst $2, $3)) } | NONFIX EqIdent_seq1 { mkLoc(FIXITYdec(NONFIXst, $2)) } ; ValBind : Pat EQUALS Exp AndValBind_opt { let val (pvbs, rvbs) = $4 in (ValBind(ref $1, $3)::pvbs, rvbs) end } | REC FnValBind { ([], $2) } ; AndValBind_opt : AND ValBind { $2 } | /* */ { ([], []) } ; PrimValBind : OpIdent COLON Ty EQUALS Arity STRING AndPrimValBind_opt { ($1, $3, $5, $6) :: $7 } ; AndPrimValBind_opt : AND PrimValBind { $2 } | /* */ { [] } ; FnValBind : Pat EQUALS Exp AndFnValBind_opt { ValBind(ref $1, $3) :: $4 } | REC FnValBind { $2 } ; AndFnValBind_opt : AND FnValBind { $2 } | /* */ { [] } ; TypBind : TyVarSeq TyCon EQUALS Ty AndTypBind_opt { ($1, $2, $4) :: $5 } ; AndTypBind_opt : AND TypBind { $2 } | /* */ { [] } ; DatBind : TyVarSeq TyCon EQUALS ConBind AndDatBind_opt { ($1, $2, $4) :: $5 } ; DatBind_0 : TyCon EQUALS ConBind AndDatBind_opt { ([], $1, $3) :: $4 } ; DatBind_n : TyVarSeq1 TyCon EQUALS ConBind AndDatBind_opt { ($1, $2, $4) :: $5 } ; AndDatBind_opt : AND DatBind { $2 } | /* */ { [] } ; ConBind : OpIdent OfTy_opt BarConBind_opt { ConBind($1, $2) :: $3 } ; BarConBind_opt : BAR ConBind { $2 } | /* */ { [] } ; WithType_opt : WITHTYPE TypBind { SOME $2 } | /* */ { NONE } ExBind : OpIdent OfTy_opt AndExBind_opt { EXDECexbind($1,$2) :: $3 } | OpIdent EQUALS LongOpEqIdent AndExBind_opt { EXEQUALexbind($1,$3) :: $4 } ; AndExBind_opt : AND ExBind { $2 } | /* */ { [] } ; ExDesc : OpIdent OfTy_opt AndExDesc_opt { ($1,$2) :: $3 } ; AndExDesc_opt : AND ExDesc { $2 } | /* */ { [] } ; ColonTy_opt : COLON Ty { SOME $2 } | /* */ { NONE } OfTy_opt : OF Ty { SOME $2 } | /* */ { NONE } ; FValBind : FClauseWithLoc AndFValBind_opt { $1 :: $2 } ; AndFValBind_opt : AND FValBind { $2 } | /* */ { [] } ; FClauseWithLoc : FClause { mkLoc $1 } ; FClause : AtPat_seq1 ColonTy_opt EQUALS Exp BarFClause_opt { let val rhs = (case $2 of SOME ty => (xxLR ty $4, TYPEDexp($4,ty)) | NONE => $4) in FClause(ref $1, rhs) :: $5 end } ; BarFClause_opt : BAR FClause { $2 } | /* */ { [] } ; SCon : Integer { INTscon $1 } | WORD { WORDscon $1 } | CHAR { CHARscon $1 } | REAL { REALscon $1 } | STRING { STRINGscon $1 } ; VIdPathInfo : LongOpEqIdent {RESvidpath $1} ; AtExp : SCon { mkLoc(SCONexp($1, ref NONE)) } | VIdPathInfo { mkLoc(VIDPATHexp(ref $1)) } | LET Dec IN Exp END { mkLoc(LETexp($2,$4)) } | HASH Label { hashLabelExp(mkLoc $2) } | LPAREN Exp RPAREN { mkLoc(PARexp $2) } | LPAREN RPAREN { tupleExp(mkLoc []) } | LPAREN ExpComma_seq2 RPAREN { tupleExp(mkLoc $2) } | LPAREN ExpSemicolon_seq2 RPAREN { seqExp $2 } | LBRACE ExpRow_opt RBRACE { mkLoc(RECexp(ref (RECre $2))) } | LET Dec IN ExpSemicolon_seq2 END { mkLoc(LETexp($2, seqExp $4)) } | LBRACKET STRUCTURE ModExp AS SigExp RBRACKET { mkLoc(STRUCTUREexp($3,$5,ref NONE)) } | LBRACKET FUNCTOR ModExp AS SigExp RBRACKET { mkLoc(FUNCTORexp($3,$5,ref NONE)) } | LBRACKET ExpComma_seq0 RBRACKET { listExp(mkLoc $2) } | HASHLBRACKET ExpComma_seq0 RBRACKET { mkLoc(VECexp $2) } | QUOTEL QuoteTail { listExp(mkLoc $2) } ; QuoteTail : QUOTER { [quoteExp(mkLoc(SCONexp(STRINGscon $1, ref NONE)))] } | QUOTEM ExpQuoteTail { quoteExp(mkLoc(SCONexp(STRINGscon $1, ref NONE))) :: $2 } ; ExpQuoteTail : Exp QuoteTail { antiquoteExp($1) :: $2 } ; ExpComma_seq0 : ExpComma_seq1 { $1 } | /* */ { [] } ; ExpComma_seq1 : Exp COMMA ExpComma_seq1 { $1 :: $3 } | Exp { [$1] } ; ExpComma_seq2 : Exp COMMA ExpComma_seq1 { $1 :: $3 } ; ExpSemicolon_seq2 : Exp SEMICOLON ExpSemicolon_seq2 { $1 :: $3 } | Exp SEMICOLON Exp { [$1, $3] } AtExp_seq1 : AtExp AtExp_seq1 { $1 :: $2 } | AtExp { [$1] } ; ExpRow_opt : ExpRow { $1 } | /* */ { [] } ; ExpRow : Label EQUALS Exp CommaExpRow_opt { ($1,$3)::$4 } ; CommaExpRow_opt : COMMA ExpRow { $2 } | /* */ { [] } ; InfixExp : AtExp_seq1 {UNRESinfixexp $1} Exp : InfixExp { mkLoc(INFIXexp (ref $1)) } | Exp COLON Ty { mkLoc(TYPEDexp($1,$3)) } | Exp ANDALSO Exp { mkLoc(ANDALSOexp($1,$3)) } | Exp ORELSE Exp { mkLoc(ORELSEexp($1,$3)) } | Exp HANDLE Match { mkLoc(HANDLEexp($1,$3)) } | RAISE Exp { mkLoc(RAISEexp $2) } | IF Exp THEN Exp ELSE Exp { mkLoc(IFexp($2,$4,$6)) } | WHILE Exp DO Exp { mkLoc(WHILEexp($2,$4)) } | CASE Exp OF MatchWithLoc { let val (loc, mrules) = $4 in mkLoc(APPexp((loc, FNexp mrules), $2)) end } | FN Match { mkLoc(FNexp $2) } ; MatchWithLoc : Match { mkLoc $1 } ; Match : MRule BAR Match { $1 :: $3 } | MRule %prec DARROW { [$1] } ; MRule : Pat DARROW Exp { MRule(ref [$1],$3) } ; InfixPat : AtPat_seq1 { UNRESinfixpat $1} Pat : InfixPat { mkLoc(INFIXpat (ref $1)) } | Pat COLON Ty { mkLoc(TYPEDpat($1,$3)) } | Pat AS Pat { mkLoc(LAYEREDpat($1,$3)) } ; AtPat : UNDERBAR { mkLoc(WILDCARDpat) } | SCon { mkLoc(SCONpat($1, ref NONE)) } | LongOpIdent { mkLoc(VARpat $1) } | LBRACE PatRow_opt RBRACE { let val (fs, flexible) = $2 in if flexible then mkLoc(RECpat(ref (RECrp(fs, SOME (fresh3DotType()))))) else mkLoc(RECpat(ref (RECrp(fs, NONE)))) end } | LPAREN Pat RPAREN { mkLoc(PARpat $2) } | LPAREN RPAREN { tuplePat(mkLoc []) } | LPAREN PatComma_seq2 RPAREN { tuplePat(mkLoc $2) } | LBRACKET PatComma_seq0 RBRACKET { listPat(mkLoc $2) } | HASHLBRACKET PatComma_seq0 RBRACKET { mkLoc(VECpat $2) } ; PatRow_opt : PatRow { $1 } | /* */ { ([], false) } ; PatRow : DOTDOTDOT { ([],true) } | Label EQUALS Pat CommaPatRow_opt { let val (fs, flexible) = $4 in (($1,$3)::fs, flexible) end } | IdentWithLoc ColonTy_opt AsPat_opt CommaPatRow_opt { let val (fs, flexible) = $4 in (mkLabPatOfId $1 $2 $3::fs, flexible) end } ; AsPat_opt : AS Pat { SOME $2 } | /* */ { NONE } ; CommaPatRow_opt : COMMA PatRow { $2 } | /* */ { ([], false) } ; AtPat_seq1 : AtPat AtPat_seq1 { $1 :: $2 } | AtPat { [$1] } ; PatComma_seq0 : PatComma_seq1 { $1 } | /* */ { [] } ; PatComma_seq1 : Pat COMMA PatComma_seq1 { $1 :: $3 } | Pat { [$1] } ; PatComma_seq2 : Pat COMMA PatComma_seq1 { $1 :: $3 } ; TyCon : ID {mkLoc $1} ; WhereModBind_opt : WHERE ModId OptConEqualsModExp {SOME($2,$3)} | /* */ {NONE} TyConPath : LongTypeIdent WhereModBind_opt {(case $2 of NONE => mkLoc(LONGtyconpath $1) | SOME (modid,modexp) => mkLoc(WHEREtyconpath($1,modid,modexp))) } ; Ty : TupleTy ARROW Ty { mkLoc(FNty( tupleTy $1, $3)) } | TupleTy { tupleTy $1 } ; TupleTy : Ty_sans_STAR { [$1] } | Ty_sans_STAR STAR TupleTy { $1 :: $3 } ; Ty_sans_STAR : LPAREN TyComma_seq2 RPAREN TyConPath { mkLoc(CONty($2, $4)) } | Ty_sans_STAR TyConPath { mkLoc(CONty([$1], $2)) } | AtomicTy { $1 } ; TyComma_seq2 : Ty COMMA TyComma_seq2 { $1 :: $3 } | Ty COMMA Ty { [$1, $3] } ; AtomicTy : TyConPath { mkLoc(CONty([], $1)) } | TyVar { mkLoc(TYVARty $1) } | LBRACE TyRow_opt RBRACE { mkLoc(RECty $2) } | LBRACKET SigExp RBRACKET { mkLoc(PACKty $2) } | LPAREN Ty RPAREN { mkLoc(PARty($2)) } ; TyRow_opt : TyRow { $1 } | /* */ { [] } ; TyRow : Label COLON Ty CommaTyRow_opt { ($1,$3)::$4 } ; CommaTyRow_opt : COMMA TyRow { $2 } | /* */ { [] } ; TyVarSeq : TyVarSeq1 { $1 } | /* */ { [] } ; TyVarSeq1 : TyVar { [$1] } | LPAREN TyVarComma_seq1 RPAREN { $2 } ; TyVarComma_seq1 : TyVar COMMA TyVarComma_seq1 { $1 :: $3 } | TyVar { [$1] } ; LongTyConEqnTail : LongTypeIdent { [$1]} | LongTyConEqn { $1 } LongTyConEqn : LongTypeIdent EQUALS LongTyConEqnTail {$1 :: $3} LongModIdEqnTail : LongModId { [$1]} | LongModIdEqn { $1 } ; LongModIdEqn: LongModId EQUALS LongModIdEqnTail {$1 :: $3}; ; LongModIdEqnWithLoc : LongModIdEqn {mkLoc($1)} ; Spec : Spec KWSpec { mkLoc(SEQspec($1, $2)) } | Spec SHARING TYPE LongTyConEqn {mkLoc(SHARINGTYPEspec($1,$4))} | Spec SHARING LongModIdEqnWithLoc {mkLoc(SHARINGspec($1,$3))} | Spec SEMICOLON { $1 } | /* */ {mkLoc(EMPTYspec) } ; TopSpecFile : Spec_seq EOF { TopSpecs (rev [] $1) } ; SigFile : SIGNATURE SigId EQUALS SigExp SemiEof { NamedSig{locsigid = $2, sigexp = $4 } } | CoreSpec_seq EOF { AnonSig (rev [] $1) } ; Spec_seq : Spec_seq KWSpec { $2 :: $1 } | Spec_seq SEMICOLON { $1 } | /* */ { [] } ; CoreSpec_seq : CoreSpec_seq KWCoreSpec { $2 :: $1 } | CoreSpec_seq SEMICOLON { $1 } | /* */ { [] } ; KWSpec : KWCoreSpec {$1} | KWModuleSpec {$1} ; KWCoreSpec : VAL TyVarSeq ValDesc { mkLoc(VALspec ($2,$3)) } | PRIM_VAL PrimValBind { mkLoc(PRIM_VALspec ([],$2)) } | PRIM_VAL TyVarSeq1 PrimValBind { mkLoc(PRIM_VALspec ($2,$3)) } | TYPE TypBind { mkLoc(TYPEspec $2) } | TYPE TypDesc { mkLoc(TYPEDESCspec(FALSEequ, $2)) } | EQTYPE TypDesc { mkLoc(TYPEDESCspec(TRUEequ, $2)) } | PRIM_REFTYPE TypDesc { mkLoc(TYPEDESCspec(REFequ, $2)) } | DATATYPE DatBind_0 WithType_opt { mkLoc(DATATYPEspec($2,$3)) } | DATATYPE DatBind_n WithType_opt { mkLoc(DATATYPEspec($2,$3)) } /* cvr: this simpler production cause a shift/reduce conflict with datatype replication | DATATYPE DatBind WithType_opt { mkLoc(DATATYPEspec($2,$3)) } */ | DATATYPE TyCon EQUALS DATATYPE TyConPath { mkLoc(DATATYPErepspec($2,$5))} | EXCEPTION ExDesc { mkLoc(EXCEPTIONspec $2) } | LOCAL Spec IN Spec END { mkLoc(LOCALspec($2,$4)) } | OPEN LongModIdInfo_seq1 { mkLoc(OPENspec $2) } | INFIX DIGIT_opt EqIdent_seq1 { mkLoc(FIXITYspec(INFIXst $2, $3)) } | INFIXR DIGIT_opt EqIdent_seq1 { mkLoc(FIXITYspec(INFIXRst $2, $3)) } | NONFIX EqIdent_seq1 { mkLoc(FIXITYspec(NONFIXst, $2)) } ; SigId_seq2 : SigId SigId_seq2 {$1::$2} | SigId SigId {[$1,$2]} ; KWModuleSpec : STRUCTURE ModDesc_seq1 { mkLoc(STRUCTUREspec $2)} | FUNCTOR FunDesc_seq1 { mkLoc(FUNCTORspec $2)} | INCLUDE SigExp { mkLoc(INCLUDEspec $2)} | INCLUDE SigId_seq2 /* derived form */ { mkLoc(foldR (fn locsigid => fn spec => (SEQspec(mkLoc(INCLUDEspec (xLR(locsigid), SIGIDsigexp locsigid)), mkLoc(spec)))) (EMPTYspec) ($2))} | SIGNATURE SigBind_seq1 { mkLoc(SIGNATUREspec $2)} ; ValDesc : OpIdent COLON Ty AndValDesc_opt { ($1, $3) :: $4 } ; AndValDesc_opt : AND ValDesc { $2 } | /* */ { [] } ; TypDesc : TyVarSeq TyCon AndTypDesc_opt { ($1, $2) :: $3 } ; AndTypDesc_opt : AND TypDesc { $2 } | /* */ { [] } ; ModBind_seq1 : ModId OptConEqualsModExp AndModBind_opt { (MODBINDmodbind($1, $2 )) :: $3 } | ModId AS SigExp EQUALS Exp AndModBind_opt { (ASmodbind($1,$3,$5)) :: $6 } ; AndModBind_opt : AND ModBind_seq1 { $2 } | /* */ { [] } ; /* cvr: TODO for some reason, this rule introduces loads of shift_reduce conflicts */ OptConEqualsModExp : EQUALS ModExp {$2} | COLON SigExp EQUALS ModExp {mkLoc((CONmodexp($4,$2)),ref NONE)} | COLONGT SigExp EQUALS ModExp {mkLoc((ABSmodexp($4,$2)),ref NONE)} FunBind_seq1 : /* cvr: TODO rationalize */ ModId AS SigExp EQUALS Exp AndFunBind_opt { (ASfunbind($1,$3,$5)) :: $6 } | ModId OptConEqualsModExp AndFunBind_opt { (FUNBINDfunbind($1, $2 )) :: $3 } | ModId LPAREN ModId COLON SigExp RPAREN FunBindBody AndFunBind_opt {(FUNBINDfunbind($1, mkLoc(FUNCTORmodexp(Generative true,$3,ref VARik,$5,$7), ref NONE)) ::$8)} | ModId LPAREN Spec RPAREN OptConEqualsModExp AndFunBind_opt {let val modid = (xLR $3,anonId) val longmodidinfo = (mkIdInfo (xLR $3, anonQualId) false,ref NONE) in (mkDerivedfunbind($1, Generative true, modid, (xLR $3,SPECsigexp $3), (xLR $5,(LETmodexp((xLR $5,OPENdec([longmodidinfo])), $5), ref NONE)))) :: $6 end} | ModId ModId COLON SigExp FunBindBody AndFunBind_opt {(FUNBINDfunbind($1, mkLoc(FUNCTORmodexp(Applicative,$2,ref VARik,$4,$5), ref NONE)) ::$6)} | ModId SIG Spec END OptConEqualsModExp AndFunBind_opt {let val modid = (xLR $3,anonId) val longmodidinfo = (mkIdInfo (xLR $3, anonQualId) false,ref NONE) in (mkDerivedfunbind($1, Applicative, modid, (xLR $3,SPECsigexp $3), (xLR $5,(LETmodexp((xLR $5,OPENdec([longmodidinfo])), $5), ref NONE)))) :: $6 end} /* cvr: the version below causes a shift/reduce conflict when spec is empty | FunId Spec OptConEqualsModExp AndFunBind_opt {let val modid = (xLR $3,anonId) val longmodidinfo = (mkIdInfo (xLR $2, anonQualId) false,ref NONE) in (mkDerivedfunbind($1, Applicative, modid, (xLR $2,SPECsigexp $2), (xLR $3,(LETmodexp((xLR $3,OPENdec([longmodidinfo])), $3), ref NONE)))) :: $4 end} */ ; AndFunBind_opt : AND FunBind_seq1 { $2 } | /* */ { [] } ; SigBind_seq1 : SigId EQUALS SigExp AndSigBind_opt { (SIGBINDsigbind($1, $3)) :: $4} ; AndSigBind_opt : AND SigBind_seq1 { $2 } | /* */ { [] } ; FunBindBody : OptConEqualsModExp {$1} | LPAREN ModId COLON SigExp RPAREN FunBindBody { mkLoc(FUNCTORmodexp(Generative false,$2,ref VARik,$4,$6),ref NONE) } | ModId COLON SigExp FunBindBody { mkLoc(FUNCTORmodexp(Applicative,$1,ref VARik,$3,$4),ref NONE) } ; AtModExp : STRUCT Dec END {mkLoc((DECmodexp $2,ref NONE))} | LongModId {mkLoc((LONGmodexp $1,ref NONE))} | LET Dec IN ModExp END {mkLoc((LETmodexp($2,$4),ref NONE))} | LPAREN ModExp RPAREN {mkLoc((PARmodexp($2),ref NONE))} | LPAREN Dec RPAREN {mkLoc((PARmodexp((xLR $2,(DECmodexp $2,ref NONE))),ref NONE))} /* derived form */ ; ModExp : AtModExp_seq1 {(case $1 of (atmodexp::atmodexps) => foldL (fn locmodexp => fn locfunexp => (xxLR locfunexp locmodexp, (APPmodexp(locfunexp,locmodexp),ref NONE))) atmodexp atmodexps | [] => fatalError "Parser.ModExp")} | ModExp COLONGT SigExp {mkLoc((ABSmodexp($1,$3),ref NONE))} | ModExp COLON SigExp {mkLoc((CONmodexp($1,$3),ref NONE))} | FUNCTOR ModId COLON SigExp DARROW ModExp {mkLoc((FUNCTORmodexp(Applicative,$2,ref VARik,$4,$6),ref NONE))} | FUNCTOR LPAREN ModId COLON SigExp RPAREN DARROW ModExp {mkLoc((FUNCTORmodexp(Generative false,$3,ref VARik,$5,$8),ref NONE))} | REC LPAREN ModId COLON SigExp RPAREN ModExp {mkLoc((RECmodexp($3,ref NONE,$5,$7),ref NONE))} ; AtModExp_seq1 : AtModExp AtModExp_seq1 { $1:: $2 } | AtModExp { [$1] } ; ModDesc_seq1 : ModId COLON SigExp AndModDesc_opt { (MODDESCmoddesc($1, $3 )) :: $4 } ; AndModDesc_opt : AND ModDesc_seq1 { $2 } | /* */ { [] } ; FunDescBody : COLON SigExp {$2} | LPAREN ModId COLON SigExp RPAREN FunDescBody {mkLoc(FUNSIGsigexp(Generative false,$2,$4,$6))} | ModId COLON SigExp FunDescBody {mkLoc(FUNSIGsigexp(Applicative,$1,$3,$4)) } ; FunDesc_seq1 : ModId FunDescBody AndFunDesc_opt { (FUNDESCfundesc($1, $2)) :: $3 } ; AndFunDesc_opt : AND FunDesc_seq1 { $2 } | /* */ { [] } ; /* AtSigExp : SIG Spec END {mkLoc(SPECsigexp $2)} | SigId {mkLoc(SIGIDsigexp $1)} */ SigExp : SIG Spec END {mkLoc(SPECsigexp $2)} | SigId {mkLoc(SIGIDsigexp $1)} | SigExp WHERE WhereType { foldL (fn (loc,(tyvarseq,longtycon,ty)) => fn sigexp => (loc,WHEREsigexp(sigexp,tyvarseq,longtycon,ty))) ($1) ($3)} | FUNCTOR LPAREN ModId COLON SigExp RPAREN ARROW SigExp {mkLoc(FUNSIGsigexp(Generative false,$3,$5,$8))} | FUNCTOR ModId COLON SigExp ARROW SigExp {mkLoc(FUNSIGsigexp(Applicative,$2,$4,$6))} | REC LPAREN ModId COLON SigExp RPAREN SigExp {mkLoc(RECsigexp($3,$5,$7))} ; WhereType : TYPE TyVarSeq LongTypeIdent EQUALS Ty AndWhereType_opt { mkLoc(($2,$3,$5)) :: $6 } ; AndWhereType_opt : AND WhereType { $2 } | { [] } ;