doc/ref/spec: reflect reality w.r.t. octal numbers

0123:
- cue/parser|scanner: not accepted (done)
- cue: accepted if present in AST (done)
- cue/format: accepted but convert

Also added a test for multiline label acceptance.
This is also tested in another package.

Change-Id: If3cf3892e03020528840cedca760dea9552df84c
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/3442
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/cue/format/format_test.go b/cue/format/format_test.go
index 7c5ab8d..28dd843 100644
--- a/cue/format/format_test.go
+++ b/cue/format/format_test.go
@@ -226,6 +226,45 @@
 	}
 }
 
+// TestNodes tests nodes that are that are invalid CUE, but are accepted by
+// format.
+func TestNodes(t *testing.T) {
+	testCases := []struct {
+		name string
+		in   ast.Node
+		out  string
+	}{{
+		name: "old-style octal numbers",
+		in:   &ast.BasicLit{Kind: token.INT, Value: "0123"},
+		out:  "0o123",
+	}, {
+		name: "labels with multi-line strings",
+		in: &ast.Field{
+			Label: &ast.BasicLit{
+				Kind: token.STRING,
+				Value: `"""
+					foo
+					bar
+					"""`,
+			},
+			Value: ast.NewIdent("goo"),
+		},
+		out: `"foo\nbar": goo`,
+	}}
+	for _, tc := range testCases {
+		t.Run(tc.name, func(t *testing.T) {
+			b, err := Node(tc.in)
+			if err != nil {
+				t.Fatal(err)
+			}
+			if got := string(b); got != tc.out {
+				t.Errorf("\ngot:  %v; want: %v", got, tc.out)
+			}
+		})
+	}
+
+}
+
 // Verify that the printer doesn't crash if the AST contains BadXXX nodes.
 func TestBadNodes(t *testing.T) {
 	const src = "package p\n("
diff --git a/cue/format/printer.go b/cue/format/printer.go
index 3542310..5ecec0b 100644
--- a/cue/format/printer.go
+++ b/cue/format/printer.go
@@ -107,6 +107,15 @@
 
 	case *ast.BasicLit:
 		data = x.Value
+		switch x.Kind {
+		case token.INT:
+			if len(data) > 1 &&
+				data[0] == '0' &&
+				data[1] >= '0' && data[1] <= '9' {
+				data = "0o" + data[1:]
+			}
+		}
+
 		isLit = true
 		impliedComma = true
 		p.lastTok = x.Kind
diff --git a/doc/ref/spec.md b/doc/ref/spec.md
index aab56f8..2df912c 100644
--- a/doc/ref/spec.md
+++ b/doc/ref/spec.md
@@ -302,7 +302,7 @@
 ### Integer literals
 
 An integer literal is a sequence of digits representing an integer value.
-An optional prefix sets a non-decimal base: 0 for octal,
+An optional prefix sets a non-decimal base: 0o for octal,
 0x or 0X for hexadecimal, and 0b for binary.
 In hexadecimal literals, letters a-f and A-F represent values 10 through 15.
 All integers allow interstitial underscores "_";
@@ -321,7 +321,7 @@
               "." decimals  multiplier .
 binary_lit  = "0b" binary_digit { binary_digit } .
 hex_lit     = "0" ( "x" | "X" ) hex_digit { [ "_" ] hex_digit } .
-octal_lit   = "0" [ "o" ] octal_digit { [ "_" ] octal_digit } .
+octal_lit   = "0o" octal_digit { [ "_" ] octal_digit } .
 multiplier  = ( "K" | "M" | "G" | "T" | "P" | "E" | "Y" | "Z" ) [ "i" ]
 
 float_lit   = decimals "." [ decimals ] [ exponent ] |