Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ocamlyacc and $end #2327

Closed
vicuna opened this issue Dec 20, 1999 · 1 comment
Closed

ocamlyacc and $end #2327

vicuna opened this issue Dec 20, 1999 · 1 comment

Comments

@vicuna
Copy link

vicuna commented Dec 20, 1999

Original bug ID: 4
Reporter: administrator
Status: closed (set by @damiendoligez on 2005-12-15T14:48:34Z)
Resolution: won't fix
Priority: normal
Severity: minor
Category: ~DO NOT USE (was: OCaml general)
Related to: #2823

Bug description

Full_Name: Judicael Courant
Version: 2.02
OS:
Submission from: estephe.inria.fr (128.93.11.95)
Submitted by: xleroy

(re)Bonjour,

mes étudiants font très fort. Un autre binôme a trouvé (malgré lui et
sans oser m'en parler) ce qui me semble être un bug d'ocamlyacc. En
simplifié, ça donne :

lexer.mll

{
open Parser
}

rule token =
parse [ '\n' '\t' ' '] { token lexbuf}
| ['a'-'z']+ { IDENT(Lexing.lexeme lexbuf)}
| ['0'-'9']+ { INT(int_of_string (Lexing.lexeme lexbuf))}
| ['+'] { PLUS }
| ['('] { PARENG }
| [')'] { PAREND }
| eof { FIN }

{
let get_token l =
let t = token l in
(match t with
| IDENT s -> print_string "\nIDENT:" ; print_string s; print_newline()
| INT i -> print_string "\nINT" ; print_int i; print_newline ()
| PLUS -> print_string "\nPLUS\n" ; flush stdout
| FIN -> print_string "\nEOF\n" ; flush stdout
| PARENG -> print_string "\nPARENG\n"; flush stdout
| PAREND -> print_string "\nPAREND\n"; flush stdout);
t
}

parser.mly:

%{
%}

%token INT
%token IDENT
%token PLUS
%token PARENG PAREND
%token FIN

%left PLUS

%start main
%type main

%%

main:

    instruction {print_string "\ninstruction\n"; flush stdout}
    
;

expr:
/* Constantes de types simples. */
INT
{
print_string "\nINT:"; print_int $1;flush stdout
}
|expr PLUS expr
{
print_string "\nPlus"
}
;

instruction:
expr { print_string "\ninstruction\n" ; flush stdout }

|IDENT PARENG PAREND { print_string "\nCall" ; flush stdout}

;

pc87:/tmp/test> ocamlyacc parser.mly;ocamlc -c parser.mli;ocamlc -c
parser.ml;ocamllex lexer.mll;ocamlc -c lexer.ml
8 states, 283 transitions, table size 1180 bytes
pc87:
/tmp/test>
pc87:~/tmp/test> ocaml
Objective Caml version 2.02

#load "lexer.cmo";;
#load "parser.cmo";;

# let f s =

let lexbuf = Lexing.from_string s in
Parser.main Lexer.get_token lexbuf
;;
val f : string -> unit =

f "f()+3";;

IDENT:f

PARENG

PAREND

Call
instruction

  • : unit = ()

(* Ah ok : bien que la doc ne soit pas explicite là-dessus, il

semble que l'on n'échoue pas si un préfixe de la suite de token peut
être reconnu.
Essayons donc : *)

f " 3 4 5";;

INT3

INT:3
INT4
Uncaught exception: Parsing.Parse_error

Pourquoi donc cette différence ?

Si on regarde l'automate donné par ocamlyacc -v on a :


state 2
$accept : %entry% . $end (0)

$end  accept

[..]
state 7
expr : expr . PLUS expr (3)
instruction : expr . (4)

PLUS  shift 9
$end  reduce 4

je ne suis pas sûr de bien comprendre ce que représente $end. J'avais
l'impression que c'était EOF, mais alors que se passe t-il lorsque
l'on n'a pas $end dans le premier cas et ni $end ni PLUS dans le
second cas ?

BTW, le rôle particulier joué par "EOF" n'est pas documenté dans le
manuel. En particulier, on a :

f "2+4";;

INT2

INT:2
PLUS

INT4

INT:4
Plus
EOF
Uncaught exception: Parsing.Parse_error

Mais si on remplace "FIN" par "EOF" dans lexer.mll et parser.mly, on a
bien :


f "2+4";;

INT2

INT:2
PLUS

INT4

INT:4
Plus
EOF

instruction

instruction

  • : unit = ()


En fait, il serait bien

  • soit de dire dans la doc qu'il faut toujours que les non-terminaux
    axiomes soient constitués d'une production de la forme

x:
y T { .. }

où T est un token

  • soit de dire qu'il n'est pas nécessaire d'écrire de symbole de fin, et
    que l'analyseur engendré par ocamlyacc reconnaît le flot de tokens
    analysé jusqu'au symbole EOF (qui serait un token toujours déclaré
    implicitement par ocamlyacc).

Judicaël.

Judicael.Courant@lri.fr, http://www.lri.fr/~jcourant/
[Computing timetable constraints..................done: 0 solution(s)]

@vicuna
Copy link
Author

vicuna commented Mar 13, 2003

Comment author: administrator

see #2823

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant