2011-06-15 12 views
8

Tengo un tipo expr en un archivo expr.ml. En parser.mly (archivo OCamlyacc), defino la regla expr y dar el tipo:Uso de declaraciones de tipo externas con OCamlyacc

%start expr 
    %type <expr> expr 

Sin embargo, me sale:

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

He intentado añadir

%{ 
     open Expr 
    %} 

en el comienzo del archivo .mly pero aún no funciona. ¿Cómo puedo definir este tipo expr en un archivo externo y usarlo como el valor de retorno de mi regla? Gracias.

Respuesta

9

que necesita para calificar expr tipo con el nombre del módulo. Es decir, si se define en expression.ml (usando type expr = ...) se debe utilizar

%type <Expresssion.expr> main 

Nota E la capital cuando se utiliza el nombre del módulo.

2

I "No estoy seguro de si estoy entendiendo correctamente.

Pero usted está luchando con una dependencia circular? Digamos T contiene el tipo y llame al analizador, P. P no puede producir el tipo T.t desde T depende en P, no al revés. Normalmente, he creado un tercer archivo que contiene la información de tipo, T'.

Por ejemplo,

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 no le permite especificar el texto que se generará en el archivo de interfaz (.mli). Entonces, donde sea que especifiques un tipo que vaya a la interfaz (el tipo de token o regla), necesitas usar un tipo totalmente calificado.

Aquí parece que puede usar un tipo completamente calificado, pero a veces eso no es posible porque el tipo involucra una aplicación funcionadora. Hay varias soluciones:

  • Organizar para compilar todos los funtores en una unidad de compilación independiente. Esto es fácil, pero no funciona, p. si los funtores involucran el tipo de token.
  • Haga un postproceso en el archivo .mli generado por ocamlyacc para agregar un encabezado. Puedes hacer casi cualquier cosa de esta manera, pero es feo y molesto.
  • Utilice Menhir, un reemplazo mejorado de Ocamlyacc. Es una dependencia adicional, pero resuelve las principales deficiencias de Ocamlyacc.
Cuestiones relacionadas