hcl: negative numbers and floats

This commit is contained in:
Mitchell Hashimoto 2014-08-03 17:33:29 -07:00
parent 2e6ea6c71c
commit 8c0a6c555f
5 changed files with 161 additions and 64 deletions

View File

@ -55,6 +55,10 @@ func (x *hclLex) Lex(yylval *hclSymType) int {
} }
switch c { switch c {
case '.':
return PERIOD
case '-':
return MINUS
case ',': case ',':
return COMMA return COMMA
case '=': case '=':

View File

@ -4,12 +4,16 @@
package hcl package hcl
import ( import (
"fmt"
"strconv"
"github.com/hashicorp/hcl/ast" "github.com/hashicorp/hcl/ast"
) )
%} %}
%union { %union {
item ast.Node
list []ast.Node list []ast.Node
klist []ast.KeyedNode klist []ast.KeyedNode
kitem ast.KeyedNode kitem ast.KeyedNode
@ -19,16 +23,18 @@ import (
str string str string
} }
%type <item> number
%type <list> list %type <list> list
%type <klist> objectlist %type <klist> objectlist
%type <kitem> objectitem block %type <kitem> objectitem block
%type <listitem> listitem %type <listitem> listitem
%type <num> int
%type <obj> object %type <obj> object
%type <str> blockId %type <str> blockId frac
%token <num> NUMBER %token <num> NUMBER
%token <str> COMMA IDENTIFIER EQUAL NEWLINE STRING %token <str> COMMA IDENTIFIER EQUAL NEWLINE STRING MINUS
%token <str> LEFTBRACE RIGHTBRACE LEFTBRACKET RIGHTBRACKET %token <str> LEFTBRACE RIGHTBRACE LEFTBRACKET RIGHTBRACKET PERIOD
%% %%
@ -62,14 +68,11 @@ object:
} }
objectitem: objectitem:
IDENTIFIER EQUAL NUMBER IDENTIFIER EQUAL number
{ {
$$ = ast.AssignmentNode{ $$ = ast.AssignmentNode{
K: $1, K: $1,
Value: ast.LiteralNode{ Value: $3,
Type: ast.ValueTypeInt,
Value: $3,
},
} }
} }
| IDENTIFIER EQUAL STRING | IDENTIFIER EQUAL STRING
@ -147,12 +150,9 @@ list:
} }
listitem: listitem:
NUMBER number
{ {
$$ = ast.LiteralNode{ $$ = $1
Type: ast.ValueTypeInt,
Value: $1,
}
} }
| STRING | STRING
{ {
@ -162,4 +162,42 @@ listitem:
} }
} }
number:
int
{
$$ = ast.LiteralNode{
Type: ast.ValueTypeInt,
Value: $1,
}
}
| int frac
{
fs := fmt.Sprintf("%d.%s", $1, $2)
f, err := strconv.ParseFloat(fs, 64)
if err != nil {
panic(err)
}
$$ = ast.LiteralNode{
Type: ast.ValueTypeFloat,
Value: f,
}
}
int:
MINUS int
{
$$ = $2 * -1
}
| NUMBER
{
$$ = $1
}
frac:
PERIOD NUMBER
{
$$ = strconv.FormatInt(int64($2), 10)
}
%% %%

View File

