#ocaml #lex #tiger #ocamllex
#ocaml #лекс #тигр #окамллекс #lex #tiger #ocamllex
Вопрос:
Я пытаюсь следовать «Современной реализации компилятора Appel в ML» и пишу лексер с использованием Ocamllex.
Спецификация запрашивает, чтобы лексер возвращал строки после перевода escape-последовательностей. Следующий код представляет собой выдержку из входного файла ocamllex:
rule tiger = parse
...
| '"'
{ let buffer = Buffer.create 1 in
STRING (stringl buffer lexbuf)
}
and stringl buffer = parse
| '"' { Buffer.contents buffer }
| "\t" { Buffer.add_char buffer 't'; stringl buffer lexbuf }
| "\n" { Buffer.add_char buffer 'n'; stringl buffer lexbuf }
| "\n" { Buffer.add_char buffer 'n'; stringl buffer lexbuf }
| '\' '"' { Buffer.add_char buffer '"'; stringl buffer lexbuf }
| '\' '\' { Buffer.add_char buffer '\'; stringl buffer lexbuf }
| eof { raise End_of_file }
| _ as char { Buffer.add_char buffer char; stringl buffer lexbuf }
Есть ли способ лучше?
Ответ №1:
Возможно, вам будет интересно посмотреть, как это делает лексер Ocaml (поиск and string
). По сути, это тот же метод, что и ваш, без хорошего локального буфера (я нахожу ваш код более приятным в этом вопросе, но это немного менее эффективно), немного более сложный, потому что поддерживается больше экранирования, и с использованием escape-таблицы (char_for_backslash) для факторизации аналогичных правил.
Кроме того, у вас есть правило, которое "\n"
повторяется дважды, и я думаю, 1
что это очень пессимистичная оценка вашей длины строки, я бы предпочел использовать 20
здесь (чтобы избежать ненужного изменения размера).
Комментарии:
1. Спасибо! Золотая жила примеров. Я никогда не думал, что код компилятора Ocaml будет таким понятным.
2. @nimrodm вы также должны иметь в виду, что часть кода там довольно старая, поэтому не все отражает текущую лучшую практику разработки OCaml.