mirror of
https://github.com/dolthub/dolt.git
synced 2026-04-29 19:39:52 -05:00
cdcf952270
The name param of MakeCompoundTypeRef is always the empty string. I didn't change the underlying storage or serialization. Fixes #436, #477
200 lines
5.1 KiB
Plaintext
200 lines
5.1 KiB
Plaintext
{
|
|
package pkg
|
|
|
|
type alias struct {
|
|
Name string
|
|
Target string
|
|
}
|
|
|
|
type namespaceIdent struct {
|
|
Namespace string
|
|
ID string
|
|
}
|
|
}
|
|
|
|
Package <- _ dd:Definition+ _ EOF {
|
|
aliases := map[string]string{}
|
|
usings := []types.TypeRef{}
|
|
seenTypes := map[string]bool{}
|
|
orderedTypes := []types.TypeRef{}
|
|
for _, d := range dd.([]interface{}) {
|
|
switch d := d.(type) {
|
|
default:
|
|
return nil, fmt.Errorf("Unknown definition: %v", d)
|
|
case alias:
|
|
if _, present := aliases[d.Name]; present {
|
|
return nil, fmt.Errorf("Redefinition of " + d.Name)
|
|
}
|
|
aliases[d.Name] = d.Target
|
|
case types.TypeRef:
|
|
switch d.Desc.Kind() {
|
|
default:
|
|
return nil, fmt.Errorf("%v can't be defined at the top-level", d)
|
|
case types.ListKind, types.MapKind, types.RefKind, types.SetKind:
|
|
for _, u := range usings {
|
|
if u.Equals(d) {
|
|
return nil, fmt.Errorf("%v is a duplicate using declaration", d)
|
|
}
|
|
}
|
|
usings = append(usings, d)
|
|
case types.EnumKind:
|
|
if seenTypes[d.Name()] {
|
|
return nil, fmt.Errorf("Redefinition of " + d.Name())
|
|
}
|
|
seenTypes[d.Name()] = true
|
|
orderedTypes = append(orderedTypes, d)
|
|
case types.StructKind:
|
|
ds := expandStruct(d, len(orderedTypes))
|
|
for _, d := range ds {
|
|
if d.Name() != "" {
|
|
if seenTypes[d.Name()] {
|
|
return nil, fmt.Errorf("Redefinition of " + d.Name())
|
|
}
|
|
seenTypes[d.Name()] = true
|
|
}
|
|
orderedTypes = append(orderedTypes, d)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return intermediate{"", aliases, usings, orderedTypes}, nil
|
|
}
|
|
|
|
Definition <- Struct / Using / Alias / Enum
|
|
|
|
Alias <- `alias` _ i:Ident _ `=` _ `import` _ q:QuotedString _ {
|
|
return alias{i.(string), q.(string)}, nil
|
|
}
|
|
|
|
Enum <- `enum` _ id:Ident _ `{` _ l:EnumEntry+ _ `}` _ {
|
|
entries := l.([]interface{})
|
|
ids := make([]string, len(entries))
|
|
for i, e := range entries {
|
|
ids[i] = e.(string)
|
|
}
|
|
return types.MakeEnumTypeRef(id.(string), ids...), nil
|
|
}
|
|
|
|
EnumEntry <- i:Ident _ {
|
|
return i.(string), nil
|
|
}
|
|
|
|
|
|
Using <- `using` _ ct:CompoundType _ {
|
|
return ct, nil
|
|
}
|
|
|
|
|
|
Struct <- `struct` _ i:Ident _ `{` _ l:StructEntry+ _ `}` _ {
|
|
ll := l.([]interface{})
|
|
var u types.Choices
|
|
fieldNames := map[string]bool{}
|
|
fields := make([]types.Field, 0, len(ll))
|
|
for _, e := range ll {
|
|
switch e := e.(type) {
|
|
case types.Choices:
|
|
if u != nil {
|
|
return nil, fmt.Errorf("Only one anonymous union per struct.")
|
|
}
|
|
u = e
|
|
case types.Field:
|
|
if fieldNames[e.Name] {
|
|
return nil, fmt.Errorf("Redefinition of field %s in struct %s", e.Name, i.(string))
|
|
}
|
|
fieldNames[e.Name] = true
|
|
fields = append(fields, e)
|
|
default:
|
|
return nil, fmt.Errorf("Structs must be made up of field declarations and at most one anonymous union.")
|
|
}
|
|
}
|
|
return types.MakeStructTypeRef(i.(string), fields, u), nil
|
|
}
|
|
|
|
StructEntry <- Union / Field
|
|
|
|
|
|
Union <- `union` _ `{` _ u:UnionField+ _ `}` _ {
|
|
uu := u.([]interface{})
|
|
choiceNames := map[string]bool{}
|
|
desc := make(types.Choices, 0, len(uu))
|
|
for _, f := range uu {
|
|
ff := f.(types.Field)
|
|
if choiceNames[ff.Name] {
|
|
return nil, fmt.Errorf("Redefinition of union choice %s", ff.Name)
|
|
}
|
|
choiceNames[ff.Name] = true
|
|
desc = append(desc, ff)
|
|
}
|
|
return desc, nil
|
|
}
|
|
|
|
Field <- i:Ident _ `:` _ o:(`optional` _)? t:Type _ {
|
|
return types.Field{i.(string), t.(types.TypeRef), o != nil}, nil
|
|
}
|
|
|
|
UnionField <- i:Ident _ `:` _ t:Type _ {
|
|
return types.Field{i.(string), t.(types.TypeRef), false}, nil
|
|
}
|
|
|
|
Type <- t:(PrimitiveType / CompoundType / Union / NamespaceIdent) {
|
|
switch t := t.(type) {
|
|
case types.TypeRef:
|
|
return t, nil
|
|
case types.Choices:
|
|
return types.MakeStructTypeRef("", nil, t), nil
|
|
case namespaceIdent:
|
|
return types.MakeUnresolvedTypeRef(t.Namespace, t.ID), nil
|
|
default:
|
|
return nil, fmt.Errorf("%v is %T, not something that satisfies TypeRef", t, t)
|
|
}
|
|
}
|
|
|
|
CompoundType <- `List` _ `(` _ t:Type _ `)` _ {
|
|
return types.MakeCompoundTypeRef(types.ListKind, t.(types.TypeRef)), nil
|
|
} / `Map` _ `(` _ k:Type _ `,` _ v:Type _ `)` _ {
|
|
return types.MakeCompoundTypeRef(types.MapKind, k.(types.TypeRef), v.(types.TypeRef)), nil
|
|
} / `Set` _ `(` _ t:Type _ `)` _ {
|
|
return types.MakeCompoundTypeRef(types.SetKind, t.(types.TypeRef)), nil
|
|
} / `Ref` _ `(` _ t:Type _ `)` _ {
|
|
return types.MakeCompoundTypeRef(types.RefKind, t.(types.TypeRef)), nil
|
|
}
|
|
|
|
PrimitiveType <- p:(`UInt64` / `UInt32` / `UInt16` / `UInt8` / `Int64` / `Int32` / `Int16` / `Int8` / `Float64` / `Float32` / `Bool` / `String` / `Blob` / `Value` / `TypeRef`) {
|
|
return types.MakePrimitiveTypeRefByString(string(p.([]uint8))), nil
|
|
}
|
|
|
|
QuotedString <- `"` n:String `"` {
|
|
return n.(string), nil
|
|
}
|
|
|
|
String <- (StringPiece `\"` StringPiece `\"` StringPiece / StringPiece) {
|
|
return string(c.text), nil
|
|
}
|
|
|
|
StringPiece <- (`\` !`"` / [^"\\])*
|
|
|
|
NamespaceIdent <- n:(Ident '.')* id:Ident {
|
|
nn := n.([]interface{})
|
|
ns := make([]string, len(nn))
|
|
for i, e := range nn {
|
|
ns[i] = e.([]interface{})[0].(string)
|
|
}
|
|
return namespaceIdent{strings.Join(ns, "."), id.(string)}, nil
|
|
}
|
|
|
|
Ident <- [\pL_] [\pL\pN_]* {
|
|
return string(c.text), nil
|
|
}
|
|
|
|
_ "optional whitespace" <- WS (Comment WS)* {
|
|
return nil, nil
|
|
}
|
|
|
|
WS <- [\r\n\t\pZ]*
|
|
|
|
Comment <- `//` [^\n]* / MultilineComment
|
|
|
|
MultilineComment <- `/*` (`*` !`/` / [^*])* `*/`
|
|
|
|
EOF <- _ !.
|