@ -43,6 +43,10 @@ func TestParse(t *testing.T) {
"assign_deep.hcl", "assign_deep.hcl",
true, true,
}, },
{
"types.hcl",
false,
},
} }
for _, tc := range cases { for _, tc := range cases {

View File

@ -0,0 +1,5 @@
foo = "bar"
bar = 7
baz = [1,2,3]
foo = -12
bar = 3.14159

148
hcl/y.go
View File

@ -5,12 +5,16 @@ import __yyfmt__ "fmt"
//line parse.y:4 //line parse.y:4
import ( import (
"fmt"
"strconv"
"github.com/hashicorp/hcl/ast" "github.com/hashicorp/hcl/ast"
) )
//line parse.y:12 //line parse.y:15
type hclSymType struct { type hclSymType struct {
yys int yys int
item ast.Node
list []ast.Node list []ast.Node
klist []ast.KeyedNode klist []ast.KeyedNode
kitem ast.KeyedNode kitem ast.KeyedNode
@ -26,10 +30,12 @@ const IDENTIFIER = 57348
const EQUAL = 57349 const EQUAL = 57349
const NEWLINE = 57350 const NEWLINE = 57350
const STRING = 57351 const STRING = 57351
const LEFTBRACE = 57352 const MINUS = 57352
const RIGHTBRACE = 57353 const LEFTBRACE = 57353
const LEFTBRACKET = 57354 const RIGHTBRACE = 57354
const RIGHTBRACKET = 57355 const LEFTBRACKET = 57355
const RIGHTBRACKET = 57356
const PERIOD = 57357
var hclToknames = []string{ var hclToknames = []string{
"NUMBER", "NUMBER",
@ -38,10 +44,12 @@ var hclToknames = []string{
"EQUAL", "EQUAL",
"NEWLINE", "NEWLINE",
"STRING", "STRING",
"MINUS",
"LEFTBRACE", "LEFTBRACE",
"RIGHTBRACE", "RIGHTBRACE",
"LEFTBRACKET", "LEFTBRACKET",
"RIGHTBRACKET", "RIGHTBRACKET",
"PERIOD",
} }
var hclStatenames = []string{} var hclStatenames = []string{}
@ -49,7 +57,7 @@ const hclEofCode = 1
const hclErrCode = 2 const hclErrCode = 2
const hclMaxDepth = 200 const hclMaxDepth = 200
//line parse.y:165 //line parse.y:203
//line yacctab:1 //line yacctab:1
var hclExca = []int{ var hclExca = []int{
@ -58,52 +66,59 @@ var hclExca = []int{
-2, 0, -2, 0,
} }
const hclNprod = 19 const hclNprod = 24
const hclPrivate = 57344 const hclPrivate = 57344
var hclTokenNames []string var hclTokenNames []string
var hclStates []string var hclStates []string
const hclLast = 33 const hclLast = 42
var hclAct = []int{ var hclAct = []int{
21, 14, 24, 26, 2, 1, 15, 12, 8, 17, 24, 18, 20, 28, 32, 30, 2, 15, 19, 12,
4, 25, 10, 7, 9, 19, 13, 18, 22, 7, 8, 17, 4, 31, 9, 7, 10, 13, 22, 21,
12, 4, 16, 23, 7, 5, 6, 27, 3, 20, 7, 29, 12, 20, 20, 25, 16, 33, 26, 19,
0, 0, 11, 19, 4, 5, 34, 7, 14, 1, 27, 6, 11,
3, 23,
} }
var hclPact = []int{ var hclPact = []int{
15, -1000, -1000, 15, 7, -1000, 10, -1000, -1000, -3, 25, -1000, -1000, 25, 7, -1000, 11, -1000, -1000, -2,
-1000, -1000, 4, -1000, -1000, -1000, -1000, 14, -9, -1000, -1000, -1000, 6, -1000, -1000, -1000, -1000, 19, -12, 20,
-2, -1000, -1000, -1000, -1000, -1000, 14, -1000, -1000, -7, -1000, -1, -1000, -1000, -1000, -1000, 23, -1000,
-1000, -1000, 19, -1000, -1000,
} }
var hclPgo = []int{ var hclPgo = []int{
0, 29, 4, 28, 25, 0, 12, 26, 5, 0, 25, 41, 6, 40, 32, 0, 1, 16, 38,
37, 36,
} }
var hclR1 = []int{ var hclR1 = []int{
0, 8, 2, 2, 6, 6, 3, 3, 3, 3, 0, 11, 3, 3, 8, 8, 4, 4, 4, 4,
3, 4, 4, 7, 7, 1, 1, 5, 5, 4, 5, 5, 9, 9, 2, 2, 6, 6, 1,
1, 7, 7, 10,
} }
var hclR2 = []int{ var hclR2 = []int{
0, 1, 1, 2, 3, 2, 3, 3, 3, 5, 0, 1, 1, 2, 3, 2, 3, 3, 3, 5,
1, 2, 2, 1, 1, 1, 3, 1, 1, 1, 2, 2, 1, 1, 1, 3, 1, 1, 1,
2, 2, 1, 2,
} }
var hclChk = []int{ var hclChk = []int{
-1000, -8, -2, -3, 6, -4, -7, 9, -2, 7, -1000, -11, -3, -4, 6, -5, -9, 9, -3, 7,
-6, -4, 10, 6, 4, 9, -6, 12, -2, 11, -8, -5, 11, 6, -1, 9, -8, 13, -7, 10,
-1, -5, 4, 9, 11, 13, 5, -5, 4, -3, 12, -2, -6, -1, 9, -10, 15, -7,
12, 14, 5, 4, -6,
} }
var hclDef = []int{ var hclDef = []int{
0, -2, 1, 2, 13, 10, 0, 14, 3, 0, 0, -2, 1, 2, 13, 10, 0, 14, 3, 0,
11, 12, 0, 13, 6, 7, 8, 0, 0, 5, 11, 12, 0, 13, 6, 7, 8, 0, 19, 0,
0, 15, 17, 18, 4, 9, 0, 16, 22, 0, 5, 0, 15, 17, 18, 20, 0, 21,
4, 9, 0, 23, 16,
} }
var hclTok1 = []int{ var hclTok1 = []int{
@ -112,7 +127,7 @@ var hclTok1 = []int{
var hclTok2 = []int{ var hclTok2 = []int{
2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
12, 13, 12, 13, 14, 15,
} }
var hclTok3 = []int{ var hclTok3 = []int{
0, 0,
@ -344,7 +359,7 @@ hcldefault:
switch hclnt { switch hclnt {
case 1: case 1:
//line parse.y:37 //line parse.y:43
{ {
hclResult = &ast.ObjectNode{ hclResult = &ast.ObjectNode{
K: "", K: "",
@ -352,38 +367,35 @@ hcldefault:
} }
} }
case 2: case 2:
//line parse.y:46 //line parse.y:52
{ {
hclVAL.klist = []ast.KeyedNode{hclS[hclpt-0].kitem} hclVAL.klist = []ast.KeyedNode{hclS[hclpt-0].kitem}
} }
case 3: case 3:
//line parse.y:50 //line parse.y:56
{ {
hclVAL.klist = append(hclS[hclpt-0].klist, hclS[hclpt-1].kitem) hclVAL.klist = append(hclS[hclpt-0].klist, hclS[hclpt-1].kitem)
} }
case 4: case 4:
//line parse.y:56 //line parse.y:62
{ {
hclVAL.obj = ast.ObjectNode{Elem: hclS[hclpt-1].klist} hclVAL.obj = ast.ObjectNode{Elem: hclS[hclpt-1].klist}
} }
case 5: case 5:
//line parse.y:60 //line parse.y:66
{ {
hclVAL.obj = ast.ObjectNode{} hclVAL.obj = ast.ObjectNode{}
} }
case 6: case 6:
//line parse.y:66 //line parse.y:72
{ {
hclVAL.kitem = ast.AssignmentNode{ hclVAL.kitem = ast.AssignmentNode{
K: hclS[hclpt-2].str, K: hclS[hclpt-2].str,
Value: ast.LiteralNode{ Value: hclS[hclpt-0].item,
Type: ast.ValueTypeInt,
Value: hclS[hclpt-0].num,
},
} }
} }
case 7: case 7:
//line parse.y:76 //line parse.y:79
{ {
hclVAL.kitem = ast.AssignmentNode{ hclVAL.kitem = ast.AssignmentNode{
K: hclS[hclpt-2].str, K: hclS[hclpt-2].str,
@ -394,7 +406,7 @@ hcldefault:
} }
} }
case 8: case 8:
//line parse.y:86 //line parse.y:89
{ {
hclVAL.kitem = ast.AssignmentNode{ hclVAL.kitem = ast.AssignmentNode{
K: hclS[hclpt-2].str, K: hclS[hclpt-2].str,
@ -402,7 +414,7 @@ hcldefault:
} }
} }
case 9: case 9:
//line parse.y:93 //line parse.y:96
{ {
hclVAL.kitem = ast.AssignmentNode{ hclVAL.kitem = ast.AssignmentNode{
K: hclS[hclpt-4].str, K: hclS[hclpt-4].str,
@ -410,12 +422,12 @@ hcldefault:
} }
} }
case 10: case 10:
//line parse.y:100 //line parse.y:103
{ {
hclVAL.kitem = hclS[hclpt-0].kitem hclVAL.kitem = hclS[hclpt-0].kitem
} }
case 11: case 11:
//line parse.y:106 //line parse.y:109
{ {
hclVAL.kitem = ast.AssignmentNode{ hclVAL.kitem = ast.AssignmentNode{
K: hclS[hclpt-1].str, K: hclS[hclpt-1].str,
@ -425,7 +437,7 @@ hcldefault:
} }
} }
case 12: case 12:
//line parse.y:115 //line parse.y:118
{ {
obj := ast.ObjectNode{ obj := ast.ObjectNode{
K: hclS[hclpt-0].kitem.Key(), K: hclS[hclpt-0].kitem.Key(),
@ -440,32 +452,29 @@ hcldefault:
} }
} }
case 13: case 13:
//line parse.y:131 //line parse.y:134
{ {
hclVAL.str = hclS[hclpt-0].str hclVAL.str = hclS[hclpt-0].str
} }
case 14: case 14:
//line parse.y:135 //line parse.y:138
{ {
hclVAL.str = hclS[hclpt-0].str hclVAL.str = hclS[hclpt-0].str
} }
case 15: case 15:
//line parse.y:141 //line parse.y:144
{ {
hclVAL.list = []ast.Node{hclS[hclpt-0].listitem} hclVAL.list = []ast.Node{hclS[hclpt-0].listitem}
} }
case 16: case 16:
//line parse.y:145 //line parse.y:148
{ {
hclVAL.list = append(hclS[hclpt-2].list, hclS[hclpt-0].listitem) hclVAL.list = append(hclS[hclpt-2].list, hclS[hclpt-0].listitem)
} }
case 17: case 17:
//line parse.y:151 //line parse.y:154
{ {
hclVAL.listitem = ast.LiteralNode{ hclVAL.listitem = hclS[hclpt-0].item
Type: ast.ValueTypeInt,
Value: hclS[hclpt-0].num,
}
} }
case 18: case 18:
//line parse.y:158 //line parse.y:158
@ -475,6 +484,43 @@ hcldefault:
Value: hclS[hclpt-0].str, Value: hclS[hclpt-0].str,
} }
} }
case 19:
//line parse.y:167
{
hclVAL.item = ast.LiteralNode{
Type: ast.ValueTypeInt,
Value: hclS[hclpt-0].num,
}
}
case 20:
//line parse.y:174
{
fs := fmt.Sprintf("%d.%s", hclS[hclpt-1].num, hclS[hclpt-0].str)
f, err := strconv.ParseFloat(fs, 64)
if err != nil {
panic(err)
}
hclVAL.item = ast.LiteralNode{
Type: ast.ValueTypeFloat,
Value: f,
}
}
case 21:
//line parse.y:189
{
hclVAL.num = hclS[hclpt-0].num * -1
}
case 22:
//line parse.y:193
{
hclVAL.num = hclS[hclpt-0].num
}
case 23:
//line parse.y:199
{
hclVAL.str = strconv.FormatInt(int64(hclS[hclpt-0].num), 10)
}
} }
goto hclstack /* stack new state and value */ goto hclstack /* stack new state and value */
} }