pleasehalp
pleasehalp

Reputation: 136

ParserErr generates "index out of bounds exception"

I am creating a compiler and am trying to extract line information from the parser. I wish to attach this to the AST node as metadata so that any error at a later point can be reported easily. I was successfully able to extract the line information in the Lexer by using this:

exception LexErr of string
exception ParseErr of string

let error msg start finish  = 
    Printf.sprintf "(line %d: char %d..%d): %s" start.pos_lnum 
      (start.pos_cnum -start.pos_bol) (finish.pos_cnum - finish.pos_bol) msg

let lex_error lexbuf = 
    raise ( LexErr (error (lexeme lexbuf) (lexeme_start_p lexbuf) (lexeme_end_p lexbuf)))

This generates the line number, char number for Lexer perfectly after using it in this manner:

rule read = parse
(* Lexing tokens *)
| _ { lex_error lexbuf }

For parser, I am using this method:

exception LexErr of string
exception ParseErr of string

let error msg start finish = 
    Printf.sprintf "(line %d: char %d..%d): %s" start.pos_lnum 
      (start.pos_cnum -start.pos_bol) (finish.pos_cnum - finish.pos_bol) msg

let parse_error msg nterm =
    raise (ParseErr (error msg (rhs_start_pos nterm) (rhs_end_pos nterm)))

My parser looks like this:

%start <Ast.stmt> program

%%

program:
  | s = stmt; EOF { s }
  ;

stmt:
  | TINT; e = expr { Decl(e) }
  | e1 = expr; EQUALS; e2 = expr { Assign(e1,e2) }
  | error             { parse_error "wsorword" 1 }
  ;

expr:
  | i = INT; { Const i }
  | x = ID { Var x }
  | e1 = expr; b = binop; e2 = expr; { Binop(e1,b,e2) }
  ;

binop:
  | SUM { Sum }
  | SUB { Sub }
  | MUL { Mul }
  | DIV { Div }
  ;

On running this, if a parser error is detected, it throws the invalid_argument "Index out of bounds" exception. This is detected on raise (ParseErr (error msg (rhs_start_pos nterm) (rhs_end_pos nterm))) line. I would ultimately like to create an AST node which contains this parser line information as it's metadata but can't get through this exception. I am not sure if my method of implementation is wrong or if I'm making some other mistake. Would love some help on this.

Upvotes: 1

Views: 538

Answers (1)

octachron
octachron

Reputation: 18912

The function rhs_start_pos nth can not be used with menhir parsers; in this case, you should use $symbolstartpos or $startpos.

Similarly, e = expr is not valid with ocamlyacc.

Thus, I am not sure which parser generator you are trying to use.

Upvotes: 1

Related Questions