caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] accidentally mutating caml grammar with camlp4?
@ 2004-08-15 16:18 Jeff Henrikson
  2004-08-15 16:35 ` Alain Frisch
  0 siblings, 1 reply; 2+ messages in thread
From: Jeff Henrikson @ 2004-08-15 16:18 UTC (permalink / raw)
  To: caml-list

-- 
Hello,

I am experiencing a camlp4 effect I do not understand.  I use (Grammar.Entry.create Pcaml.gram) and EXTEND to build up a quick and dirty grammar for C types.  (patterns on C types, actually.)  I intend to ultimately extend MLast.expr and/or MLast.patt with some derived form to incorporate the expansion that I write on my pattern type as a camlp4 macro, but for now I have only run EXTEND on my own entry points, not any MLast entry.

The problem is that once I run all these, I somehow break the basic caml grammar.  I have used the keywords "int" and "float" as they are used in C, but somehow inadvertently I have made these valid caml expressions unparsable:

# let f (x:int) = x;;
Toplevel input:
# let f (x:int) = x;;
           ^^^
Parse error: [type] expected after ':' (in [patt])
# let f (x:float) = x;;
Toplevel input:
# let f (x:float) = x;;
           ^^^^^
Parse error: [type] expected after ':' (in [patt])

I am currently surmising that it is related to my use of the corresponding C keywords, since 

# let f (x:string) = x;;
val f : string -> string = <fun>

Works just fine.  I have summarized a reproduction of the problem into one file as I will append below.  I would appreciate the eyes of any camlp4 wizard who might be able to tell why I am breaking.

Regards,


Jeff Henrikson



#load "camlp4o.cma";;
#load "pr_o.cmo";;

#load "q_MLast.cmo";;
#load "pa_extend.cmo";;


open Pcaml;;  (* for str_item, etc. *)
let loc = (0,0);;    (* for <:expr< >> *)



module Cabs =  (* extracted from frontc *)
  struct
    type expression = unit
    and size = NO_SIZE | SHORT | LONG | LONG_LONG
    and sign = NO_SIGN | SIGNED | UNSIGNED
    and storage = NO_STORAGE | AUTO | STATIC | EXTERN | REGISTER
    and base_type =
	NO_TYPE
      | VOID
      | CHAR of sign
      | INT of size * sign
      | BITFIELD of sign * expression
      | FLOAT of bool
      | DOUBLE of bool
      | PTR of base_type
      | ARRAY of base_type * expression
      | STRUCT of string * name_group list
      | UNION of string * name_group list
      | PROTO of proto
      | OLD_PROTO of old_proto	
      | NAMED_TYPE of string
      | ENUM of string * enum_item list
      | CONST of base_type
      | VOLATILE of base_type
and name = string * base_type * unit * expression
and name_group = base_type * storage * name list
and single_name = base_type * storage * name
and enum_item = string * expression
and proto = base_type * single_name list * bool
and old_proto = base_type * string list * bool
end;;



type pat_iden =
    PIDEN_LIT of string              (* spat *)
  | PIDEN_CASEI of string * string  (* spat, id *)
  | PIDEN_REGEXP of string * string (* regexp, id *)
  | PIDEN_BIND of string;;           (* id *)

type pat_size = PSIZE_ANY | PNO_SIZE | PSHORT | PLONG 
  | PLONG_LONG | PSIZE_BIND of string
and pat_sign = PSIGN_ANY | PNO_SIGN | PSIGNED | PUNSIGNED 
  | PSIGN_BIND of string
and pat_storage = PNO_STORAGE | PAUTO | PSTATIC | PEXTERN 
  | PREGISTER | PSTOR_BIND of string;;

type pat_base_type =
    PBT_BIND of string (* id for the unknown, not a type *)
  | PBT_ANY            (* same but throw away id.  _ equivalent *)
  | PBT_DIM of string  (* id for the unknown, not a number *)
  | PBT_DIM_LIT of string (* the number *)
  | PBT_AS of pat_base_type * string   (* binding *)
  | MPBT_CONSEC of (bool * pat_iden option * pat_base_type) list 
            (* bool is for multi-occupancy*)
  | MPBT_SKIP0
  | MPBT_PERM of (bool * pat_iden option *pat_base_type) list  
            (* bool is for multi-occupancy *)
  | BT_NO_TYPE
  | BT_VOID
  | BT_CHAR of pat_sign
  | BT_INT of pat_size * pat_sign
  | BT_BITFIELD of pat_sign * Cabs.expression
  | BT_FLOAT of bool                                                         
  | BT_DOUBLE of bool                                                        
  | BT_PTR of pat_base_type
  | BT_ARRAY of pat_base_type * (MLast.expr option)
  | BT_STRUCT of string * pat_name_group list
  | BT_UNION of string * pat_name_group list
  | BT_PROTO of pat_proto
  | BT_OLD_PROTO of pat_old_proto        
  | BT_NAMED_TYPE of string
  | BT_ENUM of string * pat_enum_item list
  | BT_CONST of pat_base_type
  | BT_VOLATILE of pat_base_type
and pat_name = string * pat_base_type * unit * Cabs.expression
and pat_name_group = pat_base_type * Cabs.storage * pat_name list
and pat_single_name = pat_base_type * Cabs.storage * pat_name
and pat_enum_item = string * Cabs.expression
and pat_proto = pat_base_type * pat_single_name list * bool
and pat_old_proto = pat_base_type * string list * bool;;


let default d opt = 
  match opt with
    Some a -> a
  | None -> d;;


let gpat_bt_sign = (Grammar.Entry.create Pcaml.gram "gpat_bt_sign") ;;
EXTEND
  gpat_bt_sign: [ [ "signed" -> PSIGNED ] ];
  gpat_bt_sign: [ [ "unsigned" -> PUNSIGNED ] ];
  gpat_bt_sign: [ [ "sign"; "("; id = LIDENT; ")" -> PSIGN_BIND id ] ];
  gpat_bt_sign: [ [ "sign"; "("; "_"; ")" -> PSIGN_ANY ] ];
END;;

let gpat_bt = (Grammar.Entry.create Pcaml.gram "gpat_bt") ;;
EXTEND
    gpat_bt: [ [ sn = OPT gpat_bt_sign; "char" -> 
                BT_CHAR(default PNO_SIGN sn) ] ];
    gpat_bt: [ [ sn = OPT gpat_bt_sign; "int" -> 
      BT_INT(PNO_SIZE,default PNO_SIGN sn) ] ];
    gpat_bt: [ [ sn = OPT gpat_bt_sign; "long"; OPT "int" -> 
      BT_INT(PLONG,default PNO_SIGN sn) ] ];
    gpat_bt: [ [ sn = OPT gpat_bt_sign; "long"; "long"; OPT "int" -> 
      BT_INT(PLONG_LONG,default PNO_SIGN sn) ] ];
    gpat_bt: [ [ sn = OPT gpat_bt_sign; "short"; OPT "int" -> 
      BT_INT(PSHORT,default PNO_SIGN sn) ] ];
    gpat_bt: [ [ "float" -> BT_FLOAT(false) ] ];
    gpat_bt: [ [ "double" -> BT_DOUBLE(false) ] ];

    gpat_bt: [ [ "'"; i = UIDENT -> BT_NAMED_TYPE(i) ] ];
    gpat_bt: [ [ "'"; i = LIDENT -> BT_NAMED_TYPE(i) ] ];

    gpat_bt: [ [ t = gpat_bt; "*" -> BT_PTR(t) ] ];
    gpat_bt: [ [ t = gpat_bt; "["; e = OPT expr; "]" -> BT_ARRAY(t,e) ] ];
    gpat_bt: [ [ "Type"; "("; id = LIDENT; ")" -> PBT_BIND(id) ] ];
    gpat_bt: [ [ "_" -> PBT_ANY ] ];

    gpat_bt: [ [ a = gpat_bt; "as"; id = LIDENT -> PBT_AS(a,id) ] ];
END;;
Grammar.Entry.print gpat_bt;;

Grammar.Entry.parse gpat_bt (Stream.of_string "char");;
Grammar.Entry.parse gpat_bt (Stream.of_string "unsigned char");;
Grammar.Entry.parse gpat_bt (Stream.of_string "sign(x) char");;
Grammar.Entry.parse gpat_bt (Stream.of_string "unsigned char");;
Grammar.Entry.parse gpat_bt (Stream.of_string "unsigned short");;
Grammar.Entry.parse gpat_bt (Stream.of_string "unsigned long");;
Grammar.Entry.parse gpat_bt (Stream.of_string "unsigned int");;
Grammar.Entry.parse gpat_bt (Stream.of_string "unsigned long int");;
Grammar.Entry.parse gpat_bt (Stream.of_string "double as x");;
Grammar.Entry.parse gpat_bt (Stream.of_string "unsigned long* as x");;

Grammar.Entry.parse gpat_bt (Stream.of_string "int[5]");;
Grammar.Entry.parse gpat_bt (Stream.of_string "char* [5*7]");;

Grammar.Entry.parse gpat_bt (Stream.of_string "'MyStruct[5]");;
Grammar.Entry.parse gpat_bt (Stream.of_string "'myStruct[5]");;


let gpat_iden = Grammar.Entry.create Pcaml.gram "gpat_iden";;
EXTEND
    gpat_iden: [ [ s = STRING -> PIDEN_LIT(s) ] ];
    gpat_iden: [ [ "re"; r = STRING; ","; id = LIDENT -> 
      PIDEN_REGEXP(r,id) ] ];
    gpat_iden: [ [ "re"; r = STRING -> PIDEN_REGEXP(r,"") ] ];
    gpat_iden: [ [ "bind"; id = LIDENT -> PIDEN_BIND(id) ] ];
END;;

Grammar.Entry.parse gpat_iden (Stream.of_string "\"hello\"");;
Grammar.Entry.parse gpat_iden (Stream.of_string "re \"hello\", x");;
Grammar.Entry.parse gpat_iden (Stream.of_string "re \"hello\"");;


let gpat_bt_iden = Grammar.Entry.create Pcaml.gram "gpat_bt_iden";;
EXTEND
    gpat_bt_iden: [ [ a = gpat_bt; nopt = OPT gpat_iden -> (a,nopt) ] ];
END;;


let gpat_alt = Grammar.Entry.create Pcaml.gram "gpat_alt";;
EXTEND
    gpat_alt: [ [ "["; a = LIST1 gpat_bt_iden SEP ";"; "]" ->
		List.map (fun (a,nopt) -> (false, nopt, a)) a ] ];
    gpat_alt: [ [ p = gpat_bt_iden ->
		let (a,nopt) = p in [false, nopt, a] ] ];
END;;


let gpat_bt_guard = Grammar.Entry.create Pcaml.gram "gpat_bt_guard";;
EXTEND
    gpat_bt_guard: [ [ "when"; g = expr -> g ] ];
END;;


let gpat_bt_line = Grammar.Entry.create Pcaml.gram "gpat_bt_line";;
EXTEND
    gpat_bt_line: [ [ p = gpat_alt; g = OPT gpat_bt_guard; "->"; e = expr ->
      (p,g,e) ] ];
END;;




type macro_param_type = EXPR_PARAM | SYM_PARAM;;

let gmacro_param = (Grammar.Entry.create Pcaml.gram "gmacro_param") ;;
EXTEND
    gmacro_param: [ [ "@"; id = UIDENT; ":"; id2 = UIDENT 
		      -> (SYM_PARAM, id, Some <:expr< $lid:id2$>>) ] ];
    gmacro_param: [ [ "@"; id = LIDENT; ":"; id2 = LIDENT 
		      -> (SYM_PARAM, id, Some <:expr< $lid:id2$>>) ] ];
    gmacro_param: [ [ "@"; id = LIDENT
		      -> (SYM_PARAM, id, None ) ] ];
    gmacro_param:
      [ [ id = TILDEIDENT; ":"; e = expr -> (EXPR_PARAM,id,Some e) ] ];
    gmacro_param:
      [ [ id = TILDEIDENT -> (EXPR_PARAM,id,None) ] ];
END;;

let gmacro_param_list = (Grammar.Entry.create Pcaml.gram "gmacro_param_list");;
EXTEND
    gmacro_param_list: [ [ a = LIST0 gmacro_param -> a ] ];
END;;

Grammar.Entry.parse gmacro_param_list 
(Stream.of_string "@foo ~bar @Mama:Mama @baz:yoyo ~bubba:(joe+2)");;


let f (x:int) = x;;
let f (x:float) = x;;
let f (x:string) = x;;


-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [Caml-list] accidentally mutating caml grammar with camlp4?
  2004-08-15 16:18 [Caml-list] accidentally mutating caml grammar with camlp4? Jeff Henrikson
@ 2004-08-15 16:35 ` Alain Frisch
  0 siblings, 0 replies; 2+ messages in thread
From: Alain Frisch @ 2004-08-15 16:35 UTC (permalink / raw)
  To: Jeff Henrikson; +Cc: Caml list

On Sun, 15 Aug 2004, Jeff Henrikson wrote:

> The problem is that once I run all these, I somehow break the basic caml
> grammar.  I have used the keywords "int" and "float" as they are used in
> C, but somehow inadvertently I have made these valid caml expressions
> unparsable:

The occurences of "int" and "float" in the grammar have the side-effect of
registering these strings as keywords for the grammar lexer, but the Caml
grammar expect these to be regular identifiers, not keywords. Note that
you also register other keywords that could be used by OCaml code (e.g.
Type).

One possible solution is to use
  LIDENT "int"
instead of
  "int"
in your grammars (I didn't try it on your example, though).

Cheers,

 Alain

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2004-08-15 16:36 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-08-15 16:18 [Caml-list] accidentally mutating caml grammar with camlp4? Jeff Henrikson
2004-08-15 16:35 ` Alain Frisch

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).