Parsing 何时使用;及;Ocaml-AST中的运算符
我正在把我的语法规则翻译成AST 在定义AST时是否需要使用“and”运算符 例如,到目前为止,我已将我的语法翻译为:Parsing 何时使用;及;Ocaml-AST中的运算符,parsing,ocaml,abstract-syntax-tree,Parsing,Ocaml,Abstract Syntax Tree,我正在把我的语法规则翻译成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
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时是否需要使用“和”?而且,即使我在解析器中正确调用了AST StmtList方法,但我使用StmtList类型而不是(stmt list)是否错误?当定义是相互递归的时,您只需要
和
。也就是说,如果语句可以包含表达式,而表达式又可以包含语句,则Expr
和Stmt
必须与和
连接。如果您的代码编译时没有和
,则不需要和
PS:这与您的问题无关,但我认为使用
列表
和选项
类型比为特定类型定义自己的版本(例如stmntlist
,expropt
等)更有意义stmtprime
是另一种情况:您可以将Return
定义为returnofexpr选项
,并去掉stmtprime
类型。与stmtprime
相同,当定义是相互递归的时,只需要和
。也就是说,如果语句可以包含表达式,而表达式又可以包含语句,则Expr
和Stmt
必须与和
连接。如果您的代码编译时没有和
,则不需要和
PS:这与您的问题无关,但我认为使用
列表
和选项
类型比为特定类型定义自己的版本(例如stmntlist
,expropt
等)更有意义stmtprime
是另一种情况:您可以将Return
定义为returnofexpr选项
,并去掉stmtprime
类型。与StmtPrime
相同,我必须手工编写解析器(没有解析器生成器),这就是我创建StmtPrime等AST类型的原因。我如何定义选项?非常新的OCaml@Matt我不明白为什么手工编写解析器会影响AST的外观。“如何定义选项?”option
是标准库中的一种类型-您不需要定义它。您可以只编写返回stmt选项
而不是返回stmttime
,就这样。但是stmtprime不需要建立吗?因为StmtPrime=Semi | Expressionso从技术上讲,它不是可选的吗?@Matt我不明白你的意思stmtprime
是您定义的一种类型,可以包含表达式,也可以不包含任何内容expr选项
也是一种类型,可以包含表达式,也可以不包含任何内容。因此,这两种类型是完全可互换的,stmtprime
类型是不必要的。分号是否可选是解析器的属性,而不是AST的属性。您碰巧命名了无表达式构造函数SEMI
,这一事实并不影响解析器是否需要分号。我必须手动编写解析器(无解析器生成器),这就是我创建StmtPrime等AST类型的原因。我如何定义选项?非常新的OCaml@Matt我不明白为什么手工编写解析器会影响AST的外观。“如何定义选项?”option
是标准库中的一种类型-您不需要定义它。您可以只编写返回stmt选项
而不是返回stmttime
,就这样。但是stmtprime不需要建立吗?因为StmtPrime=Semi | Expressionso从技术上讲,它不是可选的吗?@Matt我不明白你的意思stmtprime
是您定义的一种类型,可以包含表达式,也可以不包含任何内容expr选项
也是一种类型,可以包含表达式,也可以不包含任何内容。因此,这两种类型是完全可互换的,stmtprime
类型是不必要的。分号是否可选是解析器的属性,而不是AST的属性。您碰巧命名了无表达式构造函数SEMI
,这一事实并不影响解析器是否需要分号。