我是 ML 的新手,现在学习 ocaml 只需几个小时就可以用它构建我的编译器。Lexer 和 Parser 生成没有任何问题。但是当编译器代码由 ocamlmktop 构建时,就会出现问题。
错误信息如下所示,但二进制文件 myc.top 已完成并可以运行。
请您帮我解决错误信息,非常感谢您的支持。
$ ocamlyacc parser.mly
$ ocamllex lexer.mll
24 states, 1124 transitions, table size 4640 bytes
$ ocamlmktop syntax.ml parser.mli parser.ml lexer.ml -o myc.top
File "parser.cmo", line 1:
Error (warning 31): files parser.cmo and /usr/local/lib/ocaml/compiler-libs/ocamlcommon.cma(Parser) both define a module named Parser
File "lexer.cmo", line 1:
Error (warning 31): files lexer.cmo and /usr/local/lib/ocaml/compiler-libs/ocamlcommon.cma(Lexer) both define a module named Lexer
1.词法分析器文件lexer.mll
{
open Parser
}
let space = [' ' '\t' '\n' '\r']
let digit = ['0'-'9']
let alpha = ['A'-'Z' 'a'-'z' '_']
rule token = parse
| "while"
{ WHILE }
| "print"
{ PRINT }
| alpha (digit|alpha)*
(* reserve key word *)
{ VAR(Lexing.lexeme lexbuf) }
| '-'? digit+
{ CONST(int_of_string (Lexing.lexeme lexbuf)) }
| space+
(* skip spaces *)
{ token lexbuf }
| '='
{ EQUAL }
| '+'
{ PLUS }
| '('
{ LPAREN }
| ')'
{ RPAREN }
| '>'
{ GREATER }
| '{'
{ LBRACE }
| '}'
{ RBRACE }
| ';'
{ SEMICOLON }
| _
(* other case: error heppen *)
{ failwith
(Printf.sprintf
"unknown token %s near characters %d-%d"
(Lexing.lexeme lexbuf)
(Lexing.lexeme_start lexbuf)
(Lexing.lexeme_end lexbuf)) }
2 解析器文件 Parser.mly
%{
open Syntax
%}
%token <string> VAR /* variable */
%token <int> CONST /* integer */
%token EQUAL /* = */
%token PLUS /* - */
%token WHILE /* keyword「while」 */
%token LPAREN /* ( */
%token RPAREN /* ) */
%token GREATER /* > */
%token LBRACE /* { */
%token RBRACE /* } */
%token SEMICOLON /* ; */
%token PRINT /* keyword「print」 */
%type <Syntax.statement> statement
%start statement
%%
statement: /* start */
| VAR EQUAL CONST
{ Const($1, $3) }
| VAR EQUAL VAR PLUS VAR
{ Add($1, $3, $5) }
| WHILE LPAREN VAR GREATER VAR RPAREN statement
{ While($3, $5, $7) }
| LBRACE statement_list RBRACE
{ Seq($2) }
| PRINT VAR
{ Print($2) }
| error /* other cases, error happens */
{ failwith
(Printf.sprintf
"parse error near characters %d-%d"
(Parsing.symbol_start ())
(Parsing.symbol_end ())) }
statement_list: /* start */
| statement SEMICOLON statement_list
/* one by one */
{ $1 :: $3 }
| /* 空列 */
{ [] } /* nil return */
3. 文件语法.ml
type var = string (* variable *)
type statement = (* statement *)
| Const of var * int
(* x = i *)
| Add of var * var * var
(* x = y + z *)
| While of var * var * statement
(* while (x > y) *)
| Seq of statement list
(* { s1; s2; …; sn } *)
| Print of var
(* print x *)