mirror of
https://github.com/dolthub/dolt.git
synced 2026-01-30 19:09:34 -06:00
183 lines
4.4 KiB
Plaintext
183 lines
4.4 KiB
Plaintext
{
|
|
package parse
|
|
|
|
type alias struct {
|
|
Name string
|
|
Target string
|
|
}
|
|
|
|
type namespaceIdent struct {
|
|
Namespace string
|
|
ID string
|
|
}
|
|
}
|
|
|
|
Package <- _ dd:Definition+ _ EOF {
|
|
aliases := map[string]string{}
|
|
usings := []TypeRef{}
|
|
named := map[string]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 TypeRef:
|
|
switch d.Desc.Kind() {
|
|
default:
|
|
return nil, fmt.Errorf("%v can't be defined at the top-level", d)
|
|
case ListKind, MapKind, RefKind, 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 EnumKind, StructKind:
|
|
if _, present := named[d.Name]; present {
|
|
return nil, fmt.Errorf("Redefinition of " + d.Name)
|
|
}
|
|
named[d.Name] = d
|
|
}
|
|
}
|
|
}
|
|
return Package{aliases, usings, named}, 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 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 *UnionDesc
|
|
fieldNames := map[string]bool{}
|
|
fields := make([]Field, 0, len(ll))
|
|
for _, e := range ll {
|
|
switch e := e.(type) {
|
|
case UnionDesc:
|
|
if u != nil {
|
|
return nil, fmt.Errorf("Only one anonymous union per struct.")
|
|
}
|
|
u = &e
|
|
case 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 makeStructTypeRef(i.(string), fields, u), nil
|
|
}
|
|
|
|
StructEntry <- Union / Field
|
|
|
|
|
|
Union <- `union` _ `{` _ u:Field+ _ `}` _ {
|
|
uu := u.([]interface{})
|
|
choiceNames := map[string]bool{}
|
|
desc := UnionDesc{Choices: make([]Field, 0, len(uu))}
|
|
for _, f := range uu {
|
|
ff := f.(Field)
|
|
if choiceNames[ff.Name] {
|
|
return nil, fmt.Errorf("Redefinition of union choice %s", ff.Name)
|
|
}
|
|
choiceNames[ff.Name] = true
|
|
desc.Choices = append(desc.Choices, ff)
|
|
}
|
|
return desc, nil
|
|
}
|
|
|
|
Field <- i:Ident _ `:` _ t:Type _ {
|
|
return Field{i.(string), t.(TypeRef)}, nil
|
|
}
|
|
|
|
Type <- t:(PrimitiveType / CompoundType / Union / NamespaceIdent) {
|
|
switch t := t.(type) {
|
|
case TypeRef:
|
|
return t, nil
|
|
case UnionDesc:
|
|
return makeStructTypeRef("", nil, &t), nil
|
|
case namespaceIdent:
|
|
return TypeRef{PkgRef:t.Namespace, Name:t.ID}, nil
|
|
default:
|
|
return nil, fmt.Errorf("%v is %T, not something that satisfies TypeRef", t, t)
|
|
}
|
|
}
|
|
|
|
CompoundType <- `List` _ `(` _ t:Type _ `)` _ {
|
|
return makeCompoundTypeRef(ListKind, []TypeRef{t.(TypeRef)}), nil
|
|
} / `Map` _ `(` _ k:Type _ `,` _ v:Type _ `)` _ {
|
|
return makeCompoundTypeRef(MapKind, []TypeRef{k.(TypeRef), v.(TypeRef)}), nil
|
|
} / `Set` _ `(` _ t:Type _ `)` _ {
|
|
return makeCompoundTypeRef(SetKind, []TypeRef{t.(TypeRef)}), nil
|
|
} / `Ref` _ `(` _ t:Type _ `)` _ {
|
|
return makeCompoundTypeRef(RefKind, []TypeRef{t.(TypeRef)}), nil
|
|
}
|
|
|
|
PrimitiveType <- p:(`UInt64` / `UInt32` / `UInt16` / `UInt8` / `Int64` / `Int32` / `Int16` / `Int8` / `Float64` / `Float32` / `Bool` / `String` / `Blob` / `Value`) {
|
|
return makePrimitiveTypeRef(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 <- _ !.
|