J'ai déjà fait ça... je vais essayé de voir si je le retrouve...
Bon, j'espère que j'ai récupéré tous les morceaux. L'idée principale est de récupérer les coordonnées de l'erreur dans le fichier analysé. Il faut donc compter la position où on en est dans le lexeur : on se défini une petite fonction :
1 2 3 4 5
| let newline lexbuf =
let pos = lexbuf.Lexing.lex_curr_p in
lexbuf.Lexing.lex_curr_p <-
{ pos with Lexing.pos_lnum = pos.Lexing.pos_lnum + 1;
Lexing.pos_bol = pos.Lexing.pos_cnum } |
et on l'appelle à droite des règles. Comme il s'agit ici de compter les lignes,
il suffit de l'appeler quand on analyse un \n.
Si on veut, on peut aussi initialiser le nom du fichier analysé avant de lancer l'analyse :
1 2
| let init_pos = lexbuf.Lexing.lex_curr_p in
lexbuf.Lexing.lex_curr_p <- { init_pos with Lexing.pos_fname = filename }; |
Voilà pour le lexeur...
J'ai ensuite défini une petite fonction :
1 2 3 4
| let yacc_error pos msg =
Format.fprintf fmt "ERROR : File %s, line %d : %s"
lexpos.Lexing.pos_fname lexpos.Lexing.pos_lnum msg;
raise Error |
Que l'utilise dans ma grammaire :
truc : truc1 | truc2 | error { yacc_error "Bad truc" };
Sinon, je vois dans mon code que j'utilisais :
let pos = mk_pos (symbol_start_pos()) (symbol_end_pos()) in ...
pour mémoriser la position de certains éléments dans la grammaire...
Désolée, je n'ai pas le temps de tester pour voir si ce que j'ai copié/collé est correct, mais ça peut peut-être te donner des pistes.
Partager