ParserErr генерирует «исключение индекса вне границ» - PullRequest
0 голосов
/ 08 мая 2018

Я создаю компилятор и пытаюсь извлечь информацию о строке из парсера. Я хочу присоединить это к узлу AST в качестве метаданных, чтобы можно было легко сообщать о любой ошибке на более позднем этапе. Я успешно смог извлечь информацию о линии в Lexer с помощью этого:

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

Это генерирует номер строки, номер символа для Lexer после его использования следующим образом:

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

Для парсера я использую этот метод:

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

Мой парсер выглядит так:

%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 }
  ;

При выполнении этого, если обнаружена ошибка синтаксического анализатора, он генерирует исключение invalid_argument "Index out of bounds". Это обнаружено в строке raise (ParseErr (error msg (rhs_start_pos nterm) (rhs_end_pos nterm))). В конечном итоге я хотел бы создать узел AST, который содержит эту информацию о строке анализатора в виде метаданных, но не может пройти через это исключение. Я не уверен, что мой метод реализации неправильный или я делаю какую-то другую ошибку. Хотелось бы помочь с этим.

1 Ответ

0 голосов
/ 08 мая 2018

Функция rhs_start_pos nth не может использоваться с парсерами менгира;в этом случае вы должны использовать $symbolstartpos или $startpos.

Аналогично, e = expr недопустимо для ocamlyacc.

Таким образом, я не уверен, какой генератор парсера вы пытаетесь использовать.

...