1

这是 OCaml 解析器的示例代码:

%{ open Ast %}

%token PLUS MINUS TIMES DIVIDE EOF
%token <int> LITERAL

%left PLUS MINUS
%left TIMES DIVIDE

%start expr
%type < Ast.expr> expr

%%

expr:
  expr PLUS   expr { Binop($1, Add, $3) }
| expr MINUS  expr { Binop($1, Sub, $3) }
| expr TIMES  expr { Binop($1, Mul, $3) }
| expr DIVIDE expr { Binop($1, Div, $3) }
| LITERAL          { Lit($1) }

我也有扫描仪和 AST(抽象语法树)的代码。这里的 1 美元和 3 美元是什么意思?

附录: 我想为变量赋值。我还想将所有变量的值存储在一个数组中。我怎样才能做到这一点?

4

2 回答 2

1

它们指的是语法规则右侧的第一部分和第三部分的解析返回的值。换句话说,就是子表达式的值。在最后一种情况下,$1指的是文字的值。

更新

这里涉及两种语言,所以很难知道你在问什么。我猜你希望你的语言包含拥有变量并为它们赋值的能力。为此,您的扫描仪必须有一个用于变量名的标记和一个用于赋值的标记。您需要扩展您的语法以包括赋值(可能作为具有值的运算符,如在 C 中)。

我也猜你想保留一个带有变量值的OCaml数组。您可以使用全局变量(不纯但有效)来执行此操作。或者,您可以将一个数组与其余的解析状态一起通过解析树。

哈希表或映射可能更适合表示变量名称及其值。

我想知道您的语言是否允许给定变量在多个位置赋予值。

于 2014-07-19T03:51:43.863 回答
0

这实际上是 ocamlyacc 的语法,如果您开始一个新项目,则不应使用它,在这种情况下,您应该使用具有更易读语法的 menhir(并且由于许多其他原因更好)。有些人想用 menhir 重写 OCaml 编译器,但似乎还没有人这样做。

menhir 语法是:

expr:
  e1 = expr PLUS   e2 = expr { Binop(e1, Add, e2) }
| e1 = expr MINUS  e2 = expr { Binop(e1, Sub, e2) }
| e1 = expr TIMES  e2 = expr { Binop(e1, Mul, e2) }
| e1 = expr DIVIDE e2 = expr { Binop(e1, Div, e2) }
| l = LITERAL                { Lit(l) }
于 2014-07-21T09:08:51.213 回答