Version française
Home     About     Download     Resources     Contact us    
Browse thread
[Caml-list] symbolic reference to the nonterminals in ocamlyacc action part
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: wakita@i...
Subject: [Caml-list] symbolic reference to the nonterminals in ocamlyacc action part

I added a small feature to ocamlyacc.  The attached micro-patch allows
one to reference an instance of non-terminal symbol in the action part
by the symbolic name (e.g., expr) as well as the occurence position
number (e.g., $1).

As in original ocamlyacc, an instance of the i'th occurence of the
symbol in the grammar rule can be referenced in the action part by $i.

An instance of $i$'th occurrence of the symbol, sym, can be referenced
in the action part by sym$i$ or by sym followed by $i-1$ number of
quote.

Example:

| expr PLUS  expr { Op(Plus,  $1,    $3) }
| expr MINUS expr { Op(Minus, expr1, expr2) }
| expr TIMES expr { Op(Times, expr,  expr') }
| expr DIV   expr { Op(Div,   expr,  $3) }

I have rewrote the parser.mly's found in the ocaml distribution using
the added features.  If you are interested, the full patch file
including these examples is found:

http://www.is.titech.ac.jp/~wakita/ocaml/ocamlyacc.patch

Ken Wakita
Tokyo Institute of Technology

diff -r -c ocaml-3.01/yacc/reader.c ocaml/yacc/reader.c
*** ocaml-3.01/yacc/reader.c	Sat Mar  4 00:15:43 2000
--- ocaml/yacc/reader.c	Wed Apr 18 18:14:01 2001
***************
*** 1220,1225 ****
--- 1220,1226 ----
      for (i = nitems - 1; pitem[i]; --i) ++n;
  
      for (i = 1; i <= n; i++) {
+       char uscore = ' ';
        item = pitem[nitems + i - n - 1];
        if (item->class == TERM && !item->tag) continue;
        fprintf(f, "    let _%d = ", i);
***************
*** 1229,1234 ****
--- 1230,1248 ----
          fprintf(f, "peek_val parser_env %d in\n", n - i);
        else
          fprintf(f, "(peek_val parser_env %d : '%s) in\n", n - i, item->name);
+       {
+ 	char uscore = isupper(item->name[0]) ? '_' : ' ';
+ 	int j, match = 0;
+ 	for (j = 1; j <= i; j++) {
+ 	  if (strcmp((const char *)item->name,
+ 		     (const char *)pitem[nitems + j - n - 1]->name) == 0)
+ 	    match++;
+ 	}
+ 	fprintf(f, "    let %c%s%d = _%d in\n", uscore, item->name, match, i);
+ 	fprintf(f, "    let %c%s", uscore, item->name);
+ 	for (j = 1; j < match; j++) fputc('\'', f);
+ 	fprintf(f, " = _%d in\n", i);
+       }
      }
      fprintf(f, "    Obj.repr((\n");
      fprintf(f, "# %d \"%s\"\n", lineno, input_file_name);
-------------------
To unsubscribe, mail caml-list-request@inria.fr.  Archives: http://caml.inria.fr