Я новичок в OCaml, но его документация заставляет меня плакать.
Я хочу написать парсер на ocaml и интегрировать его в проект C ++.
Я сделал c ++ — привязку OCaml правильно, как описано здесь
http://www.mega-nerd.com/erikd/Blog/CodeHacking/Ocaml/calling_ocaml.html
поэтому я могу получить исполняемый файл, вызывающий код OCaml, с помощью следующих команд:
Но потом я добавил «open Genlex ;;» к ocaml-called-from-c.ml и попробуйте написать простой парсер, например, как описано здесь:
http://caml.inria.fr/pub/docs/manual-ocaml/libref/Genlex.html
Как говорится:
«Следует заметить, что использование ключевого слова parser и связанной нотации для потоков доступно только через расширения camlp4. Это означает, что нужно предварительно обработать его источники, например, с помощью ключа командной строки« -pp »компиляторов».
но
ocamlopt -pp camlp4 -o build / ocaml-call-from-c.cmx -c ocaml-called-from-c.ml
получает
Ошибка разбора: запись [Implem] пуста
Ошибка при запуске внешнего препроцессора
Командная строка: camlp4 ‘ocaml-called-from-c.ml’> / tmp / ocamlpp162c63
без -pp это падает на:
синтаксический анализатор
| [< n1 = parse_atom; n2 = parse_remainder n1>] -> n2
с
Файл «ocaml-called-from-c.ml», строка 99, символы 13-14:
Ошибка: синтаксическая ошибка
На мой взгляд, Genlex предназначен для быстрых взломов. Если ваш язык вообще интересен, вы можете заглянуть в Менгир, как предлагает Василий Старинкевич.
Документация Genlex говорит вам, что make_lexer
Функция использует потоки. Хотя сами потоки являются частью основного языка (в Потоковый модуль), синтаксис прохладного потока является расширением OCaml. Синтаксис раньше был частью языка, но некоторое время назад был перенесен в расширение.
Область расширений синтаксиса для OCaml в настоящее время находится в довольно изменчивом состоянии. Наиболее полное описание, которое я могу найти для расширения Stream, находится в Глава 2 старого руководства camlp4. Есть также хорошее учебное описание на Страница потока выражений OCaml.org.
Я смог сделать пример из документации следующим образом. Я использую OCaml 4.01.0 на OS X 10.9.2.
Мой исходный файл gl.ml
выглядит так (Я добавил main
функция).
open Genlex
let lexer = make_lexer ["+";"-";"*";"/";"let";"="; "("; ")"]
let rec parse_expr = parser
| [< n1 = parse_atom; n2 = parse_remainder n1 >] -> n2
and parse_atom = parser
| [< 'Int n >] -> n
| [< 'Kwd "("; n = parse_expr; 'Kwd ")" >] -> n
and parse_remainder n1 = parser
| [< 'Kwd "+"; n2 = parse_expr >] -> n1+n2
| [< >] -> n1
let main () =
let s = Stream.of_channel stdin in
let n = parse_expr (lexer s) in
Printf.printf "%d\n" n
let () = main ()
Я компилирую следующим образом.
$ ocamlopt -o gl -pp camlp4o gl.ml
Я бегу следующим образом:
$ echo '3 + (5 + 8)' | gl
16
Таким образом, Genlex можно заставить работать.
Для вашего случая я думаю, что ваша командная строка будет выглядеть так:
$ ocamlopt -o gl.o -c -pp camlp4o gl.ml
Это работает для меня. Это создает оба gl.o
а также gl.cmx
,
Возможно, это не решит все ваши проблемы, но я надеюсь, что это поможет.