我正在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.mly和sib_syntax.ml。它们编译得很好,但是当我用程序测试二进制文件时,它会抛出一个解析器错误。有人可以帮忙吗?非常感谢你!
答案 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)。