When to use “and” operator in Ocaml AST









up vote
0
down vote

favorite












I am translating the rules of my grammar into an AST.



Is it necessary to use the "and" operator in defining our AST?



For instance, I have translated my grammar thus far like so:



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


But it looks as though this example from Illinois uses a slightly different structure:



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


Is it necessary to use "and" when defining my AST? And moreover, is it wrong for me to use a StmtList type rather than (stmt list) even though I call the AST StmtList method correctly in my parser?










share|improve this question

























    up vote
    0
    down vote

    favorite












    I am translating the rules of my grammar into an AST.



    Is it necessary to use the "and" operator in defining our AST?



    For instance, I have translated my grammar thus far like so:



    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


    But it looks as though this example from Illinois uses a slightly different structure:



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


    Is it necessary to use "and" when defining my AST? And moreover, is it wrong for me to use a StmtList type rather than (stmt list) even though I call the AST StmtList method correctly in my parser?










    share|improve this question























      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      I am translating the rules of my grammar into an AST.



      Is it necessary to use the "and" operator in defining our AST?



      For instance, I have translated my grammar thus far like so:



      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


      But it looks as though this example from Illinois uses a slightly different structure:



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


      Is it necessary to use "and" when defining my AST? And moreover, is it wrong for me to use a StmtList type rather than (stmt list) even though I call the AST StmtList method correctly in my parser?










      share|improve this question













      I am translating the rules of my grammar into an AST.



      Is it necessary to use the "and" operator in defining our AST?



      For instance, I have translated my grammar thus far like so:



      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


      But it looks as though this example from Illinois uses a slightly different structure:



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


      Is it necessary to use "and" when defining my AST? And moreover, is it wrong for me to use a StmtList type rather than (stmt list) even though I call the AST StmtList method correctly in my parser?







      parsing ocaml abstract-syntax-tree






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 9 at 21:12









      Matt

      4731624




      4731624






















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          2
          down vote



          accepted










          You only need and when your definitions are mutually recursive. That is, if a statement could contain an expression and an expression could in turn contain a statement, then Expr and Stmt would have to be connected with an and. If your code compiles without and, you don't need the and.



          PS: This is unrelated to your question, but I think it would make a lot more sense to use the list and option types than to define your own versions for specific types (such as stmntlist, expropt etc.). stmtprime is another such case: You could just define Return as Return of expr option and get rid of the stmtprime type. Same with stmtprimeprime.






          share|improve this answer






















          • I had to write the parser by hand (no parser generator) which is why I created StmtPrime, etc AST types. How would I define option? Very new to OCaml
            – Matt
            Nov 9 at 21:30










          • @Matt I don't see why writing the parser by hand would affect what the AST looks like. "How would I define option?" option is a type from the standard library - you don't need to define it. You can just write Return of stmt option instead of Return of stmtprime and that's it.
            – sepp2k
            Nov 9 at 21:34










          • But doesn't Stmt prime need to be built up? Because StmtPrime = Semi | Expression
            – Matt
            Nov 9 at 21:38










          • so technically, its not optional?
            – Matt
            Nov 9 at 21:38






          • 1




            @Matt I'm not following you. stmtprime is a type that you defined that could either contain an expression or nothing. expr option is also a type that could either contain an expression or nothing. Therefore these two types are completely interchangeable and the stmtprime type is unnecessary. Whether the semicolon is optional or not is a property of your parser, not your AST. The fact that you happened to name your no-expression constructor SEMI does not affect whether or not the parser expects a semicolon.
            – sepp2k
            Nov 9 at 21:48










          Your Answer






          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "1"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader:
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          ,
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













           

          draft saved


          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53233330%2fwhen-to-use-and-operator-in-ocaml-ast%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          2
          down vote



          accepted










          You only need and when your definitions are mutually recursive. That is, if a statement could contain an expression and an expression could in turn contain a statement, then Expr and Stmt would have to be connected with an and. If your code compiles without and, you don't need the and.



          PS: This is unrelated to your question, but I think it would make a lot more sense to use the list and option types than to define your own versions for specific types (such as stmntlist, expropt etc.). stmtprime is another such case: You could just define Return as Return of expr option and get rid of the stmtprime type. Same with stmtprimeprime.






          share|improve this answer






















          • I had to write the parser by hand (no parser generator) which is why I created StmtPrime, etc AST types. How would I define option? Very new to OCaml
            – Matt
            Nov 9 at 21:30










          • @Matt I don't see why writing the parser by hand would affect what the AST looks like. "How would I define option?" option is a type from the standard library - you don't need to define it. You can just write Return of stmt option instead of Return of stmtprime and that's it.
            – sepp2k
            Nov 9 at 21:34










          • But doesn't Stmt prime need to be built up? Because StmtPrime = Semi | Expression
            – Matt
            Nov 9 at 21:38










          • so technically, its not optional?
            – Matt
            Nov 9 at 21:38






          • 1




            @Matt I'm not following you. stmtprime is a type that you defined that could either contain an expression or nothing. expr option is also a type that could either contain an expression or nothing. Therefore these two types are completely interchangeable and the stmtprime type is unnecessary. Whether the semicolon is optional or not is a property of your parser, not your AST. The fact that you happened to name your no-expression constructor SEMI does not affect whether or not the parser expects a semicolon.
            – sepp2k
            Nov 9 at 21:48














          up vote
          2
          down vote



          accepted










          You only need and when your definitions are mutually recursive. That is, if a statement could contain an expression and an expression could in turn contain a statement, then Expr and Stmt would have to be connected with an and. If your code compiles without and, you don't need the and.



          PS: This is unrelated to your question, but I think it would make a lot more sense to use the list and option types than to define your own versions for specific types (such as stmntlist, expropt etc.). stmtprime is another such case: You could just define Return as Return of expr option and get rid of the stmtprime type. Same with stmtprimeprime.






          share|improve this answer






















          • I had to write the parser by hand (no parser generator) which is why I created StmtPrime, etc AST types. How would I define option? Very new to OCaml
            – Matt
            Nov 9 at 21:30










          • @Matt I don't see why writing the parser by hand would affect what the AST looks like. "How would I define option?" option is a type from the standard library - you don't need to define it. You can just write Return of stmt option instead of Return of stmtprime and that's it.
            – sepp2k
            Nov 9 at 21:34










          • But doesn't Stmt prime need to be built up? Because StmtPrime = Semi | Expression
            – Matt
            Nov 9 at 21:38










          • so technically, its not optional?
            – Matt
            Nov 9 at 21:38






          • 1




            @Matt I'm not following you. stmtprime is a type that you defined that could either contain an expression or nothing. expr option is also a type that could either contain an expression or nothing. Therefore these two types are completely interchangeable and the stmtprime type is unnecessary. Whether the semicolon is optional or not is a property of your parser, not your AST. The fact that you happened to name your no-expression constructor SEMI does not affect whether or not the parser expects a semicolon.
            – sepp2k
            Nov 9 at 21:48












          up vote
          2
          down vote



          accepted







          up vote
          2
          down vote



          accepted






          You only need and when your definitions are mutually recursive. That is, if a statement could contain an expression and an expression could in turn contain a statement, then Expr and Stmt would have to be connected with an and. If your code compiles without and, you don't need the and.



          PS: This is unrelated to your question, but I think it would make a lot more sense to use the list and option types than to define your own versions for specific types (such as stmntlist, expropt etc.). stmtprime is another such case: You could just define Return as Return of expr option and get rid of the stmtprime type. Same with stmtprimeprime.






          share|improve this answer














          You only need and when your definitions are mutually recursive. That is, if a statement could contain an expression and an expression could in turn contain a statement, then Expr and Stmt would have to be connected with an and. If your code compiles without and, you don't need the and.



          PS: This is unrelated to your question, but I think it would make a lot more sense to use the list and option types than to define your own versions for specific types (such as stmntlist, expropt etc.). stmtprime is another such case: You could just define Return as Return of expr option and get rid of the stmtprime type. Same with stmtprimeprime.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 9 at 21:42

























          answered Nov 9 at 21:21









          sepp2k

          290k36592604




          290k36592604











          • I had to write the parser by hand (no parser generator) which is why I created StmtPrime, etc AST types. How would I define option? Very new to OCaml
            – Matt
            Nov 9 at 21:30










          • @Matt I don't see why writing the parser by hand would affect what the AST looks like. "How would I define option?" option is a type from the standard library - you don't need to define it. You can just write Return of stmt option instead of Return of stmtprime and that's it.
            – sepp2k
            Nov 9 at 21:34










          • But doesn't Stmt prime need to be built up? Because StmtPrime = Semi | Expression
            – Matt
            Nov 9 at 21:38










          • so technically, its not optional?
            – Matt
            Nov 9 at 21:38






          • 1




            @Matt I'm not following you. stmtprime is a type that you defined that could either contain an expression or nothing. expr option is also a type that could either contain an expression or nothing. Therefore these two types are completely interchangeable and the stmtprime type is unnecessary. Whether the semicolon is optional or not is a property of your parser, not your AST. The fact that you happened to name your no-expression constructor SEMI does not affect whether or not the parser expects a semicolon.
            – sepp2k
            Nov 9 at 21:48
















          • I had to write the parser by hand (no parser generator) which is why I created StmtPrime, etc AST types. How would I define option? Very new to OCaml
            – Matt
            Nov 9 at 21:30










          • @Matt I don't see why writing the parser by hand would affect what the AST looks like. "How would I define option?" option is a type from the standard library - you don't need to define it. You can just write Return of stmt option instead of Return of stmtprime and that's it.
            – sepp2k
            Nov 9 at 21:34










          • But doesn't Stmt prime need to be built up? Because StmtPrime = Semi | Expression
            – Matt
            Nov 9 at 21:38










          • so technically, its not optional?
            – Matt
            Nov 9 at 21:38






          • 1




            @Matt I'm not following you. stmtprime is a type that you defined that could either contain an expression or nothing. expr option is also a type that could either contain an expression or nothing. Therefore these two types are completely interchangeable and the stmtprime type is unnecessary. Whether the semicolon is optional or not is a property of your parser, not your AST. The fact that you happened to name your no-expression constructor SEMI does not affect whether or not the parser expects a semicolon.
            – sepp2k
            Nov 9 at 21:48















          I had to write the parser by hand (no parser generator) which is why I created StmtPrime, etc AST types. How would I define option? Very new to OCaml
          – Matt
          Nov 9 at 21:30




          I had to write the parser by hand (no parser generator) which is why I created StmtPrime, etc AST types. How would I define option? Very new to OCaml
          – Matt
          Nov 9 at 21:30












          @Matt I don't see why writing the parser by hand would affect what the AST looks like. "How would I define option?" option is a type from the standard library - you don't need to define it. You can just write Return of stmt option instead of Return of stmtprime and that's it.
          – sepp2k
          Nov 9 at 21:34




          @Matt I don't see why writing the parser by hand would affect what the AST looks like. "How would I define option?" option is a type from the standard library - you don't need to define it. You can just write Return of stmt option instead of Return of stmtprime and that's it.
          – sepp2k
          Nov 9 at 21:34












          But doesn't Stmt prime need to be built up? Because StmtPrime = Semi | Expression
          – Matt
          Nov 9 at 21:38




          But doesn't Stmt prime need to be built up? Because StmtPrime = Semi | Expression
          – Matt
          Nov 9 at 21:38












          so technically, its not optional?
          – Matt
          Nov 9 at 21:38




          so technically, its not optional?
          – Matt
          Nov 9 at 21:38




          1




          1




          @Matt I'm not following you. stmtprime is a type that you defined that could either contain an expression or nothing. expr option is also a type that could either contain an expression or nothing. Therefore these two types are completely interchangeable and the stmtprime type is unnecessary. Whether the semicolon is optional or not is a property of your parser, not your AST. The fact that you happened to name your no-expression constructor SEMI does not affect whether or not the parser expects a semicolon.
          – sepp2k
          Nov 9 at 21:48




          @Matt I'm not following you. stmtprime is a type that you defined that could either contain an expression or nothing. expr option is also a type that could either contain an expression or nothing. Therefore these two types are completely interchangeable and the stmtprime type is unnecessary. Whether the semicolon is optional or not is a property of your parser, not your AST. The fact that you happened to name your no-expression constructor SEMI does not affect whether or not the parser expects a semicolon.
          – sepp2k
          Nov 9 at 21:48

















           

          draft saved


          draft discarded















































           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53233330%2fwhen-to-use-and-operator-in-ocaml-ast%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          How to how show current date and time by default on contact form 7 in WordPress without taking input from user in datetimepicker

          Syphilis

          Darth Vader #20