2 /**********************************************************************
5 * LEX grammar for Haskell. *
6 * ------------------------ *
8 * (c) Copyright K. Hammond, University of Glasgow, *
9 * 10th. February 1989 *
11 * Modification History *
12 * -------------------- *
14 * 22/08/91 kh Initial Haskell 1.1 version. *
15 * 18/10/91 kh Added 'ccall'. *
16 * 19/11/91 kh Tidied generally. *
17 * 04/12/91 kh Added Int#. *
18 * 31/01/92 kh Haskell 1.2 version. *
19 * 19/03/92 Jon Hill Added Data Parallel Notation *
20 * 24/04/92 ps Added 'scc'. *
21 * 03/06/92 kh Changed Infix/Prelude Handling. *
28 **********************************************************************/
31 #include "hsparser-DPH.tab.h"
34 #include "constants.h"
36 char *input_filename = NULL;
41 /**********************************************************************
47 **********************************************************************/
51 unsigned yylastlineno = 0; /* Line number of previous token */
52 unsigned startlineno = 0; /* temp; used to save the line no where something starts */
53 int yylastposn = 0; /* Absolute position of last token */
54 int yylinestart = 0; /* Absolute position of line start */
56 static int yyposn = 0;
58 /* Essential forward declarations */
60 static int readstring(), readasciiname(), readcomment(),
61 lookupascii(), yynewid() /* OLD:, parse_pragma()*/;
64 static BOOLEAN incomment = FALSE;
65 static unsigned commentdepth = 0;
67 static BOOLEAN indenteof = FALSE;
70 /* OLD: char *pragmatype, *pragmaid, *pragmavalue; */
72 /* Special file handling for IMPORTS */
74 static FILE *yyin_save = NULL; /* Saved File Pointer */
75 static char *filename_save; /* File Name */
76 static int yylineno_save = 0, /* Line Number */
77 yyposn_save = 0, /* This Token */
78 yylastposn_save = 0, /* Last Token */
79 yyindent_save, /* Indentation */
80 yylindent_save, /* Left Indentation */
81 yytchar_save = 0, /* Next Input Character */
82 icontexts_save = 0; /* Indent Context Level */
83 static unsigned yylastlineno_save = 0; /* Line Number of Prev. token */
85 static BOOLEAN leof = FALSE; /* EOF for interfaces */
88 extern BOOLEAN ignorePragmas; /* True when we should ignore pragmas */
89 extern BOOLEAN ignoreArityPragmas; /* And various specific flavors... */
90 extern BOOLEAN ignoreSpecializePragmas;
91 extern BOOLEAN ignoreStrictnessPragmas;
92 extern BOOLEAN ignoreUpdatePragmas;
96 /**********************************************************************
102 **********************************************************************/
106 The following section deals with Haskell Layout conventions
107 forcing insertion of ; or } as appropriate
112 yyindent = 0, /* Current indentation */
113 yylindent = 0, /* Indentation of the leftmost char in the current lexeme */
114 yyslindent = -1, /* Indentation of the leftmost char in a string */
115 yytabindent = 0, /* Indentation before a tab in case we have to backtrack */
116 forgetindent = FALSE; /* Don't bother applying indentation rules */
118 static int yysttok = -1; /* Stacked Token:
120 -ve -- ";" inserted before token
121 +ve -- "}" inserted before token
124 short icontexts = 0; /* Which context we're in */
129 Table of indentations: right bit indicates whether to use
130 indentation rules (1 = use rules; 0 = ignore)
133 push one of these "contexts" at every "case" or "where"; the right bit says
134 whether user supplied braces,etc., or not. pop appropriately (yyendindent).
136 ALSO, a push/pop when enter/exit a new file (e.g., on importing). A -1 is
137 pushed (the "column" for "module", "interface" and EOF). The -1 from the initial
138 push is shown just below.
143 static short indenttab[MAX_CONTEXTS] = { -1 };
145 #define INDENTPT (indenttab[icontexts]>>1)
146 #define INDENTON (indenttab[icontexts]&1)
151 return(!leof && !forgetindent && INDENTON);
155 /* Enter new context and set new indentation level */
159 fprintf(stderr,"yysetindent:yyindent=%d,yylindent=%d,INDENTPT[%d]=%d\n",yyindent,yylindent,icontexts,INDENTPT);
162 /* partain: first chk that new indent won't be less than current one;
163 this code doesn't make sense to me; yyindent tells the position of the _end_
164 of the current token; what that has to do with indenting, I don't know.
168 if(yyindent-1 <= INDENTPT)
171 return; /* Empty input OK for Haskell 1.1 */
174 char errbuf[ERR_BUF_SIZE];
175 sprintf(errbuf,"Layout error -- indentation should be > %d cols",INDENTPT);
179 yyentercontext((yylindent << 1) | 1);
183 /* Enter a new context without changing the indentation level */
188 fprintf(stderr,"yyincindent:yyindent=%d,yylindent=%d,INDENTPT[%d]=%d\n",yyindent,yylindent,icontexts,INDENTPT);
190 yyentercontext(indenttab[icontexts] & ~1);
194 /* Turn off indentation processing, usually because an explicit "{" has been seen */
202 /* Enter a new layout context. */
204 yyentercontext(indent)
207 /* Enter new context and set indentation as specified */
208 if(++icontexts >= MAX_CONTEXTS)
210 char errbuf[ERR_BUF_SIZE];
211 sprintf(errbuf,"'wheres' and 'cases' nested too deeply (>%d)", MAX_CONTEXTS-1);
215 forgetindent = FALSE;
216 indenttab[icontexts] = indent;
218 fprintf(stderr,"yyentercontext:indent=%d,yyindent=%d,yylindent=%d,INDENTPT[%d]=%d\n",indent,yyindent,yylindent,icontexts,INDENTPT);
223 /* Exit a layout context */
229 fprintf(stderr,"yyendindent:yyindent=%d,yylindent=%d,INDENTPT[%d]=%d\n",yyindent,yylindent,icontexts,INDENTPT);
237 * Return checks the indentation level and returns ;, } or the specified token.
240 #define RETURN(tok) return(Return(tok))
247 yylindent = yyslindent;
251 yylindent = yyindent-yyleng;
253 if (yyshouldindent())
255 if (yylindent < INDENTPT)
258 fprintf(stderr,"inserted '}' before %d (%d:%d:%d:%d)\n",tok,yylindent,yyindent,yyleng,INDENTPT);
264 else if (yylindent == INDENTPT)
267 fprintf(stderr,"inserted ';' before %d (%d:%d)\n",tok,yylindent,INDENTPT);
276 fprintf(stderr,"returning %d (%d:%d)\n",tok,yylindent,INDENTPT);
282 /**********************************************************************
285 * Input Processing for Interfaces *
288 **********************************************************************/
291 /* setyyin(file) open file as new yyin */
292 /* partain: got rid of .ext stuff */
296 char fbuf[FILENAME_SIZE];
302 if((yyin=fopen(fbuf,"r"))==NULL)
304 char errbuf[ERR_BUF_SIZE];
305 sprintf(errbuf,"can't read \"%-.50s\"", fbuf);
309 yylineno_save = yylineno;
310 yylastlineno_save = yylastlineno;
311 yylineno = yylastlineno = 0;
313 yylastposn_save = yylastposn;
314 yyposn_save = yyposn;
315 yyposn = yylastposn = -1;
317 filename_save = xmalloc(strlen(input_filename)+1);
318 strcpy(filename_save,input_filename);
320 yyindent_save = yyindent;
321 yylindent_save = yylindent;
322 yyindent = yylindent = 0;
323 yyentercontext(-1); /* partain: changed this from 0 */
324 icontexts_save = icontexts;
325 yytchar_save = yytchar;
327 fprintf(stderr,"yytchar = %c(%d)\n",yytchar,(int)yytchar);
331 fprintf(stderr,"reading %s (%d:%d:%d)\n",input_filename,yyindent_save,yylindent_save,INDENTPT);
338 input() is the raw input routine used by yylex()
341 #undef input /* so we can define our own versions to handle layout */
349 yyindent = 0; /* Avoid problems with backtracking over EOL */
351 yytchar=yytchar==EOF?EOF:(++yyposn,yysptr>yysbuf?U(*--yysptr):getc(yyin));
355 yylinestart = yyposn;
361 yytabindent = yyindent; /* Remember TAB indentation - only 1, though! */
362 yyindent += 8 - (yyindent % 8); /* Tabs stops are 8 columns apart */
368 /* Special EOF processing inserts all missing '}'s into the input stream */
372 if(icontexts>icontexts_save && !incomment)
376 indenttab[icontexts] = 0;
381 yyerror("missing '}' at end of file");
384 else if (yyin_save != NULL)
389 new_filename(filename_save);
391 yylineno = yylineno_save;
392 yylastlineno = yylastlineno_save;
395 yyindent = yyindent_save;
396 yylindent = yylindent_save;
398 icontexts = icontexts_save -1;
401 yyposn = yyposn_save;
402 yylastposn = yylastposn_save;
404 fprintf(stderr,"finished reading interface (%d:%d:%d)\n",yyindent,yylindent,INDENTPT);
406 return('\001'); /* YUCK */
418 startlineno = yylineno -1;
420 startlineno = yylineno;
425 * unput() backtracks over a character. With luck it will never backtrack over
426 * multiple EOLs and TABs (since these are lexical delimiters).
433 /* fprintf(stderr,"Unputting %c\n",c); */
437 if(yytchar=='\n' || yytchar=='\r')
442 yyindent = yytabindent;
451 * Redefine yylex to check for stacked tokens, yylex1() is the original yylex()
468 /* not quite right, and should take account of stacking */
469 yylastlineno = yylineno;
475 #define yylex() yylex1()
484 S [!#$%&*+./<=>?@\\^|~:]
485 NS [^!#$%&*+./<=>?@\\^|~:]
487 Char [ !\"#$%&()*+,\-./0-9:;<=>?@A-Z\[\]^_`a-z{|}~]
492 A (NUL|SOH|STX|ETX|EOT|ENQ|ACK|BEL|BS|HT|LF|VT|FF|CR|SO|SI|DLE|DC1|DC2|DC3|DC4|NAK|SYN|ETB|CAN|EM|SUB|ESC|FS|GS|RS|US|SP|DEL)
504 ^"# ".*[\n\r] { char tempf[FILENAME_SIZE];
505 sscanf(yytext+1, "%d \"%[^\"]", &yylineno, tempf);
509 ^"{-# LINE ".*"-}"[\n\r] { /* partain: pragma-style line directive */
510 char tempf[FILENAME_SIZE];
511 sscanf(yytext+9, "%d \"%[^\"]", &yylineno, tempf);
515 "{-# ARITY " { if ( ignorePragmas || ignoreArityPragmas ) {
520 RETURN(ARITY_PRAGMA);
523 "{-# SPECIALIZE " { if ( ignorePragmas || ignoreSpecializePragmas ) {
528 RETURN(SPECIALIZE_PRAGMA);
531 "{-# STRICTNESS " { if ( ignorePragmas || ignoreStrictnessPragmas ) {
536 RETURN(STRICTNESS_PRAGMA);
539 "{-# UPDATE " { if ( ignorePragmas || ignoreUpdatePragmas ) {
544 RETURN(UPDATE_PRAGMA);
548 " #-}" { RETURN(END_PRAGMA); }
550 <PRIM>"void#" { RETURN(VOIDPRIM); }
551 <PRIM>{Id}"#" { yynewid(yytext,yyleng);
552 RETURN(isconstr(yytext)? CONID: VARID);
553 /* Must appear before keywords -- KH */
556 "case" { RETURN(CASE); }
557 "class" { RETURN(CLASS); }
558 "data" { RETURN(DATA); }
559 "default" { RETURN(DEFAULT); }
560 "deriving" { RETURN(DERIVING); }
561 "else" { RETURN(ELSE); }
562 "hiding" { RETURN(HIDING); }
564 "import" { RETURN(IMPORT); }
565 "infix" { RETURN(INFIX); }
566 "infixl" { RETURN(INFIXL); }
567 "infixr" { RETURN(INFIXR); }
568 "instance" { RETURN(INSTANCE); }
569 "interface" { RETURN(INTERFACE); }
570 "module" { RETURN(MODULE); }
572 "renaming" { RETURN(RENAMING); }
573 "then" { RETURN(THEN); }
575 "type" { RETURN(TYPE); }
576 "where" { RETURN(WHERE); }
578 "let" { RETURN(LET); }
579 "ccall" { RETURN(CCALL); }
580 "veryDangerousCcall" { RETURN(CCALL_DANGEROUS); }
581 "casm" { RETURN(CASM); }
582 "veryDangerousCasm" { RETURN(CASM_DANGEROUS); }
583 "scc" { RETURN(SCC); }
585 ".." { RETURN(DOTDOT); }
586 ";" { RETURN(SEMI); }
587 "," { RETURN(COMMA); }
588 "|" { RETURN(VBAR); }
589 "=" { RETURN(EQUAL); }
590 "<-" { RETURN(LARROW); }
591 "->" { RETURN(RARROW); }
592 "=>" { RETURN(DARROW); }
593 "::" { RETURN(DCOLON); }
594 "(" { RETURN(OPAREN); }
595 ")" { RETURN(CPAREN); }
596 "[" { RETURN(OBRACK); }
597 "]" { RETURN(CBRACK); }
598 "{" { RETURN(OCURLY); }
599 "}" { RETURN(CCURLY); }
600 "+" { RETURN(PLUS); }
602 "\\" { RETURN(LAMBDA); }
603 "_" { RETURN(WILDCARD); }
604 "`" { RETURN(BQUOTE); }
605 "<<" { RETURN(OPOD); }
606 ">>" { RETURN(CPOD); }
607 "(|" { RETURN(OPROC); }
608 "|)" { RETURN(CPROC); }
609 "<<-" { RETURN(DRAWNFROM); }
610 "<<=" { RETURN(INDEXFROM); }
613 yytext[yyleng-1] = '\0'; /* clobber the # first */
614 yylval.uid = xstrdup(yytext);
618 yylval.uid = xstrdup(yytext);
622 <PRIM>{N}"."{N}(("e"|"E")("+"|"-")?{N})?"##" {
623 yytext[yyleng-2] = '\0'; /* clobber the # first */
624 yylval.uid = xstrdup(yytext);
628 <PRIM>{N}"."{N}(("e"|"E")("+"|"-")?{N})?"#" {
629 yytext[yyleng-1] = '\0'; /* clobber the # first */
630 yylval.uid = xstrdup(yytext);
634 {N}"."{N}(("e"|"E")("+"|"-")?{N})? {
635 yylval.uid = xstrdup(yytext);
640 <PRIM>"``"[^']+"''" { yytext[yyleng-2] = '\0'; /* clobber '' first */
641 yynewid(yytext+2,yyleng-2);
645 {Id} { yynewid(yytext,yyleng);
646 RETURN(isconstr(yytext)? CONID: VARID);
649 {SId} { yynewid(yytext,yyleng);
653 else if ( *yytext == '-' )
655 RETURN(isconstr(yytext)? CONSYM: VARSYM);
658 <PRIM>"`"{Id}"#`" { yynewid(yytext+1,yyleng-2);
659 RETURN(isconstr(yytext+1)? CONSYM: VARSYM);
664 yylval.uid = xstrdup(yytext);
668 we don't yet return CHARPRIMs
673 '\\(a|b|f|n|r|t|v)' {
674 yytext[1] = escval(yytext[2]);
676 yylval.uid = xstrdup(yytext);
681 yytext[1] = yytext[2];
683 yylval.uid = xstrdup(yytext);
687 '\\{A}' { yytext[yyleng-1] = '\0';
688 if(strcmp(yytext+2,"DEL")==0)
690 yylval.uid = xstrdup("'\177");
695 int a = lookupascii(yytext+2);
700 yylval.uid = xstrdup(yytext);
705 char errbuf[ERR_BUF_SIZE];
706 sprintf(errbuf,"invalid ASCII name in character constant: %s",yytext);
712 '\\{D}+' { if(convchar(yytext+2,yyleng-3,10))
716 '\\o{O}+' { if(convchar(yytext+3,yyleng-4,8))
720 '\\x{H}+' { if(convchar(yytext+3,yyleng-4,16))
724 '\\\^[A-Z\[\\\]^_]' { yytext[1] = yytext[3]-'A'+ 1;
726 yylval.uid = xstrdup(yytext);
730 '\\\^@' { yytext[1] = '\0'; /* partain: most doubtful... */
732 yylval.uid = xstrdup(yytext);
738 yylval.uid = installString(yyleng, yytext);
743 "--".*[\n\r] ; /* hm-hm -style comment */
751 fprintf(stderr, "illegal char: %c (%d) in line %d\n",
752 yytext[0], yytext[0], yylineno);
755 "\002" { if (indenteof)
761 fprintf(stderr, "illegal char: %c (%d) in line %d\n",
762 yytext[0], yytext[0], yylineno);
767 . { fprintf(stderr, "illegal char: %c (%d) in line %d\n",
768 yytext[0], yytext[0], yylineno);
779 /**********************************************************************
782 * YACC/LEX Initialisation etc. *
785 **********************************************************************/
789 We initialise input_filename to "<NONAME>".
790 This allows unnamed sources to be piped into the parser.
795 extern BOOLEAN acceptPrim;
797 input_filename = xstrdup("<NONAME>");
809 if(input_filename != NULL)
810 free(input_filename);
811 input_filename = xstrdup(f);
822 /**********************************************************************
828 **********************************************************************/
833 readcomment() reads Haskell nested comments {- ... -}
834 Indentation is automatically taken care of since input() is used.
836 While in principle this could be done using Lex rules, in
837 practice it's easier and neater to use special code for this
846 while ((c = input()) != '-' && !eof(c))
849 if ((c=input()) == '-')
854 yyerror("comment not terminated by end of file");
866 yyerror("comment not terminated by end of file");
874 eof(c) Returns TRUE when EOF read.
880 return (c == 0 || c == 1 && leof);
885 /**********************************************************************
888 * Identifier Processing *
891 **********************************************************************/
895 yynewid Enters an id of length n into the symbol table.
898 static yynewid(yyt,len)
905 yylval.uid = installid(yybuf);
910 isconstr(s) True iff s is a constructor id.
916 return(*s == ':' || isupper(*s));
922 /**********************************************************************
925 * Character Kind Predicates *
928 **********************************************************************/
932 * ishspace(ch) determines whether ch is a valid Haskell space character
936 static int ishspace(ch)
939 return(ch == '\n' || ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f');
944 * isddigit(ch) determines whether ch is a valid Decimal digit
948 static int isddigit(ch)
951 return (isdigit(ch));
956 * ishexdigit(ch) determines whether ch is a valid Hexadecimal digit
960 static int ishexdigit(ch)
963 return (isdigit(ch) || (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f'));
967 * isodigit(ch) determines whether ch is a valid Octal digit
971 static int isodigit(ch)
974 return ((ch >= '0' && ch <= '7'));
978 /**********************************************************************
981 * Lexical Analysis of Strings -- Gaps and escapes mean that *
982 * lex isn't (wo)man enough for this job. *
985 **********************************************************************/
989 * readstring() reads a string constant and places it in yytext
996 yyslindent = yyindent-1;
1010 ch = readescnum(isddigit,10,ch);
1016 ch = readescnum(isodigit,8,ch);
1019 char errbuf[ERR_BUF_SIZE];
1020 sprintf(errbuf,"strange Octal character code (%c) in string",ch);
1029 ch = readescnum(ishexdigit,16,ch);
1032 char errbuf[ERR_BUF_SIZE];
1033 sprintf(errbuf,"strange Hexadecimal character code (%c) in string",ch);
1038 else if(ch == '"' || ch == '\\' || ch == '\'')
1041 else if (isupper(ch))
1043 if((ch = readasciiname(ch)) == -1)
1044 yyerror("invalid ASCII name in string");
1049 if(isupper(ch = input()) || (ch >= '[' && ch <= '_'))
1055 char errbuf[ERR_BUF_SIZE];
1056 sprintf(errbuf,"strange control sequence (^%c) in string",ch);
1061 else if (ishspace(ch))
1063 /* partain: we may want clearer error msgs if \v, \f seen */
1065 while (ch == '\t' || ch == ' ')
1068 if (ch != '\n' && ch != '\r')
1069 yyerror("newline not seen when expected in string gap");
1073 while (ch == '\t' || ch == ' ')
1077 yyerror("trailing \\ not seen when expected in string gap");
1108 char errbuf[ERR_BUF_SIZE];
1109 sprintf(errbuf,"invalid escape sequence (\\%c) in string",ch);
1114 else if (ch == '\n' || ch == '\r' || ch == '\f' || ch == '\v' || ch == 0 || ch == '"')
1117 else if (!isprint(ch) && !ishspace(ch))
1119 char errbuf[ERR_BUF_SIZE];
1120 sprintf(errbuf,"invalid character (%c) in string",ch);
1124 if((yyleng < YYLMAX-3 && ch != -1) || (yyleng == YYLMAX-3 && (ch == '\t' || ch == '\\')))
1126 /* The LML back-end treats \\ and \t specially in strings... */
1128 if(ch == '\t' || ch == '\\')
1130 yytext[yyleng++] = '\\';
1136 yytext[yyleng++] = ch;
1137 yytext[yyleng] = '\0';
1142 char errbuf[ERR_BUF_SIZE];
1143 sprintf(errbuf,"string too long (> %d characters)",YYLMAX-3-2);
1150 yyerror("string incorrectly terminated");
1154 yytext[yyleng++] = '"';
1155 yytext[yyleng] = '\0';
1158 fprintf(stderr,"string: %s (%d chars)\n",yytext,yyleng-2);
1164 /**********************************************************************
1167 * Haskell String and Character Escape Codes *
1170 **********************************************************************/
1173 /* Names of ASCII control characters, used in strings and character constants */
1175 static char *asciinames[] =
1177 "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL", "BS", "HT",
1178 "LF", "VT", "FF", "CR", "SO", "SI", "DLE", "DC1", "DC2", "DC3",
1179 "DC4", "NAK", "SYN", "ETB", "CAN", "EM", "SUB", "ESC", "FS", "GS",
1180 "RS", "US", "SP", "DEL"
1185 * readasciiname() read ASCII name and translate to an ASCII code
1186 * -1 indicates invalid name
1189 static int readasciiname(ch)
1195 if(!isupper(asciiname[1]= input()))
1197 unput(asciiname[1]);
1201 if(!isupper(asciiname[2]=input()))
1203 /* partain: have to have something extra for DC[1-4] */
1204 if (asciiname[0] == 'D' && asciiname[1] == 'C' && isdigit(asciiname[2])) {
1205 asciiname[3] = '\0';
1207 unput(asciiname[2]);
1208 asciiname[2] = '\0';
1212 asciiname[3] = '\0';
1214 if (strcmp(asciiname,"DEL") == 0)
1218 return(lookupascii(asciiname));
1223 lookupascii(ascii) look up ascii in asciinames[]
1225 returns -1 if ascii is not found, otherwise its index.
1228 static int lookupascii(ascii)
1232 for(i='\0'; i <= ' '; ++i)
1233 if(strcmp(ascii,asciinames[i])==0)
1239 /**********************************************************************
1242 * Numeric Escapes in Characters/Strings *
1245 **********************************************************************/
1247 int convnum(num,numlen,base)
1251 int i, res = 0, mul;
1253 for (i = numlen-1, mul = 1; i >= 0; --i, mul *= base)
1256 res += (num[i] - '0') * mul;
1257 else if (isupper(num[i]))
1258 res += (num[i] - 'A' + 10) * mul;
1259 else if (islower(num[i]))
1260 res += (num[i] - 'a' + 10) * mul;
1265 convchar(num,numlen,base)
1269 int n = convnum(num,numlen,base);
1270 if (n <= MAX_ESC_CHAR)
1274 yylval.uid = xstrdup(yytext);
1279 char errbuf[ERR_BUF_SIZE];
1280 sprintf(errbuf,"ASCII code > %d in character constant",MAX_ESC_CHAR);
1285 readescnum(isadigit,mulbase,ch)
1290 char digit[MAX_ESC_DIGITS];
1296 while((*isadigit)(ch=input()))
1298 if(digcount < MAX_ESC_DIGITS)
1299 digit[digcount] = ch;
1305 if(digcount > MAX_ESC_DIGITS)
1307 char errbuf[ERR_BUF_SIZE];
1308 sprintf(errbuf,"numeric character code too long (> %d characters) in string",MAX_ESC_DIGITS);
1312 ch = convnum(digit,digcount,mulbase);
1314 if (ch > MAX_ESC_CHAR)
1316 char errbuf[ERR_BUF_SIZE];
1317 sprintf(errbuf,"character code > ASCII %d in string",MAX_ESC_CHAR);
1326 escval(c) return the value of an escaped character.
1336 These definitions are standard ANSI C values.
1339 static char escval(c)
1342 return(c == 'a'? '\007': c == 'b'? '\b': c == 'f'? '\f': c == 'n'? '\n':
1343 c == 'r'? '\r': c == 't'? '\t': c == 'v'? '\v': '\0');
1347 OLD: Lexical analysis for Haskell pragmas.
1351 static parse_pragma(s,len)
1355 char pragma_name[1024];
1356 char identifier[1024];
1366 for(i=0; !isspace(*s); ++i, ++s)
1367 pragma_name[i] = *s;
1368 pragma_name[i] = '\0';
1374 for(i=0; !isspace(*s); ++i, ++s)
1376 identifier[i] = '\0';
1388 for(i=0; !isspace(*s); ++i, ++s)
1392 pragmatype = installid(pragma_name);
1393 pragmaid = installid(identifier);
1394 pragmavalue = xstrdup(value);