Использование ocamlyacc с sedlex - PullRequest
       29

Использование ocamlyacc с sedlex

0 голосов
/ 24 сентября 2018

Я пытаюсь выяснить, как использовать ocamlyacc с sedlex.

lexer.ml (с использованием sedlex):

let rec lex (lexbuf: Sedlexing.lexbuf) =
    match%sedlex lexbuf with
    | white_space -> lex lexbuf
    (* ... other lexing rules ... *)
    | _ -> failwith "Unrecognized."

У меня также есть файл ocamlyacc с именем parser.mly,который содержит parse в качестве одного из правил грамматики.

Чтобы проанализировать строку, я использовал это:

let lexbuf = Sedlexing.Utf8.from_string s in
let parsed = (Parser.parse Lexer.lex) lexbuf in
(* ... do things ... *)

Но во время компиляции появляется эта ошибка (вызванная Lexer.lexвыше):

Ошибка: это выражение имеет тип Sedlexing.lexbuf -> Parser.token, но ожидалось выражение типа Lexing.lexbuf -> Parser.token Тип Sedlexing.lexbuf несовместим с типомLexing.lexbuf

Насколько я понимаю, эта ошибка возникает из-за того, что ocamlyacc ожидает, что лексер будет создан ocamllex, а не sedlex.Итак, вопрос: как я могу использовать ocamlyacc с sedlex?

1 Ответ

0 голосов
/ 24 сентября 2018

Если у вас нет особой причины использовать ocamlyacc, а не Menhir, возможно, гораздо проще использовать Menhir и преобразовать функцию синтаксического анализа в пересмотренный API, для чего требуется только функция производителя токенов типа unit -> token * position * position:

 let provider lexbuf () =
    let tok = generated_lexer lexbuf in
    let start, stop =  Sedlexing.lexing_positions lexbuf in
    tok, start, stop

 let parser_result = MenhirLib.Convert.Simplified.traditional2revised
     generated_parser_entry_point
     (provider lexbuf)

В противном случае вам необходимо создать функцию Lexing.lexbuf -> token из вашего Sedlexing.lexbuf -> token, которая принимает в качестве входного значения фиктивный лексбуф, применяет функцию истинного лексирования к буферу sedlex, копирует информацию о местоположении в фиктивнуюLexing.lexbuf и затем возвращает токен.

...