これは私が解析しようとしているものです
type Number(); // define a type called "Number" with no member variables
type Point(Number x, Number y); // define a type called Point with member variables
// and something with generic types
type Pair[T, V](T first, V second);
// and even something cyclic:
type LinkedList[T](T payload, LinkedList[T] rest);
そして、これを可能にする私の xtext 文法は次のとおりです。
TypeDecl returns SSType:
'type' name=TypeName
('[' typeParams += TypeName (',' typeParams += TypeName)* ']')?
'(' (args += Arg (',' args += Arg)*)? ')' ';'
;
TypeName returns SSTypeName:
name=ID
;
Type:
tn = [SSTypeName] ('[' typeParams += Type (',' typeParams += Type)* ']')?
;
Arg:
type = Type argName = ID
;
これは機能しますが、受け入れる内容があまりにもリベラルです。何かがジェネリック (上記の例の LinkedList など) として宣言されている場合、それをジェネリックとして使用することのみが有効であり (たとえばLinkedList[Number]
ではなくLinkedList
)、理想的には型引数のアリティが強制されます。
もちろん、何かがジェネリック型 (Number など) でないと宣言されている場合、型引数を与えることは有効ではありません。
誤って受け入れるものの例:
type Wrong1(Number[Blah] a); // number doesn't have type arguments
type Wrong2(Pair a); // Pair has type arguments
type Wrong3(Pair[Number, Number, Number] a); // wrong arity
これを適切に行う方法に関する提案、コメント、コード、またはヒントは大歓迎です。