diff --git a/internal/attrs.go b/internal/attrs.go
new file mode 100644
index 0000000..c0d03c8
--- /dev/null
+++ b/internal/attrs.go
@@ -0,0 +1,205 @@
+// Copyright 2020 CUE Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package internal
+
+import (
+	"fmt"
+	"strconv"
+	"strings"
+
+	"cuelang.org/go/cue/errors"
+	"cuelang.org/go/cue/literal"
+	"cuelang.org/go/cue/token"
+)
+
+// Attr holds positional information for a single Attr.
+type Attr struct {
+	Fields []keyValue
+	Err    error
+}
+
+// NewNonExisting creates a non-existing attribute.
+func NewNonExisting(key string) Attr {
+	const msgNotExist = "attribute %q does not exist"
+	return Attr{Err: errors.Newf(token.NoPos, msgNotExist, key)}
+}
+
+type keyValue struct {
+	data  string
+	equal int // index of equal sign or 0 if non-existing
+}
+
+func (kv *keyValue) Text() string { return kv.data }
+func (kv *keyValue) Key() string  { return kv.data[:kv.equal] }
+func (kv *keyValue) Value() string {
+	return strings.TrimSpace(kv.data[kv.equal+1:])
+}
+
+func (a *Attr) hasPos(p int) error {
+	if a.Err != nil {
+		return a.Err
+	}
+	if p >= len(a.Fields) {
+		return fmt.Errorf("field does not exist")
+	}
+	return nil
+}
+
+// String reports the possibly empty string value at the given position or
+// an error the attribute is invalid or if the position does not exist.
+func (a *Attr) String(pos int) (string, error) {
+	if err := a.hasPos(pos); err != nil {
+		return "", err
+	}
+	return a.Fields[pos].Text(), nil
+}
+
+// Int reports the integer at the given position or an error if the attribute is
+// invalid, the position does not exist, or the value at the given position is
+// not an integer.
+func (a *Attr) Int(pos int) (int64, error) {
+	if err := a.hasPos(pos); err != nil {
+		return 0, err
+	}
+	// TODO: use CUE's literal parser once it exists, allowing any of CUE's
+	// number types.
+	return strconv.ParseInt(a.Fields[pos].Text(), 10, 64)
+}
+
+// Flag reports whether an entry with the given name exists at position pos or
+// onwards or an error if the attribute is invalid or if the first pos-1 entries
+// are not defined.
+func (a *Attr) Flag(pos int, key string) (bool, error) {
+	if err := a.hasPos(pos - 1); err != nil {
+		return false, err
+	}
+	for _, kv := range a.Fields[pos:] {
+		if kv.Text() == key {
+			return true, nil
+		}
+	}
+	return false, nil
+}
+
+// Lookup searches for an entry of the form key=value from position pos onwards
+// and reports the value if found. It reports an error if the attribute is
+// invalid or if the first pos-1 entries are not defined.
+func (a *Attr) Lookup(pos int, key string) (val string, found bool, err error) {
+	if err := a.hasPos(pos - 1); err != nil {
+		return "", false, err
+	}
+	for _, kv := range a.Fields[pos:] {
+		if kv.Key() == key {
+			return kv.Value(), true, nil
+		}
+	}
+	return "", false, nil
+}
+
+func ParseAttrBody(pos token.Pos, s string) (a Attr) {
+	i := 0
+	for {
+		// always scan at least one, possibly empty element.
+		n, err := scanAttributeElem(pos, s[i:], &a)
+		if err != nil {
+			return Attr{Err: err}
+		}
+		if i += n; i >= len(s) {
+			break
+		}
+		if s[i] != ',' {
+			return Attr{Err: errors.Newf(pos, "invalid attribute: expected comma")}
+		}
+		i++
+	}
+	return a
+}
+
+func scanAttributeElem(pos token.Pos, s string, a *Attr) (n int, err errors.Error) {
+	// try CUE string
+	kv := keyValue{}
+	if n, kv.data, err = scanAttributeString(pos, s); n == 0 {
+		// try key-value pair
+		p := strings.IndexAny(s, ",=") // ) is assumed to be stripped.
+		switch {
+		case p < 0:
+			kv.data = s
+			n = len(s)
+
+		default: // ','
+			n = p
+			kv.data = s[:n]
+
+		case s[p] == '=':
+			kv.equal = p
+			offset := p + 1
+			var str string
+			if p, str, err = scanAttributeString(pos, s[offset:]); p > 0 {
+				n = offset + p
+				kv.data = s[:offset] + str
+			} else {
+				n = len(s)
+				if p = strings.IndexByte(s[offset:], ','); p >= 0 {
+					n = offset + p
+				}
+				kv.data = s[:n]
+			}
+		}
+	}
+	if a != nil {
+		a.Fields = append(a.Fields, kv)
+	}
+	return n, err
+}
+
+func scanAttributeString(pos token.Pos, s string) (n int, str string, err errors.Error) {
+	if s == "" || (s[0] != '#' && s[0] != '"' && s[0] != '\'') {
+		return 0, "", nil
+	}
+
+	nHash := 0
+	for {
+		if nHash < len(s) {
+			if s[nHash] == '#' {
+				nHash++
+				continue
+			}
+			if s[nHash] == '\'' || s[nHash] == '"' {
+				break
+			}
+		}
+		return nHash, s[:nHash], errors.Newf(pos, "invalid attribute string")
+	}
+
+	// Determine closing quote.
+	nQuote := 1
+	if c := s[nHash]; nHash+6 < len(s) && s[nHash+1] == c && s[nHash+2] == c {
+		nQuote = 3
+	}
+	close := s[nHash:nHash+nQuote] + s[:nHash]
+
+	// Search for closing quote.
+	index := strings.Index(s[len(close):], close)
+	if index == -1 {
+		return len(s), "", errors.Newf(pos, "attribute string not terminated")
+	}
+
+	index += 2 * len(close)
+	s, err2 := literal.Unquote(s[:index])
+	if err2 != nil {
+		return index, "", errors.Newf(pos, "invalid attribute string: %v", err2)
+	}
+	return index, s, nil
+}
diff --git a/internal/attrs_test.go b/internal/attrs_test.go
new file mode 100644
index 0000000..01cba60
--- /dev/null
+++ b/internal/attrs_test.go
@@ -0,0 +1,104 @@
+// Copyright 2020 CUE Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package internal
+
+import (
+	"fmt"
+	"strings"
+	"testing"
+
+	"cuelang.org/go/cue/token"
+)
+
+func TestAttributeBody(t *testing.T) {
+	testdata := []struct {
+		in, out string
+		err     string
+	}{{
+		in:  "",
+		out: "[{ 0}]",
+	}, {
+		in:  "bb",
+		out: "[{bb 0}]",
+	}, {
+		in:  "a,",
+		out: "[{a 0} { 0}]",
+	}, {
+		in:  `"a",`,
+		out: "[{a 0} { 0}]",
+	}, {
+		in:  "a,b",
+		out: "[{a 0} {b 0}]",
+	}, {
+		in:  `foo,"bar",#"baz"#`,
+		out: "[{foo 0} {bar 0} {baz 0}]",
+	}, {
+		in:  `bar=str`,
+		out: "[{bar=str 3}]",
+	}, {
+		in:  `bar="str"`,
+		out: "[{bar=str 3}]",
+	}, {
+		in:  `foo.bar="str"`,
+		out: "[{foo.bar=str 7}]",
+	}, {
+		in:  `bar=,baz=`,
+		out: "[{bar= 3} {baz= 3}]",
+	}, {
+		in:  `foo=1,bar="str",baz=free form`,
+		out: "[{foo=1 3} {bar=str 3} {baz=free form 3}]",
+	}, {
+		in: `"""
+		"""`,
+		out: "[{ 0}]",
+	}, {
+		in: `#'''
+			\#x20
+			'''#`,
+		out: "[{  0}]",
+	}, {
+		in:  "'' ,b",
+		err: "invalid attribute",
+	}, {
+		in:  "' ,b",
+		err: "not terminated",
+	}, {
+		in:  `"\ "`,
+		err: "invalid attribute",
+	}, {
+		in:  `# `,
+		err: "invalid attribute",
+	}}
+	for _, tc := range testdata {
+		t.Run(tc.in, func(t *testing.T) {
+			pa := ParseAttrBody(token.NoPos, tc.in)
+			err := pa.Err
+
+			if tc.err != "" {
+				if !strings.Contains(err.Error(), tc.err) {
+					t.Errorf("error was %v; want %v", err, tc.err)
+				}
+				return
+			}
+			if err != nil {
+				t.Fatal(err)
+			}
+
+			if got := fmt.Sprint(pa.Fields); got != tc.out {
+				t.Errorf("got %v; want %v", got, tc.out)
+			}
+		})
+	}
+}
