Использование типов записей в 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 { $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

Каков правильный синтаксис для "любого" производства в последних двух строках?

1 ответ

Решение

Разве вы не имеете в виду 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 быть типом Ast.A, Поэтому, так как вы используете нетерминал tuple непосредственно, tuple должен быть типа Ast.A, Таким образом, вы должны обернуть запись в IntTupleтак синтаксис IntTuple {x = $2; y = $3} в отличие от просто {x = $2; y = $3},

Другие вопросы по тегам