parse floats 1.02 properly [GH-19]

This commit is contained in:
Mitchell Hashimoto 2014-11-12 21:29:07 -08:00
parent 88ef419bd9
commit e51eabcdf8
9 changed files with 281 additions and 223 deletions

View File

@ -50,6 +50,13 @@ func TestDecode_interface(t *testing.T) {
"foo": "bar\"baz\\n", "foo": "bar\"baz\\n",
}, },
}, },
{
"float.hcl",
false,
map[string]interface{}{
"a": 1.02,
},
},
{ {
"multiline_bad.hcl", "multiline_bad.hcl",
false, false,
@ -209,6 +216,10 @@ func TestDecode_equal(t *testing.T) {
"basic.hcl", "basic.hcl",
"basic.json", "basic.json",
}, },
{
"float.hcl",
"float.json",
},
/* /*
{ {
"structure.hcl", "structure.hcl",

View File

@ -307,14 +307,21 @@ func (x *hclLex) lexHeredoc(yylval *hclSymType) int {
// lexNumber lexes out a number // lexNumber lexes out a number
func (x *hclLex) lexNumber(yylval *hclSymType) int { func (x *hclLex) lexNumber(yylval *hclSymType) int {
var b bytes.Buffer var b bytes.Buffer
gotPeriod := false
for { for {
c := x.next() c := x.next()
if c == lexEOF { if c == lexEOF {
break break
} }
// No more numeric characters if c == '.' {
if c < '0' || c > '9' { if gotPeriod {
x.backup()
break
}
gotPeriod = true
} else if c < '0' || c > '9' {
x.backup() x.backup()
break break
} }
@ -325,14 +332,25 @@ func (x *hclLex) lexNumber(yylval *hclSymType) int {
} }
} }
v, err := strconv.ParseInt(b.String(), 0, 0) if !gotPeriod {
v, err := strconv.ParseInt(b.String(), 0, 0)
if err != nil {
x.createErr(fmt.Sprintf("Expected number: %s", err))
return lexEOF
}
yylval.num = int(v)
return NUMBER
}
f, err := strconv.ParseFloat(b.String(), 64)
if err != nil { if err != nil {
x.createErr(fmt.Sprintf("Expected number: %s", err)) x.createErr(fmt.Sprintf("Expected float: %s", err))
return lexEOF return lexEOF
} }
yylval.num = int(v) yylval.f = float64(f)
return NUMBER return FLOAT
} }
// lexString extracts a string from the input // lexString extracts a string from the input

View File

@ -12,19 +12,22 @@ import (
%union { %union {
b bool b bool
f float64
num int num int
str string str string
obj *Object obj *Object
objlist []*Object objlist []*Object
} }
%type <f> float
%type <num> int %type <num> int
%type <objlist> list listitems objectlist %type <objlist> list listitems objectlist
%type <obj> block number object objectitem %type <obj> block number object objectitem
%type <obj> listitem %type <obj> listitem
%type <str> blockId exp objectkey frac %type <str> blockId exp objectkey
%token <b> BOOL %token <b> BOOL
%token <f> FLOAT
%token <num> NUMBER %token <num> NUMBER
%token <str> COMMA COMMAEND IDENTIFIER EQUAL NEWLINE STRING MINUS %token <str> COMMA COMMAEND IDENTIFIER EQUAL NEWLINE STRING MINUS
%token <str> LEFTBRACE RIGHTBRACE LEFTBRACKET RIGHTBRACKET PERIOD %token <str> LEFTBRACE RIGHTBRACE LEFTBRACKET RIGHTBRACKET PERIOD
@ -189,17 +192,11 @@ number:
Value: $1, Value: $1,
} }
} }
| int frac | float
{ {
fs := fmt.Sprintf("%d.%s", $1, $2)
f, err := strconv.ParseFloat(fs, 64)
if err != nil {
panic(err)
}
$$ = &Object{ $$ = &Object{
Type: ValueTypeFloat, Type: ValueTypeFloat,
Value: f, Value: $1,
} }
} }
| int exp | int exp
@ -215,9 +212,9 @@ number:
Value: f, Value: f,
} }
} }
| int frac exp | float exp
{ {
fs := fmt.Sprintf("%d.%s%s", $1, $2, $3) fs := fmt.Sprintf("%f%s", $1, $2)
f, err := strconv.ParseFloat(fs, 64) f, err := strconv.ParseFloat(fs, 64)
if err != nil { if err != nil {
panic(err) panic(err)
@ -239,6 +236,16 @@ int:
$$ = $1 $$ = $1
} }
float:
MINUS float
{
$$ = $2 * -1
}
| FLOAT
{
$$ = $1
}
exp: exp:
EPLUS NUMBER EPLUS NUMBER
{ {
@ -249,10 +256,4 @@ exp:
$$ = "e-" + strconv.FormatInt(int64($2), 10) $$ = "e-" + strconv.FormatInt(int64($2), 10)
} }
frac:
PERIOD NUMBER
{
$$ = strconv.FormatInt(int64($2), 10)
}
%% %%

194
hcl/y.go
View File

@ -13,6 +13,7 @@ import (
type hclSymType struct { type hclSymType struct {
yys int yys int
b bool b bool
f float64
num int num int
str string str string
obj *Object obj *Object
@ -20,24 +21,26 @@ type hclSymType struct {
} }
const BOOL = 57346 const BOOL = 57346
const NUMBER = 57347 const FLOAT = 57347
const COMMA = 57348 const NUMBER = 57348
const COMMAEND = 57349 const COMMA = 57349
const IDENTIFIER = 57350 const COMMAEND = 57350
const EQUAL = 57351 const IDENTIFIER = 57351
const NEWLINE = 57352 const EQUAL = 57352
const STRING = 57353 const NEWLINE = 57353
const MINUS = 57354 const STRING = 57354
const LEFTBRACE = 57355 const MINUS = 57355
const RIGHTBRACE = 57356 const LEFTBRACE = 57356
const LEFTBRACKET = 57357 const RIGHTBRACE = 57357
const RIGHTBRACKET = 57358 const LEFTBRACKET = 57358
const PERIOD = 57359 const RIGHTBRACKET = 57359
const EPLUS = 57360 const PERIOD = 57360
const EMINUS = 57361 const EPLUS = 57361
const EMINUS = 57362
var hclToknames = []string{ var hclToknames = []string{
"BOOL", "BOOL",
"FLOAT",
"NUMBER", "NUMBER",
"COMMA", "COMMA",
"COMMAEND", "COMMAEND",
@ -60,7 +63,7 @@ const hclEofCode = 1
const hclErrCode = 2 const hclErrCode = 2
const hclMaxDepth = 200 const hclMaxDepth = 200
//line parse.y:258 //line parse.y:259
//line yacctab:1 //line yacctab:1
var hclExca = []int{ var hclExca = []int{
@ -68,73 +71,73 @@ var hclExca = []int{
1, -1, 1, -1,
-2, 0, -2, 0,
-1, 6, -1, 6,
9, 7, 10, 7,
-2, 17, -2, 17,
-1, 7, -1, 7,
9, 8, 10, 8,
-2, 18, -2, 18,
} }
const hclNprod = 35 const hclNprod = 36
const hclPrivate = 57344 const hclPrivate = 57344
var hclTokenNames []string var hclTokenNames []string
var hclStates []string var hclStates []string
const hclLast = 63 const hclLast = 62
var hclAct = []int{ var hclAct = []int{
34, 28, 3, 21, 10, 9, 29, 30, 31, 30, 35, 3, 21, 22, 9, 30, 31, 29, 17, 26,
31, 17, 24, 42, 6, 44, 45, 7, 18, 23, 25, 26, 25, 10, 26, 25, 18, 24, 13, 24,
13, 41, 22, 40, 24, 43, 1, 37, 9, 39, 23, 37, 24, 44, 45, 42, 34, 38, 39, 9,
36, 23, 2, 6, 6, 33, 7, 7, 14, 38, 32, 6, 6, 43, 7, 7, 2, 40, 28, 26,
26, 15, 24, 13, 24, 46, 25, 11, 36, 23, 25, 6, 41, 11, 7, 46, 37, 24, 14, 36,
35, 23, 27, 5, 4, 8, 32, 20, 19, 0, 27, 15, 5, 13, 19, 1, 4, 8, 33, 20,
0, 16, 12, 16, 12,
} }
var hclPact = []int{ var hclPact = []int{
6, -1000, 6, -1000, -5, -1000, -1000, -1000, 30, -1000, 32, -1000, 32, -1000, 3, -1000, -1000, -1000, 39, -1000,
7, -1000, -1000, 26, -1000, -1000, -1000, -1000, -1000, -1000, 4, -1000, -1000, 23, -1000, -1000, -1000, -1000, -1000, -1000,
-1000, -11, 19, 39, -1000, 25, -1000, -9, -1000, 18, -1000, -14, -14, 9, 6, -1000, -1000, 22, -1000, -1000,
16, 8, 9, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 36, 19, -1000, 16, -1000, -1000, -1000, -1000, -1000, -1000,
-1000, -1000, -1000, -1000, 37, -1000, -1000, -1000, -1000, -1000, -1000, 34, -1000, -1000,
} }
var hclPgo = []int{ var hclPgo = []int{
0, 3, 57, 56, 32, 53, 50, 47, 2, 0, 0, 3, 2, 59, 58, 36, 52, 49, 43, 1,
55, 1, 54, 52, 26, 0, 57, 7, 56, 55,
} }
var hclR1 = []int{ var hclR1 = []int{
0, 14, 14, 4, 4, 7, 7, 12, 12, 8, 0, 14, 14, 5, 5, 8, 8, 13, 13, 9,
8, 8, 8, 8, 8, 5, 5, 10, 10, 2, 9, 9, 9, 9, 9, 6, 6, 11, 11, 3,
2, 3, 3, 3, 9, 9, 6, 6, 6, 6, 3, 4, 4, 4, 10, 10, 7, 7, 7, 7,
1, 1, 11, 11, 13, 2, 2, 1, 1, 12, 12,
} }
var hclR2 = []int{ var hclR2 = []int{
0, 0, 1, 1, 2, 3, 2, 1, 1, 3, 0, 0, 1, 1, 2, 3, 2, 1, 1, 3,
3, 3, 3, 3, 1, 2, 2, 1, 1, 3, 3, 3, 3, 3, 1, 2, 2, 1, 1, 3,
2, 1, 3, 2, 1, 1, 1, 2, 2, 3, 2, 1, 3, 2, 1, 1, 1, 1, 2, 2,
2, 1, 2, 2, 2, 2, 1, 2, 1, 2, 2,
} }
var hclChk = []int{ var hclChk = []int{
-1000, -14, -4, -8, -12, -5, 8, 11, -10, -8, -1000, -14, -5, -9, -13, -6, 9, 12, -11, -9,
9, -7, -5, 13, 8, 11, -6, 4, 11, -7, 10, -8, -6, 14, 9, 12, -7, 4, 12, -8,
-2, -1, 15, 12, 5, -4, 14, -13, -11, 17, -3, -2, -1, 16, 13, 6, 5, -5, 15, -12,
18, 19, -3, 16, -9, -6, 11, -1, 14, -11, 19, 20, -12, -4, 17, -10, -7, 12, -2, -1,
5, 5, 5, 16, 6, 7, -9, 15, 6, 6, 17, 7, 8, -10,
} }
var hclDef = []int{ var hclDef = []int{
1, -2, 2, 3, 0, 14, -2, -2, 0, 4, 1, -2, 2, 3, 0, 14, -2, -2, 0, 4,
0, 15, 16, 0, 17, 18, 9, 10, 11, 12, 0, 15, 16, 0, 17, 18, 9, 10, 11, 12,
13, 26, 0, 0, 31, 0, 6, 27, 28, 0, 13, 26, 27, 0, 0, 31, 33, 0, 6, 28,
0, 0, 0, 20, 21, 24, 25, 30, 5, 29, 0, 0, 29, 0, 20, 21, 24, 25, 30, 32,
34, 32, 33, 19, 0, 23, 22, 5, 34, 35, 19, 0, 23, 22,
} }
var hclTok1 = []int{ var hclTok1 = []int{
@ -143,7 +146,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, 14, 15, 16, 17, 18, 19, 12, 13, 14, 15, 16, 17, 18, 19, 20,
} }
var hclTok3 = []int{ var hclTok3 = []int{
0, 0,
@ -375,12 +378,12 @@ hcldefault:
switch hclnt { switch hclnt {
case 1: case 1:
//line parse.y:36 //line parse.y:39
{ {
hclResult = &Object{Type: ValueTypeObject} hclResult = &Object{Type: ValueTypeObject}
} }
case 2: case 2:
//line parse.y:40 //line parse.y:43
{ {
hclResult = &Object{ hclResult = &Object{
Type: ValueTypeObject, Type: ValueTypeObject,
@ -388,17 +391,17 @@ hcldefault:
} }
} }
case 3: case 3:
//line parse.y:49 //line parse.y:52
{ {
hclVAL.objlist = []*Object{hclS[hclpt-0].obj} hclVAL.objlist = []*Object{hclS[hclpt-0].obj}
} }
case 4: case 4:
//line parse.y:53 //line parse.y:56
{ {
hclVAL.objlist = append(hclS[hclpt-1].objlist, hclS[hclpt-0].obj) hclVAL.objlist = append(hclS[hclpt-1].objlist, hclS[hclpt-0].obj)
} }
case 5: case 5:
//line parse.y:59 //line parse.y:62
{ {
hclVAL.obj = &Object{ hclVAL.obj = &Object{
Type: ValueTypeObject, Type: ValueTypeObject,
@ -406,30 +409,30 @@ hcldefault:
} }
} }
case 6: case 6:
//line parse.y:66 //line parse.y:69
{ {
hclVAL.obj = &Object{ hclVAL.obj = &Object{
Type: ValueTypeObject, Type: ValueTypeObject,
} }
} }
case 7: case 7:
//line parse.y:74 //line parse.y:77
{ {
hclVAL.str = hclS[hclpt-0].str hclVAL.str = hclS[hclpt-0].str
} }
case 8: case 8:
//line parse.y:78 //line parse.y:81
{ {
hclVAL.str = hclS[hclpt-0].str hclVAL.str = hclS[hclpt-0].str
} }
case 9: case 9:
//line parse.y:84 //line parse.y:87
{ {
hclVAL.obj = hclS[hclpt-0].obj hclVAL.obj = hclS[hclpt-0].obj
hclVAL.obj.Key = hclS[hclpt-2].str hclVAL.obj.Key = hclS[hclpt-2].str
} }
case 10: case 10:
//line parse.y:89 //line parse.y:92
{ {
hclVAL.obj = &Object{ hclVAL.obj = &Object{
Key: hclS[hclpt-2].str, Key: hclS[hclpt-2].str,
@ -438,7 +441,7 @@ hcldefault:
} }
} }
case 11: case 11:
//line parse.y:97 //line parse.y:100
{ {
hclVAL.obj = &Object{ hclVAL.obj = &Object{
Key: hclS[hclpt-2].str, Key: hclS[hclpt-2].str,
@ -447,13 +450,13 @@ hcldefault:
} }
} }
case 12: case 12:
//line parse.y:105 //line parse.y:108
{ {
hclS[hclpt-0].obj.Key = hclS[hclpt-2].str hclS[hclpt-0].obj.Key = hclS[hclpt-2].str
hclVAL.obj = hclS[hclpt-0].obj hclVAL.obj = hclS[hclpt-0].obj
} }
case 13: case 13:
//line parse.y:110 //line parse.y:113
{ {
hclVAL.obj = &Object{ hclVAL.obj = &Object{
Key: hclS[hclpt-2].str, Key: hclS[hclpt-2].str,
@ -462,18 +465,18 @@ hcldefault:
} }
} }
case 14: case 14:
//line parse.y:118 //line parse.y:121
{ {
hclVAL.obj = hclS[hclpt-0].obj hclVAL.obj = hclS[hclpt-0].obj
} }
case 15: case 15:
//line parse.y:124 //line parse.y:127
{ {
hclS[hclpt-0].obj.Key = hclS[hclpt-1].str hclS[hclpt-0].obj.Key = hclS[hclpt-1].str
hclVAL.obj = hclS[hclpt-0].obj hclVAL.obj = hclS[hclpt-0].obj
} }
case 16: case 16:
//line parse.y:129 //line parse.y:132
{ {
hclVAL.obj = &Object{ hclVAL.obj = &Object{
Key: hclS[hclpt-1].str, Key: hclS[hclpt-1].str,
@ -482,47 +485,47 @@ hcldefault:
} }
} }
case 17: case 17:
//line parse.y:139 //line parse.y:142
{ {
hclVAL.str = hclS[hclpt-0].str hclVAL.str = hclS[hclpt-0].str
} }
case 18: case 18:
//line parse.y:143 //line parse.y:146
{ {
hclVAL.str = hclS[hclpt-0].str hclVAL.str = hclS[hclpt-0].str
} }
case 19: case 19:
//line parse.y:149 //line parse.y:152
{ {
hclVAL.objlist = hclS[hclpt-1].objlist hclVAL.objlist = hclS[hclpt-1].objlist
} }
case 20: case 20:
//line parse.y:153 //line parse.y:156
{ {
hclVAL.objlist = nil hclVAL.objlist = nil
} }
case 21: case 21:
//line parse.y:159 //line parse.y:162
{ {
hclVAL.objlist = []*Object{hclS[hclpt-0].obj} hclVAL.objlist = []*Object{hclS[hclpt-0].obj}
} }
case 22: case 22:
//line parse.y:163 //line parse.y:166
{ {
hclVAL.objlist = append(hclS[hclpt-2].objlist, hclS[hclpt-0].obj) hclVAL.objlist = append(hclS[hclpt-2].objlist, hclS[hclpt-0].obj)
} }
case 23: case 23:
//line parse.y:167 //line parse.y:170
{ {
hclVAL.objlist = hclS[hclpt-1].objlist hclVAL.objlist = hclS[hclpt-1].objlist
} }
case 24: case 24:
//line parse.y:173 //line parse.y:176
{ {
hclVAL.obj = hclS[hclpt-0].obj hclVAL.obj = hclS[hclpt-0].obj
} }
case 25: case 25:
//line parse.y:177 //line parse.y:180
{ {
hclVAL.obj = &Object{ hclVAL.obj = &Object{
Type: ValueTypeString, Type: ValueTypeString,
@ -530,7 +533,7 @@ hcldefault:
} }
} }
case 26: case 26:
//line parse.y:186 //line parse.y:189
{ {
hclVAL.obj = &Object{ hclVAL.obj = &Object{
Type: ValueTypeInt, Type: ValueTypeInt,
@ -538,21 +541,15 @@ hcldefault:
} }
} }
case 27: case 27:
//line parse.y:193 //line parse.y:196
{ {
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.obj = &Object{ hclVAL.obj = &Object{
Type: ValueTypeFloat, Type: ValueTypeFloat,
Value: f, Value: hclS[hclpt-0].f,
} }
} }
case 28: case 28:
//line parse.y:206 //line parse.y:203
{ {
fs := fmt.Sprintf("%d%s", hclS[hclpt-1].num, hclS[hclpt-0].str) fs := fmt.Sprintf("%d%s", hclS[hclpt-1].num, hclS[hclpt-0].str)
f, err := strconv.ParseFloat(fs, 64) f, err := strconv.ParseFloat(fs, 64)
@ -566,9 +563,9 @@ hcldefault:
} }
} }
case 29: case 29:
//line parse.y:219 //line parse.y:216
{ {
fs := fmt.Sprintf("%d.%s%s", hclS[hclpt-2].num, hclS[hclpt-1].str, hclS[hclpt-0].str) fs := fmt.Sprintf("%f%s", hclS[hclpt-1].f, hclS[hclpt-0].str)
f, err := strconv.ParseFloat(fs, 64) f, err := strconv.ParseFloat(fs, 64)
if err != nil { if err != nil {
panic(err) panic(err)
@ -580,30 +577,35 @@ hcldefault:
} }
} }
case 30: case 30:
//line parse.y:234 //line parse.y:231
{ {
hclVAL.num = hclS[hclpt-0].num * -1 hclVAL.num = hclS[hclpt-0].num * -1
} }
case 31: case 31:
//line parse.y:238 //line parse.y:235
{ {
hclVAL.num = hclS[hclpt-0].num hclVAL.num = hclS[hclpt-0].num
} }
case 32: case 32:
//line parse.y:244 //line parse.y:241
{
hclVAL.f = hclS[hclpt-0].f * -1
}
case 33:
//line parse.y:245
{
hclVAL.f = hclS[hclpt-0].f
}
case 34:
//line parse.y:251
{ {
hclVAL.str = "e" + strconv.FormatInt(int64(hclS[hclpt-0].num), 10) hclVAL.str = "e" + strconv.FormatInt(int64(hclS[hclpt-0].num), 10)
} }
case 33: case 35:
//line parse.y:248 //line parse.y:255
{ {
hclVAL.str = "e-" + strconv.FormatInt(int64(hclS[hclpt-0].num), 10) hclVAL.str = "e-" + strconv.FormatInt(int64(hclS[hclpt-0].num), 10)
} }
case 34:
//line parse.y:254
{
hclVAL.str = strconv.FormatInt(int64(hclS[hclpt-0].num), 10)
}
} }
goto hclstack /* stack new state and value */ goto hclstack /* stack new state and value */
} }

