1

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 { $1 }
    | atomI { $1 }
    | either { $1 }

atomI:
    | ATOMTOKEN INT   { Int($2) }

atomS:
    | ATOMTOKEN STRING { String($2)  }

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

タイプ B とタプルが推論されることを期待します。ただし、FSYACC は、"!!!" でマークされた両方の行でエラーを返します。

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

最後の 2 行の "either" 生成の正しい構文は何ですか?

4

1 に答える 1

2

IntTuple($2, $3)とは反対の意味じゃないB($2, $3)?やってみますIntTuple{x=$2; y=$3}

編集:これは機能します:

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 { $1 }
    | tuple { $1 }

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

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

編集 2:%type < Ast.A > a行では非端末aが type である必要があることに注意してくださいAst.A。したがって、非端末tupleを直接使用しているためtuple、 type である必要がありますAst.A。そのため、レコードを でラップする必要があるため、IntTuple構文は.IntTuple {x = $2; y = $3}{x = $2; y = $3}

于 2015-04-16T14:00:07.607 に答える