Version française
Home     About     Download     Resources     Contact us    
Browse thread
[Caml-list] explain this Genlex behavior
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Chris Hecker <checker@d...>
Subject: [Caml-list] explain this Genlex behavior

I was writing a parser with Genlex, and came across strange behavior.
I was trying to parse two numbers separated by a colon (:), but it was
failing when the second number was negative.  So, "1.0:1.0" would
parse, but "1.0:-1.0" would not.  I know about the greedy lexing of
minus (-) to the number, and in fact that should help me here.  The
strange thing is a semi-colon works fine, so "1.0;-1.0" parses.

I decided to figure out which characters worked and which didn't.
Here's the output of the program below:

# test_it ();;
Passed: } { ` _ ] [ ; . , ) ( 
Failed: ~ | ^ \ @ ? > = < : / - + * ' & % $ # " ! 
Passed: ~ } | { ` _ ^ ] \ [ @ ? > = < ; : / . - , + * ) ( & % $ # ! 
Failed: ' " 

The first pair of pass/fails are for no space between the separator,
so "n:-n", etc.  The second pair are with a space "n: -n".

What's the deal here?

Chris

----------------
open Genlex

(* make a simple expression parser for "n?n" where "?" is a
   parameterized separator *)

let do_it sep space =
  let s = "1.0" ^ sep ^ space ^ "-2.0" in
  let rec parse_it = parser
      [< num1 = parse_num; 'Kwd sep ; num2 = parse_num >] -> num1,num2
  and parse_num = parser
      [< 'Float f1 >] -> f1
    | [< 'Int i1 >] -> float i1 in
  let lex = make_lexer [sep] in
  parse_it (lex(Stream.of_string s))
    
let seps = [
  "!"; "\""; "#"; "$"; "%"; "&"; "'"; "("; ")"; "*"; "+"; ",";
  "-"; "."; "/"; ":"; ";"; "<"; "="; ">"; "?"; "@"; "["; "\\"; "]";
    "^"; "_"; "`"; "{"; "|"; "}"; "~";]

let test_it () =
  let do_test s = 
    let pass,fail = ref [],ref [] in
    List.iter
      ~f:(fun el ->
        try
          ignore (do_it el s);
          pass := el :: !pass;
        with _ ->
          fail := el :: !fail
         ) seps;
    print_string "Passed: ";
    List.iter ~f:(fun el -> Printf.printf "%s " el) !pass;
    print_string "\nFailed: ";
    List.iter ~f:(fun el -> Printf.printf "%s " el) !fail;
    print_newline ()
  in
  do_test "";
  do_test " "
    


-------------------
To unsubscribe, mail caml-list-request@inria.fr.  Archives: http://caml.inria.fr