ocaml - 关于 ocamlyacc,函数应用语法和优先级

标签 ocaml grammar yacc ocamlyacc

我是 OCaml 新手,我正在尝试编写一个简单的类似 OCaml 的语法,但我无法弄清楚。我的语法允许这样的事情:

let sub = fun x -> fun y -> x - y;;

但是,如果我想使用这样定义的函数,我可以写:(sub 7) 3但我不会写 sub 7 3 ,这真的让我很烦恼。出于某种原因,它被解释为好像我写了 sub (7 3) (这会将 7 视为带有参数 3 的函数)。相关部分是:
/* other operators, then at the very end: */
%left APPLY

/* ... */

expr:
    /* ... */
    | expr expr %prec APPLY      { Apply($1, $2) }

谢谢!

最佳答案

ocaml 编译器执行如下函数应用:(来自 ocaml/parsing/parser.mly)

expr:
...
  | simple_expr simple_labeled_expr_list
      { mkexp(Pexp_apply($1, List.rev $2)) }

哪里simple_expr是可以计算为函数而无需括号的可能 expr 值的子集。这排除了与函数调用内联使用的所有非自括号构造。它还阐明了子表达式的结合性,因为第二个子表达式明确是一个列表。

至于您为何尝试使用 %left APPLY从 ocaml 的 parser.mly 中的注释中获得正确的关联性不起作用:
We will only use associativities with operators of the kind  x * x -> x
for example, in the rules of the form    expr: expr BINOP expr
in all other cases, we define two precedences if needed to resolve
conflicts.

我会说这意味着你不能在没有运算符的情况下使用 %prec 进行关联。尝试通过定义更多规则来创建您想要的关联性,然后看看会导致什么结果。

关于ocaml - 关于 ocamlyacc,函数应用语法和优先级,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2847399/

相关文章:

haskell - 如何实现纯函数式标准二进制堆(ocaml 或 haskell)?

linux - OCaml 文件 I/O : why is add_channel returning empty content for/proc/<PID>/cmdline?

rust - 使用 Pest.rs 如何管理一行以 "\"结尾的多行语法?

python - PLY:C 解析器中的 token 移位问题

oop - 无法从另一个实例变量的定义中访问实例变量 super

ocaml - 参数化局部抽象类型

c - 编程语言中的术语 "context"以及加载和更新如何影响上下文?

performance - Perl6 : What is the best way for dealing with very big files?

c++ - 如何使用 flex 和 bison 解析非常大的缓冲区

python - LALR 语法、尾随逗号和多行列表分配