ошибка анализа ocamlyacc: какой маркер?

Я использую ocamlyacc и ocamllex. У меня есть ошибочное производство в моей грамматике, которая сигнализирует о пользовательском исключении. До сих пор я могу заставить это сообщать об ошибочном положении:

| error { raise (Parse_failure (string_of_position (symbol_start_pos ()))) }

Но, я также хочу знать, какой маркер был считан. Должен быть путь---, кто-либо знает?

Спасибо.

15
задан Arjun Guha 19 December 2009 в 14:56
поделиться

3 ответа

Токены генерируются лексером, поэтому вы можете использовать текущий токен лексера при возникновении ошибки:

  let parse_buf_exn lexbuf =
    try
      T.input T.rule lexbuf
    with exn ->
      begin
        let curr = lexbuf.Lexing.lex_curr_p in
        let line = curr.Lexing.pos_lnum in
        let cnum = curr.Lexing.pos_cnum - curr.Lexing.pos_bol in
        let tok = Lexing.lexeme lexbuf in
        let tail = Sql_lexer.ruleTail "" lexbuf in
        raise (Error (exn,(line,cnum,tok,tail)))
      end

Lexing.lexeme lexbuf - это то, что тебе нужно. ruleTail объединит все оставшиеся токены в строку, чтобы пользователь мог легко определить местоположение ошибки. lexbuf.Lexing.lex_curr_p следует обновить в лексере, чтобы он содержал правильные позиции. ( источник )

16
ответ дан 1 December 2019 в 01:10
поделиться

Я думаю, что, как и yacc, токены хранятся в переменных, соответствующих символам в правиле грамматики. Здесь, поскольку есть один символ (ошибка), вы можете просто вывести $1, используя printf, и т.д.

Edit: response to comment.

Why do you use a error terminal? Я читаю учебник ocamlyacc, в котором говорится, что при возникновении ошибки при разборе вызывается специальная рутина обработки ошибок. Например:

3.1.5. Error Reporting Routine

When ther parser function detects a синтаксическая ошибка, она вызывает функцию под названием parse_error со строкой "синтаксическая ошибка" в качестве аргумента. по умолчанию parse_error функция делает следующее ничего и возвращается, таким образом инициируя исправление ошибок (см. "Восстановление ошибок"). Пользователь может определить настраиваемый функция parse_error в заголовке раздел грамматического файла, такой как:

let parse_error s = (* Called by the parser function on error *)
  print_endline s;
  flush stdout

Ну, похоже, что с помощью этой функции вы получаете только "синтаксическую ошибку". Оставайтесь с нами для дополнительной информации.

2
ответ дан 1 December 2019 в 01:10
поделиться

Наилучший способ отладки парсера ocamlyacc - это установить параметр OCAMLRUNPARAM для включения символа p - это приведет к заставить парсер печатать все состояния, через которые он проходит, и каждый сдвиг / уменьшение, которое он выполняет.

Если вы используете bash, вы можете сделать это с помощью следующей команды:

$ export OCAMLRUNPARAM='p'
20
ответ дан 1 December 2019 в 01:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: