From mboxrd@z Thu Jan 1 00:00:00 1970 Received: (from weis@localhost) by pauillac.inria.fr (8.7.6/8.7.3) id UAA10200 for caml-redistribution; Fri, 12 Dec 1997 20:36:45 +0100 (MET) Received: from nez-perce.inria.fr (nez-perce.inria.fr [192.93.2.78]) by pauillac.inria.fr (8.7.6/8.7.3) with ESMTP id TAA08825 for ; Fri, 12 Dec 1997 19:08:29 +0100 (MET) Received: from relay5.eunet.fr (relay5.eunet.fr [193.107.193.102]) by nez-perce.inria.fr (8.8.7/8.8.5) with SMTP id TAA13945 for ; Fri, 12 Dec 1997 19:08:27 +0100 (MET) Received: from relay2.eunet.fr by relay5.eunet.fr (5.65c8d/96.05.03) via EUnet-France id AA26195; Fri, 12 Dec 1997 19:08:26 +0100 (MET) Received: from dassav (dassav.dassault-aviation.fr [193.106.72.131]) by relay2.eunet.fr (8.8.5/8.8.5) with SMTP id TAA22830 for ; Fri, 12 Dec 1997 19:08:19 +0100 (MET) Received: from fnet-ia1.dassault-aviation.fr by dassav (5.x/SMI-SVR4) id AA02001; Fri, 12 Dec 1997 15:30:58 +0100 Received: from fnet-ia1 by fnet-ia1.dassault-aviation.fr (SMI-8.6/SMI-SVR4) id PAA13760; Fri, 12 Dec 1997 15:36:27 +0100 Message-Id: <34914BEB.3940@dassault-aviation.fr> Date: Fri, 12 Dec 1997 15:36:27 +0100 From: Thierry Bravier Organization: Dassault Aviation DGT/DTN/ELO/EAV X-Mailer: Mozilla 3.01Gold (X11; I; SunOS 5.5.1 sun4u) Mime-Version: 1.0 To: caml-list@inria.fr Subject: ocamlyacc with friendly dollar-symbols References: <199712111743.SAA10686@pauillac.inria.fr> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Sender: weis Dear ocamlers, Here is a small extension to ocamlyacc. It comes as a short patch to file reader.c in the standard distribution of ocamlyacc. This extension provides two features: 1/ # line "file.mly" generated in file.ml This is useful when the ML code written in the header or trailer or in the semantic actions cannot compile: the error message now reports the problem in the source not in the generated code. 2/ In semantic actions, dollar-number values are still there ( ie $1 ); they are now completed by dollar-symbol values ( ie $expr ). This convenience makes code clearer and more robust relatively to grammar evolutions. The syntax is easy: `$symbol' refers to `symbol' in the right hand side of the rule provided there is only one occurence of `symbol' which is most often true and is checked. `$symbol#i' (where i is a positive integer literal) refers to the i-th occurrence of `symbol' in the rule. `$i' (where i is a positive integer literal) still refers to the i-th symbol of the rule. BUG: Error messages should be adapted to the new `$symbol#i'/`$symbol' feature. SEE ALSO: This feature is provided in SML/NJ .grm syntax (equivalent of .mly files) and can also be found in camlp4 (where semantic values can even be named with free identifiers). EXAMPLE: Here is the modified calc parser from the ocaml user manual: /* File parser.mly */ %token INT %token PLUS MINUS TIMES DIV %token LPAREN RPAREN %token EOL %left PLUS MINUS /* lowest precedence */ %left TIMES DIV /* medium precedence */ %nonassoc UMINUS /* highest precedence */ %start main /* the entry point */ %type main %% main: expr EOL { $expr } ; expr: INT { $INT } | LPAREN expr RPAREN { $expr } | expr PLUS expr { $expr#1 + $expr#2 } | expr MINUS expr { $expr#1 - $expr#2 } | expr TIMES expr { $expr#1 * $expr#2 } | expr DIV expr { $expr#1 / $expr#2 } | MINUS expr %prec UMINUS { - $expr } ; Hope you find it useful. Thierry Bravier Dassault Aviation - DGT / DPR / DESA 78, Quai Marcel Dassault F-92214 Saint-Cloud Cedex - France Telephone : (33) 01 47 11 53 07 Telecopie : (33) 01 47 11 52 83 E-Mail : mailto:thierry.bravier@dassault-aviation.fr Here is a diff output of the modified reader.c file from version /* $Id: reader.c,v 1.13 1997/11/13 09:57:52 xleroy Exp $ */ in the 1.06 distribution. By default both features are enabled, they can be switched off by compiling with -DNO_SOURCE_LOCATION and/or -DNO_DOLLAR_IDENT. % diff -C 1 reader.distrib.c reader.c *** reader.distrib.c Thu Nov 13 10:57:52 1997 --- reader.c Fri Dec 12 14:31:43 1997 *************** *** 49,51 **** --- 49,55 ---- + #ifndef NO_SOURCE_LOCATION + char line_format[] = "\n# %d \"%s\"\n"; + #else char line_format[] = "(* Line %d, file %s *)\n"; + #endif *************** *** 322,323 **** --- 326,330 ---- + #ifndef NO_SOURCE_LOCATION + fprintf(f, line_format, lineno+1, input_file_name); + #endif if (*cptr == '\n') *************** *** 1187,1189 **** --- 1194,1276 ---- + #ifndef NO_DOLLAR_IDENT + int + get_ident(int n) + { + register int c = *cptr; + char *t_cptr = cptr; + if (IS_IDENT(c)) + { + cinc = 0; + for (;;) { + if (IS_IDENT(c)) { + cachec(c); + } else + break; + c = *++cptr; + } + cachec(NUL); + { + int sharp; + char *ident = MALLOC(strlen (cache) + 1); + strcpy(ident, cache); + if (cptr[0] == '#' && isdigit(cptr[1])) { + register int c; + ++cptr; + sharp = 0; + for (c = *cptr; isdigit(c); c = *++cptr) + sharp = 10*sharp + (c - '0'); + } else { + sharp = 0; + } + { + int i; + bucket *item = 0; + if (sharp) { + int s = 0; + for (i = 1; i <= n; i++) { + item = pitem[nitems + i - n - 1]; + if (!strcmp (ident, item->name)) { + if (++s == sharp) { + /* found sharp-th ident occurrence */ + break; + } + } + } + } else { + int found = 0; + for (i = 1; i <= n; i++) { + item = pitem[nitems + i - n - 1]; + if (!strcmp (ident, item->name)) { + if (found) { + /* more than one name matches ident: error */ + found = 0; + break; + } else { + /* first time a name matches ident */ + found = i; + } + } + } + if (found) { + i = found; + item = pitem[nitems + i - n - 1]; + } else { + i = 0; + } + } + if (i <= 0 || i > n) + unknown_rhs(i); + if (item->class == TERM && !item->tag) + illegal_token_ref(i, item->name); + FREE (ident); + return i; + } + } + } + syntax_error(lineno, line, t_cptr); + /*NOTREACHED*/ + return 0; + } + #endif void copy_action(void) *************** *** 1190,1191 **** --- 1277,1281 ---- { + #ifndef NO_SOURCE_LOCATION + int start_column = cptr - line + 1; + #endif register int c; *************** *** 1227,1228 **** --- 1317,1327 ---- fprintf(f, "\tObj.repr(("); + #ifndef NO_SOURCE_LOCATION + fprintf(f, line_format, lineno+1, input_file_name); + { + int i; + for (i = 0; i < start_column; i++) { + fprintf(f, " "); + } + } + #endif *************** *** 1248,1249 **** --- 1347,1356 ---- } + #ifndef NO_DOLLAR_IDENT + if (isalnum(cptr[1])) + { + ++cptr; + fprintf(f, "dollar__%d", get_ident (n)); + goto loop; + } + #endif } -- Thierry Bravier Dassault Aviation - DGT / DPR / DESA 78, Quai Marcel Dassault F-92214 Saint-Cloud Cedex - France Telephone : (33) 01 47 11 53 07 Telecopie : (33) 01 47 11 52 83 E-Mail : mailto:thierry.bravier@dassault-aviation.fr