Version française
Home     About     Download     Resources     Contact us    
Browse thread
tricky camlp4 question.
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Pietro Abate <Pietro.Abate@a...>
Subject: tricky camlp4 question.
Hi all,

I wrote a small camlp4 extension that by using a specification that is
at the beginning of the input file, extends itself and to parse the rest
of the file. My problem is that by giving the user the file to extend
the grammar with which the input file is parsed, I indirectly give
him/her also the power to introduce new keywords. This is very annoying
as if the user define a new keyword, say "a", then the variable "a"
cannot be used anywhere in the file, except that as a keyword. This
restriction makes sense most of the time, but it would be great if
keywords were bounded within their grammatical scope, instead of been
global. 

A simple trick to avoid polluting the grammar with out-of-scope keywords
is not to use Gramext.Stoken (that is not to specify the keyword as a
string in the EXTEND statement), but to generate an entry from a parser
that matches exactly that keyword (from Hendrik Tews). Since I extend
the grammar on the fly, I have a function that given the specification
generates for me the extension. In this function, associated with a
symbol s (given by the user), I generated an entry that look like this:

Gramext.Snterm (Grammar.Entry.obj (Hashtbl.find symbol_table s))

where symbol_table of type (string, 'a Grammar.Entry.e) Hashtbl.t and 'a
is the type of the resulting action that is not important here.

Now to generate one entry for each user provided keyword and I use the
function add_symbol_table that gets a string and generates an entry
using the parser checksym.

let checksym sym strm =
    let s = match Stream.peek strm with
        |Some("",s) when s = sym -> s
        |Some("LIDENT",s)
        |Some("UIDENT",s) when s = sym -> s
        |_ -> raise Stream.Failure
    in
    try Stream.junk strm; s
    with Stream.Failure -> raise Stream.Failure

let add_symbol_table s =
    let e = Grammar.Entry.of_parser Pcaml.gram ("__entry"^s) (checksym s) in
    Hashtbl.add symbol_table s e

This is all well and good. Everything type-checks correctly, but when I
try to use any of these entries generated using Grammar.Entry.of_parser
I get a sigsegv. I think the problem is with the function
Grammar.Entry.obj but I don't understand why this is wrong...

any suggestions ?

p

-- 
++ Blog: http://blog.rsise.anu.edu.au/?q=pietro
++ 
++ "All great truths begin as blasphemies." -George Bernard Shaw
++ Please avoid sending me Word or PowerPoint attachments.
   See http://www.fsf.org/philosophy/no-word-attachments.html