Start the decoder
This commit is contained in:
parent
3a02b49a51
commit
59e0ca9d5a
29
ast/ast.go
29
ast/ast.go
@ -17,6 +17,13 @@ type Node interface {
|
||||
Accept(Visitor)
|
||||
}
|
||||
|
||||
// KeyedNode is a node that has a key associated with it.
|
||||
type KeyedNode interface {
|
||||
Node
|
||||
|
||||
Key() string
|
||||
}
|
||||
|
||||
// Visitor is the interface that must be implemented by any
|
||||
// structures who want to be visited as part of the visitor pattern
|
||||
// on the AST.
|
||||
@ -29,14 +36,14 @@ type Visitor interface {
|
||||
// be validated/removed at a semantic check, rather than at a
|
||||
// syntax level.
|
||||
type ObjectNode struct {
|
||||
Key string
|
||||
Elem []Node
|
||||
K string
|
||||
Elem []KeyedNode
|
||||
}
|
||||
|
||||
// AssignmentNode represents a direct assignment with an equals
|
||||
// sign.
|
||||
type AssignmentNode struct {
|
||||
Key string
|
||||
K string
|
||||
Value Node
|
||||
}
|
||||
|
||||
@ -52,24 +59,32 @@ type LiteralNode struct {
|
||||
}
|
||||
|
||||
func (n ObjectNode) Accept(v Visitor) {
|
||||
v.Visit(n)
|
||||
|
||||
for _, e := range n.Elem {
|
||||
e.Accept(v)
|
||||
}
|
||||
}
|
||||
|
||||
v.Visit(n)
|
||||
func (n ObjectNode) Key() string {
|
||||
return n.K
|
||||
}
|
||||
|
||||
func (n AssignmentNode) Accept(v Visitor) {
|
||||
n.Value.Accept(v)
|
||||
v.Visit(n)
|
||||
n.Value.Accept(v)
|
||||
}
|
||||
|
||||
func (n AssignmentNode) Key() string {
|
||||
return n.K
|
||||
}
|
||||
|
||||
func (n ListNode) Accept(v Visitor) {
|
||||
v.Visit(n)
|
||||
|
||||
for _, e := range n.Elem {
|
||||
e.Accept(v)
|
||||
}
|
||||
|
||||
v.Visit(n)
|
||||
}
|
||||
|
||||
func (n LiteralNode) Accept(v Visitor) {
|
||||
|
@ -7,13 +7,13 @@ import (
|
||||
|
||||
func TestAssignmentNode_accept(t *testing.T) {
|
||||
n := AssignmentNode{
|
||||
Key: "foo",
|
||||
K: "foo",
|
||||
Value: LiteralNode{Value: "foo"},
|
||||
}
|
||||
|
||||
expected := []Node{
|
||||
n.Value,
|
||||
n,
|
||||
n.Value,
|
||||
}
|
||||
|
||||
v := new(MockVisitor)
|
||||
@ -33,9 +33,9 @@ func TestListNode_accept(t *testing.T) {
|
||||
}
|
||||
|
||||
expected := []Node{
|
||||
n,
|
||||
n.Elem[0],
|
||||
n.Elem[1],
|
||||
n,
|
||||
}
|
||||
|
||||
v := new(MockVisitor)
|
||||
@ -48,17 +48,19 @@ func TestListNode_accept(t *testing.T) {
|
||||
|
||||
func TestObjectNode_accept(t *testing.T) {
|
||||
n := ObjectNode{
|
||||
Key: "foo",
|
||||
Elem: []Node{
|
||||
LiteralNode{Value: "foo"},
|
||||
LiteralNode{Value: "bar"},
|
||||
K: "foo",
|
||||
Elem: []KeyedNode{
|
||||
AssignmentNode{K: "foo", Value: LiteralNode{Value: "foo"}},
|
||||
AssignmentNode{K: "bar", Value: LiteralNode{Value: "bar"}},
|
||||
},
|
||||
}
|
||||
|
||||
expected := []Node{
|
||||
n.Elem[0],
|
||||
n.Elem[1],
|
||||
n,
|
||||
n.Elem[0],
|
||||
n.Elem[0].(AssignmentNode).Value,
|
||||
n.Elem[1],
|
||||
n.Elem[1].(AssignmentNode).Value,
|
||||
}
|
||||
|
||||
v := new(MockVisitor)
|
||||
|
144
decoder.go
Normal file
144
decoder.go
Normal file
@ -0,0 +1,144 @@
|
||||
package hcl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/hashicorp/hcl/ast"
|
||||
)
|
||||
|
||||
// Decode reads the given input and decodes it into the structure
|
||||
// given by `out`.
|
||||
func Decode(out interface{}, in string) error {
|
||||
obj, err := Parse(in)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return DecodeAST(out, obj)
|
||||
}
|
||||
|
||||
// DecodeAST is a lower-level version of Decode. It decodes a
|
||||
// raw AST into the given output.
|
||||
func DecodeAST(out interface{}, obj *ast.ObjectNode) error {
|
||||
return decode("", *obj, reflect.ValueOf(out).Elem())
|
||||
}
|
||||
|
||||
func decode(name string, n ast.Node, result reflect.Value) error {
|
||||
switch result.Kind() {
|
||||
case reflect.Interface:
|
||||
// When we see an interface, we make our own thing
|
||||
return decodeInterface(name, n, result)
|
||||
case reflect.Map:
|
||||
return decodeMap(name, n, result)
|
||||
case reflect.String:
|
||||
return decodeString(name, n, result)
|
||||
default:
|
||||
return fmt.Errorf("%s: unknown kind: %s", name, result.Kind())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func decodeInterface(name string, raw ast.Node, result reflect.Value) error {
|
||||
var set reflect.Value
|
||||
|
||||
switch n := raw.(type) {
|
||||
case ast.ObjectNode:
|
||||
result := make(map[string]interface{})
|
||||
set = reflect.ValueOf(result)
|
||||
case ast.LiteralNode:
|
||||
switch n.Type {
|
||||
case ast.ValueTypeString:
|
||||
set = reflect.Indirect(reflect.New(reflect.TypeOf("")))
|
||||
default:
|
||||
return fmt.Errorf(
|
||||
"%s: unknown literal type: %s",
|
||||
name, n.Type)
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf(
|
||||
"%s: cannot decode into interface: %T",
|
||||
name, raw)
|
||||
}
|
||||
|
||||
// Revisit the node so that we can use the newly instantiated
|
||||
// thing and populate it.
|
||||
if err := decode(name, raw, set); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Set the result to what its supposed to be, then reset
|
||||
// result so we don't reflect into this method anymore.
|
||||
result.Set(set)
|
||||
return nil
|
||||
}
|
||||
|
||||
func decodeMap(name string, raw ast.Node, result reflect.Value) error {
|
||||
obj, ok := raw.(ast.ObjectNode)
|
||||
if !ok {
|
||||
return fmt.Errorf("%s: not an object type", name)
|
||||
}
|
||||
|
||||
resultType := result.Type()
|
||||
resultElemType := resultType.Elem()
|
||||
resultKeyType := resultType.Key()
|
||||
if resultKeyType.Kind() != reflect.String {
|
||||
return fmt.Errorf(
|
||||
"%s: map must have string keys", name)
|
||||
}
|
||||
|
||||
// Make a map if it is nil
|
||||
resultMap := result
|
||||
if result.IsNil() {
|
||||
resultMap = reflect.MakeMap(
|
||||
reflect.MapOf(resultKeyType, resultElemType))
|
||||
}
|
||||
|
||||
// Go through each element and decode it.
|
||||
for _, elem := range obj.Elem {
|
||||
n := elem.(ast.AssignmentNode)
|
||||
|
||||
// Make the field name
|
||||
fieldName := fmt.Sprintf("%s[%s]", name, n.Key())
|
||||
|
||||
// Get the key/value as reflection values
|
||||
key := reflect.ValueOf(n.Key())
|
||||
val := reflect.Indirect(reflect.New(resultElemType))
|
||||
|
||||
// If we have a pre-existing value in the map, use that
|
||||
oldVal := resultMap.MapIndex(key)
|
||||
if oldVal.IsValid() {
|
||||
val.Set(oldVal)
|
||||
}
|
||||
|
||||
// Decode!
|
||||
if err := decode(fieldName, n.Value, val); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Set the value on the map
|
||||
resultMap.SetMapIndex(key, val)
|
||||
}
|
||||
|
||||
// Set the final map
|
||||
result.Set(resultMap)
|
||||
return nil
|
||||
}
|
||||
|
||||
func decodeString(name string, raw ast.Node, result reflect.Value) error {
|
||||
n, ok := raw.(ast.LiteralNode)
|
||||
if !ok {
|
||||
return fmt.Errorf("%s: not a literal type", name)
|
||||
}
|
||||
|
||||
switch n.Type {
|
||||
case ast.ValueTypeString:
|
||||
println(n.Value.(string))
|
||||
result.SetString(n.Value.(string))
|
||||
default:
|
||||
return fmt.Errorf("%s: unknown type %s", name, n.Type)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
41
decoder_test.go
Normal file
41
decoder_test.go
Normal file
@ -0,0 +1,41 @@
|
||||
package hcl
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDecode(t *testing.T) {
|
||||
cases := []struct {
|
||||
File string
|
||||
Err bool
|
||||
Out interface{}
|
||||
}{
|
||||
{
|
||||
"basic.hcl",
|
||||
false,
|
||||
map[string]interface{}{
|
||||
"foo": "bar",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
d, err := ioutil.ReadFile(filepath.Join(fixtureDir, tc.File))
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
var out map[string]interface{}
|
||||
err = Decode(&out, string(d))
|
||||
if (err != nil) != tc.Err {
|
||||
t.Fatalf("Input: %s\n\nError: %s", tc.File, err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(out, tc.Out) {
|
||||
t.Fatalf("Input: %s\n\n%#v", tc.File, out)
|
||||
}
|
||||
}
|
||||
}
|
26
hcl/parse.y
26
hcl/parse.y
@ -11,14 +11,18 @@ import (
|
||||
|
||||
%union {
|
||||
list []ast.Node
|
||||
klist []ast.KeyedNode
|
||||
kitem ast.KeyedNode
|
||||
listitem ast.Node
|
||||
num int
|
||||
obj ast.ObjectNode
|
||||
str string
|
||||
}
|
||||
|
||||
%type <list> list objectlist
|
||||
%type <listitem> listitem objectitem
|
||||
%type <list> list
|
||||
%type <klist> objectlist
|
||||
%type <kitem> objectitem
|
||||
%type <listitem> listitem
|
||||
%type <obj> block object
|
||||
%type <str> blockId
|
||||
|
||||
@ -32,7 +36,7 @@ top:
|
||||
objectlist
|
||||
{
|
||||
hclResult = &ast.ObjectNode{
|
||||
Key: "",
|
||||
K: "",
|
||||
Elem: $1,
|
||||
}
|
||||
}
|
||||
@ -40,7 +44,7 @@ top:
|
||||
objectlist:
|
||||
objectitem
|
||||
{
|
||||
$$ = []ast.Node{$1}
|
||||
$$ = []ast.KeyedNode{$1}
|
||||
}
|
||||
| objectitem objectlist
|
||||
{
|
||||
@ -61,7 +65,7 @@ objectitem:
|
||||
IDENTIFIER EQUAL NUMBER
|
||||
{
|
||||
$$ = ast.AssignmentNode{
|
||||
Key: $1,
|
||||
K: $1,
|
||||
Value: ast.LiteralNode{
|
||||
Type: ast.ValueTypeInt,
|
||||
Value: $3,
|
||||
@ -71,7 +75,7 @@ objectitem:
|
||||
| IDENTIFIER EQUAL STRING
|
||||
{
|
||||
$$ = ast.AssignmentNode{
|
||||
Key: $1,
|
||||
K: $1,
|
||||
Value: ast.LiteralNode{
|
||||
Type: ast.ValueTypeString,
|
||||
Value: $3,
|
||||
@ -81,14 +85,14 @@ objectitem:
|
||||
| IDENTIFIER EQUAL object
|
||||
{
|
||||
$$ = ast.AssignmentNode{
|
||||
Key: $1,
|
||||
K: $1,
|
||||
Value: $3,
|
||||
}
|
||||
}
|
||||
| IDENTIFIER EQUAL LEFTBRACKET list RIGHTBRACKET
|
||||
{
|
||||
$$ = ast.AssignmentNode{
|
||||
Key: $1,
|
||||
K: $1,
|
||||
Value: ast.ListNode{Elem: $4},
|
||||
}
|
||||
}
|
||||
@ -101,13 +105,13 @@ block:
|
||||
blockId object
|
||||
{
|
||||
$$ = $2
|
||||
$$.Key = $1
|
||||
$$.K = $1
|
||||
}
|
||||
| blockId block
|
||||
{
|
||||
$$ = ast.ObjectNode{
|
||||
Key: $1,
|
||||
Elem: []ast.Node{$2},
|
||||
K: $1,
|
||||
Elem: []ast.KeyedNode{$2},
|
||||
}
|
||||
}
|
||||
|
||||
|
94
hcl/y.go
94
hcl/y.go
@ -12,6 +12,8 @@ import (
|
||||
type hclSymType struct {
|
||||
yys int
|
||||
list []ast.Node
|
||||
klist []ast.KeyedNode
|
||||
kitem ast.KeyedNode
|
||||
listitem ast.Node
|
||||
num int
|
||||
obj ast.ObjectNode
|
||||
@ -47,7 +49,7 @@ const hclEofCode = 1
|
||||
const hclErrCode = 2
|
||||
const hclMaxDepth = 200
|
||||
|
||||
//line parse.y:150
|
||||
//line parse.y:154
|
||||
|
||||
//line yacctab:1
|
||||
var hclExca = []int{
|
||||
@ -79,12 +81,12 @@ var hclPact = []int{
|
||||
}
|
||||
var hclPgo = []int{
|
||||
|
||||
0, 29, 4, 0, 28, 25, 12, 26, 5,
|
||||
0, 29, 4, 28, 0, 25, 12, 26, 5,
|
||||
}
|
||||
var hclR1 = []int{
|
||||
|
||||
0, 8, 2, 2, 6, 6, 4, 4, 4, 4,
|
||||
4, 5, 5, 7, 7, 1, 1, 3, 3,
|
||||
0, 8, 2, 2, 6, 6, 3, 3, 3, 3,
|
||||
3, 5, 5, 7, 7, 1, 1, 4, 4,
|
||||
}
|
||||
var hclR2 = []int{
|
||||
|
||||
@ -93,9 +95,9 @@ var hclR2 = []int{
|
||||
}
|
||||
var hclChk = []int{
|
||||
|
||||
-1000, -8, -2, -4, 6, -5, -7, 9, -2, 7,
|
||||
-1000, -8, -2, -3, 6, -5, -7, 9, -2, 7,
|
||||
-6, -5, 10, 6, 4, 9, -6, 12, -2, 11,
|
||||
-1, -3, 4, 9, 11, 13, 5, -3,
|
||||
-1, -4, 4, 9, 11, 13, 5, -4,
|
||||
}
|
||||
var hclDef = []int{
|
||||
|
||||
@ -342,38 +344,38 @@ hcldefault:
|
||||
switch hclnt {
|
||||
|
||||
case 1:
|
||||
//line parse.y:33
|
||||
//line parse.y:37
|
||||
{
|
||||
hclResult = &ast.ObjectNode{
|
||||
Key: "",
|
||||
Elem: hclS[hclpt-0].list,
|
||||
K: "",
|
||||
Elem: hclS[hclpt-0].klist,
|
||||
}
|
||||
}
|
||||
case 2:
|
||||
//line parse.y:42
|
||||
{
|
||||
hclVAL.list = []ast.Node{hclS[hclpt-0].listitem}
|
||||
}
|
||||
case 3:
|
||||
//line parse.y:46
|
||||
{
|
||||
hclVAL.list = append(hclS[hclpt-0].list, hclS[hclpt-1].listitem)
|
||||
hclVAL.klist = []ast.KeyedNode{hclS[hclpt-0].kitem}
|
||||
}
|
||||
case 3:
|
||||
//line parse.y:50
|
||||
{
|
||||
hclVAL.klist = append(hclS[hclpt-0].klist, hclS[hclpt-1].kitem)
|
||||
}
|
||||
case 4:
|
||||
//line parse.y:52
|
||||
//line parse.y:56
|
||||
{
|
||||
hclVAL.obj = ast.ObjectNode{Elem: hclS[hclpt-1].list}
|
||||
hclVAL.obj = ast.ObjectNode{Elem: hclS[hclpt-1].klist}
|
||||
}
|
||||
case 5:
|
||||
//line parse.y:56
|
||||
//line parse.y:60
|
||||
{
|
||||
hclVAL.obj = ast.ObjectNode{}
|
||||
}
|
||||
case 6:
|
||||
//line parse.y:62
|
||||
//line parse.y:66
|
||||
{
|
||||
hclVAL.listitem = ast.AssignmentNode{
|
||||
Key: hclS[hclpt-2].str,
|
||||
hclVAL.kitem = ast.AssignmentNode{
|
||||
K: hclS[hclpt-2].str,
|
||||
Value: ast.LiteralNode{
|
||||
Type: ast.ValueTypeInt,
|
||||
Value: hclS[hclpt-0].num,
|
||||
@ -381,10 +383,10 @@ hcldefault:
|
||||
}
|
||||
}
|
||||
case 7:
|
||||
//line parse.y:72
|
||||
//line parse.y:76
|
||||
{
|
||||
hclVAL.listitem = ast.AssignmentNode{
|
||||
Key: hclS[hclpt-2].str,
|
||||
hclVAL.kitem = ast.AssignmentNode{
|
||||
K: hclS[hclpt-2].str,
|
||||
Value: ast.LiteralNode{
|
||||
Type: ast.ValueTypeString,
|
||||
Value: hclS[hclpt-0].str,
|
||||
@ -392,62 +394,62 @@ hcldefault:
|
||||
}
|
||||
}
|
||||
case 8:
|
||||
//line parse.y:82
|
||||
//line parse.y:86
|
||||
{
|
||||
hclVAL.listitem = ast.AssignmentNode{
|
||||
Key: hclS[hclpt-2].str,
|
||||
hclVAL.kitem = ast.AssignmentNode{
|
||||
K: hclS[hclpt-2].str,
|
||||
Value: hclS[hclpt-0].obj,
|
||||
}
|
||||
}
|
||||
case 9:
|
||||
//line parse.y:89
|
||||
//line parse.y:93
|
||||
{
|
||||
hclVAL.listitem = ast.AssignmentNode{
|
||||
Key: hclS[hclpt-4].str,
|
||||
hclVAL.kitem = ast.AssignmentNode{
|
||||
K: hclS[hclpt-4].str,
|
||||
Value: ast.ListNode{Elem: hclS[hclpt-1].list},
|
||||
}
|
||||
}
|
||||
case 10:
|
||||
//line parse.y:96
|
||||
//line parse.y:100
|
||||
{
|
||||
hclVAL.listitem = hclS[hclpt-0].obj
|
||||
hclVAL.kitem = hclS[hclpt-0].obj
|
||||
}
|
||||
case 11:
|
||||
//line parse.y:102
|
||||
//line parse.y:106
|
||||
{
|
||||
hclVAL.obj = hclS[hclpt-0].obj
|
||||
hclVAL.obj.Key = hclS[hclpt-1].str
|
||||
hclVAL.obj.K = hclS[hclpt-1].str
|
||||
}
|
||||
case 12:
|
||||
//line parse.y:107
|
||||
//line parse.y:111
|
||||
{
|
||||
hclVAL.obj = ast.ObjectNode{
|
||||
Key: hclS[hclpt-1].str,
|
||||
Elem: []ast.Node{hclS[hclpt-0].obj},
|
||||
K: hclS[hclpt-1].str,
|
||||
Elem: []ast.KeyedNode{hclS[hclpt-0].obj},
|
||||
}
|
||||
}
|
||||
case 13:
|
||||
//line parse.y:116
|
||||
{
|
||||
hclVAL.str = hclS[hclpt-0].str
|
||||
}
|
||||
case 14:
|
||||
//line parse.y:120
|
||||
{
|
||||
hclVAL.str = hclS[hclpt-0].str
|
||||
}
|
||||
case 14:
|
||||
//line parse.y:124
|
||||
{
|
||||
hclVAL.str = hclS[hclpt-0].str
|
||||
}
|
||||
case 15:
|
||||
//line parse.y:126
|
||||
//line parse.y:130
|
||||
{
|
||||
hclVAL.list = []ast.Node{hclS[hclpt-0].listitem}
|
||||
}
|
||||
case 16:
|
||||
//line parse.y:130
|
||||
//line parse.y:134
|
||||
{
|
||||
hclVAL.list = append(hclS[hclpt-2].list, hclS[hclpt-0].listitem)
|
||||
}
|
||||
case 17:
|
||||
//line parse.y:136
|
||||
//line parse.y:140
|
||||
{
|
||||
hclVAL.listitem = ast.LiteralNode{
|
||||
Type: ast.ValueTypeInt,
|
||||
@ -455,7 +457,7 @@ hcldefault:
|
||||
}
|
||||
}
|
||||
case 18:
|
||||
//line parse.y:143
|
||||
//line parse.y:147
|
||||
{
|
||||
hclVAL.listitem = ast.LiteralNode{
|
||||
Type: ast.ValueTypeString,
|
||||
|
4
hcl_test.go
Normal file
4
hcl_test.go
Normal file
@ -0,0 +1,4 @@
|
||||
package hcl
|
||||
|
||||
// This is the directory where our test fixtures are.
|
||||
const fixtureDir = "./test-fixtures"
|
@ -13,6 +13,7 @@ import (
|
||||
array ast.ListNode
|
||||
assign ast.AssignmentNode
|
||||
item ast.Node
|
||||
klist []ast.KeyedNode
|
||||
list []ast.Node
|
||||
num int
|
||||
str string
|
||||
@ -22,7 +23,8 @@ import (
|
||||
%type <array> array
|
||||
%type <assign> pair
|
||||
%type <item> value
|
||||
%type <list> elements members
|
||||
%type <klist> members
|
||||
%type <list> elements
|
||||
%type <obj> object
|
||||
|
||||
%token <num> NUMBER
|
||||
@ -52,7 +54,7 @@ object:
|
||||
members:
|
||||
pair
|
||||
{
|
||||
$$ = []ast.Node{$1}
|
||||
$$ = []ast.KeyedNode{$1}
|
||||
}
|
||||
| pair COMMA members
|
||||
{
|
||||
@ -63,7 +65,7 @@ pair:
|
||||
STRING COLON value
|
||||
{
|
||||
$$ = ast.AssignmentNode{
|
||||
Key: $1,
|
||||
K: $1,
|
||||
Value: $3,
|
||||
}
|
||||
}
|
||||
|
57
json/y.go
57
json/y.go
@ -14,6 +14,7 @@ type jsonSymType struct {
|
||||
array ast.ListNode
|
||||
assign ast.AssignmentNode
|
||||
item ast.Node
|
||||
klist []ast.KeyedNode
|
||||
list []ast.Node
|
||||
num int
|
||||
str string
|
||||
@ -57,7 +58,7 @@ const jsonEofCode = 1
|
||||
const jsonErrCode = 2
|
||||
const jsonMaxDepth = 200
|
||||
|
||||
//line parse.y:136
|
||||
//line parse.y:138
|
||||
|
||||
//line yacctab:1
|
||||
var jsonExca = []int{
|
||||
@ -89,12 +90,12 @@ var jsonPact = []int{
|
||||
}
|
||||
var jsonPgo = []int{
|
||||
|
||||
0, 34, 32, 17, 0, 23, 29, 31,
|
||||
0, 34, 32, 17, 23, 0, 29, 31,
|
||||
}
|
||||
var jsonR1 = []int{
|
||||
|
||||
0, 7, 6, 6, 5, 5, 2, 3, 3, 3,
|
||||
3, 3, 3, 3, 1, 1, 4, 4,
|
||||
0, 7, 6, 6, 4, 4, 2, 3, 3, 3,
|
||||
3, 3, 3, 3, 1, 1, 5, 5,
|
||||
}
|
||||
var jsonR2 = []int{
|
||||
|
||||
@ -103,9 +104,9 @@ var jsonR2 = []int{
|
||||
}
|
||||
var jsonChk = []int{
|
||||
|
||||
-1000, -7, -6, 11, -5, 12, -2, 10, 12, 6,
|
||||
5, -5, -3, 10, 4, -6, -1, 15, 16, 17,
|
||||
13, 14, -4, -3, 14, 6, -4,
|
||||
-1000, -7, -6, 11, -4, 12, -2, 10, 12, 6,
|
||||
5, -4, -3, 10, 4, -6, -1, 15, 16, 17,
|
||||
13, 14, -5, -3, 14, 6, -5,
|
||||
}
|
||||
var jsonDef = []int{
|
||||
|
||||
@ -352,41 +353,41 @@ jsondefault:
|
||||
switch jsonnt {
|
||||
|
||||
case 1:
|
||||
//line parse.y:37
|
||||
//line parse.y:39
|
||||
{
|
||||
obj := jsonS[jsonpt-0].obj
|
||||
jsonResult = &obj
|
||||
}
|
||||
case 2:
|
||||
//line parse.y:44
|
||||
//line parse.y:46
|
||||
{
|
||||
jsonVAL.obj = ast.ObjectNode{Elem: jsonS[jsonpt-1].list}
|
||||
jsonVAL.obj = ast.ObjectNode{Elem: jsonS[jsonpt-1].klist}
|
||||
}
|
||||
case 3:
|
||||
//line parse.y:48
|
||||
//line parse.y:50
|
||||
{
|
||||
jsonVAL.obj = ast.ObjectNode{}
|
||||
}
|
||||
case 4:
|
||||
//line parse.y:54
|
||||
//line parse.y:56
|
||||
{
|
||||
jsonVAL.list = []ast.Node{jsonS[jsonpt-0].assign}
|
||||
jsonVAL.klist = []ast.KeyedNode{jsonS[jsonpt-0].assign}
|
||||
}
|
||||
case 5:
|
||||
//line parse.y:58
|
||||
//line parse.y:60
|
||||
{
|
||||
jsonVAL.list = append(jsonS[jsonpt-0].list, jsonS[jsonpt-2].assign)
|
||||
jsonVAL.klist = append(jsonS[jsonpt-0].klist, jsonS[jsonpt-2].assign)
|
||||
}
|
||||
case 6:
|
||||
//line parse.y:64
|
||||
//line parse.y:66
|
||||
{
|
||||
jsonVAL.assign = ast.AssignmentNode{
|
||||
Key: jsonS[jsonpt-2].str,
|
||||
K: jsonS[jsonpt-2].str,
|
||||
Value: jsonS[jsonpt-0].item,
|
||||
}
|
||||
}
|
||||
case 7:
|
||||
//line parse.y:73
|
||||
//line parse.y:75
|
||||
{
|
||||
jsonVAL.item = ast.LiteralNode{
|
||||
Type: ast.ValueTypeString,
|
||||
@ -394,7 +395,7 @@ jsondefault:
|
||||
}
|
||||
}
|
||||
case 8:
|
||||
//line parse.y:80
|
||||
//line parse.y:82
|
||||
{
|
||||
jsonVAL.item = ast.LiteralNode{
|
||||
Type: ast.ValueTypeInt,
|
||||
@ -402,17 +403,17 @@ jsondefault:
|
||||
}
|
||||
}
|
||||
case 9:
|
||||
//line parse.y:87
|
||||
//line parse.y:89
|
||||
{
|
||||
jsonVAL.item = jsonS[jsonpt-0].obj
|
||||
}
|
||||
case 10:
|
||||
//line parse.y:91
|
||||
//line parse.y:93
|
||||
{
|
||||
jsonVAL.item = jsonS[jsonpt-0].array
|
||||
}
|
||||
case 11:
|
||||
//line parse.y:95
|
||||
//line parse.y:97
|
||||
{
|
||||
jsonVAL.item = ast.LiteralNode{
|
||||
Type: ast.ValueTypeBool,
|
||||
@ -420,7 +421,7 @@ jsondefault:
|
||||
}
|
||||
}
|
||||
case 12:
|
||||
//line parse.y:102
|
||||
//line parse.y:104
|
||||
{
|
||||
jsonVAL.item = ast.LiteralNode{
|
||||
Type: ast.ValueTypeBool,
|
||||
@ -428,7 +429,7 @@ jsondefault:
|
||||
}
|
||||
}
|
||||
case 13:
|
||||
//line parse.y:109
|
||||
//line parse.y:111
|
||||
{
|
||||
jsonVAL.item = ast.LiteralNode{
|
||||
Type: ast.ValueTypeNil,
|
||||
@ -436,22 +437,22 @@ jsondefault:
|
||||
}
|
||||
}
|
||||
case 14:
|
||||
//line parse.y:118
|
||||
//line parse.y:120
|
||||
{
|
||||
jsonVAL.array = ast.ListNode{}
|
||||
}
|
||||
case 15:
|
||||
//line parse.y:122
|
||||
//line parse.y:124
|
||||
{
|
||||
jsonVAL.array = ast.ListNode{Elem: jsonS[jsonpt-1].list}
|
||||
}
|
||||
case 16:
|
||||
//line parse.y:128
|
||||
//line parse.y:130
|
||||
{
|
||||
jsonVAL.list = []ast.Node{jsonS[jsonpt-0].item}
|
||||
}
|
||||
case 17:
|
||||
//line parse.y:132
|
||||
//line parse.y:134
|
||||
{
|
||||
jsonVAL.list = append(jsonS[jsonpt-0].list, jsonS[jsonpt-2].item)
|
||||
}
|
||||
|
1
test-fixtures/basic.hcl
Normal file
1
test-fixtures/basic.hcl
Normal file
@ -0,0 +1 @@
|
||||
foo = "bar"
|
Loading…
Reference in New Issue
Block a user