2011-06-15 81 views
8

我在expr.ml文件中有一個類型expr。在parser.mly(OCamlyacc文件),我定義使expr規則,並給予類型:使用外部類型聲明與OCamlyacc

%start expr 
    %type <expr> expr 

不過,我得到:

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

我嘗試添加

%{ 
     open Expr 
    %} 

在.mly文件的開頭,但它仍然不起作用。我如何在外部文件中定義此expr類型並將其用作我規則的返回值?謝謝。

回答

9

需要判定expr類型模塊名。即,如果在expression.ml定義(使用type expr = ...),你應該使用模塊名時使用

%type <Expresssion.expr> main 

注資本E

2

我「米不知道如果我理解正確。

但是你是一個循環依賴掙扎?比方說T包含您的類型,並調用解析器,P。因爲T取決於P不能生產型T.tP,不是周圍的其他方式。通常情況下,我創建了一個第三個文件包含的類型信息,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

Ocamlyacc不允許您指定要在界面(.mli)文件中生成的文本。因此,只要指定進入界面的類型(令牌或規則的類型),就需要使用完全限定的類型。

在這裏它看起來像你可以使用完全限定類型,但有時這是不可能的,因爲類型涉及一個仿函數應用程序。有幾種解決方法:

  • 安排在單獨的編譯單元中構建所有函子。這很簡單,但不起作用,例如如果函子涉及令牌類型。
  • 對ocamlyacc生成的.mli文件進行後處理以添加標頭。你可以用這種方式做任何事情,但這很醜陋。
  • 使用Menhir,一種改進的Ocamlyacc替代品。這是一個額外的依賴,但它確實解決了Ocamlyacc的主要缺陷。