Merge branch 'master' into dev

This commit is contained in:
z7zmey 2018-06-26 22:58:18 +03:00
commit b62cb4359b
12 changed files with 312 additions and 88 deletions

View File

@ -165,7 +165,7 @@ nodes := &stmt.StmtList{
file := os.Stdout file := os.Stdout
p := printer.NewPrinter(file, " ") p := printer.NewPrinter(file, " ")
p.PrintFile(nodes) p.Print(nodes)
``` ```
It prints to stdout: It prints to stdout:

View File

@ -202,6 +202,7 @@ func TestArrayItems(t *testing.T) {
}, },
}, },
}, },
nil,
}, },
}, },
}, },

View File

@ -386,3 +386,193 @@ func TestListList(t *testing.T) {
actual = php5parser.GetRootNode() actual = php5parser.GetRootNode()
assertEqual(t, expected, actual) assertEqual(t, expected, actual)
} }
func TestListEmptyItem(t *testing.T) {
src := `<? list(, $a) = $b;`
expected := &node.Root{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 4,
EndPos: 19,
},
Stmts: []node.Node{
&stmt.Expression{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 4,
EndPos: 19,
},
Expr: &assign.Assign{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 4,
EndPos: 18,
},
Variable: &expr.List{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 4,
EndPos: 13,
},
Items: []node.Node{
nil,
&expr.ArrayItem{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 11,
EndPos: 12,
},
Val: &expr.Variable{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 11,
EndPos: 12,
},
VarName: &node.Identifier{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 11,
EndPos: 12,
},
Value: "a",
},
},
},
},
},
Expression: &expr.Variable{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 17,
EndPos: 18,
},
VarName: &node.Identifier{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 17,
EndPos: 18,
},
Value: "b",
},
},
},
},
},
}
php7parser := php7.NewParser(bytes.NewBufferString(src), "test.php")
php7parser.Parse()
actual := php7parser.GetRootNode()
assertEqual(t, expected, actual)
php5parser := php5.NewParser(bytes.NewBufferString(src), "test.php")
php5parser.Parse()
actual = php5parser.GetRootNode()
assertEqual(t, expected, actual)
}
func TestListEmptyItems(t *testing.T) {
src := `<? list(, , $a, ) = $b;`
expected := &node.Root{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 4,
EndPos: 23,
},
Stmts: []node.Node{
&stmt.Expression{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 4,
EndPos: 23,
},
Expr: &assign.Assign{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 4,
EndPos: 22,
},
Variable: &expr.List{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 4,
EndPos: 17,
},
Items: []node.Node{
nil,
nil,
&expr.ArrayItem{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 13,
EndPos: 14,
},
Val: &expr.Variable{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 13,
EndPos: 14,
},
VarName: &node.Identifier{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 13,
EndPos: 14,
},
Value: "a",
},
},
},
nil,
},
},
Expression: &expr.Variable{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 21,
EndPos: 22,
},
VarName: &node.Identifier{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 21,
EndPos: 22,
},
Value: "b",
},
},
},
},
},
}
php7parser := php7.NewParser(bytes.NewBufferString(src), "test.php")
php7parser.Parse()
actual := php7parser.GetRootNode()
assertEqual(t, expected, actual)
php5parser := php5.NewParser(bytes.NewBufferString(src), "test.php")
php5parser.Parse()
actual = php5parser.GetRootNode()
assertEqual(t, expected, actual)
}

View File

@ -202,6 +202,7 @@ func TestShortArrayItems(t *testing.T) {
}, },
}, },
}, },
nil,
}, },
}, },
}, },

View File

