Sin el correspondiente analizador ocamlyacc, nadie podrá encontrar el problema con su código ya que su lexer funciona perfectamente bien!
Me he tomado la libertad de escribir el siguiente pequeño analizador (parser.mly) que construye una lista de pares de identificadores, p. entrada "a = b" debería dar la lista singleton [("a", "b")].
%{%}
%token <string> Identifier
%token EqualsSign
%token Semicolon
%token EOF
%start start
%type <(string * string) list> start
%%
start:
| EOF {[]}
| Identifier EqualsSign Identifier Semicolon start {($1, $3) :: $5}
;
%%
Para probar si el analizador hace lo que prometí, creamos otro archivo (main.ml) que analiza la cadena "a = b;" e imprime el resultado.
let print_list = List.iter (fun (a, b) -> Printf.printf "%s = %s;\n" a b)
let() = print_list (Parser.start Lexer.next (Lexing.from_string "a=b;"))
El código debe compilar (por ejemplo ocamlbuild main.byte) sin ninguna queja y el programa debe ser la salida "a = b;" como fue prometido.
En respuesta a la última edición:
En general, no creo que la captura de excepciones de la biblioteca estándar que están destinados a indicar un fallo o mal uso (como Invalid_argument o fracaso) es una buena idea. La razón es que se utilizan de forma ubicua en toda la biblioteca, de modo que, por lo general, no se puede saber qué función provocó la excepción y por qué lo hizo.
Además, está desperdiciando la única información útil: ¡el mensaje de error! El mensaje de error debe decirle cuál es el origen del problema (mi mejor estimación es un problema relacionado con IO). Por lo tanto, debe imprimir el mensaje de error o dejar que la excepción se propague a toplevel. Personalmente, prefiero la última opción.
Sin embargo, es probable que todavía desee tratar las entradas sintácticamente mal formadas de una manera elegante. Para esto, puede definir una nueva excepción en el lexer y agregar un caso predeterminado que capture tokens no válidos.
{
exception Unexpected_token
}
...
| _ {raise Unexpected_token}
Ahora, se puede coger la excepción que acaba de definir en el archivo principal y, a diferencia de antes, la excepción es específica a las entradas no válidas sintácticamente. En consecuencia, usted sabe tanto la fuente como la causa de la excepción que le da la oportunidad de hacer algo mucho más significativo que antes.
Indicación de desarrollo de OCaml bastante aleatoria: Si compila el programa con información de depuración habilitada, establecer la variable de entorno OCAMLRUNPARAM en "b" (por ejemplo, exportar OCAMLRUNPARAM = b) ¡habilita las trazas de pila para excepciones no detectadas!
¿Podría proporcionar el archivo ML donde definió los constructores como identificador? Además, ¿podría confirmar que ocamllex y ocamlc no presentaron una queja en el momento de la compilación? – Surikator
Se definieron en parser.mly como estándar y ninguno se queja. – marsolk
@marsolk: Tengo curiosidad, ¿alguna vez te diste cuenta? ¿Cual fue el problema? – lebowski