解析器的错误

时间:2011-07-01 21:16:58

标签: parsing ocaml

我正在Ocaml中编写一个编译器。我想要实现类似的东西:

program test;
var
   a,b : boolean;
   n : integer;
name
   ([2,3], [4,5]) : boolean;
   ([7,8], [9,10]), ([12,13], [14,15]) : integer;  
begin
   ...
end.

实际上,我的每个程序都包含一个二维数组。 ([2,3], [4,5]) : boolean声明[2,3] x [4,5]中的所有元素都是布尔值。

我的问题是关于如何让解析器很好地读取名称声明,这是我的sib_parser.mlysib_syntax.ml。它们编译得很好,但是当我用程序测试二进制文件时,它会抛出一个解析器错误。有人可以帮忙吗?非常感谢你!

1 个答案:

答案 0 :(得分:2)

您需要对代码进行分解;你所展示的规则不仅难以阅读,而且还有很多冗余。例如,除后一个终端外,这两个规则基本相同;您可以轻松地按特定规则对该部分进行分解:

type_name:
| INTEGER { St_int }
| BOOLEAN { St_bool }

要回答你的问题,参数化规则应用程序中的参数不能是终端序列(整个事物应返回什么?),而只有一个“实际”,即终端,非终端或应用程序参数化规则。这迫使你将你的语法分解成单独的作品,这很好。

%inline couple(open_sep,X,close_sep):
| open_sep x1 = X COMMA x2 = X close_sep { (x1, x2) }

rectangle:
| rect = couple(LPAREN, couple(LBRACKET, INT, RBRACKET), RPAREN) { rect }

type_name:
| INTEGER { St_int }
| BOOLEAN { St_bool }

binding_names:
| ids_names = separated_nonempty_list (COMMA, rectangle) COLON ty = type_name
    { [] (* put what you want here *) }

在这种情况下,rectangle会返回(int * int) * (int * int)

PS:如果您再次遇到类似错误,请不要犹豫,阅读menhir documentation (PDF)