1 /**************************************************************************
4 * Author: Maria M. Gutierrez *
5 * Modified by: Kevin Hammond *
6 * Last date revised: December 13 1991. KH. *
7 * Modification: Haskell 1.1 Syntax. *
10 * Description: This file contains the LALR(1) grammar for Haskell. *
12 * Entry Point: module *
14 * Problems: None known. *
17 * LALR(1) Syntax for Haskell 1.2 *
19 **************************************************************************/
31 #include "constants.h"
34 /**********************************************************************
37 * Imported Variables and Functions *
40 **********************************************************************/
42 static BOOLEAN expect_ccurly = FALSE; /* Used to signal that a CCURLY could be inserted here */
45 extern char *input_filename;
46 static char *the_module_name;
47 static maybe module_exports;
50 extern list reverse_list();
53 /* For FN, SAMEFN macros */
55 extern BOOLEAN samefn[];
56 extern short icontexts;
59 extern int hsplineno, hspcolno;
60 extern int modulelineno;
61 extern int startlineno;
64 /**********************************************************************
67 * Fixity and Precedence Declarations *
70 **********************************************************************/
72 static int Fixity = 0, Precedence = 0;
74 char *ineg PROTO((char *));
76 long source_version = 0;
77 BOOLEAN pat_check=TRUE;
103 /**********************************************************************
106 * These are lexemes. *
109 **********************************************************************/
112 %token VARID CONID QVARID QCONID
113 VARSYM CONSYM QVARSYM QCONSYM
115 %token INTEGER FLOAT CHAR STRING
116 CHARPRIM STRINGPRIM INTPRIM FLOATPRIM
121 /**********************************************************************
127 **********************************************************************/
129 %token OCURLY CCURLY VCCURLY
130 %token COMMA SEMI OBRACK CBRACK
131 %token BQUOTE OPAREN CPAREN
132 %token OUNBOXPAREN CUNBOXPAREN
135 /**********************************************************************
138 * Reserved Operators *
141 **********************************************************************/
143 %token DOTDOT DCOLON EQUAL LAMBDA
144 %token VBAR RARROW LARROW
145 %token AT LAZY DARROW
148 /**********************************************************************
151 * Reserved Identifiers *
154 **********************************************************************/
156 %token CASE CLASS DATA
157 %token DEFAULT DERIVING DO
158 %token ELSE IF IMPORT
159 %token IN INFIX INFIXL
160 %token INFIXR INSTANCE LET
161 %token MODULE NEWTYPE OF
162 %token THEN TYPE WHERE
165 %token CCALL CCALL_GC CASM CASM_GC
168 %token EXPORT UNSAFE STDCALL C_CALL LABEL
169 %token PASCAL FASTCALL FOREIGN DYNAMIC
171 /**********************************************************************
174 * Special symbols/identifiers which need to be recognised *
177 **********************************************************************/
179 %token MINUS BANG PLUS
180 %token AS HIDING QUALIFIED
183 /**********************************************************************
186 * Special Symbols for the Lexer *
189 **********************************************************************/
191 %token INTERFACE_UPRAGMA SPECIALISE_UPRAGMA
192 %token INLINE_UPRAGMA NOINLINE_UPRAGMA MAGIC_UNFOLDING_UPRAGMA
194 %token SOURCE_UPRAGMA
196 /**********************************************************************
199 * Precedences of the various tokens *
202 **********************************************************************/
207 SCC CASM CCALL CASM_GC CCALL_GC
209 %left VARSYM CONSYM QVARSYM QCONSYM
210 MINUS BQUOTE BANG DARROW PLUS
216 %left OCURLY OBRACK OPAREN
222 /**********************************************************************
225 * Type Declarations *
228 **********************************************************************/
231 %type <ulist> caserest alts quals
233 rbinds rbinds1 rpats rpats1 list_exps list_rest
235 constrs fields conargatypes
238 pats simple_context simple_context_list
241 impdecls maybeimpdecls impdecl
244 lampats cexps gd texps
245 tyvars1 constr_context forall
249 %type <ugrhsb> valrhs altrhs
251 %type <umaybe> maybeexports impspec deriving
252 ext_name opt_sig opt_asig
254 %type <uliteral> lit_constant
256 %type <utree> exp oexp dexp kexp fexp aexp rbind
257 expL oexpL kexpL expLno oexpLno dexpLno kexpLno
258 funlhs funlhs1 funlhs2 funlhs3 qual leftexp
259 pat dpat cpat bpat apat apatc conpat rpat
260 patk bpatk apatck conpatk
263 %type <uid> MINUS PLUS DARROW AS LAZY
264 VARID CONID VARSYM CONSYM
265 var con varop conop op
266 vark varid varsym varsym_nominus
267 tycon modid ccallid tyvar
270 %type <uqid> QVARID QCONID QVARSYM QCONSYM
271 qvarid qconid qvarsym qconsym
272 qvar qcon qvarop qconop qop
273 qvark qconk qtycon qtycls
274 gcon gconk gtycon itycon qop1 qvarop1
277 %type <ubinding> topdecl topdecls topdecls1 letdecls
278 typed datad newtd classd instd defaultd foreignd
279 decl decls decls1 fixdecl fix_op fix_ops valdef
280 maybe_where type_and_maybe_id
282 %type <uttype> polytype
283 conargatype conapptype
287 simple_con_app simple_con_app1 inst_type
289 %type <uconstr> constr constr_after_context field constr1
291 %type <ustring> FLOAT INTEGER INTPRIM
292 FLOATPRIM DOUBLEPRIM CLITLIT
294 %type <uhstring> STRING STRINGPRIM CHAR CHARPRIM
296 %type <uentid> export import
298 %type <ulong> commas importkey get_line_no
301 /**********************************************************************
304 * Start Symbol for the Parser *
307 **********************************************************************/
312 module : modulekey modid maybeexports
314 modulelineno = startlineno;
315 the_module_name = $2;
321 the_module_name = install_literal("Main");
322 module_exports = mknothing();
327 body : ocurly { setstartlineno(); } main_body ccurly
328 | vocurly main_body vccurly
331 main_body : interface_pragma maybeimpdecls topdecls
333 root = mkhmodule(the_module_name, $2, module_exports,
334 $3, source_version,modulelineno);
336 | interface_pragma impdecls
338 root = mkhmodule(the_module_name, $2, module_exports,
339 mknullbind(), source_version, modulelineno);
342 interface_pragma : /* empty */
343 | INTERFACE_UPRAGMA INTEGER END_UPRAGMA SEMI
345 source_version = atoi($2);
349 maybeexports : /* empty */ { $$ = mknothing(); }
350 | OPAREN export_list CPAREN { $$ = mkjust($2); }
351 | OPAREN export_list COMMA CPAREN { $$ = mkjust($2); }
355 export { $$ = lsing($1); }
356 | export_list COMMA export { $$ = lapp($1, $3); }
359 export : qvar { $$ = mkentid($1); }
360 | gtycon { $$ = mkenttype($1); }
361 | gtycon OPAREN DOTDOT CPAREN { $$ = mkenttypeall($1); }
362 | gtycon OPAREN CPAREN { $$ = mkenttypenamed($1,Lnil); }
363 | gtycon OPAREN enames CPAREN { $$ = mkenttypenamed($1,$3); }
364 | MODULE modid { $$ = mkentmod($2); }
367 enames : ename { $$ = lsing($1); }
368 | enames COMMA ename { $$ = lapp($1,$3); }
375 maybeimpdecls : /* empty */ { $$ = Lnil; }
376 | impdecls SEMI { $$ = $1; }
379 impdecls: impdecl { $$ = $1; }
380 | impdecls SEMI impdecl { $$ = lconc($1,$3); }
384 impdecl : importkey modid impspec
385 { $$ = lsing(mkimport($2,0,mknothing(),$3,$1,startlineno)); }
386 | importkey QUALIFIED modid impspec
387 { $$ = lsing(mkimport($3,1,mknothing(),$4,$1,startlineno)); }
388 | importkey QUALIFIED modid AS modid impspec
389 { $$ = lsing(mkimport($3,1,mkjust($5),$6,$1,startlineno)); }
390 | importkey modid AS modid impspec
391 { $$ = lsing(mkimport($3,1,mkjust($4),$5,$1,startlineno)); }
394 impspec : /* empty */ { $$ = mknothing(); }
395 | OPAREN CPAREN { $$ = mkjust(mkleft(Lnil)); }
396 | OPAREN import_list CPAREN { $$ = mkjust(mkleft($2)); }
397 | OPAREN import_list COMMA CPAREN { $$ = mkjust(mkleft($2)); }
398 | HIDING OPAREN CPAREN { $$ = mkjust(mkright(Lnil)); }
399 | HIDING OPAREN import_list CPAREN { $$ = mkjust(mkright($3)); }
400 | HIDING OPAREN import_list COMMA CPAREN { $$ = mkjust(mkright($3)); }
404 import { $$ = lsing($1); }
405 | import_list COMMA import { $$ = lapp($1, $3); }
408 import : var { $$ = mkentid(mknoqual($1)); }
409 | itycon { $$ = mkenttype($1); }
410 | itycon OPAREN DOTDOT CPAREN { $$ = mkenttypeall($1); }
411 | itycon OPAREN CPAREN { $$ = mkenttypenamed($1,Lnil);}
412 | itycon OPAREN inames CPAREN { $$ = mkenttypenamed($1,$3); }
415 itycon : tycon { $$ = mknoqual($1); }
416 | OBRACK CBRACK { $$ = creategid(NILGID); }
417 | OPAREN CPAREN { $$ = creategid(UNITGID); }
418 | OPAREN commas CPAREN { $$ = creategid($2); }
421 inames : iname { $$ = lsing($1); }
422 | inames COMMA iname { $$ = lapp($1,$3); }
424 iname : var { $$ = mknoqual($1); }
425 | con { $$ = mknoqual($1); }
428 /**********************************************************************
431 * Fixes and Decls etc *
434 **********************************************************************/
436 topdecls: topdecls1 opt_semi { $$ = $1; }
439 | topdecls1 SEMI topdecl
458 topdecl : typed { $$ = $1; FN = NULL; SAMEFN = 0; }
459 | datad { $$ = $1; FN = NULL; SAMEFN = 0; }
460 | newtd { $$ = $1; FN = NULL; SAMEFN = 0; }
461 | classd { $$ = $1; FN = NULL; SAMEFN = 0; }
462 | instd { $$ = $1; FN = NULL; SAMEFN = 0; }
463 | defaultd { $$ = $1; FN = NULL; SAMEFN = 0; }
464 | foreignd { $$ = $1; FN = NULL; SAMEFN = 0; }
468 typed : typekey simple_con_app EQUAL tautype { $$ = mknbind($2,$4,startlineno); }
472 datad : datakey simple_con_app EQUAL constrs deriving
473 { $$ = mktbind(Lnil,$2,$4,$5,startlineno); }
474 | datakey simple_context DARROW simple_con_app EQUAL constrs deriving
475 { $$ = mktbind($2,$4,$6,$7,startlineno); }
478 newtd : newtypekey simple_con_app EQUAL constr1 deriving
479 { $$ = mkntbind(Lnil,$2,lsing($4),$5,startlineno); }
480 | newtypekey simple_context DARROW simple_con_app EQUAL constr1 deriving
481 { $$ = mkntbind($2,$4,lsing($6),$7,startlineno); }
484 deriving: /* empty */ { $$ = mknothing(); }
485 | DERIVING dtyclses { $$ = mkjust($2); }
488 classd : classkey apptype DARROW simple_con_app1 maybe_where
489 /* Context can now be more than simple_context */
490 { $$ = mkcbind(type2context($2),$4,$5,startlineno); }
491 | classkey apptype maybe_where
492 /* We have to say apptype rather than simple_con_app1, else
493 we get reduce/reduce errs */
494 { check_class_decl_head($2);
495 $$ = mkcbind(Lnil,$2,$3,startlineno); }
498 instd : instkey inst_type maybe_where { $$ = mkibind($2,$3,startlineno); }
501 /* Compare polytype */
502 /* [July 98: first production was tautype DARROW tautype, but I can't see why.] */
503 inst_type : apptype DARROW apptype { is_context_format( $3, 0 ); /* Check the instance head */
504 $$ = mkforall(Lnil,type2context($1),$3); }
505 | apptype { is_context_format( $1, 0 ); /* Check the instance head */
510 defaultd: defaultkey OPAREN tautypes CPAREN { $$ = mkdbind($3,startlineno); }
511 | defaultkey OPAREN CPAREN { $$ = mkdbind(Lnil,startlineno); }
514 /* FFI primitive declarations - GHC/Hugs specific */
515 foreignd: foreignkey IMPORT callconv ext_name unsafe_flag qvarid DCOLON tautype
516 { $$ = mkfobind($6,$8,$4,$5,$3,FOREIGN_IMPORT,startlineno); }
517 | foreignkey EXPORT callconv ext_name qvarid DCOLON tautype
518 { $$ = mkfobind($5,$7,$4,0,$3,FOREIGN_EXPORT,startlineno); }
519 | foreignkey LABEL ext_name qvarid DCOLON tautype
520 { $$ = mkfobind($4,$6,$3,0,-1,FOREIGN_LABEL,startlineno); }
523 callconv: STDCALL { $$ = CALLCONV_STDCALL; }
524 | C_CALL { $$ = CALLCONV_CCALL; }
525 | PASCAL { $$ = CALLCONV_PASCAL; }
526 | FASTCALL { $$ = CALLCONV_FASTCALL; }
527 /* If you leave out the specification of a calling convention, you'll (probably) get C's. */
528 | /*empty*/ { $$ = CALLCONV_NONE; }
531 ext_name: STRING { $$ = mkjust(lsing($1)); }
532 | STRING STRING { $$ = mkjust(mklcons ($1,lsing($2))); }
533 | DYNAMIC { $$ = mknothing(); }
535 unsafe_flag: UNSAFE { $$ = 1; }
536 | /*empty*/ { $$ = 0; }
539 decls : decls1 opt_semi { $$ = $1; }
559 Note: if there is an iclasop_pragma here, then we must be
560 doing a class-op in an interface -- unless the user is up
561 to real mischief (ugly, but likely to work).
566 | qvarsk DCOLON polytype
567 { $$ = mksbind($1,$3,startlineno);
568 FN = NULL; SAMEFN = 0;
571 | qvark DCOLON polytype
572 { $$ = mksbind(lsing($1),$3,startlineno);
573 FN = NULL; SAMEFN = 0;
576 /* User-specified pragmas come in as "signatures"...
577 They are similar in that they can appear anywhere in the module,
578 and have to be "joined up" with their related entity.
580 Have left out the case specialising to an overloaded type.
581 Let's get real, OK? (WDP)
583 | SPECIALISE_UPRAGMA qvark DCOLON types_and_maybe_ids END_UPRAGMA
585 $$ = mkvspec_uprag($2, $4, startlineno);
586 FN = NULL; SAMEFN = 0;
589 | SPECIALISE_UPRAGMA INSTANCE gtycon atype END_UPRAGMA
591 $$ = mkispec_uprag($3, $4, startlineno);
592 FN = NULL; SAMEFN = 0;
595 | SPECIALISE_UPRAGMA DATA gtycon atypes END_UPRAGMA
597 $$ = mkdspec_uprag($3, $4, startlineno);
598 FN = NULL; SAMEFN = 0;
601 | INLINE_UPRAGMA qvark END_UPRAGMA
603 $$ = mkinline_uprag($2, startlineno);
604 FN = NULL; SAMEFN = 0;
607 | NOINLINE_UPRAGMA qvark END_UPRAGMA
609 $$ = mknoinline_uprag($2, startlineno);
610 FN = NULL; SAMEFN = 0;
613 | MAGIC_UNFOLDING_UPRAGMA qvark vark END_UPRAGMA
615 $$ = mkmagicuf_uprag($2, $3, startlineno);
616 FN = NULL; SAMEFN = 0;
619 /* end of user-specified pragmas */
624 fixdecl : INFIXL INTEGER { Precedence = checkfixity($2); Fixity = INFIXL; }
626 | INFIXR INTEGER { Precedence = checkfixity($2); Fixity = INFIXR; }
628 | INFIX INTEGER { Precedence = checkfixity($2); Fixity = INFIX; }
630 | INFIXL { Fixity = INFIXL; Precedence = 9; }
632 | INFIXR { Fixity = INFIXR; Precedence = 9; }
634 | INFIX { Fixity = INFIX; Precedence = 9; }
638 /* Grotesque global-variable hack to
639 make a separate fixity decl for each op */
641 | fix_ops COMMA fix_op { $$ = mkabind($1,$3); }
644 fix_op : op { $$ = mkfixd(mknoqual($1),infixint(Fixity),Precedence,startlineno); }
647 qvarsk : qvark COMMA qvars_list { $$ = mklcons($1,$3); }
650 qvars_list: qvar { $$ = lsing($1); }
651 | qvars_list COMMA qvar { $$ = lapp($1,$3); }
654 types_and_maybe_ids :
655 type_and_maybe_id { $$ = lsing($1); }
656 | types_and_maybe_ids COMMA type_and_maybe_id { $$ = lapp($1,$3); }
660 tautype { $$ = mkvspec_ty_and_id($1,mknothing()); }
661 | tautype EQUAL qvark { $$ = mkvspec_ty_and_id($1,mkjust($3)); }
664 /**********************************************************************
670 **********************************************************************/
672 /* "DCOLON context => tautype" vs "DCOLON tautype" is a problem,
673 because you can't distinguish between
675 foo :: (Baz a, Baz a)
676 bar :: (Baz a, Baz a) => [a] -> [a] -> [a]
678 with one token of lookahead. The HACK is to have "DCOLON apptype"
679 in the first case, then check that it has the right
680 form C a, or (C1 a, C2 b, ... Cn z) and convert it into a
684 /* --------------------------- */
689 polytype : FORALL tyvars1 DOT
690 apptype DARROW tautype { $$ = mkforall($2, type2context($4), $6); }
691 | FORALL tyvars1 DOT tautype { $$ = mkforall($2, Lnil, $4); }
692 | apptype DARROW tautype { $$ = mkforall(Lnil, type2context($1), $3); }
696 /* --------------------------- */
697 /* tautype is just a monomorphic type.
698 But it may have nested for-alls if we're in a rank-2 type */
700 tautype : apptype RARROW tautype { $$ = mktfun($1,$3); }
701 | apptype { $$ = $1; }
704 tautypes : tautype { $$ = lsing($1); }
705 | tautypes COMMA tautype { $$ = lapp($1,$3); }
708 /* --------------------------- */
709 /* apptype: type application */
711 apptype : apptype atype { $$ = mktapp($1,$2); }
715 /* --------------------------- */
716 /* atype: an atomic or bracketed type: T, x, [ty], tuple ty */
718 atypes : atype { $$ = lsing($1); }
719 | atype atypes { $$ = mklcons($1,$2); }
722 atype : gtycon { $$ = mktname($1); }
723 | tyvar { $$ = mknamedtvar($1); }
725 | OPAREN tautype COMMA
726 tautypes CPAREN { $$ = mkttuple(mklcons($2,$4)); }
728 | OUNBOXPAREN tautype COMMA
729 tautypes CUNBOXPAREN { $$ = mktutuple(mklcons($2,$4)); }
731 | OBRACK tautype CBRACK { $$ = mktllist($2); }
732 | OPAREN polytype CPAREN { $$ = $2; }
735 /* --------------------------- */
737 | OPAREN RARROW CPAREN { $$ = creategid(ARROWGID); }
738 | OBRACK CBRACK { $$ = creategid(NILGID); }
739 | OPAREN CPAREN { $$ = creategid(UNITGID); }
740 | OPAREN commas CPAREN { $$ = creategid($2); }
743 commas : COMMA { $$ = 1; }
744 | commas COMMA { $$ = $1 + 1; }
747 /**********************************************************************
750 * Declaration stuff *
753 **********************************************************************/
755 /* C a b c, where a,b,c are type variables */
756 /* C can be a class or tycon */
758 /* simple_con_app can have no args; simple_con_app1 must have at least one */
759 simple_con_app: gtycon { $$ = mktname($1); }
760 | simple_con_app1 { $$ = $1; }
763 simple_con_app1: gtycon tyvar { $$ = mktapp(mktname($1),mknamedtvar($2)); }
764 | simple_con_app1 tyvar { $$ = mktapp($1, mknamedtvar($2)); }
767 simple_context : OPAREN simple_context_list CPAREN { $$ = $2; }
768 | OPAREN CPAREN { $$ = Lnil; }
769 | simple_con_app1 { $$ = lsing($1); }
772 simple_context_list : simple_con_app1 { $$ = lsing($1); }
773 | simple_context_list COMMA simple_con_app1 { $$ = lapp($1,$3); }
776 constrs : constr { $$ = lsing($1); }
777 | constrs VBAR constr { $$ = lapp($1,$3); }
780 constr : forall constr_context DARROW constr_after_context { $$ = mkconstrex ( $1, $2, $4 ); }
781 | forall constr_after_context { $$ = mkconstrex ( $1, Lnil, $2 ); }
784 forall : { $$ = Lnil }
785 | FORALL tyvars1 DOT { $$ = $2; }
789 : conapptype conargatype { $$ = type2context( mktapp($1,$2) ); }
790 | conargatype { $$ = type2context( $1 ); }
793 constr_after_context :
795 /* We have to parse the constructor application as a *type*, else we get
796 into terrible ambiguity problems. Consider the difference between
798 data T = S Int Int Int `R` Int
800 data T = S Int Int Int
802 It isn't till we get to the operator that we discover that the "S" is
803 part of a type in the first, but part of a constructor application in the
807 /* Con !Int (Tree a) */
808 conapptype { qid tyc; list tys;
809 splittyconapp($1, &tyc, &tys);
810 $$ = mkconstrpre(tyc,tys,hsplineno); }
812 /* (::) (Tree a) Int */
813 | OPAREN qconsym CPAREN conargatypes { $$ = mkconstrpre($2,$4,hsplineno); }
815 /* !Int `Con` Tree a */
816 | conargatype qconop conargatype { $$ = mkconstrinf($1,$2,$3,hsplineno); }
818 /* Con { op1 :: Int } */
819 | qtycon OCURLY CCURLY { $$ = mkconstrrec($1,Lnil,hsplineno); }
820 | qtycon OCURLY fields CCURLY { $$ = mkconstrrec($1,$3,hsplineno); }
821 | OPAREN qconsym CPAREN OCURLY fields CCURLY { $$ = mkconstrrec($2,$5,hsplineno); }
823 /* 1 S/R conflict on OCURLY -> shift */
826 conapptype : gtycon { $$ = mktname($1); }
827 | conapptype conargatype { $$ = mktapp($1, $2); }
830 conargatype : polyatype { $$ = $1; }
831 | BANG polyatype { $$ = mktbang( $2 ); }
834 conargatypes : { $$ = Lnil; }
835 | conargatype conargatypes { $$ = mklcons($1,$2); }
838 fields : field { $$ = lsing($1); }
839 | fields COMMA field { $$ = lapp($1,$3); }
842 field : qvars_list DCOLON polytype { $$ = mkfield($1,$3); }
843 | qvars_list DCOLON BANG polyatype { $$ = mkfield($1,mktbang($4)); }
846 constr1 : gtycon conargatype { $$ = mkconstrnew($1,$2,mknothing(),hsplineno); }
847 | gtycon OCURLY qvar DCOLON polytype CCURLY { $$ = mkconstrnew($1,$5,mkjust($3),hsplineno); }
851 dtyclses: OPAREN dtycls_list CPAREN { $$ = $2; }
852 | OPAREN CPAREN { $$ = Lnil; }
853 | qtycls { $$ = lsing($1); }
856 dtycls_list: qtycls { $$ = lsing($1); }
857 | dtycls_list COMMA qtycls { $$ = lapp($1,$3); }
860 valdef : funlhs opt_sig { checksamefn($1); }
861 get_line_no valrhs { $$ = mkfbind( lsing(mkpmatch( lsing($1), $2, $5 )), $4); }
863 /* Special case for f :: type = e
864 We treat it as a special kind of pattern binding */
865 | qvark DCOLON tautype
866 get_line_no valrhs { $$ = mkpbind( mkrestr( mkident($1), $3 ), $5, $4 );
867 FN = NULL; SAMEFN = 0; }
870 get_line_no valrhs { $$ = mkpbind($1, $3, $2);
871 FN = NULL; SAMEFN = 0; }
873 get_line_no : { $$ = hsplineno; /* startlineno; */ }
875 /* This grammar still isn't quite right
878 you should get a function binding, but actually the (x+3) will
879 parse as a pattern, and you'll get a parse error. */
881 funlhs : patk qvarop cpat { $$ = mkinfixap($2,$1,$3); }
882 | funlhs1 apat { $$ = mkap( $1, $2 ); }
884 funlhs1 : oparenkey funlhs2 CPAREN { $$ = mkpar($2); }
885 | funlhs1 apat { $$ = mkap( $1, $2 ); }
886 | qvark { $$ = mkident($1); }
889 funlhs2 : cpat qvarop cpat { $$ = mkinfixap($2,$1,$3); }
890 | funlhs3 apat { $$ = mkap( $1, $2 ); }
892 funlhs3 : OPAREN funlhs2 CPAREN { $$ = mkpar($2); }
893 | funlhs3 apat { $$ = mkap( $1, $2 ); }
894 | qvar { $$ = mkident($1); }
897 opt_sig : { $$ = mknothing(); }
898 | DCOLON tautype { $$ = mkjust($2); }
901 /* opt_asig is the same, but with a parenthesised type */
902 opt_asig : { $$ = mknothing(); }
903 | DCOLON atype { $$ = mkjust($2); }
906 valrhs : EQUAL get_line_no exp maybe_where { $$ = mkpnoguards($2, $3, $4); }
907 | gdrhs maybe_where { $$ = mkpguards($1, $2); }
910 gdrhs : gd EQUAL get_line_no exp { $$ = lsing(mkpgdexp($1,$3,$4)); }
911 | gd EQUAL get_line_no exp gdrhs { $$ = mklcons(mkpgdexp($1,$3,$4),$5); }
915 WHERE ocurly decls ccurly { $$ = $3; }
916 | WHERE vocurly decls vccurly { $$ = $3; }
917 /* A where containing no decls is OK */
918 | WHERE { $$ = mknullbind(); }
919 | /* empty */ { $$ = mknullbind(); }
922 gd : VBAR quals { $$ = $2; }
926 /**********************************************************************
932 **********************************************************************/
934 exp : oexp DCOLON polytype { $$ = mkrestr($1,$3); }
939 Operators must be left-associative at the same precedence for
940 precedence parsing to work.
942 /* 10 S/R conflicts on qop -> shift */
943 oexp : oexp qop dexp %prec MINUS { $$ = mkinfixap($2,$1,$3); }
948 This comes here because of the funny precedence rules concerning
951 dexp : MINUS kexp { $$ = mknegate($2); }
956 We need to factor out a leading let expression so we can set
957 pat_check=FALSE when parsing (non let) expressions inside stmts and quals
959 expLno : oexpLno DCOLON polytype { $$ = mkrestr($1,$3); }
962 oexpLno : oexpLno qop oexp %prec MINUS { $$ = mkinfixap($2,$1,$3); }
965 dexpLno : MINUS kexp { $$ = mknegate($2); }
969 expL : oexpL DCOLON polytype { $$ = mkrestr($1,$3); }
972 oexpL : oexpL qop oexp %prec MINUS { $$ = mkinfixap($2,$1,$3); }
977 let/if/lambda/case have higher precedence than infix operators.
984 /* kexpL = a let expression */
985 kexpL : letdecls IN exp { $$ = mklet($1,$3); }
988 /* kexpLno = any other expression more tightly binding than operator application */
990 { hsincindent(); /* push new context for FN = NULL; */
991 FN = NULL; /* not actually concerned about indenting */
996 RARROW get_line_no exp /* lambda abstraction */
997 { $$ = mklambda( mkpmatch( $3, $4, mkpnoguards( $7, $8, mknullbind() ) ) ); }
1000 | IF {$<ulong>$ = hsplineno;}
1001 exp THEN exp ELSE exp { $$ = mkife($3,$5,$7,$<ulong>2); }
1003 /* Case Expression */
1004 | CASE {$<ulong>$ = hsplineno;}
1005 exp OF caserest { $$ = mkcasee($3,$5,$<ulong>2); }
1008 | DO {$<ulong>$ = hsplineno;}
1009 dorest { $$ = mkdoe($3,$<ulong>2); }
1011 /* CCALL/CASM Expression */
1012 | CCALL ccallid cexps { $$ = mkccall($2,install_literal("n"),$3); }
1013 | CCALL ccallid { $$ = mkccall($2,install_literal("n"),Lnil); }
1014 | CCALL_GC ccallid cexps { $$ = mkccall($2,install_literal("p"),$3); }
1015 | CCALL_GC ccallid { $$ = mkccall($2,install_literal("p"),Lnil); }
1016 | CASM CLITLIT cexps { $$ = mkccall($2,install_literal("N"),$3); }
1017 | CASM CLITLIT { $$ = mkccall($2,install_literal("N"),Lnil); }
1018 | CASM_GC CLITLIT cexps { $$ = mkccall($2,install_literal("P"),$3); }
1019 | CASM_GC CLITLIT { $$ = mkccall($2,install_literal("P"),Lnil); }
1021 /* SCC Expression */
1026 "\"%s\":%d: _scc_ (`set [profiling] cost centre') ignored\n",
1027 input_filename, hsplineno);
1029 $$ = mkpar($3); /* Note the mkpar(). If we don't have it, then
1030 (x >> _scc_ y >> z) parses as (x >> (y >> z)),
1031 right associated. But the precedence reorganiser expects
1032 the parser to *left* associate all operators unless there
1033 are explicit parens. The _scc_ acts like an explicit paren,
1034 so if we omit it we'd better add explicit parens instead. */
1042 fexp : fexp aexp { $$ = mkap($1,$2); }
1046 /* simple expressions */
1047 aexp : qvar { $$ = mkident($1); }
1048 | gcon { $$ = mkident($1); }
1049 | lit_constant { $$ = mklit($1); }
1050 | OPAREN exp CPAREN { $$ = mkpar($2); } /* mkpar: stop infix parsing at ()'s */
1051 | qcon OCURLY rbinds CCURLY { $$ = mkrecord($1,$3); } /* 1 S/R conflict on OCURLY -> shift */
1052 | OBRACK list_exps CBRACK { $$ = mkllist($2); }
1053 | OPAREN exp COMMA texps CPAREN { $$ = mktuple(mklcons($2,$4)); }
1054 /* unboxed tuples */
1055 | OUNBOXPAREN exp COMMA texps CUNBOXPAREN
1056 { $$ = mkutuple(mklcons($2,$4)); }
1058 /* only in expressions ... */
1059 | aexp OCURLY rbinds1 CCURLY { $$ = mkrupdate($1,$3); }
1060 | OBRACK exp VBAR quals CBRACK { $$ = mkcomprh($2,$4); }
1061 | OBRACK exp COMMA exp DOTDOT exp CBRACK {$$= mkeenum($2,mkjust($4),mkjust($6)); }
1062 | OBRACK exp COMMA exp DOTDOT CBRACK { $$ = mkeenum($2,mkjust($4),mknothing()); }
1063 | OBRACK exp DOTDOT exp CBRACK { $$ = mkeenum($2,mknothing(),mkjust($4)); }
1064 | OBRACK exp DOTDOT CBRACK { $$ = mkeenum($2,mknothing(),mknothing()); }
1065 | OPAREN oexp qop CPAREN { $$ = mklsection($2,$3); }
1066 | OPAREN qop1 oexp CPAREN { $$ = mkrsection($2,$3); }
1068 /* only in patterns ... */
1069 /* these add 2 S/R conflict with with aexp . OCURLY rbinds CCURLY */
1070 | qvar AT aexp { checkinpat(); $$ = mkas($1,$3); }
1071 | LAZY aexp { checkinpat(); $$ = mklazyp($2); }
1074 /* ccall arguments */
1075 cexps : cexps aexp { $$ = lapp($1,$2); }
1076 | aexp { $$ = lsing($1); }
1079 caserest: ocurly alts ccurly { $$ = $2; }
1080 | vocurly alts vccurly { $$ = $2; }
1082 dorest : ocurly stmts ccurly { checkdostmts($2); $$ = $2; }
1083 | vocurly stmts vccurly { checkdostmts($2); $$ = $2; }
1086 rbinds : /* empty */ { $$ = Lnil; }
1090 rbinds1 : rbind { $$ = lsing($1); }
1091 | rbinds1 COMMA rbind { $$ = lapp($1,$3); }
1094 rbind : qvar EQUAL exp { $$ = mkrbind($1,mkjust($3)); }
1097 texps : exp { $$ = lsing($1); }
1098 | exp COMMA texps { $$ = mklcons($1, $3) }
1099 /* right recursion? WDP */
1103 exp { $$ = lsing($1); }
1104 | exp COMMA exp { $$ = mklcons( $1, lsing($3) ); }
1105 | exp COMMA exp COMMA list_rest { $$ = mklcons( $1, mklcons( $3, reverse_list( $5 ))); }
1108 /* Use left recusion for list_rest, because we sometimes get programs with
1109 very long explicit lists. */
1110 list_rest : exp { $$ = lsing($1); }
1111 | list_rest COMMA exp { $$ = mklcons( $3, $1 ); }
1115 exp { $$ = lsing($1); }
1116 | exp COMMA list_exps { $$ = mklcons($1, $3); }
1118 /* right recursion? (WDP)
1120 It has to be this way, though, otherwise you
1121 may do the wrong thing to distinguish between...
1123 [ e1 , e2 .. ] -- an enumeration ...
1124 [ e1 , e2 , e3 ] -- a list
1126 (In fact, if you change the grammar and throw yacc/bison
1127 at it, it *will* do the wrong thing [WDP 94/06])
1130 letdecls: LET { pat_check = TRUE; } ocurly decls ccurly { $$ = $4; }
1131 | LET { pat_check = TRUE; } vocurly decls vccurly { $$ = $4; }
1135 When parsing patterns inside do stmt blocks or quals, we have
1136 to tentatively parse them as expressions, since we don't know at
1137 the time of parsing `p' whether it will be part of "p <- e" (pat)
1138 or "p" (expr). When we eventually can tell the difference, the parse
1139 of `p' is examined to see if it consitutes a syntactically legal pattern
1142 The expr rule used to parse the pattern/expression do contain
1143 pattern-special productions (e.g., _ , a@pat, etc.), which are
1144 illegal in expressions. Since we don't know whether what
1145 we're parsing is an expression rather than a pattern, we turn off
1146 the check and instead do it later.
1148 The rather clumsy way that this check is turned on/off is there
1149 to work around a Bison feature/shortcoming. Turning the flag
1150 on/off just around the relevant nonterminal by decorating it
1151 with simple semantic actions, e.g.,
1153 {pat_check = FALSE; } expLNo { pat_check = TRUE; }
1155 causes Bison to generate a parser where in one state it either
1156 has to reduce/perform a semantic action ( { pat_check = FALSE; })
1157 or reduce an error (the error production used to implement
1158 vccurly.) Bison picks the semantic action, which it ideally shouldn't.
1159 The work around is to lift out the setting of { pat_check = FALSE; }
1160 and then later reset pat_check. Not pretty.
1165 quals : { pat_check = FALSE;} qual { pat_check = TRUE; $$ = lsing($2); }
1166 | quals COMMA { pat_check = FALSE; } qual { pat_check = TRUE; $$ = lapp($1,$4); }
1169 qual : letdecls { $$ = mkseqlet($1); }
1170 | expL { expORpat(LEGIT_EXPR,$1); $$ = $1; }
1171 | expLno { pat_check = TRUE; } leftexp
1173 expORpat(LEGIT_EXPR,$1);
1176 expORpat(LEGIT_PATT,$1);
1182 alts : /* empty */ { $$ = Lnil; }
1183 | alt { $$ = lsing($1); }
1184 | alt SEMI alts { $$ = mklcons($1,$3); }
1185 | SEMI alts { $$ = $2; }
1188 alt : dpat opt_sig altrhs { $$ = mkpmatch( lsing($1), $2, $3 ); }
1191 altrhs : RARROW get_line_no exp maybe_where { $$ = mkpnoguards($2, $3, $4); }
1192 | gdpat maybe_where { $$ = mkpguards($1, $2); }
1195 gdpat : gd RARROW get_line_no exp { $$ = lsing(mkpgdexp($1,$3,$4)); }
1196 | gd RARROW get_line_no exp gdpat { $$ = mklcons(mkpgdexp($1,$3,$4),$5); }
1199 stmts : {pat_check = FALSE;} stmt {pat_check=TRUE; $$ = $2; }
1200 | stmts SEMI {pat_check=FALSE;} stmt {pat_check=TRUE; $$ = lconc($1,$4); }
1203 stmt : /* empty */ { $$ = Lnil; }
1204 | letdecls { $$ = lsing(mkseqlet($1)); }
1205 | expL { expORpat(LEGIT_EXPR,$1); $$ = lsing(mkdoexp($1,hsplineno)); }
1206 | expLno {pat_check=TRUE;} leftexp
1208 expORpat(LEGIT_EXPR,$1);
1209 $$ = lsing(mkdoexp($1,endlineno));
1211 expORpat(LEGIT_PATT,$1);
1212 $$ = lsing(mkdobind($1,$3,endlineno));
1218 leftexp : LARROW exp { $$ = $2; }
1219 | /* empty */ { $$ = NULL; }
1222 /**********************************************************************
1228 **********************************************************************/
1230 pat : dpat DCOLON tautype { $$ = mkrestr($1,$3); }
1234 dpat : qvar PLUS INTEGER { $$ = mkplusp($1, mkinteger($3)); }
1238 cpat : cpat qconop bpat { $$ = mkinfixap($2,$1,$3); }
1244 | qcon OCURLY rpats CCURLY { $$ = mkrecord($1,$3); }
1245 | MINUS INTEGER { $$ = mknegate(mklit(mkinteger($2))); }
1246 | MINUS FLOAT { $$ = mknegate(mklit(mkfloatr($2))); }
1249 conpat : gcon { $$ = mkident($1); }
1250 | conpat apat { $$ = mkap($1,$2); }
1253 apat : gcon { $$ = mkident($1); }
1254 | qcon OCURLY rpats CCURLY { $$ = mkrecord($1,$3); }
1258 apatc : qvar { $$ = mkident($1); }
1259 | qvar AT apat { $$ = mkas($1,$3); }
1260 | lit_constant { $$ = mklit($1); }
1261 | OPAREN pat CPAREN { $$ = mkpar($2); }
1262 | OPAREN pat COMMA pats CPAREN { $$ = mktuple(mklcons($2,$4)); }
1263 | OUNBOXPAREN pat COMMA pats CUNBOXPAREN { $$ = mkutuple(mklcons($2,$4)); }
1264 | OBRACK pats CBRACK { $$ = mkllist($2); }
1265 | LAZY apat { $$ = mklazyp($2); }
1269 INTEGER { $$ = mkinteger($1); }
1270 | FLOAT { $$ = mkfloatr($1); }
1271 | CHAR { $$ = mkcharr($1); }
1272 | STRING { $$ = mkstring($1); }
1273 | CHARPRIM { $$ = mkcharprim($1); }
1274 | STRINGPRIM { $$ = mkstringprim($1); }
1275 | INTPRIM { $$ = mkintprim($1); }
1276 | FLOATPRIM { $$ = mkfloatprim($1); }
1277 | DOUBLEPRIM { $$ = mkdoubleprim($1); }
1278 | CLITLIT /* yurble yurble */ { $$ = mkclitlit($1); }
1281 /* Sequence of apats for a lambda abstraction */
1282 lampats : apat lampats { $$ = mklcons($1,$2); }
1283 | apat { $$ = lsing($1); }
1284 /* right recursion? (WDP) */
1287 /* Comma-separated sequence of pats */
1288 pats : pat COMMA pats { $$ = mklcons($1, $3); }
1289 | pat { $$ = lsing($1); }
1290 /* right recursion? (WDP) */
1293 /* Comma separated sequence of record patterns, each of form 'field=pat' */
1294 rpats : /* empty */ { $$ = Lnil; }
1298 rpats1 : rpat { $$ = lsing($1); }
1299 | rpats1 COMMA rpat { $$ = lapp($1,$3); }
1302 rpat : qvar EQUAL pat { $$ = mkrbind($1,mkjust($3)); }
1306 /* I can't figure out just what these ...k patterns are for.
1307 It seems to have something to do with recording the line number */
1309 /* Corresponds to a cpat */
1310 patk : patk qconop bpat { $$ = mkinfixap($2,$1,$3); }
1316 | qconk OCURLY rpats CCURLY { $$ = mkrecord($1,$3); }
1317 | minuskey INTEGER { $$ = mknegate(mklit(mkinteger($2))); }
1318 | minuskey FLOAT { $$ = mknegate(mklit(mkfloatr($2))); }
1321 conpatk : gconk { $$ = mkident($1); }
1322 | conpatk apat { $$ = mkap($1,$2); }
1325 apatck : qvark { $$ = mkident($1); }
1326 | qvark AT apat { $$ = mkas($1,$3); }
1327 | lit_constant { $$ = mklit($1); setstartlineno(); }
1328 | oparenkey pat CPAREN { $$ = mkpar($2); }
1329 | oparenkey pat COMMA pats CPAREN { $$ = mktuple(mklcons($2,$4)); }
1330 | ounboxparenkey pat COMMA pats CUNBOXPAREN
1331 { $$ = mkutuple(mklcons($2,$4)); }
1332 | obrackkey pats CBRACK { $$ = mkllist($2); }
1333 | lazykey apat { $$ = mklazyp($2); }
1338 | OBRACK CBRACK { $$ = creategid(NILGID); }
1339 | OPAREN CPAREN { $$ = creategid(UNITGID); }
1340 | OPAREN commas CPAREN { $$ = creategid($2); }
1344 | obrackkey CBRACK { $$ = creategid(NILGID); }
1345 | oparenkey CPAREN { $$ = creategid(UNITGID); }
1346 | oparenkey commas CPAREN { $$ = creategid($2); }
1349 /**********************************************************************
1352 * Keywords which record the line start *
1355 **********************************************************************/
1357 importkey: IMPORT { setstartlineno(); $$ = 0; }
1358 | IMPORT SOURCE_UPRAGMA { setstartlineno(); $$ = 1; }
1361 datakey : DATA { setstartlineno();
1364 printf("%u\n",startlineno);
1366 fprintf(stderr,"%u\tdata\n",startlineno);
1371 typekey : TYPE { setstartlineno();
1374 printf("%u\n",startlineno);
1376 fprintf(stderr,"%u\ttype\n",startlineno);
1381 newtypekey : NEWTYPE { setstartlineno();
1384 printf("%u\n",startlineno);
1386 fprintf(stderr,"%u\tnewtype\n",startlineno);
1391 instkey : INSTANCE { setstartlineno();
1394 printf("%u\n",startlineno);
1397 fprintf(stderr,"%u\tinstance\n",startlineno);
1402 defaultkey: DEFAULT { setstartlineno(); }
1405 foreignkey: FOREIGN { setstartlineno(); }
1408 classkey: CLASS { setstartlineno();
1411 printf("%u\n",startlineno);
1413 fprintf(stderr,"%u\tclass\n",startlineno);
1418 modulekey: MODULE { setstartlineno();
1421 printf("%u\n",startlineno);
1423 fprintf(stderr,"%u\tmodule\n",startlineno);
1428 oparenkey: OPAREN { setstartlineno(); }
1431 ounboxparenkey: OUNBOXPAREN { setstartlineno(); }
1434 obrackkey: OBRACK { setstartlineno(); }
1437 lazykey : LAZY { setstartlineno(); }
1440 minuskey: MINUS { setstartlineno(); }
1444 /**********************************************************************
1447 * Basic qualified/unqualified ids/ops *
1450 **********************************************************************/
1453 | OPAREN qvarsym CPAREN { $$ = $2; }
1456 | OPAREN qconsym CPAREN { $$ = $2; }
1459 | BQUOTE qvarid BQUOTE { $$ = $2; }
1462 | BQUOTE qconid BQUOTE { $$ = $2; }
1468 /* Non "-" op, used in right sections */
1473 /* Non "-" varop, used in right sections */
1475 | varsym_nominus { $$ = mknoqual($1); }
1476 | BQUOTE qvarid BQUOTE { $$ = $2; }
1481 | OPAREN varsym CPAREN { $$ = $2; }
1483 con : tycon /* using tycon removes conflicts */
1484 | OPAREN CONSYM CPAREN { $$ = $2; }
1487 | BQUOTE varid BQUOTE { $$ = $2; }
1490 | BQUOTE CONID BQUOTE { $$ = $2; }
1496 qvark : qvarid { setstartlineno(); $$ = $1; }
1497 | oparenkey qvarsym CPAREN { $$ = $2; }
1499 qconk : qconid { setstartlineno(); $$ = $1; }
1500 | oparenkey qconsym CPAREN { $$ = $2; }
1502 vark : varid { setstartlineno(); $$ = $1; }
1503 | oparenkey varsym CPAREN { $$ = $2; }
1507 | varid { $$ = mknoqual($1); }
1510 | varsym { $$ = mknoqual($1); }
1513 | tycon { $$ = mknoqual($1); } /* using tycon removes conflicts */
1516 | CONSYM { $$ = mknoqual($1); }
1519 | tycon { $$ = mknoqual($1); } /* using tycon removes conflicts */
1522 | tycon { $$ = mknoqual($1); } /* using tycon removes conflicts */
1525 varsym : varsym_nominus
1526 | MINUS { $$ = install_literal("-"); }
1529 /* PLUS, BANG are valid varsyms */
1530 varsym_nominus : VARSYM
1531 | PLUS { $$ = install_literal("+"); }
1532 | BANG { $$ = install_literal("!"); }
1533 | DOT { $$ = install_literal("."); }
1536 /* AS HIDING QUALIFIED are valid varids */
1537 varid : varid_noforall
1538 | FORALL { $$ = install_literal("forall"); }
1543 | AS { $$ = install_literal("as"); }
1544 | HIDING { $$ = install_literal("hiding"); }
1545 | QUALIFIED { $$ = install_literal("qualified"); }
1546 /* The rest of these guys are used by the FFI decls, a ghc (and hugs) extension. */
1547 | EXPORT { $$ = install_literal("export"); }
1548 | UNSAFE { $$ = install_literal("unsafe"); }
1549 | DYNAMIC { $$ = install_literal("dynamic"); }
1550 | LABEL { $$ = install_literal("label"); }
1551 | C_CALL { $$ = install_literal("ccall"); }
1552 | STDCALL { $$ = install_literal("stdcall"); }
1553 | PASCAL { $$ = install_literal("pascal"); }
1565 /* ---------------------------------------------- */
1566 tyvar : varid_noforall { $$ = $1; }
1569 /* tyvars1: At least one tyvar */
1570 tyvars1 : tyvar { $$ = lsing($1); }
1571 | tyvar tyvars1 { $$ = mklcons($1,$2); }
1574 /**********************************************************************
1577 * Stuff to do with layout *
1580 **********************************************************************/
1582 ocurly : layout OCURLY { hsincindent(); }
1584 vocurly : layout { hssetindent(); }
1587 layout : { hsindentoff(); }
1593 FN = NULL; SAMEFN = 0;
1598 vccurly : { expect_ccurly = 1; } vccurly1 { expect_ccurly = 0; }
1604 FN = NULL; SAMEFN = 0;
1610 FN = NULL; SAMEFN = 0;
1617 /**********************************************************************
1619 * Error Processing and Reporting *
1621 * (This stuff is here in case we want to use Yacc macros and such.) *
1623 **********************************************************************/
1630 hsperror("pattern syntax used in expression");
1633 /* The parser calls "hsperror" when it sees a
1634 `report this and die' error. It sets the stage
1635 and calls "yyerror".
1637 There should be no direct calls in the parser to
1638 "yyerror", except for the one from "hsperror". Thus,
1639 the only other calls will be from the error productions
1640 introduced by yacc/bison/whatever.
1642 We need to be able to recognise the from-error-production
1643 case, because we sometimes want to say, "Oh, never mind",
1644 because the layout rule kicks into action and may save
1648 static BOOLEAN error_and_I_mean_it = FALSE;
1654 error_and_I_mean_it = TRUE;
1658 extern char *yytext;
1665 /* We want to be able to distinguish 'error'-raised yyerrors
1666 from yyerrors explicitly coded by the parser hacker.
1668 if ( expect_ccurly && ! error_and_I_mean_it ) {
1672 fprintf(stderr, "%s:%d:%d: %s on input: ",
1673 input_filename, hsplineno, hspcolno + 1, s);
1675 if (yyleng == 1 && *yytext == '\0')
1676 fprintf(stderr, "<EOF>");
1680 format_string(stderr, (unsigned char *) yytext, yyleng);
1683 fputc('\n', stderr);
1685 /* a common problem */
1686 if (strcmp(yytext, "#") == 0)
1687 fprintf(stderr, "\t(Perhaps you forgot a `-cpp' or `-fglasgow-exts' flag?)\n");
1694 format_string(fp, s, len)
1701 case '\0': fputs("\\NUL", fp); break;
1702 case '\007': fputs("\\a", fp); break;
1703 case '\010': fputs("\\b", fp); break;
1704 case '\011': fputs("\\t", fp); break;
1705 case '\012': fputs("\\n", fp); break;
1706 case '\013': fputs("\\v", fp); break;
1707 case '\014': fputs("\\f", fp); break;
1708 case '\015': fputs("\\r", fp); break;
1709 case '\033': fputs("\\ESC", fp); break;
1710 case '\034': fputs("\\FS", fp); break;
1711 case '\035': fputs("\\GS", fp); break;
1712 case '\036': fputs("\\RS", fp); break;
1713 case '\037': fputs("\\US", fp); break;
1714 case '\177': fputs("\\DEL", fp); break;
1719 fprintf(fp, "\\^%c", *s + '@');