0

我在 parser.mly 中得到了这条规则:

intervalue:
| c = CST(* True False 1 7 89 "sfr" *)
    { Ecst c }
| id = ident (* a-z [a-z]* *)
    { Eident id }
| iv = LSQ l = separated_list(TWOPoints, intervalue) RSQ /* [1..4]*/
    { Elist l }
;

我需要将 [start .. end] 的值传递给 list "l"。示例([1..4])。我手动搜索,separated_list(TWOPoints, intervalue)只得到值 1 和 4。但我需要 1 到 4 之间的所有值,包括像这样的 [1..2..3..4],但不必详尽无遗。

4

1 回答 1

1

separated_list据我所知,不反映您想要的语法。但是,也没有使用intervalue间隔的限制。

separated_list不正确,因为它用于由分隔符分隔的任何正数元素的列表。特别是,separated_list(TWOPoints, intervalue)不仅会匹配1..4,而且还会匹配1, 和1..4..7,等等。那些其他的东西包括嵌套intervalue的 s,例如2..[4..7],这似乎不太可能是一个理想的构造(尽管因为我不知道你的语言是什么样的,也许它是)。

您似乎separated_list错误地认为这是将减少转换为 OCanl 列表的唯一方法。这不是真的,因为您可以使用 OCaml 的全部功能;你可以把这个产品写成

| LSQ low = CST TWOPoints high = CST RSQ     { [ low high] }

甚至

| LSQ low = CST TWOPoints high = CST RSQ     { [ low .. high] }

尽管这不适用于所有可能的CST标记(例如[1 .. "a"])。此外,它不允许使用非常量限制,例如[1 .. limit].

但是几乎可以肯定,将语法与运行时语义混合在一起并不是您想要的。您将如何处理如上例 ( [1 .. limit]) 中的程序文​​本,limit在程序执行期间将被赋值的变量在哪里?(甚至许多值,因为程序在循环中执行。)解析器应该限制自己产生一个有用的程序来执行的表示,最有可能的生产规则将是这样的(Value需要根据实际需要的语法):+

| LSQ low = Value TWOPoints high = Value RSQ     { Einterval low high }
于 2019-12-16T17:46:06.337 回答