@ -97,6 +97,9 @@ func (l *Parser) GetComments() parser.Comments {
// helpers // helpers
func lastNode(nn []node.Node) node.Node { func lastNode(nn []node.Node) node.Node {
if len(nn) == 0 {
return nil
}
return nn[len(nn)-1] return nn[len(nn)-1]
} }

View File

@ -346,7 +346,7 @@ const yyEofCode = 1
const yyErrCode = 2 const yyErrCode = 2
const yyInitialStackSize = 16 const yyInitialStackSize = 16
//line php5/php5.y:6785 //line php5/php5.y:6795
type simpleIndirectReference struct { type simpleIndirectReference struct {
all []*expr.Variable all []*expr.Variable
last *expr.Variable last *expr.Variable
@ -8740,16 +8740,22 @@ yydefault:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php5/php5.y:6190 //line php5/php5.y:6190
{ {
if len(yyDollar[1].list) == 0 {
yyDollar[1].list = []node.Node{nil}
}
yyVAL.list = append(yyDollar[1].list, yyDollar[3].node) yyVAL.list = append(yyDollar[1].list, yyDollar[3].node)
// save comments // save comments
lastNode(yyDollar[1].list).AddComments(yyDollar[2].token.Comments, comment.CommaToken) if lastNode(yyDollar[1].list) != nil {
lastNode(yyDollar[1].list).AddComments(yyDollar[2].token.Comments, comment.CommaToken)
}
yylex.(*Parser).returnTokenToPool(yyDollar, &yyVAL) yylex.(*Parser).returnTokenToPool(yyDollar, &yyVAL)
} }
case 477: case 477:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php5/php5.y:6199 //line php5/php5.y:6205
{ {
if yyDollar[1].node == nil { if yyDollar[1].node == nil {
yyVAL.list = []node.Node{} yyVAL.list = []node.Node{}
@ -8761,7 +8767,7 @@ yydefault:
} }
case 478: case 478:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php5/php5.y:6213 //line php5/php5.y:6219
{ {
yyVAL.node = expr.NewArrayItem(nil, yyDollar[1].node) yyVAL.node = expr.NewArrayItem(nil, yyDollar[1].node)
@ -8772,7 +8778,7 @@ yydefault:
} }
case 479: case 479:
yyDollar = yyS[yypt-4 : yypt+1] yyDollar = yyS[yypt-4 : yypt+1]
//line php5/php5.y:6222 //line php5/php5.y:6228
{ {
item := expr.NewList(yyDollar[3].list) item := expr.NewList(yyDollar[3].list)
yyVAL.node = expr.NewArrayItem(nil, item) yyVAL.node = expr.NewArrayItem(nil, item)
@ -8790,7 +8796,7 @@ yydefault:
} }
case 480: case 480:
yyDollar = yyS[yypt-0 : yypt+1] yyDollar = yyS[yypt-0 : yypt+1]
//line php5/php5.y:6238 //line php5/php5.y:6244
{ {
yyVAL.node = nil yyVAL.node = nil
@ -8798,7 +8804,7 @@ yydefault:
} }
case 481: case 481:
yyDollar = yyS[yypt-0 : yypt+1] yyDollar = yyS[yypt-0 : yypt+1]
//line php5/php5.y:6248 //line php5/php5.y:6254
{ {
yyVAL.list = []node.Node{} yyVAL.list = []node.Node{}
@ -8806,10 +8812,14 @@ yydefault:
} }
case 482: case 482:
yyDollar = yyS[yypt-2 : yypt+1] yyDollar = yyS[yypt-2 : yypt+1]
//line php5/php5.y:6254 //line php5/php5.y:6260
{ {
yyVAL.list = yyDollar[1].list yyVAL.list = yyDollar[1].list
if yyDollar[2].token != nil {
yyVAL.list = append(yyDollar[1].list, nil)
}
// save comments // save comments
if yyDollar[2].token != nil { if yyDollar[2].token != nil {
lastNode(yyDollar[1].list).AddComments(yyDollar[2].token.Comments, comment.CommaToken) lastNode(yyDollar[1].list).AddComments(yyDollar[2].token.Comments, comment.CommaToken)
@ -8819,7 +8829,7 @@ yydefault:
} }
case 483: case 483:
yyDollar = yyS[yypt-5 : yypt+1] yyDollar = yyS[yypt-5 : yypt+1]
//line php5/php5.y:6268 //line php5/php5.y:6278
{ {
arrayItem := expr.NewArrayItem(yyDollar[3].node, yyDollar[5].node) arrayItem := expr.NewArrayItem(yyDollar[3].node, yyDollar[5].node)
yyVAL.list = append(yyDollar[1].list, arrayItem) yyVAL.list = append(yyDollar[1].list, arrayItem)
@ -8835,7 +8845,7 @@ yydefault:
} }
case 484: case 484:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php5/php5.y:6282 //line php5/php5.y:6292
{ {
arrayItem := expr.NewArrayItem(nil, yyDollar[3].node) arrayItem := expr.NewArrayItem(nil, yyDollar[3].node)
yyVAL.list = append(yyDollar[1].list, arrayItem) yyVAL.list = append(yyDollar[1].list, arrayItem)
@ -8850,7 +8860,7 @@ yydefault:
} }
case 485: case 485:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php5/php5.y:6295 //line php5/php5.y:6305
{ {
arrayItem := expr.NewArrayItem(yyDollar[1].node, yyDollar[3].node) arrayItem := expr.NewArrayItem(yyDollar[1].node, yyDollar[3].node)
yyVAL.list = []node.Node{arrayItem} yyVAL.list = []node.Node{arrayItem}
@ -8865,7 +8875,7 @@ yydefault:
} }
case 486: case 486:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php5/php5.y:6308 //line php5/php5.y:6318
{ {
arrayItem := expr.NewArrayItem(nil, yyDollar[1].node) arrayItem := expr.NewArrayItem(nil, yyDollar[1].node)
yyVAL.list = []node.Node{arrayItem} yyVAL.list = []node.Node{arrayItem}
@ -8877,7 +8887,7 @@ yydefault:
} }
case 487: case 487:
yyDollar = yyS[yypt-6 : yypt+1] yyDollar = yyS[yypt-6 : yypt+1]
//line php5/php5.y:6318 //line php5/php5.y:6328
{ {
reference := expr.NewReference(yyDollar[6].node) reference := expr.NewReference(yyDollar[6].node)
arrayItem := expr.NewArrayItem(yyDollar[3].node, reference) arrayItem := expr.NewArrayItem(yyDollar[3].node, reference)
@ -8896,7 +8906,7 @@ yydefault:
} }
case 488: case 488:
yyDollar = yyS[yypt-4 : yypt+1] yyDollar = yyS[yypt-4 : yypt+1]
//line php5/php5.y:6335 //line php5/php5.y:6345
{ {
reference := expr.NewReference(yyDollar[4].node) reference := expr.NewReference(yyDollar[4].node)
arrayItem := expr.NewArrayItem(nil, reference) arrayItem := expr.NewArrayItem(nil, reference)
@ -8914,7 +8924,7 @@ yydefault:
} }
case 489: case 489:
yyDollar = yyS[yypt-4 : yypt+1] yyDollar = yyS[yypt-4 : yypt+1]
//line php5/php5.y:6351 //line php5/php5.y:6361
{ {
reference := expr.NewReference(yyDollar[4].node) reference := expr.NewReference(yyDollar[4].node)
arrayItem := expr.NewArrayItem(yyDollar[1].node, reference) arrayItem := expr.NewArrayItem(yyDollar[1].node, reference)
@ -8932,7 +8942,7 @@ yydefault:
} }
case 490: case 490:
yyDollar = yyS[yypt-2 : yypt+1] yyDollar = yyS[yypt-2 : yypt+1]
//line php5/php5.y:6367 //line php5/php5.y:6377
{ {
reference := expr.NewReference(yyDollar[2].node) reference := expr.NewReference(yyDollar[2].node)
arrayItem := expr.NewArrayItem(nil, reference) arrayItem := expr.NewArrayItem(nil, reference)
@ -8949,7 +8959,7 @@ yydefault:
} }
case 491: case 491:
yyDollar = yyS[yypt-2 : yypt+1] yyDollar = yyS[yypt-2 : yypt+1]
//line php5/php5.y:6385 //line php5/php5.y:6395
{ {
yyVAL.list = append(yyDollar[1].list, yyDollar[2].node) yyVAL.list = append(yyDollar[1].list, yyDollar[2].node)
@ -8957,7 +8967,7 @@ yydefault:
} }
case 492: case 492:
yyDollar = yyS[yypt-2 : yypt+1] yyDollar = yyS[yypt-2 : yypt+1]
//line php5/php5.y:6391 //line php5/php5.y:6401
{ {
encapsed := scalar.NewEncapsedStringPart(yyDollar[2].token.Value) encapsed := scalar.NewEncapsedStringPart(yyDollar[2].token.Value)
yyVAL.list = append(yyDollar[1].list, encapsed) yyVAL.list = append(yyDollar[1].list, encapsed)
@ -8972,7 +8982,7 @@ yydefault:
} }
case 493: case 493:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php5/php5.y:6404 //line php5/php5.y:6414
{ {
yyVAL.list = []node.Node{yyDollar[1].node} yyVAL.list = []node.Node{yyDollar[1].node}
@ -8980,7 +8990,7 @@ yydefault:
} }
case 494: case 494:
yyDollar = yyS[yypt-2 : yypt+1] yyDollar = yyS[yypt-2 : yypt+1]
//line php5/php5.y:6410 //line php5/php5.y:6420
{ {
encapsed := scalar.NewEncapsedStringPart(yyDollar[1].token.Value) encapsed := scalar.NewEncapsedStringPart(yyDollar[1].token.Value)
yyVAL.list = []node.Node{encapsed, yyDollar[2].node} yyVAL.list = []node.Node{encapsed, yyDollar[2].node}
@ -8995,7 +9005,7 @@ yydefault:
} }
case 495: case 495:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php5/php5.y:6426 //line php5/php5.y:6436
{ {
name := node.NewIdentifier(strings.TrimLeftFunc(yyDollar[1].token.Value, isDollar)) name := node.NewIdentifier(strings.TrimLeftFunc(yyDollar[1].token.Value, isDollar))
yyVAL.node = expr.NewVariable(name) yyVAL.node = expr.NewVariable(name)
@ -9011,7 +9021,7 @@ yydefault:
} }
case 496: case 496:
yyDollar = yyS[yypt-4 : yypt+1] yyDollar = yyS[yypt-4 : yypt+1]
//line php5/php5.y:6440 //line php5/php5.y:6450
{ {
identifier := node.NewIdentifier(strings.TrimLeftFunc(yyDollar[1].token.Value, isDollar)) identifier := node.NewIdentifier(strings.TrimLeftFunc(yyDollar[1].token.Value, isDollar))
variable := expr.NewVariable(identifier) variable := expr.NewVariable(identifier)
@ -9031,7 +9041,7 @@ yydefault:
} }
case 497: case 497:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php5/php5.y:6458 //line php5/php5.y:6468
{ {
identifier := node.NewIdentifier(strings.TrimLeftFunc(yyDollar[1].token.Value, isDollar)) identifier := node.NewIdentifier(strings.TrimLeftFunc(yyDollar[1].token.Value, isDollar))
variable := expr.NewVariable(identifier) variable := expr.NewVariable(identifier)
@ -9053,7 +9063,7 @@ yydefault:
} }
case 498: case 498:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php5/php5.y:6478 //line php5/php5.y:6488
{ {
yyVAL.node = expr.NewVariable(yyDollar[2].node) yyVAL.node = expr.NewVariable(yyDollar[2].node)
@ -9068,7 +9078,7 @@ yydefault:
} }
case 499: case 499:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php5/php5.y:6491 //line php5/php5.y:6501
{ {
name := node.NewIdentifier(yyDollar[2].token.Value) name := node.NewIdentifier(yyDollar[2].token.Value)
yyVAL.node = expr.NewVariable(name) yyVAL.node = expr.NewVariable(name)
@ -9086,7 +9096,7 @@ yydefault:
} }
case 500: case 500:
yyDollar = yyS[yypt-6 : yypt+1] yyDollar = yyS[yypt-6 : yypt+1]
//line php5/php5.y:6507 //line php5/php5.y:6517
{ {
identifier := node.NewIdentifier(yyDollar[2].token.Value) identifier := node.NewIdentifier(yyDollar[2].token.Value)
variable := expr.NewVariable(identifier) variable := expr.NewVariable(identifier)
@ -9108,7 +9118,7 @@ yydefault:
} }
case 501: case 501:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php5/php5.y:6527 //line php5/php5.y:6537
{ {
yyVAL.node = yyDollar[2].node yyVAL.node = yyDollar[2].node
@ -9116,7 +9126,7 @@ yydefault:
} }
case 502: case 502:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php5/php5.y:6536 //line php5/php5.y:6546
{ {
yyVAL.node = scalar.NewString(yyDollar[1].token.Value) yyVAL.node = scalar.NewString(yyDollar[1].token.Value)
@ -9130,7 +9140,7 @@ yydefault:
} }
case 503: case 503:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php5/php5.y:6548 //line php5/php5.y:6558
{ {
// TODO: add option to handle 64 bit integer // TODO: add option to handle 64 bit integer
if _, err := strconv.Atoi(yyDollar[1].token.Value); err == nil { if _, err := strconv.Atoi(yyDollar[1].token.Value); err == nil {
@ -9149,7 +9159,7 @@ yydefault:
} }
case 504: case 504:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php5/php5.y:6565 //line php5/php5.y:6575
{ {
identifier := node.NewIdentifier(strings.TrimLeftFunc(yyDollar[1].token.Value, isDollar)) identifier := node.NewIdentifier(strings.TrimLeftFunc(yyDollar[1].token.Value, isDollar))
yyVAL.node = expr.NewVariable(identifier) yyVAL.node = expr.NewVariable(identifier)
@ -9165,7 +9175,7 @@ yydefault:
} }
case 505: case 505:
yyDollar = yyS[yypt-4 : yypt+1] yyDollar = yyS[yypt-4 : yypt+1]
//line php5/php5.y:6582 //line php5/php5.y:6592
{ {
yyVAL.node = expr.NewIsset(yyDollar[3].list) yyVAL.node = expr.NewIsset(yyDollar[3].list)
@ -9181,7 +9191,7 @@ yydefault:
} }
case 506: case 506:
yyDollar = yyS[yypt-4 : yypt+1] yyDollar = yyS[yypt-4 : yypt+1]
//line php5/php5.y:6596 //line php5/php5.y:6606
{ {
yyVAL.node = expr.NewEmpty(yyDollar[3].node) yyVAL.node = expr.NewEmpty(yyDollar[3].node)
@ -9197,7 +9207,7 @@ yydefault:
} }
case 507: case 507:
yyDollar = yyS[yypt-4 : yypt+1] yyDollar = yyS[yypt-4 : yypt+1]
//line php5/php5.y:6610 //line php5/php5.y:6620
{ {
yyVAL.node = expr.NewEmpty(yyDollar[3].node) yyVAL.node = expr.NewEmpty(yyDollar[3].node)
@ -9213,7 +9223,7 @@ yydefault:
} }
case 508: case 508:
yyDollar = yyS[yypt-2 : yypt+1] yyDollar = yyS[yypt-2 : yypt+1]
//line php5/php5.y:6624 //line php5/php5.y:6634
{ {
yyVAL.node = expr.NewInclude(yyDollar[2].node) yyVAL.node = expr.NewInclude(yyDollar[2].node)
@ -9227,7 +9237,7 @@ yydefault:
} }
case 509: case 509:
yyDollar = yyS[yypt-2 : yypt+1] yyDollar = yyS[yypt-2 : yypt+1]
//line php5/php5.y:6636 //line php5/php5.y:6646
{ {
yyVAL.node = expr.NewIncludeOnce(yyDollar[2].node) yyVAL.node = expr.NewIncludeOnce(yyDollar[2].node)
@ -9241,7 +9251,7 @@ yydefault:
} }
case 510: case 510:
yyDollar = yyS[yypt-4 : yypt+1] yyDollar = yyS[yypt-4 : yypt+1]
//line php5/php5.y:6648 //line php5/php5.y:6658
{ {
yyVAL.node = expr.NewEval(yyDollar[3].node) yyVAL.node = expr.NewEval(yyDollar[3].node)
@ -9257,7 +9267,7 @@ yydefault:
} }
case 511: case 511:
yyDollar = yyS[yypt-2 : yypt+1] yyDollar = yyS[yypt-2 : yypt+1]
//line php5/php5.y:6662 //line php5/php5.y:6672
{ {
yyVAL.node = expr.NewRequire(yyDollar[2].node) yyVAL.node = expr.NewRequire(yyDollar[2].node)
@ -9271,7 +9281,7 @@ yydefault:
} }
case 512: case 512:
yyDollar = yyS[yypt-2 : yypt+1] yyDollar = yyS[yypt-2 : yypt+1]
//line php5/php5.y:6674 //line php5/php5.y:6684
{ {
yyVAL.node = expr.NewRequireOnce(yyDollar[2].node) yyVAL.node = expr.NewRequireOnce(yyDollar[2].node)
@ -9285,7 +9295,7 @@ yydefault:
} }
case 513: case 513:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php5/php5.y:6689 //line php5/php5.y:6699
{ {
yyVAL.list = []node.Node{yyDollar[1].node} yyVAL.list = []node.Node{yyDollar[1].node}
@ -9293,7 +9303,7 @@ yydefault:
} }
case 514: case 514:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php5/php5.y:6695 //line php5/php5.y:6705
{ {
yyVAL.list = append(yyDollar[1].list, yyDollar[3].node) yyVAL.list = append(yyDollar[1].list, yyDollar[3].node)
@ -9304,7 +9314,7 @@ yydefault:
} }
case 515: case 515:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php5/php5.y:6707 //line php5/php5.y:6717
{ {
yyVAL.node = yyDollar[1].node yyVAL.node = yyDollar[1].node
@ -9312,7 +9322,7 @@ yydefault:
} }
case 516: case 516:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php5/php5.y:6713 //line php5/php5.y:6723
{ {
yyVAL.node = yyDollar[1].node yyVAL.node = yyDollar[1].node
@ -9320,7 +9330,7 @@ yydefault:
} }
case 517: case 517:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php5/php5.y:6722 //line php5/php5.y:6732
{ {
target := node.NewIdentifier(yyDollar[3].token.Value) target := node.NewIdentifier(yyDollar[3].token.Value)
yyVAL.node = expr.NewClassConstFetch(yyDollar[1].node, target) yyVAL.node = expr.NewClassConstFetch(yyDollar[1].node, target)
@ -9336,7 +9346,7 @@ yydefault:
} }
case 518: case 518:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php5/php5.y:6736 //line php5/php5.y:6746
{ {
target := node.NewIdentifier(yyDollar[3].token.Value) target := node.NewIdentifier(yyDollar[3].token.Value)
yyVAL.node = expr.NewClassConstFetch(yyDollar[1].node, target) yyVAL.node = expr.NewClassConstFetch(yyDollar[1].node, target)
@ -9352,7 +9362,7 @@ yydefault:
} }
case 519: case 519:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php5/php5.y:6753 //line php5/php5.y:6763
{ {
target := node.NewIdentifier(yyDollar[3].token.Value) target := node.NewIdentifier(yyDollar[3].token.Value)
yyVAL.node = expr.NewClassConstFetch(yyDollar[1].node, target) yyVAL.node = expr.NewClassConstFetch(yyDollar[1].node, target)
@ -9368,7 +9378,7 @@ yydefault:
} }
case 520: case 520:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php5/php5.y:6770 //line php5/php5.y:6780
{ {
target := node.NewIdentifier(yyDollar[3].token.Value) target := node.NewIdentifier(yyDollar[3].token.Value)
yyVAL.node = expr.NewClassConstFetch(yyDollar[1].node, target) yyVAL.node = expr.NewClassConstFetch(yyDollar[1].node, target)

View File

@ -6188,10 +6188,16 @@ simple_indirect_reference:
assignment_list: assignment_list:
assignment_list ',' assignment_list_element assignment_list ',' assignment_list_element
{ {
if len($1) == 0 {
$1 = []node.Node{nil}
}
$$ = append($1, $3) $$ = append($1, $3)
// save comments // save comments
lastNode($1).AddComments($2.Comments, comment.CommaToken) if lastNode($1) != nil {
lastNode($1).AddComments($2.Comments, comment.CommaToken)
}
yylex.(*Parser).returnTokenToPool(yyDollar, &yyVAL) yylex.(*Parser).returnTokenToPool(yyDollar, &yyVAL)
} }
@ -6254,6 +6260,10 @@ array_pair_list:
{ {
$$ = $1 $$ = $1
if $2 != nil {
$$ = append($1, nil)
}
// save comments // save comments
if $2 != nil { if $2 != nil {
lastNode($1).AddComments($2.Comments, comment.CommaToken) lastNode($1).AddComments($2.Comments, comment.CommaToken)

View File

@ -8216,6 +8216,7 @@ func TestPhp5(t *testing.T) {
}, },
}, },
}, },
nil,
}, },
}, },
}, },
@ -11018,6 +11019,7 @@ func TestPhp5(t *testing.T) {
}, },
}, },
}, },
nil,
}, },
}, },
}, },

