Version française
Home     About     Download     Resources     Contact us    
Browse thread
[Caml-list] segmentation fault at parsing
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Florent Bouchez <florent.bouchez@e...>
Subject: [Caml-list] segmentation fault at parsing

Hi,

I have a problem in using the error recovery mode of ocamlyacc:

the dummy parser included here reads from "integer.input" a list of integers, defined like this: "integer 42".

I want the user to know his error: error in integer writing or else, but the parsing must continue.

But, where I catch the corresponding error token, in the rule Int, the rule must return (int * int), and I don't want to return an arbitrary value that would be kept. Instead I prefer to re-raise a Parsing.Parse_error, so that the preceding rule can discard this attempt.

The problem is than the Exception is quit of ignored : the "Int:" rule returns something of value 0 => if the rule returns something of type "int" instead of "int * int", there is a 0 in the integer list. But if the type is a more complicated type, then something horrible happens and I get a "zsh: segmentation fault  ./test".


Is it forbidden to re-raise a Parse_error in the action part of a rule that matches the symbol "error" ?


I use "Objective Caml version 3.07+2"


Here are the sources

---------
parser.mly, the most important :

%token EOF
%token INTEGER
%token <int> INT
%token <string> WORD

%start main
%type <(int*int) list> main
  %%
main:
| IntList EOF  { $1 } ;
    ;

IntList:
| IntList Int  { $2 :: $1 }
| Int       { [$1] }
| error     { Printf.eprintf "---- Some error\n" ;
	      [] }
    ;


  Int:
| INTEGER INT   { $2,$2 }
| INTEGER error { Printf.eprintf "++++ This is not an integer\n" ;
		  raise Parsing.Parse_error
		}
    ;


--------------
lexer.mll:

{
 open Parser
}


  rule token = parse
| [' ' '\t' '\n']     { token lexbuf }
| '#'                 { comment lexbuf }
| "integer" { INTEGER }
| ['0'-'9']+ as i { INT (int_of_string i) }
| ['a'-'z']+ as w { WORD w }
| eof            { EOF }

and comment = parse
| '\n' {token lexbuf }
| _    {comment lexbuf }



------------
test.ml, the main program:
open Lexer
open Parser

let _ =
  let fd = open_in_bin "integer.input" in
  let lexbuf = Lexing.from_channel fd in
  try
    let l = Parser.main Lexer.token lexbuf in
    flush stderr ;
    print_string "Parsing done:\n" ;
    List.iter
      (fun (a,b) -> print_int a ; print_string "\n" )
      l ;
    print_string "[]\n" ;
  with e ->
    Printf.eprintf "Exception !\n" ;
    raise e



--------
Makefile:
all:
	ocamllex lexer.mll
	ocamlyacc -v parser.mly
	ocamlc -g -c parser.mli
	ocamlc -g -c lexer.ml
	ocamlc -g -c parser.ml
	ocamlc -g -c test.ml
	ocamlc -g -o test lexer.cmo parser.cmo test.cmo

---------
integer.input:

integer 1

foo

integer 3
integer 4

# if you put an '#' at the beginning of the following line, it's OK
integer bar

integer 2
integer 5




Thanks

Florent Bouchez

-------------------
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