我正在将语法规则转换为AST。
在定义AST时是否需要使用“和”运算符?
例如,到目前为止,我已经翻译了我的语法:
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)对我来说是错误的吗?
答案 0 :(得分:2)
仅在定义相互递归时才需要and
。也就是说,如果一个语句可以包含一个表达式,而一个表达式又可以包含一个语句,则Expr
和Stmt
必须与and
连接。如果您的代码在没有and
的情况下进行编译,则您不需要and
。
PS:这与您的问题无关,但我认为使用list
和option
类型比为特定类型定义自己的版本(例如{ {1}},stmntlist
等)。 expropt
是另一种这样的情况:您可以将stmtprime
定义为Return
并摆脱Return of expr option
类型。与stmtprime
相同。