【问题标题】:When to use "and" operator in Ocaml AST何时在 Ocaml AST 中使用“and”运算符
【发布时间】:2018-11-09 21:12:01
【问题描述】:

我正在将我的语法规则翻译成 AST。

在定义我们的 AST 时有必要使用“and”运算符吗?

例如,到目前为止,我已经翻译了我的语法:

type program =
   |  Decls of typ * identifier * decls_prime

type typ =
   | INT
   | BOOL
   | VOID

type identifier = string

(* decls_prime = vdecl decls | fdecl decls *)
type declsprime =
   | Vdecl of variabledeclaration * decls
   | Fdecl of functiondeclaration * decls

(*“lparen” formals_opt “rparen” “LBRACE” vdecl_list stmt_list “RBRACE”*)
type functiondeclaration =
    | Fdecl of variabledeclarationlist * stmtlist

(*formals_opt = formal_list | epsilon *)
type FormalsOpt =
   |FormalsOpt of formallist

(* typ “ID” formal_list_prime *)
type formalList =
    | FormalList of typ * identifier * formallistprime

type formallistprime =
    | FormalListPrime of formalList

type variabledeclarationlist =
    | VdeclList of variabledeclaration * variabledeclarationlist

(*stmt stmt_list | epsilon*)
type stmtlist =
    | StmtList of stmt * stmtlist
    | StmtlistNil 

(* stmt = “RETURN” stmt_prime| expr SEMI |“LBRACE” stmt_list RBRACE| IF LPAREN expr RPAREN stmt stmt_prime_prime| FOR LPAREN expr_opt SEMI expr SEMI expr_opt RPAREN stmt| WHILE LPAREN expr RPAREN stmt*)
type Stmt
| Return of stmtprime
| Expression of expr
| StmtList of stmtlist
| IF of expr * stmt * stmtprimeprime
| FOR of expropt * expr * expropt * stmt 
| WHILE of expr * stmt

(*stmt_prime = SEMI| expr SEMI*)
type stmtprime
| SEMI 
| Expression of expr 

(*NOELSE | ELSE stmt*)
type stmtprimeprime
| NOELSE 
| ELSE of stmt

(* Expr_opt = expr | epsilon *)
type expropt =
| Expression of expr 
| ExprNil 

type Expr

type ExprPrime

(* Actuals_opt  = actuals_list  | epsilon *)
type ActualsOpt= 
| ActualsList of actualslist 
| ActualsNil

type ActualsList = 
| ActualsList of expr * actualslistprime

(*actualslistprime = COMMA expr actuals_list_prime | epsilon*)
type actualslistprime = 
| ActualsListPrime of expr * actualslistprime
| ALPNil

但看起来伊利诺伊州的这个例子使用了稍微不同的结构:

type program = Program of (class_decl list)
and class_decl = Class of id * id * (var_decl list) * (method_decl list)
and method_decl = Method....

在定义我的 AST 时是否需要使用“and”?而且,即使我在解析器中正确调用了 AST StmtList 方法,使用 StmtList 类型而不是 (stmt list) 对我来说是错误的吗?

【问题讨论】:

    标签: parsing ocaml abstract-syntax-tree


    【解决方案1】:

    当您的定义相互递归时,您只需要and。也就是说,如果一个语句可以包含一个表达式,而一个表达式又可以包含一个语句,那么ExprStmt 必须与and 连接。如果您的代码在没有and 的情况下编译,则不需要and

    PS:这与您的问题无关,但我认为使用listoption 类型比为特定类型定义您自己的版本(例如stmntlist,@ 987654330@ 等)。 stmtprime 是另一种情况:您可以将 Return 定义为 Return of expr option 并去掉 stmtprime 类型。与stmtprimeprime 相同。

    【讨论】:

    • 我不得不手动编写解析器(没有解析器生成器),这就是我创建 StmtPrime 等 AST 类型的原因。我将如何定义选项? OCaml 的新手
    • @Matt 我不明白为什么手动编写解析器会影响 AST 的样子。 “我将如何定义选项?” option 是标准库中的一个类型——你不需要定义它。您可以只写Return of stmt option 而不是Return of stmtprime,就是这样。
    • 但是 Stmt prime 不需要建立吗?因为 StmtPrime = Semi |表达式
    • 从技术上讲,它不是可选的吗?
    • @Matt 我没有关注你。 stmtprime 是您定义的类型,可以包含表达式或不包含任何内容。 expr option 也是一种可以包含表达式或不包含任何内容的类型。因此这两种类型是完全可以互换的,stmtprime 类型是不必要的。分号是否可选是您的解析器的属性,而不是您的 AST。您碰巧将无表达式构造函数命名为 SEMI 这一事实不会影响解析器是否需要分号。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-07
    • 2015-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-10
    相关资源
    最近更新 更多