View File

@ -86,6 +86,9 @@ func (l *Parser) GetComments() parser.Comments {
// helpers // helpers
func lastNode(nn []node.Node) node.Node { func lastNode(nn []node.Node) node.Node {
if len(nn) == 0 {
return nil
}
return nn[len(nn)-1] return nn[len(nn)-1]
} }

View File

@ -346,7 +346,7 @@ const yyEofCode = 1
const yyErrCode = 2 const yyErrCode = 2
const yyInitialStackSize = 16 const yyInitialStackSize = 16
//line php7/php7.y:5346 //line php7/php7.y:5348
//line yacctab:1 //line yacctab:1
var yyExca = [...]int{ var yyExca = [...]int{
@ -7517,8 +7517,8 @@ yydefault:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:4861 //line php7/php7.y:4861
{ {
if yyDollar[1].list[len(yyDollar[1].list)-1] == nil { if len(yyDollar[1].list) == 1 && yyDollar[1].list[0] == nil {
yyVAL.list = yyDollar[1].list[:len(yyDollar[1].list)-1] yyVAL.list = yyDollar[1].list[:0]
} else { } else {
yyVAL.list = yyDollar[1].list yyVAL.list = yyDollar[1].list
} }
@ -7548,15 +7548,15 @@ yydefault:
yyVAL.list = append(yyDollar[1].list, yyDollar[3].node) yyVAL.list = append(yyDollar[1].list, yyDollar[3].node)
// save comments // save comments
if yyDollar[3].node != nil { if lastNode(yyDollar[1].list) != nil {
yyDollar[3].node.AddComments(yyDollar[2].token.Comments, comment.CommaToken) lastNode(yyDollar[1].list).AddComments(yyDollar[2].token.Comments, comment.CommaToken)
} }
yylex.(*Parser).returnTokenToPool(yyDollar, &yyVAL) yylex.(*Parser).returnTokenToPool(yyDollar, &yyVAL)
} }
case 458: case 458:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:4898 //line php7/php7.y:4900
{ {
yyVAL.list = []node.Node{yyDollar[1].node} yyVAL.list = []node.Node{yyDollar[1].node}
@ -7564,7 +7564,7 @@ yydefault:
} }
case 459: case 459:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php7/php7.y:4907 //line php7/php7.y:4909
{ {
yyVAL.node = expr.NewArrayItem(yyDollar[1].node, yyDollar[3].node) yyVAL.node = expr.NewArrayItem(yyDollar[1].node, yyDollar[3].node)
@ -7578,7 +7578,7 @@ yydefault:
} }
case 460: case 460:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:4919 //line php7/php7.y:4921
{ {
yyVAL.node = expr.NewArrayItem(nil, yyDollar[1].node) yyVAL.node = expr.NewArrayItem(nil, yyDollar[1].node)
@ -7589,7 +7589,7 @@ yydefault:
} }
case 461: case 461:
yyDollar = yyS[yypt-4 : yypt+1] yyDollar = yyS[yypt-4 : yypt+1]
//line php7/php7.y:4928 //line php7/php7.y:4930
{ {
reference := expr.NewReference(yyDollar[4].node) reference := expr.NewReference(yyDollar[4].node)
yyVAL.node = expr.NewArrayItem(yyDollar[1].node, reference) yyVAL.node = expr.NewArrayItem(yyDollar[1].node, reference)
@ -7606,7 +7606,7 @@ yydefault:
} }
case 462: case 462:
yyDollar = yyS[yypt-2 : yypt+1] yyDollar = yyS[yypt-2 : yypt+1]
//line php7/php7.y:4943 //line php7/php7.y:4945
{ {
reference := expr.NewReference(yyDollar[2].node) reference := expr.NewReference(yyDollar[2].node)
yyVAL.node = expr.NewArrayItem(nil, reference) yyVAL.node = expr.NewArrayItem(nil, reference)
@ -7622,7 +7622,7 @@ yydefault:
} }
case 463: case 463:
yyDollar = yyS[yypt-6 : yypt+1] yyDollar = yyS[yypt-6 : yypt+1]
//line php7/php7.y:4957 //line php7/php7.y:4959
{ {
// TODO: Cannot use list() as standalone expression // TODO: Cannot use list() as standalone expression
list := expr.NewList(yyDollar[5].list) list := expr.NewList(yyDollar[5].list)
@ -7642,7 +7642,7 @@ yydefault:
} }
case 464: case 464:
yyDollar = yyS[yypt-4 : yypt+1] yyDollar = yyS[yypt-4 : yypt+1]
//line php7/php7.y:4975 //line php7/php7.y:4977
{ {
// TODO: Cannot use list() as standalone expression // TODO: Cannot use list() as standalone expression
list := expr.NewList(yyDollar[3].list) list := expr.NewList(yyDollar[3].list)
@ -7661,7 +7661,7 @@ yydefault:
} }
case 465: case 465:
yyDollar = yyS[yypt-2 : yypt+1] yyDollar = yyS[yypt-2 : yypt+1]
//line php7/php7.y:4995 //line php7/php7.y:4997
{ {
yyVAL.list = append(yyDollar[1].list, yyDollar[2].node) yyVAL.list = append(yyDollar[1].list, yyDollar[2].node)
@ -7669,7 +7669,7 @@ yydefault:
} }
case 466: case 466:
yyDollar = yyS[yypt-2 : yypt+1] yyDollar = yyS[yypt-2 : yypt+1]
//line php7/php7.y:5001 //line php7/php7.y:5003
{ {
encapsed := scalar.NewEncapsedStringPart(yyDollar[2].token.Value) encapsed := scalar.NewEncapsedStringPart(yyDollar[2].token.Value)
yyVAL.list = append(yyDollar[1].list, encapsed) yyVAL.list = append(yyDollar[1].list, encapsed)
@ -7684,7 +7684,7 @@ yydefault:
} }
case 467: case 467:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:5014 //line php7/php7.y:5016
{ {
yyVAL.list = []node.Node{yyDollar[1].node} yyVAL.list = []node.Node{yyDollar[1].node}
@ -7692,7 +7692,7 @@ yydefault:
} }
case 468: case 468:
yyDollar = yyS[yypt-2 : yypt+1] yyDollar = yyS[yypt-2 : yypt+1]
//line php7/php7.y:5020 //line php7/php7.y:5022
{ {
encapsed := scalar.NewEncapsedStringPart(yyDollar[1].token.Value) encapsed := scalar.NewEncapsedStringPart(yyDollar[1].token.Value)
yyVAL.list = []node.Node{encapsed, yyDollar[2].node} yyVAL.list = []node.Node{encapsed, yyDollar[2].node}
@ -7707,7 +7707,7 @@ yydefault:
} }
case 469: case 469:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:5036 //line php7/php7.y:5038
{ {
name := node.NewIdentifier(strings.TrimLeftFunc(yyDollar[1].token.Value, isDollar)) name := node.NewIdentifier(strings.TrimLeftFunc(yyDollar[1].token.Value, isDollar))
yyVAL.node = expr.NewVariable(name) yyVAL.node = expr.NewVariable(name)
@ -7723,7 +7723,7 @@ yydefault:
} }
case 470: case 470:
yyDollar = yyS[yypt-4 : yypt+1] yyDollar = yyS[yypt-4 : yypt+1]
//line php7/php7.y:5050 //line php7/php7.y:5052
{ {
identifier := node.NewIdentifier(strings.TrimLeftFunc(yyDollar[1].token.Value, isDollar)) identifier := node.NewIdentifier(strings.TrimLeftFunc(yyDollar[1].token.Value, isDollar))
variable := expr.NewVariable(identifier) variable := expr.NewVariable(identifier)
@ -7743,7 +7743,7 @@ yydefault:
} }
case 471: case 471:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php7/php7.y:5068 //line php7/php7.y:5070
{ {
identifier := node.NewIdentifier(strings.TrimLeftFunc(yyDollar[1].token.Value, isDollar)) identifier := node.NewIdentifier(strings.TrimLeftFunc(yyDollar[1].token.Value, isDollar))
variable := expr.NewVariable(identifier) variable := expr.NewVariable(identifier)
@ -7765,7 +7765,7 @@ yydefault:
} }
case 472: case 472:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php7/php7.y:5088 //line php7/php7.y:5090
{ {
yyVAL.node = expr.NewVariable(yyDollar[2].node) yyVAL.node = expr.NewVariable(yyDollar[2].node)
@ -7780,7 +7780,7 @@ yydefault:
} }
case 473: case 473:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php7/php7.y:5101 //line php7/php7.y:5103
{ {
name := node.NewIdentifier(yyDollar[2].token.Value) name := node.NewIdentifier(yyDollar[2].token.Value)
yyVAL.node = expr.NewVariable(name) yyVAL.node = expr.NewVariable(name)
@ -7798,7 +7798,7 @@ yydefault:
} }
case 474: case 474:
yyDollar = yyS[yypt-6 : yypt+1] yyDollar = yyS[yypt-6 : yypt+1]
//line php7/php7.y:5117 //line php7/php7.y:5119
{ {
identifier := node.NewIdentifier(yyDollar[2].token.Value) identifier := node.NewIdentifier(yyDollar[2].token.Value)
variable := expr.NewVariable(identifier) variable := expr.NewVariable(identifier)
@ -7820,7 +7820,7 @@ yydefault:
} }
case 475: case 475:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php7/php7.y:5137 //line php7/php7.y:5139
{ {
yyVAL.node = yyDollar[2].node yyVAL.node = yyDollar[2].node
@ -7828,7 +7828,7 @@ yydefault:
} }
case 476: case 476:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:5146 //line php7/php7.y:5148
{ {
yyVAL.node = scalar.NewString(yyDollar[1].token.Value) yyVAL.node = scalar.NewString(yyDollar[1].token.Value)
@ -7842,7 +7842,7 @@ yydefault:
} }
case 477: case 477:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:5158 //line php7/php7.y:5160
{ {
// TODO: add option to handle 64 bit integer // TODO: add option to handle 64 bit integer
if _, err := strconv.Atoi(yyDollar[1].token.Value); err == nil { if _, err := strconv.Atoi(yyDollar[1].token.Value); err == nil {
@ -7861,7 +7861,7 @@ yydefault:
} }
case 478: case 478:
yyDollar = yyS[yypt-2 : yypt+1] yyDollar = yyS[yypt-2 : yypt+1]
//line php7/php7.y:5175 //line php7/php7.y:5177
{ {
var lnumber *scalar.Lnumber var lnumber *scalar.Lnumber
// TODO: add option to handle 64 bit integer // TODO: add option to handle 64 bit integer
@ -7894,7 +7894,7 @@ yydefault:
} }
case 479: case 479:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:5206 //line php7/php7.y:5208
{ {
identifier := node.NewIdentifier(strings.TrimLeftFunc(yyDollar[1].token.Value, isDollar)) identifier := node.NewIdentifier(strings.TrimLeftFunc(yyDollar[1].token.Value, isDollar))
yyVAL.node = expr.NewVariable(identifier) yyVAL.node = expr.NewVariable(identifier)
@ -7910,7 +7910,7 @@ yydefault:
} }
case 480: case 480:
yyDollar = yyS[yypt-5 : yypt+1] yyDollar = yyS[yypt-5 : yypt+1]
//line php7/php7.y:5223 //line php7/php7.y:5225
{ {
yyVAL.node = expr.NewIsset(yyDollar[3].list) yyVAL.node = expr.NewIsset(yyDollar[3].list)
@ -7929,7 +7929,7 @@ yydefault:
} }
case 481: case 481:
yyDollar = yyS[yypt-4 : yypt+1] yyDollar = yyS[yypt-4 : yypt+1]
//line php7/php7.y:5240 //line php7/php7.y:5242
{ {
yyVAL.node = expr.NewEmpty(yyDollar[3].node) yyVAL.node = expr.NewEmpty(yyDollar[3].node)
@ -7945,7 +7945,7 @@ yydefault:
} }
case 482: case 482:
yyDollar = yyS[yypt-2 : yypt+1] yyDollar = yyS[yypt-2 : yypt+1]
//line php7/php7.y:5254 //line php7/php7.y:5256
{ {
yyVAL.node = expr.NewInclude(yyDollar[2].node) yyVAL.node = expr.NewInclude(yyDollar[2].node)
@ -7959,7 +7959,7 @@ yydefault:
} }
case 483: case 483:
yyDollar = yyS[yypt-2 : yypt+1] yyDollar = yyS[yypt-2 : yypt+1]
//line php7/php7.y:5266 //line php7/php7.y:5268
{ {
yyVAL.node = expr.NewIncludeOnce(yyDollar[2].node) yyVAL.node = expr.NewIncludeOnce(yyDollar[2].node)
@ -7973,7 +7973,7 @@ yydefault:
} }
case 484: case 484:
yyDollar = yyS[yypt-4 : yypt+1] yyDollar = yyS[yypt-4 : yypt+1]
//line php7/php7.y:5278 //line php7/php7.y:5280
{ {
yyVAL.node = expr.NewEval(yyDollar[3].node) yyVAL.node = expr.NewEval(yyDollar[3].node)
@ -7989,7 +7989,7 @@ yydefault:
} }
case 485: case 485:
yyDollar = yyS[yypt-2 : yypt+1] yyDollar = yyS[yypt-2 : yypt+1]
//line php7/php7.y:5292 //line php7/php7.y:5294
{ {
yyVAL.node = expr.NewRequire(yyDollar[2].node) yyVAL.node = expr.NewRequire(yyDollar[2].node)
@ -8003,7 +8003,7 @@ yydefault:
} }
case 486: case 486:
yyDollar = yyS[yypt-2 : yypt+1] yyDollar = yyS[yypt-2 : yypt+1]
//line php7/php7.y:5304 //line php7/php7.y:5306
{ {
yyVAL.node = expr.NewRequireOnce(yyDollar[2].node) yyVAL.node = expr.NewRequireOnce(yyDollar[2].node)
@ -8017,7 +8017,7 @@ yydefault:
} }
case 487: case 487:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:5319 //line php7/php7.y:5321
{ {
yyVAL.list = []node.Node{yyDollar[1].node} yyVAL.list = []node.Node{yyDollar[1].node}
@ -8025,7 +8025,7 @@ yydefault:
} }
case 488: case 488:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php7/php7.y:5325 //line php7/php7.y:5327
{ {
yyVAL.list = append(yyDollar[1].list, yyDollar[3].node) yyVAL.list = append(yyDollar[1].list, yyDollar[3].node)
@ -8036,7 +8036,7 @@ yydefault:
} }
case 489: case 489:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:5337 //line php7/php7.y:5339
{ {
yyVAL.node = yyDollar[1].node yyVAL.node = yyDollar[1].node

View File

@ -4859,8 +4859,8 @@ property_name:
array_pair_list: array_pair_list:
non_empty_array_pair_list non_empty_array_pair_list
{ {
if ($1[len($1)-1] == nil) { if (len($1) == 1 && $1[0] == nil) {
$$ = $1[:len($1)-1] $$ = $1[:0]
} else { } else {
$$ = $1 $$ = $1
} }
@ -4890,7 +4890,9 @@ non_empty_array_pair_list:
$$ = append($1, $3) $$ = append($1, $3)
// save comments // save comments
if $3 != nil {$3.AddComments($2.Comments, comment.CommaToken)} if lastNode($1) != nil {
lastNode($1).AddComments($2.Comments, comment.CommaToken)
}
yylex.(*Parser).returnTokenToPool(yyDollar, &yyVAL) yylex.(*Parser).returnTokenToPool(yyDollar, &yyVAL)
} }

View File

@ -9034,6 +9034,7 @@ func TestPhp7(t *testing.T) {
}, },
}, },
}, },
nil,
}, },
}, },
}, },
@ -11168,6 +11169,7 @@ func TestPhp7(t *testing.T) {
}, },
}, },
}, },
nil,
}, },
}, },
}, },