Использование внешних объявлений типов с OCamlyacc - PullRequest
9 голосов
/ 15 июня 2011

У меня есть тип expr в файле expr.ml. В parser.mly (файл OCamlyacc) я определяю правило expr и даю тип:

    %start expr
    %type <expr> expr

Однако я получаю:

    File "parser.mli", line 34, characters 48-52:
    Error: Unbound type constructor expr

Я пытался добавить

    %{
      open Expr
    %}

в начале файла .mly, но он все еще не работает. Как я могу определить этот тип expr во внешнем файле и использовать его в качестве возвращаемого значения моего правила? Благодаря.

Ответы [ 3 ]

10 голосов
/ 15 июня 2011

Вам необходимо указать expr тип с именем модуля.То есть, если оно определено в expression.ml (с использованием type expr = ...), вы должны использовать

%type <Expresssion.expr> main

Обратите внимание на заглавную букву E при использовании имени модуля.

2 голосов
/ 15 июня 2011

Я не уверен, правильно ли я понимаю.

Но вы боретесь с круговой зависимостью? Допустим, T содержит ваш тип и вызывает синтаксический анализатор, P. Pне может создать тип T.t, поскольку T зависит от P, а не наоборот. Обычно я создал третий файл, содержащий информацию о типе, T'.

Например,

T.ml

 let parse filename : T'.t =
     filename
         |> open_in
         |> Lexing.from_channel
         |> P.command L.token

P.mly

%type <T'.t> command
%start command
%%

T'.ml

type t = Label of String
       | Integer of String
       | Float of string
       | Star of t
1 голос
/ 16 июня 2011

Ocamlyacc не позволяет указывать текст, который будет сгенерирован в файле интерфейса (.mli). Поэтому, где бы вы ни указывали тип, который входит в интерфейс (тип токена или правила), вы должны использовать полностью определенный тип.

Здесь похоже, что вы можете использовать полностью определенный тип, но иногда это невозможно, потому что тип включает в себя приложение-функтор. Есть несколько обходных путей:

  • Организовать сборку всех функторов в отдельном модуле компиляции. Это легко, но не работает, например если функторы включают тип токена.
  • Выполните постобработку файла, сгенерированного ocamlyacc .mli, чтобы добавить заголовок. Таким способом вы можете делать почти все, но это уродливо и раздражает.
  • Используйте Менгир , улучшенную замену Окамляка. Это дополнительная зависимость, но она решает основные недостатки Ocamlyacc.
...