View File

@ -83,14 +83,21 @@ func (x *jsonLex) Lex(yylval *jsonSymType) int {
// lexNumber lexes out a number // lexNumber lexes out a number
func (x *jsonLex) lexNumber(yylval *jsonSymType) int { func (x *jsonLex) lexNumber(yylval *jsonSymType) int {
var b bytes.Buffer var b bytes.Buffer
gotPeriod := false
for { for {
c := x.next() c := x.next()
if c == lexEOF { if c == lexEOF {
break break
} }
// No more numeric characters if c == '.' {
if c < '0' || c > '9' { if gotPeriod {
x.backup()
break
}
gotPeriod = true
} else if c < '0' || c > '9' {
x.backup() x.backup()
break break
} }
@ -101,14 +108,25 @@ func (x *jsonLex) lexNumber(yylval *jsonSymType) int {
} }
} }
v, err := strconv.ParseInt(b.String(), 0, 0) if !gotPeriod {
v, err := strconv.ParseInt(b.String(), 0, 0)
if err != nil {
x.createErr(fmt.Sprintf("Expected number: %s", err))
return lexEOF
}
yylval.num = int(v)
return NUMBER
}
f, err := strconv.ParseFloat(b.String(), 64)
if err != nil { if err != nil {
x.createErr(fmt.Sprintf("Expected number: %s", err)) x.createErr(fmt.Sprintf("Expected float: %s", err))
return lexEOF return lexEOF
} }
yylval.num = int(v) yylval.f = float64(f)
return NUMBER return FLOAT
} }
// lexString extracts a string from the input // lexString extracts a string from the input

