在 FSYACC 中使用记录类型

Using record types in FSYACC

在 FSYACC 中,终端生成元组是很常见的。但是,为了方便起见,我想改用记录类型。例如,如果我的抽象语法树 (AbstractSyntaxTree.fsl) 中有以下内容:

namespace FS
module AbstractSyntaxTree =

 type B = { x : int; y : int }

 type Either = 
      | Record of B
      | Tuple of int * string

 type A =
     | Int of int
     | String of string
     | IntTuple of Either

我不清楚 FSYACC (parser.fsy) 中的正确语法,因为如果我使用:

%start a
%token <string> STRING
%token <System.Int32> INT
%token ATOMTOKEN TUPLETOKEN EOF
%type < A > a

%%

a:
    | atomS {  }
    | atomI {  }
    | either {  }

atomI:
    | ATOMTOKEN INT   { Int() }

atomS:
    | ATOMTOKEN STRING { String()  }

either:
    | TUPLETOKEN INT INT { Record {x=;y=} } // !!!
    | TUPLETOKEN TUPLETOKEN INT STRING { Tuple( , ) } // !!!

我希望推断出类型 B 和元组。但是,FSYACC 给出了标有“!!!”的两行的错误:

This expression was expected to have type  A but here has type Either

最后两行 "either" 产生式的正确语法是什么?

你不是说 IntTuple(, ) 而不是 B(, ) 吗?我会尝试 IntTuple{x=; y=}

编辑: 这有效:

module Ast

type B = { x : int; y : int }
type A =
    | Int of int
    | String of string
    | IntTuple of B

%{

open Ast

%}

%start a
%token <string> STRING
%token <System.Int32> INT
%token ATOMTOKEN TUPLETOKEN 
%type < Ast.A > a


%%

a:
    | atom {  }
    | tuple {  }

atom:
    | ATOMTOKEN INT   { Int() }
    | ATOMTOKEN STRING { String() }

tuple:
    | TUPLETOKEN INT INT { IntTuple {x = ; y = } }

编辑 2: 请注意,行 %type < Ast.A > a 要求您的非终端 a 类型为 Ast.A。因此,由于您直接使用非终结符 tuple,因此 tuple 需要是 Ast.A 类型。因此,您必须将记录包装在 IntTuple 中,因此语法是 IntTuple {x = ; y = } 而不是 {x = ; y = }.