/* JungTaek Kim Copyright(c) 2000-2004 KAIST/SNU Research On Program Analysis System (National Creative Research Initiative Center 1998-2003) http://ropas.snu.ac.kr/n All rights reserved. This file is distributed under the terms of an Open Source License. */ %{ open String_ast.Ast open Location open Nsyntaxerr let syntax_error loc string = raise (Error(Other(loc,string))) let unclosed o_name o_num c_name c_num = raise(Error(Unclosed(Location.rhs_loc o_num, o_name, Location.rhs_loc c_num, c_name))) type sub = SUB | NOTSUB let loc = Location.symbol_rloc let sloc = Location.rhs_loc let nloc = Location.none let rloc s e = let l = sloc s in let l' = sloc e in {Location.loc_start = l.Location.loc_start; Location.loc_end = l'.Location.loc_end; Location.loc_ghost = false} let mkvarpat s i = VarPat((s,sloc i),sloc i) let mkvarexp s i = VarExp(([],(s,sloc i),sloc i),sloc i) let mktopexp l i = Str( SimpleDec( ValDec([], [(VarPat(("it",nloc),nloc),SeqExp(l,sloc i),sloc i)], sloc i), sloc i), sloc i) %} /* Tokens */ %token AND %token ANDALSO %token AS %token ASSIGN %token CASE %token DO %token ELSE %token END %token EXCEPTION %token FN %token FOR %token FUN %token FUNCTOR %token HANDLE %token IF %token IN %token INCLUDE %token LET %token LOCAL %token OF %token OP %token OPEN %token ORELSE %token RAISE %token REC %token REF %token SIG %token SIGNATURE %token STRUCT %token STRUCTURE %token THEN %token TYPE %token VAL %token WHERE %token WHILE %token NIL %token LID %token UID %token INT %token REAL %token STRING %token CHAR %token PATH %token UNDERSCORE %token LPAREN %token RPAREN %token LBRACE %token RBRACE %token COLON %token SEMI %token SEMISEMI %token COMMA %token STAR %token ARROW %token REVERSEARROW %token DOUBLEARROW %token BAR %token LBRACKET %token RBRACKET %token LBRACKETBAR %token BARRBRACKET %token DOT %token DOTDOTDOT %token MINUS %token MINUSMINUS %token PLUS %token PLUSPLUS %token QUOTE %token EQUAL %token COLONCOLON %token NOT %token BANG %token EOF %token PREFIX %token INFIX0 %token INFIX1 %token INFIX2 %token INFIX3 %token INFIX4 %token INFIX5 /* Precedences and associativities. Lower precedences come first. */ %nonassoc prec_where %left AND %right prec_fn prec_case prec_handle prec_match /* match ... with ... */ %nonassoc prec_one_seq %nonassoc prec_seq %nonassoc HANDLE %right prec_raise /* raise */ %right BAR %left SEMI /* e1; e2 (sequence) */ %nonassoc THEN %nonassoc ELSE %right AS /* as in patterns */ %right ARROW /* -> in type expressions */ %nonassoc COLON %left COMMA /* , in expressions, patterns, types */ %right INFIX0 ASSIGN REVERSEARROW /* assignments */ %left ORELSE /* or */ %left ANDALSO /* & */ %right NOT %left INFIX1 EQUAL %right INFIX2 %right COLONCOLON %left INFIX3 PLUS MINUS %left INFIX4 STAR /* *, / */ %right INFIX5 /* ** */ %nonassoc operator_arg %nonassoc PATH %left DOT /* ** */ %right PREFIX REF PLUSPLUS MINUSMINUS BANG /* Entry points */ %start batch_parse /* for batch parsing (read from file) */ %type batch_parse %start interactive_parse /* for interactive parsing (read from keyboard) */ %type interactive_parse %% varid: LID { ($1,loc()) } ; opidpat: PREFIX { ($1,loc()) } | INFIX0 { ($1,loc()) } | INFIX1 { ($1,loc()) } | INFIX2 { ($1,loc()) } | INFIX3 { ($1,loc()) } | INFIX4 { ($1,loc()) } | INFIX5 { ($1,loc()) } | PLUSPLUS { ("++",loc()) } | MINUSMINUS { ("--",loc()) } | PLUS { ("+",loc()) } | MINUS { ("-",loc()) } | STAR { ("*",loc()) } | EQUAL { ("=",loc()) } | ANDALSO { ("andalso",loc()) } | ORELSE { ("orelse",loc()) } | NOT { ("not",loc()) } opid: PLUSPLUS { ("++",loc()) } | MINUSMINUS { ("--",loc()) } | PLUS { ("+",loc()) } | MINUS { ("-",loc()) } | STAR { ("*",loc()) } | EQUAL { ("=",loc()) } | ANDALSO { ("andalso",loc()) } | ORELSE { ("orelse",loc()) } | NOT { ("not",loc()) } | COLONCOLON { ("::",loc()) } | PREFIX { ($1,loc()) } | INFIX0 { ($1,loc()) } | INFIX1 { ($1,loc()) } | INFIX2 { ($1,loc()) } | INFIX3 { ($1,loc()) } | INFIX4 { ($1,loc()) } | INFIX5 { ($1,loc()) } tyid: LID { ($1,loc()) } | REF { ("ref",loc()) } ; conid: UID { ($1,loc()) } ; strid: UID { ($1,loc()) } ; sigid: UID { ($1,loc()) } ; fctid: UID { ($1,loc()) } ; tyvar: QUOTE LID { ($2,loc()) } ; label: INT { (string_of_int( $1 ),loc()) } | LID { ($1,loc()) } ; varlongid: varid { ([],$1,loc()) } | PATH varlongid { match $2 with (x,y,_) -> (($1,sloc 1)::x,y,loc()) } ; oplongid: PATH opid { ([($1,sloc 1)],$2,loc()) } | PATH oplongid { match $2 with (x,y,_) -> (($1,sloc 1)::x,y,loc()) } tylongid: tyid { ([],$1,loc()) } | PATH tylongid { match $2 with (x,y,_) -> (($1,sloc 1)::x,y,loc()) } ; | PATH error { syntax_error (sloc 2) IllegalTypeId } ; conlongid: conid { ([],$1,loc()) } | PATH conlongid { match $2 with (x,y,_) -> (($1,sloc 1)::x,y,loc()) } ; strlongid: strid { ([],$1,loc()) } | PATH strlongid { match $2 with (x,y,_) -> (($1,sloc 1)::x,y,loc()) } ; sty: tyvar { VarTy($1,loc()) } | tylongid { ConstTy([],$1,loc()) } /* | sty error { syntax_error (sloc 2) IllegalTypeId } */ | sty tylongid { ConstTy([$1],$2,loc()) } | tyarg error { syntax_error (sloc 2) IllegalTypeId } | tyarg tylongid { ConstTy($1,$2,loc()) } | LPAREN error { syntax_error (sloc 2) IllegalType } | LPAREN ty error { unclosed "(" 1 ")" 3 } | LPAREN ty RPAREN { $2 } | LBRACE error { syntax_error (sloc 2) IllegalLabel } | LBRACE label COLON error { syntax_error (sloc 4) IllegalType} | LBRACE label COLON ty error { unclosed "{" 1 "}" 5 } | LBRACE label COLON ty RBRACE { RecordTy([($2,$4,rloc 2 4)],loc()) } | LBRACE tyrow error { syntax_error (sloc 3) IllegalLabel } | LBRACE tyrow label COLON error { syntax_error (sloc 5) IllegalType } | LBRACE tyrow label COLON ty error { unclosed "{" 1 "}" 6 } | LBRACE tyrow label COLON ty RBRACE { RecordTy($2@[($3,$5,rloc 3 5)],loc()) } ; ty: sty { $1 } | tytup { TupleTy($1,loc()) } | ty ARROW ty { FunTy($1,$3,loc()) } | ty ARROW error { syntax_error (sloc 3) IllegalType } ; tytup: sty STAR sty { [$1;$3] } | sty STAR error { syntax_error (sloc 3) IllegalType } | tytup STAR sty { $1@[$3] } | tytup STAR error { syntax_error (sloc 3) IllegalType } ; tyarg: LPAREN tycommas ty RPAREN { $2@[$3] } | LPAREN tycommas error { syntax_error (sloc 3) IllegalType } ; | LPAREN tycommas ty error { unclosed "(" 1 ")" 4; [] } ; tycommas: ty COMMA { [$1] } | tycommas ty COMMA { $1@[$2] } tyrow: label COLON ty COMMA { [($1,$3,loc())] } | tyrow label COLON ty COMMA { $1@[($2,$4,rloc 2 4)] } ; spat: UNDERSCORE { WildPat(loc()) } | INT { IntPat($1,loc()) } | MINUS INT { IntPat(-$2,loc()) } | PLUS INT { IntPat($2,loc()) } | STRING { StringPat($1,loc()) } | CHAR { CharPat($1,loc()) } | NIL { ListPat([],loc()) } | varid { VarPat($1,loc()) } | conlongid { ConPat($1,loc()) } | LPAREN error { syntax_error (sloc 2) IllegalPat } | LPAREN RPAREN { UnitPat(loc()) } | LPAREN opidpat RPAREN { VarPat($2,loc()) } | LPAREN opidpat error { unclosed "(" 1 ")" 3; VarPat($2,loc()) } | LPAREN pat error { unclosed "(" 1 ")" 3 } | LPAREN pat RPAREN { $2 } | LPAREN patcommas error { syntax_error (sloc 3) IllegalPat } | LPAREN patcommas pat error { unclosed "(" 1 ")" 4 } | LPAREN patcommas pat RPAREN { TuplePat($2@[$3],loc()) } | LBRACE error { syntax_error (sloc 2) IllegalLabel } | LBRACE DOTDOTDOT error { unclosed "{" 1 "}" 3 } | LBRACE DOTDOTDOT RBRACE { SubRecordPat([],loc()) } | LBRACE label EQUAL error { syntax_error (sloc 4) IllegalPat } | LBRACE label EQUAL pat error { unclosed "{" 1 "}" 4 } | LBRACE label EQUAL pat RBRACE { SubRecordPat([($2,$4,rloc 2 4)],loc()) } | LBRACE patrow error { syntax_error (sloc 3) IllegalLabel } | LBRACE patrow DOTDOTDOT error { unclosed "{" 1 "}" 4 } | LBRACE patrow DOTDOTDOT RBRACE { SubRecordPat($2,loc()) } | LBRACE patrow LID RBRACE { RecordPat($2@[(($3,loc()),mkvarpat $3 3,loc())],loc()) } | LBRACE patrow LID error { unclosed "{" 1 "}" 4 } | LBRACE patrow label EQUAL error { syntax_error (sloc 5) IllegalPat } | LBRACE patrow label EQUAL pat error { unclosed "{" 1 "}" 6 } | LBRACE patrow label EQUAL pat RBRACE { RecordPat($2@[($3,$5,rloc 3 5)],loc()) } | LBRACKET error { syntax_error (sloc 2) IllegalPat } | LBRACKET RBRACKET { ListPat([],loc()) } | LBRACKET pat error { unclosed "[" 1 "]" 3 } | LBRACKET pat RBRACKET { ListPat([$2],loc()) } | LBRACKET patcommas error { syntax_error (sloc 3) IllegalPat } | LBRACKET patcommas pat error { unclosed "[" 1 "]" 4 } | LBRACKET patcommas pat RBRACKET { ListPat($2@[$3],loc()) } | LBRACKETBAR error { syntax_error (sloc 2) IllegalPat } | LBRACKETBAR BARRBRACKET { ArrayPat([],loc()) } | LBRACKETBAR pat error { unclosed "[|" 1 "|]" 3 } | LBRACKETBAR pat BARRBRACKET { ArrayPat([$2],loc()) } | LBRACKETBAR patcommas error { syntax_error (sloc 3) IllegalPat } | LBRACKETBAR patcommas pat error { unclosed "[|" 1 "|]" 4 } | LBRACKETBAR patcommas pat BARRBRACKET { ArrayPat($2,loc()) } ; apat: spat { $1 } | REF error { syntax_error (sloc 2) IllegalPat } | REF spat { RefPat($2,loc()) } | conlongid spat { AppPat($1,$2,loc()) } | LPAREN COLONCOLON RPAREN error { syntax_error (sloc 4) IllegalPat } | LPAREN COLONCOLON RPAREN spat { AppPat(([],("::",sloc 2),sloc 2),$4,loc()) } | apat COLONCOLON error { syntax_error (sloc 3) IllegalPat } | apat COLONCOLON apat { AppPat(([],("::",sloc 2),sloc 2),TuplePat ([$1;$3],loc()),loc()) } | apat COLON error { syntax_error (sloc 3) IllegalType } ; | apat COLON ty { ConstraintPat($1,$3,loc()) } ; aspat: apat { $1 } | apat AS error { syntax_error (sloc 3) IllegalPat } ; | apat AS apat { match $1 with VarPat(v,_) -> AsPat(v,None,$3,loc()) | ConstraintPat(VarPat(v,_),t,_) -> AsPat(v,Some(t),$3,loc()) | _ -> syntax_error (sloc 1) IllegalAsPat } /* Errorcheck must check $1 is a variable */ orpat: aspat BAR error { syntax_error (sloc 3) IllegalPat } | aspat BAR aspat { [$1;$3] } | orpat BAR error { syntax_error (sloc 3) IllegalPat } ; | orpat BAR aspat { $1@[$3] } pat: aspat { $1 } | orpat { OrPat($1,loc()) } ; patrow: LID COMMA { [(($1,loc()),mkvarpat $1 1,loc())] } | label EQUAL pat COMMA { [($1,$3,loc())] } | patrow LID COMMA { $1@[(($2,loc()),mkvarpat $2 2,loc())] } | patrow label EQUAL pat COMMA { $1@[($2,$4,rloc 2 4)] } patcommas: pat COMMA { [$1] } | patcommas pat COMMA { $1@[$2] } ; sexp: INT { IntExp($1,loc()) } | REAL { RealExp($1,loc()) } | STRING { StringExp($1,loc()) } | CHAR { CharExp($1,loc()) } | NIL { ListExp([],loc()) } | varlongid { VarExp($1,loc()) } | conlongid { ConExp($1,loc()) } | oplongid { VarExp($1,loc()) } | LPAREN error { syntax_error (sloc 2) IllegalExp } | LPAREN RPAREN { UnitExp(loc()) } | LPAREN opid error { unclosed "(" 1 ")" 3 } | LPAREN opid RPAREN { VarExp(([],$2,sloc 2),loc()) } | LPAREN expseq error { unclosed "(" 1 ")" 3 } | LPAREN expseq RPAREN { SeqExp($2,loc()) } | LPAREN expcommas error { syntax_error (sloc 3) IllegalExp } | LPAREN expcommas expseq error { unclosed "(" 1 ")" 4 } | LPAREN expcommas expseq RPAREN { TupleExp($2@[SeqExp($3,sloc 3)],loc()) } | LBRACE error { syntax_error (sloc 2) IllegalLabel } | LBRACE label EQUAL error { syntax_error (sloc 4) IllegalExp } | LBRACE label EQUAL exp error { unclosed "{" 1 "}" 5 } | LBRACE label EQUAL exp RBRACE { RecordExp([($2,$4,rloc 2 4)],loc()) } | LBRACE exprow error { syntax_error (sloc 3) IllegalLabel } | LBRACE exprow label EQUAL error { syntax_error (sloc 5) IllegalExp } | LBRACE exprow label EQUAL exp error { unclosed "(" 1 ")" 6 } | LBRACE exprow label EQUAL exp RBRACE { RecordExp($2@[($3,$5,rloc 3 5)],loc()) } | LBRACKET error { syntax_error (sloc 2) IllegalExp } | LBRACKET RBRACKET { ListExp([],loc()) } | LBRACKET expseq error { unclosed "(" 1 ")" 3 } | LBRACKET expseq RBRACKET { ListExp([SeqExp($2,sloc 2)],loc()) } | LBRACKET expcommas error { syntax_error (sloc 3) IllegalExp } | LBRACKET expcommas expseq error { unclosed "[" 1 "]" 4 } | LBRACKET expcommas expseq RBRACKET { ListExp($2@[SeqExp($3,sloc 3)],loc()) } | LBRACKETBAR error { syntax_error (sloc 2) IllegalExp } | LBRACKETBAR BARRBRACKET { ArrayExp([],loc()) } | LBRACKETBAR expseq error { unclosed "[|" 1 "|]" 3 } | LBRACKETBAR expseq BARRBRACKET { ArrayExp([SeqExp($2,sloc 2)],loc()) } | LBRACKETBAR expcommas error { syntax_error (sloc 3) IllegalExp } | LBRACKETBAR expcommas expseq error { unclosed "[|" 1 "|]" 4 } | LBRACKETBAR expcommas expseq BARRBRACKET { ArrayExp($2@[SeqExp($3,sloc 3)],loc()) } | WHILE error { syntax_error (sloc 2) IllegalExp } | WHILE expseq error { unclosed "while" 3 "do" 5 } | WHILE expseq DO error { syntax_error (sloc 4) IllegalExp } | WHILE expseq DO expseq error{ unclosed "do" 3 "end" 5 } | WHILE expseq DO expseq END { WhileExp(SeqExp($2,sloc 2),SeqExp($4,sloc 4),loc()) } | FOR error { syntax_error (sloc 2) IllegalVarId } | FOR varid EQUAL error { syntax_error (sloc 4) IllegalExp } | FOR varid EQUAL exp SEMI error { syntax_error (sloc 6) IllegalExp } | FOR varid EQUAL exp SEMI exp SEMI error { syntax_error (sloc 8) IllegalExp } | FOR varid EQUAL exp SEMI exp SEMI exp error { unclosed "for" 1 "do" 9 } | FOR varid EQUAL exp SEMI exp SEMI exp DO error { syntax_error (sloc 10) IllegalExp } | FOR varid EQUAL exp SEMI exp SEMI exp DO expseq error { unclosed "do" 9 "end" 11 } | FOR varid EQUAL exp SEMI exp SEMI exp DO expseq END { ForExp($2,$4,$6,$8,SeqExp($10,sloc 10),loc()) } | LET decseq error { unclosed "let" 1 "in" 3 } | LET decseq IN error { syntax_error (sloc 4) IllegalExp } | LET decseq IN expseq error { unclosed "in" 3 "end" 5 } | LET decseq IN expseq END { LetExp(SeqDec($2,sloc 2),SeqExp($4,sloc 4),loc()) } | sexp PLUSPLUS { AppExp(mkvarexp "++" 2,$1,loc()) } | sexp MINUSMINUS { AppExp(mkvarexp "--" 2,$1,loc()) } /* | PREFIX error { syntax_error (sloc 2) IllegalExp } | NOT error { syntax_error (sloc 2) IllegalExp } | PLUS error { syntax_error (sloc 2) IllegalExp } | MINUS error { syntax_error (sloc 2) IllegalExp } */ | REF error { syntax_error (sloc 2) IllegalExp } | BANG error { syntax_error (sloc 2) IllegalExp } | PREFIX sexp { AppExp(mkvarexp $1 1,$2,loc()) } | REF sexp { RefExp($2,loc()) } | BANG sexp { DeRefExp($2,loc()) } | NOT sexp { AppExp(mkvarexp "not" 1,$2,loc()) } | PLUS sexp { $2 } | MINUS sexp { match $2 with IntExp(i,_) -> IntExp(-i,loc()) | x -> AppExp(mkvarexp "unary_minus" 1,x,loc()) } | sexp DOT error { syntax_error (sloc 3) IllegalLabel } | sexp DOT label { RecordFieldExp($1,$3,loc()) } | sexp DOT LBRACKET error { syntax_error (sloc 4) IllegalExp } | sexp DOT LBRACKET expseq error { unclosed "[" 3 "]" 5 } | sexp DOT LBRACKET expseq RBRACKET { ArrayFieldExp($1,SeqExp($4,sloc 4),loc()) } aexp: sexp { $1 } | aexp sexp { AppExp($1, $2,loc()) } /* | aexp LBRACE error { syntax_error (sloc 3) IllegalLabel } */ | aexp LBRACE label REVERSEARROW error { syntax_error (sloc 5) IllegalExp } | aexp LBRACE label REVERSEARROW expseq error { unclosed "{" 2 "}" 6 } | aexp LBRACE label REVERSEARROW expseq RBRACE { SubstRecordExp($1,$3,SeqExp($5,sloc 5),loc()) } opexp: aexp { $1 } %prec operator_arg | opexp INFIX0 error { syntax_error (sloc 3) IllegalExp } | opexp INFIX1 error { syntax_error (sloc 3) IllegalExp } | opexp INFIX2 error { syntax_error (sloc 3) IllegalExp } | opexp INFIX3 error { syntax_error (sloc 3) IllegalExp } | opexp INFIX4 error { syntax_error (sloc 3) IllegalExp } | opexp INFIX5 error { syntax_error (sloc 3) IllegalExp } | opexp ANDALSO error { syntax_error (sloc 3) IllegalExp } | opexp ORELSE error { syntax_error (sloc 3) IllegalExp } | opexp COLONCOLON error { syntax_error (sloc 3) IllegalExp } | opexp PLUS error { syntax_error (sloc 3) IllegalExp } | opexp MINUS error { syntax_error (sloc 3) IllegalExp } | opexp STAR error { syntax_error (sloc 3) IllegalExp } | opexp EQUAL error { syntax_error (sloc 3) IllegalExp } | opexp ASSIGN error { syntax_error (sloc 3) IllegalExp } | opexp INFIX0 opexp { AppExp(mkvarexp $2 2,TupleExp([$1;$3],loc()),loc()) } | opexp INFIX1 opexp { AppExp(mkvarexp $2 2,TupleExp([$1;$3],loc()),loc()) } | opexp INFIX2 opexp { AppExp(mkvarexp $2 2,TupleExp([$1;$3],loc()),loc()) } | opexp INFIX3 opexp { AppExp(mkvarexp $2 2,TupleExp([$1;$3],loc()),loc()) } | opexp INFIX4 opexp { AppExp(mkvarexp $2 2,TupleExp([$1;$3],loc()),loc()) } | opexp INFIX5 opexp { AppExp(mkvarexp $2 2,TupleExp([$1;$3],loc()),loc()) } | opexp ANDALSO opexp { AppExp(mkvarexp "andalso" 2,TupleExp([$1;$3],loc()),loc()) } | opexp ORELSE opexp { AppExp(mkvarexp "orelse" 2,TupleExp([$1;$3],loc()),loc()) } | opexp COLONCOLON opexp { AppExp(mkvarexp "::" 2,TupleExp([$1;$3],loc()),loc()) } | opexp PLUS opexp { AppExp(mkvarexp "+" 2,TupleExp([$1;$3],loc()),loc()) } | opexp MINUS opexp { AppExp(mkvarexp "-" 2,TupleExp([$1;$3],loc()),loc()) } | opexp STAR opexp { AppExp(mkvarexp "*" 2,TupleExp([$1;$3],loc()),loc()) } | opexp EQUAL opexp { AppExp(mkvarexp "=" 2,TupleExp([$1;$3],loc()),loc()) } | opexp ASSIGN opexp { AssignExp($1,$3,loc()) } /* | sexp DOT LBRACKET error { syntax_error (sloc 4) IllegalExp } */ | sexp DOT LBRACKET expseq RBRACKET REVERSEARROW error { syntax_error (sloc 7) IllegalExp } | sexp DOT LBRACKET expseq RBRACKET REVERSEARROW opexp { UpdateArrayExp($1,SeqExp($4,sloc 4),$7,loc()) } exp: opexp { $1 } | exp HANDLE matchlist { HandleExp($1,$3,loc()) } %prec prec_handle | RAISE error { syntax_error (sloc 2) IllegalExp } | RAISE exp { RaiseExp($2,loc()) } %prec prec_raise | FN fnmatchlist { FnExp($2,loc()) } %prec prec_fn | CASE error { syntax_error (sloc 2) IllegalExp } | CASE expseq OF matchlist { CaseExp(SeqExp($2,sloc 2),$4,loc()) } %prec prec_case | IF error { syntax_error (sloc 2) IllegalExp } | IF expseq error { unclosed "if" 1 "then" 3 } | IF expseq THEN error { syntax_error (sloc 4) IllegalExp } | IF expseq THEN exp { IfExp(SeqExp($2,sloc 2),$4,UnitExp(nloc),loc()) } | IF expseq THEN exp ELSE error { syntax_error (sloc 6) IllegalExp } | IF expseq THEN exp ELSE exp { IfExp(SeqExp($2,sloc 2),$4,$6,loc()) } | exp COLON error { syntax_error (sloc 3) IllegalType } | exp COLON ty { ConstraintExp($1,$3,loc()) } ; expseq: exp { [$1] } %prec prec_one_seq | expseq SEMI error { syntax_error (sloc 3) IllegalExp } | expseq SEMI exp { $1@[$3] } %prec prec_seq ; expcommas: expseq COMMA { [SeqExp($1,sloc 1)] } | expcommas expseq COMMA { $1@[SeqExp($2,sloc 2)] } ; exprow: label EQUAL exp COMMA { [($1,$3,loc())] } | exprow label EQUAL exp COMMA { $1@[($2,$4,rloc 2 4)] } ; fnmatchlist: spats DOUBLEARROW error { syntax_error (sloc 3) IllegalExp } | spats DOUBLEARROW expseq { [($1,SeqExp($3,sloc 3),loc())] } %prec prec_match | fnmatchlist BAR error { syntax_error (sloc 3) IllegalPat } | fnmatchlist BAR spats DOUBLEARROW error { syntax_error (sloc 5) IllegalExp } | fnmatchlist BAR spats DOUBLEARROW expseq { $1@[($3,SeqExp($5,sloc 5),rloc 3 5)] } %prec prec_match ; matchlist: pat DOUBLEARROW error { syntax_error (sloc 3) IllegalExp } | pat DOUBLEARROW expseq { [($1,SeqExp($3,sloc 3),loc())] } %prec prec_match | matchlist BAR error { syntax_error (sloc 3) IllegalPat } | matchlist BAR pat DOUBLEARROW error { syntax_error (sloc 5) IllegalExp } | matchlist BAR pat DOUBLEARROW expseq { $1@[($3,SeqExp($5,sloc 5),rloc 3 5)] } %prec prec_match ; dec: VAL error { syntax_error (sloc 2) IllegalPat } | VAL valbinds { ValDec([],$2,loc()) } | VAL tyvseq error { syntax_error (sloc 3) IllegalPat } | VAL tyvseq valbinds { ValDec($2,$3,loc()) } | VAL REC error { syntax_error (sloc 3) IllegalPat } | VAL REC valbinds { RecValDec([],$3,loc()) } | VAL REC tyvseq error { syntax_error (sloc 4) IllegalPat } | VAL REC tyvseq valbinds { RecValDec($3,$4,loc()) } | FUN error { syntax_error (sloc 2) IllegalVarId } | FUN funbinds { FunDec([],$2,loc()) } | FUN tyvseq error { syntax_error (sloc 3) IllegalVarId } | FUN tyvseq funbinds { FunDec($2,$3,loc()) } | TYPE error { syntax_error (sloc 2) IllegalTypeId } | TYPE typbinds { TypeDec($2,loc()) } | EXCEPTION error { syntax_error (sloc 2) IllegalConId } | EXCEPTION exnbinds { ExceptionDec($2,loc()) } | OPEN error { syntax_error (sloc 2) IllegalStrId } | OPEN strlongids { OpenDec($2,loc()) } | LOCAL error { syntax_error (sloc 2) IllegalDec } | LOCAL decseq error { unclosed "local" 1 "in" 3 } | LOCAL decseq IN error { syntax_error (sloc 4) IllegalDec } | LOCAL decseq IN decseq error { unclosed "in" 3 "end" 5 } | LOCAL decseq IN decseq END { LocalDec(SeqDec($2,sloc 2),SeqDec($4,sloc 4),loc()) }; strlongids: strlongid { [$1] } | strlongids strlongid { $1@[$2] } ; decseqelm: dec { $1 } | dec SEMI { $1 } ; decseq: decseqelm { [$1] } | decseq decseqelm { $1@[$2] } ; strdec: dec { SimpleDec($1,loc()) } | STRUCTURE error { syntax_error (sloc 2) IllegalStrId } | STRUCTURE strbinds { StrDec($2, loc()) } ; strdecseqelm: strdec { $1 } | strdec SEMI { $1 } ; strdecseq: /* empty */ { [] } | strdecseq strdecseqelm { $1@[$2] } ; fctdec: FUNCTOR error { syntax_error (sloc 2) IllegalExp } | FUNCTOR fctid LPAREN error { syntax_error (sloc 4) IllegalStrId } | FUNCTOR fctid LPAREN fctarg RPAREN sigexpop EQUAL error { syntax_error (sloc 8) IllegalStrExp } | FUNCTOR fctid LPAREN fctarg RPAREN sigexpop EQUAL strexp { ($2,$4,$6,$8,loc()) } sigexpop: /* empty */ { None } | COLON error { syntax_error (sloc 2) IllegalSigExp } | COLON sigexp { Some($2) } ; fctarg: strid COLON error { syntax_error (sloc 3) IllegalSigExp } | strid COLON sigexp { [($1,$3,loc())] } | fctarg COMMA error { syntax_error (sloc 3) IllegalStrId } | fctarg COMMA strid COLON error { syntax_error (sloc 2) IllegalSigExp } | fctarg COMMA strid COLON sigexp { $1@[($3,$5,rloc 3 5)] } ; sigdec: SIGNATURE error { syntax_error (sloc 2) IllegalSigId } | SIGNATURE sigbinds { ($2,loc()) } ; strexp: strlongid { VarStr($1,loc()) } /* | STRUCT error { syntax_error (sloc 2) IllegalDec } */ | STRUCT strdecseq error { unclosed "struct" 1 "end" 3 } | STRUCT strdecseq END { StrStr(SeqStrDec($2,sloc 2),loc()) } | strexp COLON error { syntax_error (sloc 3) IllegalSigExp } | strexp COLON sigexp { SigStr($1,$3,loc()) } | fctid LPAREN error { syntax_error (sloc 2) IllegalStrExp } | fctid LPAREN strexpseq error { unclosed "(" 2 ")" 4 } | fctid LPAREN strexpseq RPAREN { FctAppStr($1,$3,loc()) } ; strexpseq: strexp { [$1] } | strexpseq COMMA error { syntax_error (sloc 3) IllegalStrExp } | strexpseq COMMA strexp { $1@[$3] } ; valbinds: pat EQUAL error { syntax_error (sloc 3) IllegalExp } | pat EQUAL exp { [($1,$3,loc())] } | valbinds AND error { syntax_error (sloc 3) IllegalPat } | valbinds AND pat EQUAL error { syntax_error (sloc 5) IllegalExp } | valbinds AND pat EQUAL exp { $1@[($3,$5,rloc 3 5)] } ; bodies: varid error { syntax_error (sloc 2) IllegalPat } | varid spat EQUAL error { syntax_error (sloc 4) IllegalExp } | varid spat EQUAL exp { [($1,[$2],$4,loc())] } | varid spats error { syntax_error (sloc 3) IllegalPat } | varid spats spat EQUAL error { syntax_error (sloc 5) IllegalExp } | varid spats spat EQUAL exp { [($1,$2@[$3],$5,loc())] } | LPAREN opid error { unclosed "(" 1 ")" 3 } | LPAREN opid RPAREN error { syntax_error (sloc 4) IllegalPat } | LPAREN opid RPAREN spat EQUAL error { syntax_error (sloc 6) IllegalExp } | LPAREN opid RPAREN spat EQUAL exp { [($2,[$4],$6,loc())] } | LPAREN opid RPAREN spats error { syntax_error (sloc 5) IllegalPat } | LPAREN opid RPAREN spats spat EQUAL error { syntax_error (sloc 7) IllegalExp } | LPAREN opid RPAREN spats spat EQUAL exp { [($2,$4@[$5],$7,loc())] } | bodies BAR error { syntax_error (sloc 3) IllegalVarId } | bodies BAR varid spat EQUAL error { syntax_error (sloc 6) IllegalExp } | bodies BAR varid spat EQUAL exp { $1@[($3,[$4],$6,loc())] } | bodies BAR varid spats error { syntax_error (sloc 5) IllegalPat } | bodies BAR varid spats spat EQUAL error { syntax_error (sloc 7) IllegalExp } | bodies BAR varid spats spat EQUAL exp { $1@[($3,$4@[$5],$7,loc())] } | bodies BAR LPAREN opid error { unclosed "(" 3 ")" 5 } | bodies BAR LPAREN opid RPAREN error { syntax_error (sloc 6) IllegalPat } | bodies BAR LPAREN opid RPAREN spat EQUAL error { syntax_error (sloc 8) IllegalExp } | bodies BAR LPAREN opid RPAREN spat EQUAL exp { $1@[($4,[$6],$8,loc())] } | bodies BAR LPAREN opid RPAREN spats error { syntax_error (sloc 7) IllegalPat } | bodies BAR LPAREN opid RPAREN spats spat EQUAL error { syntax_error (sloc 9) IllegalExp } | bodies BAR LPAREN opid RPAREN spats spat EQUAL exp { $1@[($4,$6@[$7],$9,loc())] } spats: spat { [$1] } | spats spat { $1@[$2] } ; funbinds: bodies { [($1,loc())] } | funbinds AND error { syntax_error (sloc 3) IllegalVarId } | funbinds AND bodies { $1@[($3,sloc 3)] } ; typbind: tyvseqop tyid EQUAL ty { [TypeBind($1,$2,$4,loc())] } | tyvseqop tyid EQUAL error { syntax_error (sloc 4) IllegalType } | tyvseqop tyid EQUAL conbinds { [DataBind($1,$2,$4,loc())] } ; typbinds: typbind { $1 } | typbinds AND error { syntax_error (sloc 3) IllegalTypeId } | typbinds AND typbind { $1@$3 } ; tyvseqop: /* empty */ { [] } | tyvar { [$1] } | LPAREN error { syntax_error (sloc 2) IllegalTypeVar } | LPAREN tyvar error { unclosed "(" 1 ")" 3 } | LPAREN tyvar RPAREN { [$2] } | LPAREN tyvarcommas error { syntax_error (sloc 3) IllegalTypeVar } | LPAREN tyvarcommas tyvar error { unclosed "(" 1 ")" 4 } | LPAREN tyvarcommas tyvar RPAREN { $2@[$3] } ; tyvseq: tyvar { [$1] } | LPAREN error { syntax_error (sloc 2) IllegalTypeVar } | LPAREN tyvar error { unclosed "(" 1 ")" 3 } | LPAREN tyvar RPAREN { [$2] } | LPAREN tyvarcommas error { syntax_error (sloc 3) IllegalTypeVar } | LPAREN tyvarcommas tyvar error { unclosed "(" 1 ")" 4 } | LPAREN tyvarcommas tyvar RPAREN { $2@[$3] } ; tyvarcommas: tyvar COMMA { [$1] } | tyvarcommas tyvar COMMA { $1@[$2] } ; conbind: conid { ($1,None,loc()) } | conid OF error { syntax_error (sloc 3) IllegalType } | conid OF ty { ($1,Some($3),loc()) } ; conbinds: conbind { [$1] } | conbinds BAR error { syntax_error (sloc 3) IllegalConId } | conbinds BAR conbind { $1@[$3] } ; exnbind: conid { ($1,None,loc()) } | conid OF error { syntax_error (sloc 2) IllegalType } | conid OF ty { ($1,Some($3),loc()) } ; exnbinds: exnbind { [$1] } | exnbinds AND error { syntax_error (sloc 3) IllegalConId } | exnbinds AND exnbind { $1@[$3] } ; sigbinds: sigid EQUAL error { syntax_error (sloc 2) IllegalSigExp } | sigid EQUAL sigexp { [($1,$3,loc())] } | sigbinds AND error { syntax_error (sloc 3) IllegalSigId } | sigbinds AND sigid EQUAL error { syntax_error (sloc 5) IllegalSigExp } | sigbinds AND sigid EQUAL sigexp { $1@[($3,$5,rloc 3 5)] } ; strbind: strid EQUAL error { syntax_error (sloc 3) IllegalStrExp } | strid EQUAL strexp { ($1,None,$3,loc()) } | strid COLON error { syntax_error (sloc 2) IllegalSigExp } | strid COLON sigexp EQUAL error { syntax_error (sloc 2) IllegalStrExp } | strid COLON sigexp EQUAL strexp { ($1,Some($3),$5,loc()) } ; strbinds: strbind { [$1] } | strbinds AND error { syntax_error (sloc 3) IllegalStrId } | strbinds AND strbind { $1@[$3] } ; sigexp: sigid { VarSig($1,loc()) } | SIG END { SigSig(SeqSpec([],sloc 2),loc()) } | SIG specseq error { unclosed "sig" 1 "end" 3 } | SIG specseq END { SigSig(SeqSpec($2,sloc 2),loc()) } | sigexp where { ConstraintSig($1,$2,loc()) } ; specseq: spec { [$1] } %prec prec_one_seq | spec SEMI specseq { $1::$3 } | spec specseq { $1::$2 } %prec prec_seq ; spec: VAL error { syntax_error (sloc 2) IllegalVarId } | VAL valdescs { ValSpec($2,loc()) } | TYPE error { syntax_error (sloc 2) IllegalTypeId } | TYPE typdescs { TypeSpec($2,loc()) } | EXCEPTION error { syntax_error (sloc 2) IllegalConId } | EXCEPTION exndescs { ExnSpec($2,loc()) } | INCLUDE error { syntax_error (sloc 2) IllegalSigExp } | INCLUDE sigexp { IncludeSpec($2,loc()) } | STRUCTURE error { syntax_error (sloc 2) IllegalStrId } | STRUCTURE strdescs { StrSpec($2,loc()) } valdescs: varid COLON error { syntax_error (sloc 3) IllegalType } | varid COLON ty { [($1,$3,loc())] } | LPAREN opid error { unclosed "(" 1 ")" 3 } | LPAREN opid RPAREN COLON error { syntax_error (sloc 5) IllegalType } | LPAREN opid RPAREN COLON ty { [($2,$5,loc())] } | valdescs AND error { syntax_error (sloc 3) IllegalVarId } | valdescs AND varid COLON error { syntax_error (sloc 5) IllegalType } | valdescs AND varid COLON ty { $1@[($3,$5,rloc 3 5)] } ; | valdescs AND LPAREN opid error { unclosed "(" 3 ")" 5 } | valdescs AND LPAREN opid RPAREN COLON error { syntax_error (sloc 7) IllegalType } | valdescs AND LPAREN opid RPAREN COLON ty { $1@[($4,$7,rloc 4 7)] } ; typdesc: tyvseqop tyid { [TypeDesc($1,$2,loc())] } | tyvseqop tyid EQUAL error { syntax_error (sloc 4) IllegalType } | tyvseqop tyid EQUAL ty { [TypeBindDesc($1,$2,$4,loc())] } | tyvseqop tyid EQUAL condescs { [DataDesc($1,$2,$4,loc())] } typdescs: typdesc { $1 } | typdescs AND error { syntax_error (sloc 3) IllegalTypeId } ; | typdescs AND typdesc { $1@$3 } ; condescs: condesc { [$1] } | condescs BAR error { syntax_error (sloc 3) IllegalConId } | condescs BAR condesc { $1@[$3] } ; condesc: conid { ($1,None,loc()) } | conid OF error { syntax_error (sloc 3) IllegalType } | conid OF ty { ($1,Some($3),loc()) } ; exndescs: exndesc { [$1] } | exndescs AND error { syntax_error (sloc 3) IllegalConId } | exndescs AND exndesc { $1@[$3] } ; exndesc: conid { ($1,None,loc()) } | conid OF error { syntax_error (sloc 3) IllegalType } | conid OF ty { ($1,Some($3),loc()) } ; strdescs: strid COLON error { syntax_error (sloc 3) IllegalSigExp } | strid COLON sigexp { [($1,$3,loc())] } | strdescs AND error { syntax_error (sloc 3) IllegalStrId } | strdescs AND strid COLON error { syntax_error (sloc 5) IllegalSigExp } | strdescs AND strid COLON sigexp { $1@[($3,$5,rloc 3 5)] } ; where: WHERE TYPE error { syntax_error (sloc 2) IllegalTypeId } | WHERE TYPE longtypebinds { ($3,loc()) } %prec prec_where | LPAREN WHERE TYPE error { syntax_error (sloc 2) IllegalTypeId } | LPAREN WHERE TYPE longtypebinds error { unclosed "(" 1 ")" 5 } | LPAREN WHERE TYPE longtypebinds RPAREN { ($4,loc()) } ; longtypebinds: tyvseqop tylongid EQUAL error { syntax_error (sloc 2) IllegalType } | tyvseqop tylongid EQUAL ty { [($1,$2,$4,loc())] } | longtypebinds AND error { syntax_error (sloc 3) IllegalTypeId } | longtypebinds AND tyvseqop tylongid EQUAL error { syntax_error (sloc 6) IllegalType } | longtypebinds AND tyvseqop tylongid EQUAL ty { $1@[($3,$4,$6,rloc 3 6)] } ; topdec: strdec { Str($1,loc()) } | fctdec { Fct($1,loc()) } | sigdec { Sig($1,loc()) } ; topdecselm: topdec { $1 } | topdec SEMI { $1 } ; topdecs: topdecselm { [$1] } | topdecs topdecselm { $1@[$2] } ; topdecseqtail: /* empty */ { [] } | SEMISEMI { [] } ; | SEMISEMI expseq topdecseqtail { (mktopexp $2 1)::$3 } | SEMISEMI topdec topdecseqtail { $2::$3 } ; | SEMI topdec topdecseqtail { $2::$3 } ; | topdec topdecseqtail { $1::$2 } ; topdecseq: topdecseqtail { $1 } | expseq topdecseqtail { (mktopexp $1 1)::$2 } /* Entry points */ batch_parse: topdecseq EOF { SeqTopDec($1,loc()) } ; interactive_parse: topdecs SEMISEMI { SeqTopDec($1,loc()) } | expseq SEMISEMI { mktopexp $1 1 } | EOF { raise End_of_file } ; %% (* Modification history. 2000/03/27 By Judaigi - Create typbind and typdesc rules. - Change typbinds and typdescs rules according to typbind and typdesc rules. - Change according to changes in ast. *)