View File

@ -13,17 +13,20 @@ import (
%} %}
%union { %union {
f float64
num int num int
str string str string
obj *hcl.Object obj *hcl.Object
objlist []*hcl.Object objlist []*hcl.Object
} }
%type <f> float
%type <num> int %type <num> int
%type <obj> number object pair value %type <obj> number object pair value
%type <objlist> array elements members %type <objlist> array elements members
%type <str> exp frac %type <str> exp
%token <f> FLOAT
%token <num> NUMBER %token <num> NUMBER
%token <str> COLON COMMA IDENTIFIER EQUAL NEWLINE STRING %token <str> COLON COMMA IDENTIFIER EQUAL NEWLINE STRING
%token <str> LEFTBRACE RIGHTBRACE LEFTBRACKET RIGHTBRACKET %token <str> LEFTBRACE RIGHTBRACE LEFTBRACKET RIGHTBRACKET
@ -140,17 +143,11 @@ number:
Value: $1, Value: $1,
} }
} }
| int frac | float
{ {
fs := fmt.Sprintf("%d.%s", $1, $2)
f, err := strconv.ParseFloat(fs, 64)
if err != nil {
panic(err)
}
$$ = &hcl.Object{ $$ = &hcl.Object{
Type: hcl.ValueTypeFloat, Type: hcl.ValueTypeFloat,
Value: f, Value: $1,
} }
} }
| int exp | int exp
@ -166,9 +163,9 @@ number:
Value: f, Value: f,
} }
} }
| int frac exp | float exp
{ {
fs := fmt.Sprintf("%d.%s%s", $1, $2, $3) fs := fmt.Sprintf("%f%s", $1, $2)
f, err := strconv.ParseFloat(fs, 64) f, err := strconv.ParseFloat(fs, 64)
if err != nil { if err != nil {
panic(err) panic(err)
@ -190,6 +187,16 @@ int:
$$ = $1 $$ = $1
} }
float:
MINUS float
{
$$ = $2 * -1
}
| FLOAT
{
$$ = $1
}
exp: exp:
EPLUS NUMBER EPLUS NUMBER
{ {
@ -200,10 +207,4 @@ exp:
$$ = "e-" + strconv.FormatInt(int64($2), 10) $$ = "e-" + strconv.FormatInt(int64($2), 10)
} }
frac:
PERIOD NUMBER
{
$$ = strconv.FormatInt(int64($2), 10)
}
%% %%

165
json/y.go
View File

@ -14,32 +14,35 @@ import (
//line parse.y:15 //line parse.y:15
type jsonSymType struct { type jsonSymType struct {
yys int yys int
f float64
num int num int
str string str string
obj *hcl.Object obj *hcl.Object
objlist []*hcl.Object objlist []*hcl.Object
} }
const NUMBER = 57346 const FLOAT = 57346
const COLON = 57347 const NUMBER = 57347
const COMMA = 57348 const COLON = 57348
const IDENTIFIER = 57349 const COMMA = 57349
const EQUAL = 57350 const IDENTIFIER = 57350
const NEWLINE = 57351 const EQUAL = 57351
const STRING = 57352 const NEWLINE = 57352
const LEFTBRACE = 57353 const STRING = 57353
const RIGHTBRACE = 57354 const LEFTBRACE = 57354
const LEFTBRACKET = 57355 const RIGHTBRACE = 57355
const RIGHTBRACKET = 57356 const LEFTBRACKET = 57356
const TRUE = 57357 const RIGHTBRACKET = 57357
const FALSE = 57358 const TRUE = 57358
const NULL = 57359 const FALSE = 57359
const MINUS = 57360 const NULL = 57360
const PERIOD = 57361 const MINUS = 57361
const EPLUS = 57362 const PERIOD = 57362
const EMINUS = 57363 const EPLUS = 57363
const EMINUS = 57364
var jsonToknames = []string{ var jsonToknames = []string{
"FLOAT",
"NUMBER", "NUMBER",
"COLON", "COLON",
"COMMA", "COMMA",
@ -65,7 +68,7 @@ const jsonEofCode = 1
const jsonErrCode = 2 const jsonErrCode = 2
const jsonMaxDepth = 200 const jsonMaxDepth = 200
//line parse.y:209 //line parse.y:210
//line yacctab:1 //line yacctab:1
var jsonExca = []int{ var jsonExca = []int{
@ -74,7 +77,7 @@ var jsonExca = []int{
-2, 0, -2, 0,
} }
const jsonNprod = 27 const jsonNprod = 28
const jsonPrivate = 57344 const jsonPrivate = 57344
var jsonTokenNames []string var jsonTokenNames []string
@ -84,50 +87,50 @@ const jsonLast = 53
var jsonAct = []int{ var jsonAct = []int{
12, 23, 25, 26, 27, 28, 23, 13, 3, 20, 12, 25, 24, 3, 20, 27, 28, 7, 13, 3,
21, 29, 17, 18, 19, 22, 3, 23, 27, 28, 21, 22, 30, 17, 18, 19, 23, 25, 24, 26,
22, 7, 31, 13, 3, 38, 21, 33, 17, 18, 25, 24, 36, 32, 13, 3, 10, 22, 33, 17,
19, 22, 32, 37, 9, 7, 6, 5, 10, 39, 18, 19, 23, 35, 34, 23, 38, 9, 7, 39,
8, 36, 35, 34, 15, 2, 11, 1, 24, 4, 5, 29, 6, 8, 37, 15, 2, 1, 4, 31,
30, 16, 14, 16, 14, 11,
} }
var jsonPact = []int{ var jsonPact = []int{
5, -1000, -1000, 25, 28, -1000, -1000, 33, -1000, 11, -9, -1000, -1000, 27, 30, -1000, -1000, 20, -1000, -4,
13, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 13, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
-16, -3, 2, -1000, -2, -1000, 39, 38, 37, -1000, -16, -16, -3, 16, -1000, -1000, -1000, 28, 17, -1000,
19, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 13, -1000, -1000, 29, -1000, -1000, -1000, -1000, -1000, -1000, 13, -1000,
} }
var jsonPgo = []int{ var jsonPgo = []int{
0, 9, 52, 44, 36, 0, 51, 50, 49, 2, 0, 10, 4, 51, 45, 42, 0, 50, 49, 48,
48, 47, 19, 47,
} }
var jsonR1 = []int{ var jsonR1 = []int{
0, 11, 3, 3, 8, 8, 4, 5, 5, 5, 0, 11, 4, 4, 9, 9, 5, 6, 6, 6,
5, 5, 5, 5, 6, 6, 7, 7, 2, 2, 6, 6, 6, 6, 7, 7, 8, 8, 3, 3,
2, 2, 1, 1, 9, 9, 10, 3, 3, 2, 2, 1, 1, 10, 10,
} }
var jsonR2 = []int{ var jsonR2 = []int{
0, 1, 3, 2, 1, 3, 3, 1, 1, 1, 0, 1, 3, 2, 1, 3, 3, 1, 1, 1,
1, 1, 1, 1, 2, 3, 1, 3, 1, 2, 1, 1, 1, 1, 2, 3, 1, 3, 1, 1,
2, 3, 2, 1, 2, 2, 2, 2, 2, 2, 1, 2, 1, 2, 2,
} }
var jsonChk = []int{ var jsonChk = []int{
-1000, -11, -3, 11, -8, 12, -4, 10, 12, 6, -1000, -11, -4, 12, -9, 13, -5, 11, 13, 7,
5, -4, -5, 10, -2, -3, -6, 15, 16, 17, 6, -5, -6, 11, -3, -4, -7, 16, 17, 18,
-1, 13, 18, 4, -10, -9, 19, 20, 21, 14, -2, -1, 14, 19, 5, 4, -10, 21, 22, -10,
-7, -5, -1, -9, 4, 4, 4, 14, 6, -5, 15, -8, -6, -2, -1, 5, 5, 15, 7, -6,
} }
var jsonDef = []int{ var jsonDef = []int{
0, -2, 1, 0, 0, 3, 4, 0, 2, 0, 0, -2, 1, 0, 0, 3, 4, 0, 2, 0,
0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13,
18, 0, 0, 23, 19, 20, 0, 0, 0, 14, 18, 19, 0, 0, 23, 25, 20, 0, 0, 21,
0, 16, 22, 21, 26, 24, 25, 15, 0, 17, 14, 0, 16, 22, 24, 26, 27, 15, 0, 17,
} }
var jsonTok1 = []int{ var jsonTok1 = []int{
@ -137,6 +140,7 @@ var jsonTok2 = []int{
2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
22,
} }
var jsonTok3 = []int{ var jsonTok3 = []int{
0, 0,
@ -368,12 +372,12 @@ jsondefault:
switch jsonnt { switch jsonnt {
case 1: case 1:
//line parse.y:36 //line parse.y:39
{ {
jsonResult = jsonS[jsonpt-0].obj jsonResult = jsonS[jsonpt-0].obj
} }
case 2: case 2:
//line parse.y:42 //line parse.y:45
{ {
jsonVAL.obj = &hcl.Object{ jsonVAL.obj = &hcl.Object{
Type: hcl.ValueTypeObject, Type: hcl.ValueTypeObject,
@ -381,28 +385,28 @@ jsondefault:
} }
} }
case 3: case 3:
//line parse.y:49 //line parse.y:52
{ {
jsonVAL.obj = &hcl.Object{Type: hcl.ValueTypeObject} jsonVAL.obj = &hcl.Object{Type: hcl.ValueTypeObject}
} }
case 4: case 4:
//line parse.y:55 //line parse.y:58
{ {
jsonVAL.objlist = []*hcl.Object{jsonS[jsonpt-0].obj} jsonVAL.objlist = []*hcl.Object{jsonS[jsonpt-0].obj}
} }
case 5: case 5:
//line parse.y:59 //line parse.y:62
{ {
jsonVAL.objlist = append(jsonS[jsonpt-2].objlist, jsonS[jsonpt-0].obj) jsonVAL.objlist = append(jsonS[jsonpt-2].objlist, jsonS[jsonpt-0].obj)
} }
case 6: case 6:
//line parse.y:65 //line parse.y:68
{ {
jsonS[jsonpt-0].obj.Key = jsonS[jsonpt-2].str jsonS[jsonpt-0].obj.Key = jsonS[jsonpt-2].str
jsonVAL.obj = jsonS[jsonpt-0].obj jsonVAL.obj = jsonS[jsonpt-0].obj
} }
case 7: case 7:
//line parse.y:72 //line parse.y:75
{ {
jsonVAL.obj = &hcl.Object{ jsonVAL.obj = &hcl.Object{
Type: hcl.ValueTypeString, Type: hcl.ValueTypeString,
@ -410,17 +414,17 @@ jsondefault:
} }
} }
case 8: case 8:
//line parse.y:79 //line parse.y:82
{ {
jsonVAL.obj = jsonS[jsonpt-0].obj jsonVAL.obj = jsonS[jsonpt-0].obj
} }
case 9: case 9:
//line parse.y:83 //line parse.y:86
{ {
jsonVAL.obj = jsonS[jsonpt-0].obj jsonVAL.obj = jsonS[jsonpt-0].obj
} }
case 10: case 10:
//line parse.y:87 //line parse.y:90
{ {
jsonVAL.obj = &hcl.Object{ jsonVAL.obj = &hcl.Object{
Type: hcl.ValueTypeList, Type: hcl.ValueTypeList,
@ -428,7 +432,7 @@ jsondefault:
} }
} }
case 11: case 11:
//line parse.y:94 //line parse.y:97
{ {
jsonVAL.obj = &hcl.Object{ jsonVAL.obj = &hcl.Object{
Type: hcl.ValueTypeBool, Type: hcl.ValueTypeBool,
@ -436,7 +440,7 @@ jsondefault:
} }
} }
case 12: case 12:
//line parse.y:101 //line parse.y:104
{ {
jsonVAL.obj = &hcl.Object{ jsonVAL.obj = &hcl.Object{
Type: hcl.ValueTypeBool, Type: hcl.ValueTypeBool,
@ -444,7 +448,7 @@ jsondefault:
} }
} }
case 13: case 13:
//line parse.y:108 //line parse.y:111
{ {
jsonVAL.obj = &hcl.Object{ jsonVAL.obj = &hcl.Object{
Type: hcl.ValueTypeNil, Type: hcl.ValueTypeNil,
@ -452,27 +456,27 @@ jsondefault:
} }
} }
case 14: case 14:
//line parse.y:117 //line parse.y:120
{ {
jsonVAL.objlist = nil jsonVAL.objlist = nil
} }
case 15: case 15:
//line parse.y:121 //line parse.y:124
{ {
jsonVAL.objlist = jsonS[jsonpt-1].objlist jsonVAL.objlist = jsonS[jsonpt-1].objlist
} }
case 16: case 16:
//line parse.y:127 //line parse.y:130
{ {
jsonVAL.objlist = []*hcl.Object{jsonS[jsonpt-0].obj} jsonVAL.objlist = []*hcl.Object{jsonS[jsonpt-0].obj}
} }
case 17: case 17:
//line parse.y:131 //line parse.y:134
{ {
jsonVAL.objlist = append(jsonS[jsonpt-2].objlist, jsonS[jsonpt-0].obj) jsonVAL.objlist = append(jsonS[jsonpt-2].objlist, jsonS[jsonpt-0].obj)
} }
case 18: case 18:
//line parse.y:137 //line parse.y:140
{ {
jsonVAL.obj = &hcl.Object{ jsonVAL.obj = &hcl.Object{
Type: hcl.ValueTypeInt, Type: hcl.ValueTypeInt,
@ -480,21 +484,15 @@ jsondefault:
} }
} }
case 19: case 19:
//line parse.y:144 //line parse.y:147
{ {
fs := fmt.Sprintf("%d.%s", jsonS[jsonpt-1].num, jsonS[jsonpt-0].str)
f, err := strconv.ParseFloat(fs, 64)
if err != nil {
panic(err)
}
jsonVAL.obj = &hcl.Object{ jsonVAL.obj = &hcl.Object{
Type: hcl.ValueTypeFloat, Type: hcl.ValueTypeFloat,
Value: f, Value: jsonS[jsonpt-0].f,
} }
} }
case 20: case 20:
//line parse.y:157 //line parse.y:154
{ {
fs := fmt.Sprintf("%d%s", jsonS[jsonpt-1].num, jsonS[jsonpt-0].str) fs := fmt.Sprintf("%d%s", jsonS[jsonpt-1].num, jsonS[jsonpt-0].str)
f, err := strconv.ParseFloat(fs, 64) f, err := strconv.ParseFloat(fs, 64)
@ -508,9 +506,9 @@ jsondefault:
} }
} }
case 21: case 21:
//line parse.y:170 //line parse.y:167
{ {
fs := fmt.Sprintf("%d.%s%s", jsonS[jsonpt-2].num, jsonS[jsonpt-1].str, jsonS[jsonpt-0].str) fs := fmt.Sprintf("%f%s", jsonS[jsonpt-1].f, jsonS[jsonpt-0].str)
f, err := strconv.ParseFloat(fs, 64) f, err := strconv.ParseFloat(fs, 64)
if err != nil { if err != nil {
panic(err) panic(err)
@ -522,30 +520,35 @@ jsondefault:
} }
} }
case 22: case 22:
//line parse.y:185 //line parse.y:182
{ {
jsonVAL.num = jsonS[jsonpt-0].num * -1 jsonVAL.num = jsonS[jsonpt-0].num * -1
} }
case 23: case 23:
//line parse.y:189 //line parse.y:186
{ {
jsonVAL.num = jsonS[jsonpt-0].num jsonVAL.num = jsonS[jsonpt-0].num
} }
case 24: case 24:
//line parse.y:195 //line parse.y:192
{
jsonVAL.f = jsonS[jsonpt-0].f * -1
}
case 25:
//line parse.y:196
{
jsonVAL.f = jsonS[jsonpt-0].f
}
case 26:
//line parse.y:202
{ {
jsonVAL.str = "e" + strconv.FormatInt(int64(jsonS[jsonpt-0].num), 10) jsonVAL.str = "e" + strconv.FormatInt(int64(jsonS[jsonpt-0].num), 10)
} }
case 25: case 27:
//line parse.y:199 //line parse.y:206
{ {
jsonVAL.str = "e-" + strconv.FormatInt(int64(jsonS[jsonpt-0].num), 10) jsonVAL.str = "e-" + strconv.FormatInt(int64(jsonS[jsonpt-0].num), 10)
} }
case 26:
//line parse.y:205
{
jsonVAL.str = strconv.FormatInt(int64(jsonS[jsonpt-0].num), 10)
}
} }
goto jsonstack /* stack new state and value */ goto jsonstack /* stack new state and value */
} }

1
test-fixtures/float.hcl Normal file
View File

@ -0,0 +1 @@
a = 1.02

3
test-fixtures/float.json Normal file
View File

@ -0,0 +1,3 @@
{
"a": 1.02
}