diff --git a/internal/php5/node.go b/internal/php5/node.go deleted file mode 100644 index e0963fa..0000000 --- a/internal/php5/node.go +++ /dev/null @@ -1,85 +0,0 @@ -package php5 - -import ( - "github.com/VKCOM/php-parser/pkg/ast" - "github.com/VKCOM/php-parser/pkg/position" - "github.com/VKCOM/php-parser/pkg/token" -) - -type ParserBrackets struct { - Position *position.Position - OpenBracketTkn *token.Token - Child ast.Vertex - CloseBracketTkn *token.Token -} - -func (n *ParserBrackets) Accept(v ast.Visitor) { - // do nothing -} - -func (n *ParserBrackets) GetPosition() *position.Position { - return n.Position -} - -type ParserSeparatedList struct { - Position *position.Position - Items []ast.Vertex - SeparatorTkns []*token.Token -} - -func (n *ParserSeparatedList) Accept(v ast.Visitor) { - // do nothing -} - -func (n *ParserSeparatedList) GetPosition() *position.Position { - return n.Position -} - -// TraitAdaptationList node -type TraitAdaptationList struct { - Position *position.Position - OpenCurlyBracketTkn *token.Token - Adaptations []ast.Vertex - CloseCurlyBracketTkn *token.Token -} - -func (n *TraitAdaptationList) Accept(v ast.Visitor) { - // do nothing -} - -func (n *TraitAdaptationList) GetPosition() *position.Position { - return n.Position -} - -// ArgumentList node -type ArgumentList struct { - Position *position.Position - OpenParenthesisTkn *token.Token - Arguments []ast.Vertex - SeparatorTkns []*token.Token - CloseParenthesisTkn *token.Token -} - -func (n *ArgumentList) Accept(v ast.Visitor) { - // do nothing -} - -func (n *ArgumentList) GetPosition() *position.Position { - return n.Position -} - -// TraitMethodRef node -type TraitMethodRef struct { - Position *position.Position - Trait ast.Vertex - DoubleColonTkn *token.Token - Method ast.Vertex -} - -func (n *TraitMethodRef) Accept(v ast.Visitor) { - // do nothing -} - -func (n *TraitMethodRef) GetPosition() *position.Position { - return n.Position -} diff --git a/internal/php5/parser.go b/internal/php5/parser.go deleted file mode 100644 index 8fd6578..0000000 --- a/internal/php5/parser.go +++ /dev/null @@ -1,66 +0,0 @@ -package php5 - -import ( - "github.com/VKCOM/php-parser/internal/position" - "github.com/VKCOM/php-parser/internal/scanner" - "github.com/VKCOM/php-parser/pkg/ast" - "github.com/VKCOM/php-parser/pkg/conf" - "github.com/VKCOM/php-parser/pkg/errors" - "github.com/VKCOM/php-parser/pkg/token" -) - -// Parser structure -type Parser struct { - Lexer *scanner.Lexer - currentToken *token.Token - rootNode ast.Vertex - errHandlerFunc func(*errors.Error) - builder *position.Builder -} - -// NewParser creates and returns new Parser -func NewParser(lexer *scanner.Lexer, config conf.Config) *Parser { - return &Parser{ - Lexer: lexer, - errHandlerFunc: config.ErrorHandlerFunc, - builder: position.NewBuilder(), - } -} - -// Lex proxy to scanner Lex -func (p *Parser) Lex(lval *yySymType) int { - t := p.Lexer.Lex() - - p.currentToken = t - lval.token = t - - return int(t.ID) -} - -func (p *Parser) Error(msg string) { - if p.errHandlerFunc == nil { - return - } - - p.errHandlerFunc(errors.NewError(msg, p.currentToken.Position)) -} - -// Parse the php7 Parser entrypoint -func (p *Parser) Parse() int { - p.rootNode = nil - return yyParse(p) -} - -// GetRootNode returns root node -func (p *Parser) GetRootNode() ast.Vertex { - return p.rootNode -} - -// helpers - -func lastNode(nn []ast.Vertex) ast.Vertex { - if len(nn) == 0 { - return nil - } - return nn[len(nn)-1] -} diff --git a/internal/php5/parser_test.go b/internal/php5/parser_test.go deleted file mode 100644 index dbab6a2..0000000 --- a/internal/php5/parser_test.go +++ /dev/null @@ -1,50781 +0,0 @@ -package php5_test - -import ( - "testing" - - "gotest.tools/assert" - - "github.com/VKCOM/php-parser/internal/php5" - "github.com/VKCOM/php-parser/internal/scanner" - "github.com/VKCOM/php-parser/pkg/ast" - "github.com/VKCOM/php-parser/pkg/conf" - "github.com/VKCOM/php-parser/pkg/errors" - "github.com/VKCOM/php-parser/pkg/position" - "github.com/VKCOM/php-parser/pkg/token" - "github.com/VKCOM/php-parser/pkg/version" -) - -func TestIdentifier(t *testing.T) { - src := `bar($a, ...$b); - foo::bar($a, ...$b); - $foo::bar($a, ...$b); - new foo($a, ...$b);` - - expected := &ast.Root{ - Position: &position.Position{ - StartLine: 2, - EndLine: 7, - StartPos: 5, - EndPos: 132, - }, - Stmts: []ast.Vertex{ - &ast.StmtExpression{ - Position: &position.Position{ - StartLine: 2, - EndLine: 2, - StartPos: 5, - EndPos: 20, - }, - Expr: &ast.ExprFunctionCall{ - Position: &position.Position{ - StartLine: 2, - EndLine: 2, - StartPos: 5, - EndPos: 19, - }, - Function: &ast.Name{ - Position: &position.Position{ - StartLine: 2, - EndLine: 2, - StartPos: 5, - EndPos: 8, - }, - Parts: []ast.Vertex{ - &ast.NamePart{ - Position: &position.Position{ - StartLine: 2, - EndLine: 2, - StartPos: 5, - EndPos: 8, - }, - StringTkn: &token.Token{ - ID: token.T_STRING, - Value: []byte("foo"), - Position: &position.Position{ - StartLine: 2, - EndLine: 2, - StartPos: 5, - EndPos: 8, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_OPEN_TAG, - Value: []byte(""), - Position: &position.Position{ - StartLine: 4, - EndLine: 4, - StartPos: 46, - EndPos: 48, - }, - }, - Method: &ast.Identifier{ - Position: &position.Position{ - StartLine: 4, - EndLine: 4, - StartPos: 48, - EndPos: 51, - }, - IdentifierTkn: &token.Token{ - ID: token.T_STRING, - Value: []byte("bar"), - Position: &position.Position{ - StartLine: 4, - EndLine: 4, - StartPos: 48, - EndPos: 51, - }, - }, - Value: []byte("bar"), - }, - OpenParenthesisTkn: &token.Token{ - ID: token.ID(40), - Value: []byte("("), - Position: &position.Position{ - StartLine: 4, - EndLine: 4, - StartPos: 51, - EndPos: 52, - }, - }, - Args: []ast.Vertex{ - &ast.Argument{ - Position: &position.Position{ - StartLine: 4, - EndLine: 4, - StartPos: 52, - EndPos: 54, - }, - Expr: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 4, - EndLine: 4, - StartPos: 52, - EndPos: 54, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 4, - EndLine: 4, - StartPos: 52, - EndPos: 54, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$a"), - Position: &position.Position{ - StartLine: 4, - EndLine: 4, - StartPos: 52, - EndPos: 54, - }, - }, - Value: []byte("$a"), - }, - }, - }, - &ast.Argument{ - Position: &position.Position{ - StartLine: 4, - EndLine: 4, - StartPos: 56, - EndPos: 61, - }, - VariadicTkn: &token.Token{ - ID: token.T_ELLIPSIS, - Value: []byte("..."), - Position: &position.Position{ - StartLine: 4, - EndLine: 4, - StartPos: 56, - EndPos: 59, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 4, - EndLine: 4, - StartPos: 55, - EndPos: 56, - }, - }, - }, - }, - Expr: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 4, - EndLine: 4, - StartPos: 59, - EndPos: 61, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 4, - EndLine: 4, - StartPos: 59, - EndPos: 61, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$b"), - Position: &position.Position{ - StartLine: 4, - EndLine: 4, - StartPos: 59, - EndPos: 61, - }, - }, - Value: []byte("$b"), - }, - }, - }, - }, - SeparatorTkns: []*token.Token{ - { - ID: token.ID(44), - Value: []byte(","), - Position: &position.Position{ - StartLine: 4, - EndLine: 4, - StartPos: 54, - EndPos: 55, - }, - }, - }, - CloseParenthesisTkn: &token.Token{ - ID: token.ID(41), - Value: []byte(")"), - Position: &position.Position{ - StartLine: 4, - EndLine: 4, - StartPos: 61, - EndPos: 62, - }, - }, - }, - SemiColonTkn: &token.Token{ - ID: token.ID(59), - Value: []byte(";"), - Position: &position.Position{ - StartLine: 4, - EndLine: 4, - StartPos: 62, - EndPos: 63, - }, - }, - }, - &ast.StmtExpression{ - Position: &position.Position{ - StartLine: 5, - EndLine: 5, - StartPos: 66, - EndPos: 86, - }, - Expr: &ast.ExprStaticCall{ - Position: &position.Position{ - StartLine: 5, - EndLine: 5, - StartPos: 66, - EndPos: 85, - }, - Class: &ast.Name{ - Position: &position.Position{ - StartLine: 5, - EndLine: 5, - StartPos: 66, - EndPos: 69, - }, - Parts: []ast.Vertex{ - &ast.NamePart{ - Position: &position.Position{ - StartLine: 5, - EndLine: 5, - StartPos: 66, - EndPos: 69, - }, - StringTkn: &token.Token{ - ID: token.T_STRING, - Value: []byte("foo"), - Position: &position.Position{ - StartLine: 5, - EndLine: 5, - StartPos: 66, - EndPos: 69, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte("\n\t\t"), - Position: &position.Position{ - StartLine: 4, - EndLine: 5, - StartPos: 63, - EndPos: 66, - }, - }, - }, - }, - Value: []byte("foo"), - }, - }, - }, - DoubleColonTkn: &token.Token{ - ID: token.T_PAAMAYIM_NEKUDOTAYIM, - Value: []byte("::"), - Position: &position.Position{ - StartLine: 5, - EndLine: 5, - StartPos: 69, - EndPos: 71, - }, - }, - Call: &ast.Identifier{ - Position: &position.Position{ - StartLine: 5, - EndLine: 5, - StartPos: 71, - EndPos: 74, - }, - IdentifierTkn: &token.Token{ - ID: token.T_STRING, - Value: []byte("bar"), - Position: &position.Position{ - StartLine: 5, - EndLine: 5, - StartPos: 71, - EndPos: 74, - }, - }, - Value: []byte("bar"), - }, - OpenParenthesisTkn: &token.Token{ - ID: token.ID(40), - Value: []byte("("), - Position: &position.Position{ - StartLine: 5, - EndLine: 5, - StartPos: 74, - EndPos: 75, - }, - }, - Args: []ast.Vertex{ - &ast.Argument{ - Position: &position.Position{ - StartLine: 5, - EndLine: 5, - StartPos: 75, - EndPos: 77, - }, - Expr: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 5, - EndLine: 5, - StartPos: 75, - EndPos: 77, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 5, - EndLine: 5, - StartPos: 75, - EndPos: 77, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$a"), - Position: &position.Position{ - StartLine: 5, - EndLine: 5, - StartPos: 75, - EndPos: 77, - }, - }, - Value: []byte("$a"), - }, - }, - }, - &ast.Argument{ - Position: &position.Position{ - StartLine: 5, - EndLine: 5, - StartPos: 79, - EndPos: 84, - }, - VariadicTkn: &token.Token{ - ID: token.T_ELLIPSIS, - Value: []byte("..."), - Position: &position.Position{ - StartLine: 5, - EndLine: 5, - StartPos: 79, - EndPos: 82, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 5, - EndLine: 5, - StartPos: 78, - EndPos: 79, - }, - }, - }, - }, - Expr: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 5, - EndLine: 5, - StartPos: 82, - EndPos: 84, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 5, - EndLine: 5, - StartPos: 82, - EndPos: 84, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$b"), - Position: &position.Position{ - StartLine: 5, - EndLine: 5, - StartPos: 82, - EndPos: 84, - }, - }, - Value: []byte("$b"), - }, - }, - }, - }, - SeparatorTkns: []*token.Token{ - { - ID: token.ID(44), - Value: []byte(","), - Position: &position.Position{ - StartLine: 5, - EndLine: 5, - StartPos: 77, - EndPos: 78, - }, - }, - }, - CloseParenthesisTkn: &token.Token{ - ID: token.ID(41), - Value: []byte(")"), - Position: &position.Position{ - StartLine: 5, - EndLine: 5, - StartPos: 84, - EndPos: 85, - }, - }, - }, - SemiColonTkn: &token.Token{ - ID: token.ID(59), - Value: []byte(";"), - Position: &position.Position{ - StartLine: 5, - EndLine: 5, - StartPos: 85, - EndPos: 86, - }, - }, - }, - &ast.StmtExpression{ - Position: &position.Position{ - StartLine: 6, - EndLine: 6, - StartPos: 89, - EndPos: 110, - }, - Expr: &ast.ExprStaticCall{ - Position: &position.Position{ - StartLine: 6, - EndLine: 6, - StartPos: 89, - EndPos: 109, - }, - Class: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 6, - EndLine: 6, - StartPos: 89, - EndPos: 93, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 6, - EndLine: 6, - StartPos: 89, - EndPos: 93, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$foo"), - Position: &position.Position{ - StartLine: 6, - EndLine: 6, - StartPos: 89, - EndPos: 93, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte("\n\t\t"), - Position: &position.Position{ - StartLine: 5, - EndLine: 6, - StartPos: 86, - EndPos: 89, - }, - }, - }, - }, - Value: []byte("$foo"), - }, - }, - DoubleColonTkn: &token.Token{ - ID: token.T_PAAMAYIM_NEKUDOTAYIM, - Value: []byte("::"), - Position: &position.Position{ - StartLine: 6, - EndLine: 6, - StartPos: 93, - EndPos: 95, - }, - }, - Call: &ast.Identifier{ - Position: &position.Position{ - StartLine: 6, - EndLine: 6, - StartPos: 95, - EndPos: 98, - }, - IdentifierTkn: &token.Token{ - ID: token.T_STRING, - Value: []byte("bar"), - Position: &position.Position{ - StartLine: 6, - EndLine: 6, - StartPos: 95, - EndPos: 98, - }, - }, - Value: []byte("bar"), - }, - OpenParenthesisTkn: &token.Token{ - ID: token.ID(40), - Value: []byte("("), - Position: &position.Position{ - StartLine: 6, - EndLine: 6, - StartPos: 98, - EndPos: 99, - }, - }, - Args: []ast.Vertex{ - &ast.Argument{ - Position: &position.Position{ - StartLine: 6, - EndLine: 6, - StartPos: 99, - EndPos: 101, - }, - Expr: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 6, - EndLine: 6, - StartPos: 99, - EndPos: 101, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 6, - EndLine: 6, - StartPos: 99, - EndPos: 101, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$a"), - Position: &position.Position{ - StartLine: 6, - EndLine: 6, - StartPos: 99, - EndPos: 101, - }, - }, - Value: []byte("$a"), - }, - }, - }, - &ast.Argument{ - Position: &position.Position{ - StartLine: 6, - EndLine: 6, - StartPos: 103, - EndPos: 108, - }, - VariadicTkn: &token.Token{ - ID: token.T_ELLIPSIS, - Value: []byte("..."), - Position: &position.Position{ - StartLine: 6, - EndLine: 6, - StartPos: 103, - EndPos: 106, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 6, - EndLine: 6, - StartPos: 102, - EndPos: 103, - }, - }, - }, - }, - Expr: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 6, - EndLine: 6, - StartPos: 106, - EndPos: 108, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 6, - EndLine: 6, - StartPos: 106, - EndPos: 108, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$b"), - Position: &position.Position{ - StartLine: 6, - EndLine: 6, - StartPos: 106, - EndPos: 108, - }, - }, - Value: []byte("$b"), - }, - }, - }, - }, - SeparatorTkns: []*token.Token{ - { - ID: token.ID(44), - Value: []byte(","), - Position: &position.Position{ - StartLine: 6, - EndLine: 6, - StartPos: 101, - EndPos: 102, - }, - }, - }, - CloseParenthesisTkn: &token.Token{ - ID: token.ID(41), - Value: []byte(")"), - Position: &position.Position{ - StartLine: 6, - EndLine: 6, - StartPos: 108, - EndPos: 109, - }, - }, - }, - SemiColonTkn: &token.Token{ - ID: token.ID(59), - Value: []byte(";"), - Position: &position.Position{ - StartLine: 6, - EndLine: 6, - StartPos: 109, - EndPos: 110, - }, - }, - }, - &ast.StmtExpression{ - Position: &position.Position{ - StartLine: 7, - EndLine: 7, - StartPos: 113, - EndPos: 132, - }, - Expr: &ast.ExprNew{ - Position: &position.Position{ - StartLine: 7, - EndLine: 7, - StartPos: 113, - EndPos: 131, - }, - NewTkn: &token.Token{ - ID: token.T_NEW, - Value: []byte("new"), - Position: &position.Position{ - StartLine: 7, - EndLine: 7, - StartPos: 113, - EndPos: 116, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte("\n\t\t"), - Position: &position.Position{ - StartLine: 6, - EndLine: 7, - StartPos: 110, - EndPos: 113, - }, - }, - }, - }, - Class: &ast.Name{ - Position: &position.Position{ - StartLine: 7, - EndLine: 7, - StartPos: 117, - EndPos: 120, - }, - Parts: []ast.Vertex{ - &ast.NamePart{ - Position: &position.Position{ - StartLine: 7, - EndLine: 7, - StartPos: 117, - EndPos: 120, - }, - StringTkn: &token.Token{ - ID: token.T_STRING, - Value: []byte("foo"), - Position: &position.Position{ - StartLine: 7, - EndLine: 7, - StartPos: 117, - EndPos: 120, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 7, - EndLine: 7, - StartPos: 116, - EndPos: 117, - }, - }, - }, - }, - Value: []byte("foo"), - }, - }, - }, - OpenParenthesisTkn: &token.Token{ - ID: token.ID(40), - Value: []byte("("), - Position: &position.Position{ - StartLine: 7, - EndLine: 7, - StartPos: 120, - EndPos: 121, - }, - }, - Args: []ast.Vertex{ - &ast.Argument{ - Position: &position.Position{ - StartLine: 7, - EndLine: 7, - StartPos: 121, - EndPos: 123, - }, - Expr: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 7, - EndLine: 7, - StartPos: 121, - EndPos: 123, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 7, - EndLine: 7, - StartPos: 121, - EndPos: 123, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$a"), - Position: &position.Position{ - StartLine: 7, - EndLine: 7, - StartPos: 121, - EndPos: 123, - }, - }, - Value: []byte("$a"), - }, - }, - }, - &ast.Argument{ - Position: &position.Position{ - StartLine: 7, - EndLine: 7, - StartPos: 125, - EndPos: 130, - }, - VariadicTkn: &token.Token{ - ID: token.T_ELLIPSIS, - Value: []byte("..."), - Position: &position.Position{ - StartLine: 7, - EndLine: 7, - StartPos: 125, - EndPos: 128, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 7, - EndLine: 7, - StartPos: 124, - EndPos: 125, - }, - }, - }, - }, - Expr: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 7, - EndLine: 7, - StartPos: 128, - EndPos: 130, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 7, - EndLine: 7, - StartPos: 128, - EndPos: 130, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$b"), - Position: &position.Position{ - StartLine: 7, - EndLine: 7, - StartPos: 128, - EndPos: 130, - }, - }, - Value: []byte("$b"), - }, - }, - }, - }, - SeparatorTkns: []*token.Token{ - { - ID: token.ID(44), - Value: []byte(","), - Position: &position.Position{ - StartLine: 7, - EndLine: 7, - StartPos: 123, - EndPos: 124, - }, - }, - }, - CloseParenthesisTkn: &token.Token{ - ID: token.ID(41), - Value: []byte(")"), - Position: &position.Position{ - StartLine: 7, - EndLine: 7, - StartPos: 130, - EndPos: 131, - }, - }, - }, - SemiColonTkn: &token.Token{ - ID: token.ID(59), - Value: []byte(";"), - Position: &position.Position{ - StartLine: 7, - EndLine: 7, - StartPos: 131, - EndPos: 132, - }, - }, - }, - }, - EndTkn: &token.Token{}, - } - - config := conf.Config{ - Version: &version.Version{ - Major: 5, - Minor: 6, - }, - } - lexer := scanner.NewLexer([]byte(src), config) - php5parser := php5.NewParser(lexer, config) - php5parser.Parse() - actual := php5parser.GetRootNode() - assert.DeepEqual(t, expected, actual) -} - -func TestPhp5ParameterNode(t *testing.T) { - src := `bar()";` - - expected := &ast.Root{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 22, - }, - Stmts: []ast.Vertex{ - &ast.StmtExpression{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 22, - }, - Expr: &ast.ScalarEncapsed{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 21, - }, - OpenQuoteTkn: &token.Token{ - ID: token.ID(34), - Value: []byte("\""), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 4, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_OPEN_TAG, - Value: []byte(""), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 13, - EndPos: 15, - }, - }, - Prop: &ast.Identifier{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 15, - EndPos: 18, - }, - IdentifierTkn: &token.Token{ - ID: token.T_STRING, - Value: []byte("bar"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 15, - EndPos: 18, - }, - }, - Value: []byte("bar"), - }, - }, - &ast.ScalarEncapsedStringPart{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 18, - EndPos: 20, - }, - EncapsedStrTkn: &token.Token{ - ID: token.T_ENCAPSED_AND_WHITESPACE, - Value: []byte("()"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 18, - EndPos: 20, - }, - }, - Value: []byte("()"), - }, - }, - CloseQuoteTkn: &token.Token{ - ID: token.ID(34), - Value: []byte("\""), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 20, - EndPos: 21, - }, - }, - }, - SemiColonTkn: &token.Token{ - ID: token.ID(59), - Value: []byte(";"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 21, - EndPos: 22, - }, - }, - }, - }, - EndTkn: &token.Token{}, - } - - config := conf.Config{ - Version: &version.Version{ - Major: 5, - Minor: 6, - }, - } - lexer := scanner.NewLexer([]byte(src), config) - php5parser := php5.NewParser(lexer, config) - php5parser.Parse() - actual := php5parser.GetRootNode() - assert.DeepEqual(t, expected, actual) -} - -func TestScalarEncapsed_DollarOpenCurlyBraces(t *testing.T) { - src := `bar()}";` - - expected := &ast.Root{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 24, - }, - Stmts: []ast.Vertex{ - &ast.StmtExpression{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 24, - }, - Expr: &ast.ScalarEncapsed{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 23, - }, - OpenQuoteTkn: &token.Token{ - ID: token.ID(34), - Value: []byte("\""), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 4, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_OPEN_TAG, - Value: []byte(""), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 14, - EndPos: 16, - }, - }, - Method: &ast.Identifier{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 16, - EndPos: 19, - }, - IdentifierTkn: &token.Token{ - ID: token.T_STRING, - Value: []byte("bar"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 16, - EndPos: 19, - }, - }, - Value: []byte("bar"), - }, - OpenParenthesisTkn: &token.Token{ - ID: token.ID(40), - Value: []byte("("), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 19, - EndPos: 20, - }, - }, - CloseParenthesisTkn: &token.Token{ - ID: token.ID(41), - Value: []byte(")"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 20, - EndPos: 21, - }, - }, - }, - CloseCurlyBracketTkn: &token.Token{ - ID: token.ID(125), - Value: []byte("}"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 21, - EndPos: 22, - }, - }, - }, - }, - CloseQuoteTkn: &token.Token{ - ID: token.ID(34), - Value: []byte("\""), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 22, - EndPos: 23, - }, - }, - }, - SemiColonTkn: &token.Token{ - ID: token.ID(59), - Value: []byte(";"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 23, - EndPos: 24, - }, - }, - }, - }, - EndTkn: &token.Token{}, - } - - config := conf.Config{ - Version: &version.Version{ - Major: 5, - Minor: 6, - }, - } - lexer := scanner.NewLexer([]byte(src), config) - php5parser := php5.NewParser(lexer, config) - php5parser.Parse() - actual := php5parser.GetRootNode() - assert.DeepEqual(t, expected, actual) -} - -func TestScalarHeredoc_HeredocSimpleLabel(t *testing.T) { - src := ` $v) {}` - - expected := &ast.Root{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 30, - }, - Stmts: []ast.Vertex{ - &ast.StmtForeach{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 30, - }, - ForeachTkn: &token.Token{ - ID: token.T_FOREACH, - Value: []byte("foreach"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 10, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_OPEN_TAG, - Value: []byte(""), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 21, - EndPos: 23, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 20, - EndPos: 21, - }, - }, - }, - }, - Var: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 24, - EndPos: 26, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 24, - EndPos: 26, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$v"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 24, - EndPos: 26, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 23, - EndPos: 24, - }, - }, - }, - }, - Value: []byte("$v"), - }, - }, - CloseParenthesisTkn: &token.Token{ - ID: token.ID(41), - Value: []byte(")"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 26, - EndPos: 27, - }, - }, - Stmt: &ast.StmtStmtList{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 28, - EndPos: 30, - }, - OpenCurlyBracketTkn: &token.Token{ - ID: token.ID(123), - Value: []byte("{"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 28, - EndPos: 29, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 27, - EndPos: 28, - }, - }, - }, - }, - Stmts: []ast.Vertex{}, - CloseCurlyBracketTkn: &token.Token{ - ID: token.ID(125), - Value: []byte("}"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 29, - EndPos: 30, - }, - }, - }, - }, - }, - EndTkn: &token.Token{}, - } - - config := conf.Config{ - Version: &version.Version{ - Major: 5, - Minor: 6, - }, - } - lexer := scanner.NewLexer([]byte(src), config) - php5parser := php5.NewParser(lexer, config) - php5parser.Parse() - actual := php5parser.GetRootNode() - assert.DeepEqual(t, expected, actual) -} - -func TestStmtForeach_ExprWithKey(t *testing.T) { - src := ` $v) {}` - - expected := &ast.Root{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 30, - }, - Stmts: []ast.Vertex{ - &ast.StmtForeach{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 30, - }, - ForeachTkn: &token.Token{ - ID: token.T_FOREACH, - Value: []byte("foreach"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 10, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_OPEN_TAG, - Value: []byte(""), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 21, - EndPos: 23, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 20, - EndPos: 21, - }, - }, - }, - }, - Var: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 24, - EndPos: 26, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 24, - EndPos: 26, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$v"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 24, - EndPos: 26, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 23, - EndPos: 24, - }, - }, - }, - }, - Value: []byte("$v"), - }, - }, - CloseParenthesisTkn: &token.Token{ - ID: token.ID(41), - Value: []byte(")"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 26, - EndPos: 27, - }, - }, - Stmt: &ast.StmtStmtList{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 28, - EndPos: 30, - }, - OpenCurlyBracketTkn: &token.Token{ - ID: token.ID(123), - Value: []byte("{"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 28, - EndPos: 29, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 27, - EndPos: 28, - }, - }, - }, - }, - Stmts: []ast.Vertex{}, - CloseCurlyBracketTkn: &token.Token{ - ID: token.ID(125), - Value: []byte("}"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 29, - EndPos: 30, - }, - }, - }, - }, - }, - EndTkn: &token.Token{}, - } - - config := conf.Config{ - Version: &version.Version{ - Major: 5, - Minor: 6, - }, - } - lexer := scanner.NewLexer([]byte(src), config) - php5parser := php5.NewParser(lexer, config) - php5parser.Parse() - actual := php5parser.GetRootNode() - assert.DeepEqual(t, expected, actual) -} - -func TestStmtForeach_WithRef(t *testing.T) { - src := ` &$v) {}` - - expected := &ast.Root{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 31, - }, - Stmts: []ast.Vertex{ - &ast.StmtForeach{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 31, - }, - ForeachTkn: &token.Token{ - ID: token.T_FOREACH, - Value: []byte("foreach"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 10, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_OPEN_TAG, - Value: []byte(""), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 21, - EndPos: 23, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 20, - EndPos: 21, - }, - }, - }, - }, - AmpersandTkn: &token.Token{ - ID: token.ID(38), - Value: []byte("&"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 24, - EndPos: 25, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 23, - EndPos: 24, - }, - }, - }, - }, - Var: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 25, - EndPos: 27, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 25, - EndPos: 27, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$v"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 25, - EndPos: 27, - }, - }, - Value: []byte("$v"), - }, - }, - CloseParenthesisTkn: &token.Token{ - ID: token.ID(41), - Value: []byte(")"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 27, - EndPos: 28, - }, - }, - Stmt: &ast.StmtStmtList{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 29, - EndPos: 31, - }, - OpenCurlyBracketTkn: &token.Token{ - ID: token.ID(123), - Value: []byte("{"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 29, - EndPos: 30, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 28, - EndPos: 29, - }, - }, - }, - }, - Stmts: []ast.Vertex{}, - CloseCurlyBracketTkn: &token.Token{ - ID: token.ID(125), - Value: []byte("}"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 30, - EndPos: 31, - }, - }, - }, - }, - }, - EndTkn: &token.Token{}, - } - - config := conf.Config{ - Version: &version.Version{ - Major: 5, - Minor: 6, - }, - } - lexer := scanner.NewLexer([]byte(src), config) - php5parser := php5.NewParser(lexer, config) - php5parser.Parse() - actual := php5parser.GetRootNode() - assert.DeepEqual(t, expected, actual) -} - -func TestStmtForeach_WithList(t *testing.T) { - src := ` list($v)) {}` - - expected := &ast.Root{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 36, - }, - Stmts: []ast.Vertex{ - &ast.StmtForeach{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 36, - }, - ForeachTkn: &token.Token{ - ID: token.T_FOREACH, - Value: []byte("foreach"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 10, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_OPEN_TAG, - Value: []byte(""), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 21, - EndPos: 23, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 20, - EndPos: 21, - }, - }, - }, - }, - Var: &ast.ExprList{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 24, - EndPos: 32, - }, - ListTkn: &token.Token{ - ID: token.T_LIST, - Value: []byte("list"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 24, - EndPos: 28, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 23, - EndPos: 24, - }, - }, - }, - }, - OpenBracketTkn: &token.Token{ - ID: token.ID(40), - Value: []byte("("), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 28, - EndPos: 29, - }, - }, - Items: []ast.Vertex{ - &ast.ExprArrayItem{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 29, - EndPos: 31, - }, - Val: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 29, - EndPos: 31, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 29, - EndPos: 31, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$v"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 29, - EndPos: 31, - }, - }, - Value: []byte("$v"), - }, - }, - }, - }, - CloseBracketTkn: &token.Token{ - ID: token.ID(41), - Value: []byte(")"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 31, - EndPos: 32, - }, - }, - }, - CloseParenthesisTkn: &token.Token{ - ID: token.ID(41), - Value: []byte(")"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 32, - EndPos: 33, - }, - }, - Stmt: &ast.StmtStmtList{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 34, - EndPos: 36, - }, - OpenCurlyBracketTkn: &token.Token{ - ID: token.ID(123), - Value: []byte("{"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 34, - EndPos: 35, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 33, - EndPos: 34, - }, - }, - }, - }, - Stmts: []ast.Vertex{}, - CloseCurlyBracketTkn: &token.Token{ - ID: token.ID(125), - Value: []byte("}"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 35, - EndPos: 36, - }, - }, - }, - }, - }, - EndTkn: &token.Token{}, - } - - config := conf.Config{ - Version: &version.Version{ - Major: 5, - Minor: 6, - }, - } - lexer := scanner.NewLexer([]byte(src), config) - php5parser := php5.NewParser(lexer, config) - php5parser.Parse() - actual := php5parser.GetRootNode() - assert.DeepEqual(t, expected, actual) -} - -func TestStmtFunction(t *testing.T) { - src := `
` - - expected := &ast.Root{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 17, - }, - Stmts: []ast.Vertex{ - &ast.StmtNop{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 5, - }, - SemiColonTkn: &token.Token{ - ID: token.ID(59), - Value: []byte("?>"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 5, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_OPEN_TAG, - Value: []byte(""), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 5, - EndPos: 17, - }, - }, - Value: []byte("
"), - }, - }, - EndTkn: &token.Token{}, - } - - config := conf.Config{ - Version: &version.Version{ - Major: 5, - Minor: 6, - }, - } - lexer := scanner.NewLexer([]byte(src), config) - php5parser := php5.NewParser(lexer, config) - php5parser.Parse() - actual := php5parser.GetRootNode() - assert.DeepEqual(t, expected, actual) -} - -func TestStmtInterface(t *testing.T) { - src := `1, &$b,);` - - expected := &ast.Root{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 21, - }, - Stmts: []ast.Vertex{ - &ast.StmtExpression{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 21, - }, - Expr: &ast.ExprArray{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 20, - }, - ArrayTkn: &token.Token{ - ID: token.T_ARRAY, - Value: []byte("array"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 8, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_OPEN_TAG, - Value: []byte(""), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 10, - EndPos: 12, - }, - }, - Val: &ast.ScalarLnumber{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 12, - EndPos: 13, - }, - NumberTkn: &token.Token{ - ID: token.T_LNUMBER, - Value: []byte("1"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 12, - EndPos: 13, - }, - }, - Value: []byte("1"), - }, - }, - &ast.ExprArrayItem{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 15, - EndPos: 18, - }, - AmpersandTkn: &token.Token{ - ID: token.ID(38), - Value: []byte("&"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 15, - EndPos: 16, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 14, - EndPos: 15, - }, - }, - }, - }, - Val: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 16, - EndPos: 18, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 16, - EndPos: 18, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$b"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 16, - EndPos: 18, - }, - }, - Value: []byte("$b"), - }, - }, - }, - &ast.ExprArrayItem{}, - }, - SeparatorTkns: []*token.Token{ - { - ID: token.ID(44), - Value: []byte(","), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 13, - EndPos: 14, - }, - }, - { - ID: token.ID(44), - Value: []byte(","), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 18, - EndPos: 19, - }, - }, - }, - CloseBracketTkn: &token.Token{ - ID: token.ID(41), - Value: []byte(")"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 19, - EndPos: 20, - }, - }, - }, - SemiColonTkn: &token.Token{ - ID: token.ID(59), - Value: []byte(";"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 20, - EndPos: 21, - }, - }, - }, - }, - EndTkn: &token.Token{}, - } - - config := conf.Config{ - Version: &version.Version{ - Major: 5, - Minor: 6, - }, - } - lexer := scanner.NewLexer([]byte(src), config) - php5parser := php5.NewParser(lexer, config) - php5parser.Parse() - actual := php5parser.GetRootNode() - assert.DeepEqual(t, expected, actual) -} - -func TestExprBitwiseNot(t *testing.T) { - src := `foo();` - - expected := &ast.Root{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 13, - }, - Stmts: []ast.Vertex{ - &ast.StmtExpression{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 13, - }, - Expr: &ast.ExprMethodCall{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 12, - }, - Var: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 5, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 5, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$a"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 5, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_OPEN_TAG, - Value: []byte(""), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 5, - EndPos: 7, - }, - }, - Method: &ast.Identifier{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 7, - EndPos: 10, - }, - IdentifierTkn: &token.Token{ - ID: token.T_STRING, - Value: []byte("foo"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 7, - EndPos: 10, - }, - }, - Value: []byte("foo"), - }, - OpenParenthesisTkn: &token.Token{ - ID: token.ID(40), - Value: []byte("("), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 10, - EndPos: 11, - }, - }, - CloseParenthesisTkn: &token.Token{ - ID: token.ID(41), - Value: []byte(")"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 11, - EndPos: 12, - }, - }, - }, - SemiColonTkn: &token.Token{ - ID: token.ID(59), - Value: []byte(";"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 12, - EndPos: 13, - }, - }, - }, - }, - EndTkn: &token.Token{}, - } - - config := conf.Config{ - Version: &version.Version{ - Major: 5, - Minor: 6, - }, - } - lexer := scanner.NewLexer([]byte(src), config) - php5parser := php5.NewParser(lexer, config) - php5parser.Parse() - actual := php5parser.GetRootNode() - assert.DeepEqual(t, expected, actual) -} - -func TestExprNew(t *testing.T) { - src := `b["c"]()->d["e"]();` - -func TestExprPropertyFetch(t *testing.T) { - src := `foo;` - - expected := &ast.Root{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 11, - }, - Stmts: []ast.Vertex{ - &ast.StmtExpression{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 11, - }, - Expr: &ast.ExprPropertyFetch{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 10, - }, - Var: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 5, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 5, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$a"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 5, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_OPEN_TAG, - Value: []byte(""), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 5, - EndPos: 7, - }, - }, - Prop: &ast.Identifier{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 7, - EndPos: 10, - }, - IdentifierTkn: &token.Token{ - ID: token.T_STRING, - Value: []byte("foo"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 7, - EndPos: 10, - }, - }, - Value: []byte("foo"), - }, - }, - SemiColonTkn: &token.Token{ - ID: token.ID(59), - Value: []byte(";"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 10, - EndPos: 11, - }, - }, - }, - }, - EndTkn: &token.Token{}, - } - - config := conf.Config{ - Version: &version.Version{ - Major: 5, - Minor: 6, - }, - } - lexer := scanner.NewLexer([]byte(src), config) - php5parser := php5.NewParser(lexer, config) - php5parser.Parse() - actual := php5parser.GetRootNode() - assert.DeepEqual(t, expected, actual) -} - -func TestExprShellExec(t *testing.T) { - src := "1, &$b,];` - - expected := &ast.Root{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 16, - }, - Stmts: []ast.Vertex{ - &ast.StmtExpression{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 16, - }, - Expr: &ast.ExprArray{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 15, - }, - OpenBracketTkn: &token.Token{ - ID: token.ID(91), - Value: []byte("["), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 4, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_OPEN_TAG, - Value: []byte(""), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 5, - EndPos: 7, - }, - }, - Val: &ast.ScalarLnumber{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 7, - EndPos: 8, - }, - NumberTkn: &token.Token{ - ID: token.T_LNUMBER, - Value: []byte("1"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 7, - EndPos: 8, - }, - }, - Value: []byte("1"), - }, - }, - &ast.ExprArrayItem{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 10, - EndPos: 13, - }, - AmpersandTkn: &token.Token{ - ID: token.ID(38), - Value: []byte("&"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 10, - EndPos: 11, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 9, - EndPos: 10, - }, - }, - }, - }, - Val: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 11, - EndPos: 13, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 11, - EndPos: 13, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$b"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 11, - EndPos: 13, - }, - }, - Value: []byte("$b"), - }, - }, - }, - &ast.ExprArrayItem{}, - }, - SeparatorTkns: []*token.Token{ - { - ID: token.ID(44), - Value: []byte(","), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 8, - EndPos: 9, - }, - }, - { - ID: token.ID(44), - Value: []byte(","), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 13, - EndPos: 14, - }, - }, - }, - CloseBracketTkn: &token.Token{ - ID: token.ID(93), - Value: []byte("]"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 14, - EndPos: 15, - }, - }, - }, - SemiColonTkn: &token.Token{ - ID: token.ID(59), - Value: []byte(";"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 15, - EndPos: 16, - }, - }, - }, - }, - EndTkn: &token.Token{}, - } - - config := conf.Config{ - Version: &version.Version{ - Major: 5, - Minor: 6, - }, - } - lexer := scanner.NewLexer([]byte(src), config) - php5parser := php5.NewParser(lexer, config) - php5parser.Parse() - actual := php5parser.GetRootNode() - assert.DeepEqual(t, expected, actual) -} - -func TestExprStaticCall(t *testing.T) { - src := ` $b;` - - expected := &ast.Root{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 18, - }, - Stmts: []ast.Vertex{ - &ast.StmtExpression{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 18, - }, - Expr: &ast.ExprYield{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 17, - }, - YieldTkn: &token.Token{ - ID: token.T_YIELD, - Value: []byte("yield"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 8, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_OPEN_TAG, - Value: []byte(""), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 12, - EndPos: 14, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 11, - EndPos: 12, - }, - }, - }, - }, - Val: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 15, - EndPos: 17, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 15, - EndPos: 17, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$b"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 15, - EndPos: 17, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 14, - EndPos: 15, - }, - }, - }, - }, - Value: []byte("$b"), - }, - }, - }, - SemiColonTkn: &token.Token{ - ID: token.ID(59), - Value: []byte(";"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 17, - EndPos: 18, - }, - }, - }, - }, - EndTkn: &token.Token{}, - } - - config := conf.Config{ - Version: &version.Version{ - Major: 5, - Minor: 6, - }, - } - lexer := scanner.NewLexer([]byte(src), config) - php5parser := php5.NewParser(lexer, config) - php5parser.Parse() - actual := php5parser.GetRootNode() - assert.DeepEqual(t, expected, actual) -} - -func TestExprYield_Expr(t *testing.T) { - src := ` 1;` - - expected := &ast.Root{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 17, - }, - Stmts: []ast.Vertex{ - &ast.StmtExpression{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 17, - }, - Expr: &ast.ExprYield{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 16, - }, - YieldTkn: &token.Token{ - ID: token.T_YIELD, - Value: []byte("yield"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 3, - EndPos: 8, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_OPEN_TAG, - Value: []byte(""), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 12, - EndPos: 14, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 11, - EndPos: 12, - }, - }, - }, - }, - Val: &ast.ScalarLnumber{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 15, - EndPos: 16, - }, - NumberTkn: &token.Token{ - ID: token.T_LNUMBER, - Value: []byte("1"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 15, - EndPos: 16, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 14, - EndPos: 15, - }, - }, - }, - }, - Value: []byte("1"), - }, - }, - SemiColonTkn: &token.Token{ - ID: token.ID(59), - Value: []byte(";"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 16, - EndPos: 17, - }, - }, - }, - }, - EndTkn: &token.Token{}, - } - - config := conf.Config{ - Version: &version.Version{ - Major: 5, - Minor: 6, - }, - } - lexer := scanner.NewLexer([]byte(src), config) - php5parser := php5.NewParser(lexer, config) - php5parser.Parse() - actual := php5parser.GetRootNode() - assert.DeepEqual(t, expected, actual) -} - -// expr assign - -func TestExprAssign(t *testing.T) { - src := `>= $b;` - - expected := &ast.Root{ - Position: &position.Position{ - StartLine: 2, - EndLine: 17, - StartPos: 5, - EndPos: 210, - }, - Stmts: []ast.Vertex{ - &ast.StmtExpression{ - Position: &position.Position{ - StartLine: 2, - EndLine: 2, - StartPos: 5, - EndPos: 13, - }, - Expr: &ast.ExprAssign{ - Position: &position.Position{ - StartLine: 2, - EndLine: 2, - StartPos: 5, - EndPos: 12, - }, - Var: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 2, - EndLine: 2, - StartPos: 5, - EndPos: 7, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 2, - EndLine: 2, - StartPos: 5, - EndPos: 7, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$a"), - Position: &position.Position{ - StartLine: 2, - EndLine: 2, - StartPos: 5, - EndPos: 7, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_OPEN_TAG, - Value: []byte(">="), - Position: &position.Position{ - StartLine: 17, - EndLine: 17, - StartPos: 203, - EndPos: 206, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 17, - EndLine: 17, - StartPos: 202, - EndPos: 203, - }, - }, - }, - }, - Expr: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 17, - EndLine: 17, - StartPos: 207, - EndPos: 209, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 17, - EndLine: 17, - StartPos: 207, - EndPos: 209, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$b"), - Position: &position.Position{ - StartLine: 17, - EndLine: 17, - StartPos: 207, - EndPos: 209, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 17, - EndLine: 17, - StartPos: 206, - EndPos: 207, - }, - }, - }, - }, - Value: []byte("$b"), - }, - }, - }, - SemiColonTkn: &token.Token{ - ID: token.ID(59), - Value: []byte(";"), - Position: &position.Position{ - StartLine: 17, - EndLine: 17, - StartPos: 209, - EndPos: 210, - }, - }, - }, - }, - EndTkn: &token.Token{}, - } - - config := conf.Config{ - Version: &version.Version{ - Major: 5, - Minor: 6, - }, - } - lexer := scanner.NewLexer([]byte(src), config) - php5parser := php5.NewParser(lexer, config) - php5parser.Parse() - actual := php5parser.GetRootNode() - assert.DeepEqual(t, expected, actual) -} - -// expr binary - -func TestExprBinary_BitwiseAnd(t *testing.T) { - src := `= $b; - $a > $b; - $a === $b; - $a and $b; - $a or $b; - $a xor $b; - $a - $b; - $a % $b; - $a * $b; - $a != $b; - $a !== $b; - $a + $b; - $a ** $b; - $a << $b; - $a >> $b; - $a <= $b; - $a < $b;` - - expected := &ast.Root{ - Position: &position.Position{ - StartLine: 2, - EndLine: 26, - StartPos: 5, - EndPos: 295, - }, - Stmts: []ast.Vertex{ - &ast.StmtExpression{ - Position: &position.Position{ - StartLine: 2, - EndLine: 2, - StartPos: 5, - EndPos: 13, - }, - Expr: &ast.ExprBinaryBitwiseAnd{ - Position: &position.Position{ - StartLine: 2, - EndLine: 2, - StartPos: 5, - EndPos: 12, - }, - Left: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 2, - EndLine: 2, - StartPos: 5, - EndPos: 7, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 2, - EndLine: 2, - StartPos: 5, - EndPos: 7, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$a"), - Position: &position.Position{ - StartLine: 2, - EndLine: 2, - StartPos: 5, - EndPos: 7, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_OPEN_TAG, - Value: []byte("="), - Position: &position.Position{ - StartLine: 10, - EndLine: 10, - StartPos: 99, - EndPos: 101, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 10, - EndLine: 10, - StartPos: 98, - EndPos: 99, - }, - }, - }, - }, - Right: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 10, - EndLine: 10, - StartPos: 102, - EndPos: 104, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 10, - EndLine: 10, - StartPos: 102, - EndPos: 104, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$b"), - Position: &position.Position{ - StartLine: 10, - EndLine: 10, - StartPos: 102, - EndPos: 104, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 10, - EndLine: 10, - StartPos: 101, - EndPos: 102, - }, - }, - }, - }, - Value: []byte("$b"), - }, - }, - }, - SemiColonTkn: &token.Token{ - ID: token.ID(59), - Value: []byte(";"), - Position: &position.Position{ - StartLine: 10, - EndLine: 10, - StartPos: 104, - EndPos: 105, - }, - }, - }, - &ast.StmtExpression{ - Position: &position.Position{ - StartLine: 11, - EndLine: 11, - StartPos: 108, - EndPos: 116, - }, - Expr: &ast.ExprBinaryGreater{ - Position: &position.Position{ - StartLine: 11, - EndLine: 11, - StartPos: 108, - EndPos: 115, - }, - Left: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 11, - EndLine: 11, - StartPos: 108, - EndPos: 110, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 11, - EndLine: 11, - StartPos: 108, - EndPos: 110, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$a"), - Position: &position.Position{ - StartLine: 11, - EndLine: 11, - StartPos: 108, - EndPos: 110, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte("\n\t\t"), - Position: &position.Position{ - StartLine: 10, - EndLine: 11, - StartPos: 105, - EndPos: 108, - }, - }, - }, - }, - Value: []byte("$a"), - }, - }, - OpTkn: &token.Token{ - ID: token.ID(62), - Value: []byte(">"), - Position: &position.Position{ - StartLine: 11, - EndLine: 11, - StartPos: 111, - EndPos: 112, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 11, - EndLine: 11, - StartPos: 110, - EndPos: 111, - }, - }, - }, - }, - Right: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 11, - EndLine: 11, - StartPos: 113, - EndPos: 115, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 11, - EndLine: 11, - StartPos: 113, - EndPos: 115, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$b"), - Position: &position.Position{ - StartLine: 11, - EndLine: 11, - StartPos: 113, - EndPos: 115, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 11, - EndLine: 11, - StartPos: 112, - EndPos: 113, - }, - }, - }, - }, - Value: []byte("$b"), - }, - }, - }, - SemiColonTkn: &token.Token{ - ID: token.ID(59), - Value: []byte(";"), - Position: &position.Position{ - StartLine: 11, - EndLine: 11, - StartPos: 115, - EndPos: 116, - }, - }, - }, - &ast.StmtExpression{ - Position: &position.Position{ - StartLine: 12, - EndLine: 12, - StartPos: 119, - EndPos: 129, - }, - Expr: &ast.ExprBinaryIdentical{ - Position: &position.Position{ - StartLine: 12, - EndLine: 12, - StartPos: 119, - EndPos: 128, - }, - Left: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 12, - EndLine: 12, - StartPos: 119, - EndPos: 121, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 12, - EndLine: 12, - StartPos: 119, - EndPos: 121, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$a"), - Position: &position.Position{ - StartLine: 12, - EndLine: 12, - StartPos: 119, - EndPos: 121, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte("\n\t\t"), - Position: &position.Position{ - StartLine: 11, - EndLine: 12, - StartPos: 116, - EndPos: 119, - }, - }, - }, - }, - Value: []byte("$a"), - }, - }, - OpTkn: &token.Token{ - ID: token.T_IS_IDENTICAL, - Value: []byte("==="), - Position: &position.Position{ - StartLine: 12, - EndLine: 12, - StartPos: 122, - EndPos: 125, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 12, - EndLine: 12, - StartPos: 121, - EndPos: 122, - }, - }, - }, - }, - Right: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 12, - EndLine: 12, - StartPos: 126, - EndPos: 128, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 12, - EndLine: 12, - StartPos: 126, - EndPos: 128, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$b"), - Position: &position.Position{ - StartLine: 12, - EndLine: 12, - StartPos: 126, - EndPos: 128, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 12, - EndLine: 12, - StartPos: 125, - EndPos: 126, - }, - }, - }, - }, - Value: []byte("$b"), - }, - }, - }, - SemiColonTkn: &token.Token{ - ID: token.ID(59), - Value: []byte(";"), - Position: &position.Position{ - StartLine: 12, - EndLine: 12, - StartPos: 128, - EndPos: 129, - }, - }, - }, - &ast.StmtExpression{ - Position: &position.Position{ - StartLine: 13, - EndLine: 13, - StartPos: 132, - EndPos: 142, - }, - Expr: &ast.ExprBinaryLogicalAnd{ - Position: &position.Position{ - StartLine: 13, - EndLine: 13, - StartPos: 132, - EndPos: 141, - }, - Left: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 13, - EndLine: 13, - StartPos: 132, - EndPos: 134, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 13, - EndLine: 13, - StartPos: 132, - EndPos: 134, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$a"), - Position: &position.Position{ - StartLine: 13, - EndLine: 13, - StartPos: 132, - EndPos: 134, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte("\n\t\t"), - Position: &position.Position{ - StartLine: 12, - EndLine: 13, - StartPos: 129, - EndPos: 132, - }, - }, - }, - }, - Value: []byte("$a"), - }, - }, - OpTkn: &token.Token{ - ID: token.T_LOGICAL_AND, - Value: []byte("and"), - Position: &position.Position{ - StartLine: 13, - EndLine: 13, - StartPos: 135, - EndPos: 138, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 13, - EndLine: 13, - StartPos: 134, - EndPos: 135, - }, - }, - }, - }, - Right: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 13, - EndLine: 13, - StartPos: 139, - EndPos: 141, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 13, - EndLine: 13, - StartPos: 139, - EndPos: 141, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$b"), - Position: &position.Position{ - StartLine: 13, - EndLine: 13, - StartPos: 139, - EndPos: 141, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 13, - EndLine: 13, - StartPos: 138, - EndPos: 139, - }, - }, - }, - }, - Value: []byte("$b"), - }, - }, - }, - SemiColonTkn: &token.Token{ - ID: token.ID(59), - Value: []byte(";"), - Position: &position.Position{ - StartLine: 13, - EndLine: 13, - StartPos: 141, - EndPos: 142, - }, - }, - }, - &ast.StmtExpression{ - Position: &position.Position{ - StartLine: 14, - EndLine: 14, - StartPos: 145, - EndPos: 154, - }, - Expr: &ast.ExprBinaryLogicalOr{ - Position: &position.Position{ - StartLine: 14, - EndLine: 14, - StartPos: 145, - EndPos: 153, - }, - Left: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 14, - EndLine: 14, - StartPos: 145, - EndPos: 147, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 14, - EndLine: 14, - StartPos: 145, - EndPos: 147, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$a"), - Position: &position.Position{ - StartLine: 14, - EndLine: 14, - StartPos: 145, - EndPos: 147, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte("\n\t\t"), - Position: &position.Position{ - StartLine: 13, - EndLine: 14, - StartPos: 142, - EndPos: 145, - }, - }, - }, - }, - Value: []byte("$a"), - }, - }, - OpTkn: &token.Token{ - ID: token.T_LOGICAL_OR, - Value: []byte("or"), - Position: &position.Position{ - StartLine: 14, - EndLine: 14, - StartPos: 148, - EndPos: 150, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 14, - EndLine: 14, - StartPos: 147, - EndPos: 148, - }, - }, - }, - }, - Right: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 14, - EndLine: 14, - StartPos: 151, - EndPos: 153, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 14, - EndLine: 14, - StartPos: 151, - EndPos: 153, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$b"), - Position: &position.Position{ - StartLine: 14, - EndLine: 14, - StartPos: 151, - EndPos: 153, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 14, - EndLine: 14, - StartPos: 150, - EndPos: 151, - }, - }, - }, - }, - Value: []byte("$b"), - }, - }, - }, - SemiColonTkn: &token.Token{ - ID: token.ID(59), - Value: []byte(";"), - Position: &position.Position{ - StartLine: 14, - EndLine: 14, - StartPos: 153, - EndPos: 154, - }, - }, - }, - &ast.StmtExpression{ - Position: &position.Position{ - StartLine: 15, - EndLine: 15, - StartPos: 157, - EndPos: 167, - }, - Expr: &ast.ExprBinaryLogicalXor{ - Position: &position.Position{ - StartLine: 15, - EndLine: 15, - StartPos: 157, - EndPos: 166, - }, - Left: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 15, - EndLine: 15, - StartPos: 157, - EndPos: 159, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 15, - EndLine: 15, - StartPos: 157, - EndPos: 159, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$a"), - Position: &position.Position{ - StartLine: 15, - EndLine: 15, - StartPos: 157, - EndPos: 159, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte("\n\t\t"), - Position: &position.Position{ - StartLine: 14, - EndLine: 15, - StartPos: 154, - EndPos: 157, - }, - }, - }, - }, - Value: []byte("$a"), - }, - }, - OpTkn: &token.Token{ - ID: token.T_LOGICAL_XOR, - Value: []byte("xor"), - Position: &position.Position{ - StartLine: 15, - EndLine: 15, - StartPos: 160, - EndPos: 163, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 15, - EndLine: 15, - StartPos: 159, - EndPos: 160, - }, - }, - }, - }, - Right: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 15, - EndLine: 15, - StartPos: 164, - EndPos: 166, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 15, - EndLine: 15, - StartPos: 164, - EndPos: 166, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$b"), - Position: &position.Position{ - StartLine: 15, - EndLine: 15, - StartPos: 164, - EndPos: 166, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 15, - EndLine: 15, - StartPos: 163, - EndPos: 164, - }, - }, - }, - }, - Value: []byte("$b"), - }, - }, - }, - SemiColonTkn: &token.Token{ - ID: token.ID(59), - Value: []byte(";"), - Position: &position.Position{ - StartLine: 15, - EndLine: 15, - StartPos: 166, - EndPos: 167, - }, - }, - }, - &ast.StmtExpression{ - Position: &position.Position{ - StartLine: 16, - EndLine: 16, - StartPos: 170, - EndPos: 178, - }, - Expr: &ast.ExprBinaryMinus{ - Position: &position.Position{ - StartLine: 16, - EndLine: 16, - StartPos: 170, - EndPos: 177, - }, - Left: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 16, - EndLine: 16, - StartPos: 170, - EndPos: 172, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 16, - EndLine: 16, - StartPos: 170, - EndPos: 172, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$a"), - Position: &position.Position{ - StartLine: 16, - EndLine: 16, - StartPos: 170, - EndPos: 172, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte("\n\t\t"), - Position: &position.Position{ - StartLine: 15, - EndLine: 16, - StartPos: 167, - EndPos: 170, - }, - }, - }, - }, - Value: []byte("$a"), - }, - }, - OpTkn: &token.Token{ - ID: token.ID(45), - Value: []byte("-"), - Position: &position.Position{ - StartLine: 16, - EndLine: 16, - StartPos: 173, - EndPos: 174, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 16, - EndLine: 16, - StartPos: 172, - EndPos: 173, - }, - }, - }, - }, - Right: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 16, - EndLine: 16, - StartPos: 175, - EndPos: 177, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 16, - EndLine: 16, - StartPos: 175, - EndPos: 177, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$b"), - Position: &position.Position{ - StartLine: 16, - EndLine: 16, - StartPos: 175, - EndPos: 177, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 16, - EndLine: 16, - StartPos: 174, - EndPos: 175, - }, - }, - }, - }, - Value: []byte("$b"), - }, - }, - }, - SemiColonTkn: &token.Token{ - ID: token.ID(59), - Value: []byte(";"), - Position: &position.Position{ - StartLine: 16, - EndLine: 16, - StartPos: 177, - EndPos: 178, - }, - }, - }, - &ast.StmtExpression{ - Position: &position.Position{ - StartLine: 17, - EndLine: 17, - StartPos: 181, - EndPos: 189, - }, - Expr: &ast.ExprBinaryMod{ - Position: &position.Position{ - StartLine: 17, - EndLine: 17, - StartPos: 181, - EndPos: 188, - }, - Left: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 17, - EndLine: 17, - StartPos: 181, - EndPos: 183, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 17, - EndLine: 17, - StartPos: 181, - EndPos: 183, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$a"), - Position: &position.Position{ - StartLine: 17, - EndLine: 17, - StartPos: 181, - EndPos: 183, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte("\n\t\t"), - Position: &position.Position{ - StartLine: 16, - EndLine: 17, - StartPos: 178, - EndPos: 181, - }, - }, - }, - }, - Value: []byte("$a"), - }, - }, - OpTkn: &token.Token{ - ID: token.ID(37), - Value: []byte("%"), - Position: &position.Position{ - StartLine: 17, - EndLine: 17, - StartPos: 184, - EndPos: 185, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 17, - EndLine: 17, - StartPos: 183, - EndPos: 184, - }, - }, - }, - }, - Right: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 17, - EndLine: 17, - StartPos: 186, - EndPos: 188, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 17, - EndLine: 17, - StartPos: 186, - EndPos: 188, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$b"), - Position: &position.Position{ - StartLine: 17, - EndLine: 17, - StartPos: 186, - EndPos: 188, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 17, - EndLine: 17, - StartPos: 185, - EndPos: 186, - }, - }, - }, - }, - Value: []byte("$b"), - }, - }, - }, - SemiColonTkn: &token.Token{ - ID: token.ID(59), - Value: []byte(";"), - Position: &position.Position{ - StartLine: 17, - EndLine: 17, - StartPos: 188, - EndPos: 189, - }, - }, - }, - &ast.StmtExpression{ - Position: &position.Position{ - StartLine: 18, - EndLine: 18, - StartPos: 192, - EndPos: 200, - }, - Expr: &ast.ExprBinaryMul{ - Position: &position.Position{ - StartLine: 18, - EndLine: 18, - StartPos: 192, - EndPos: 199, - }, - Left: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 18, - EndLine: 18, - StartPos: 192, - EndPos: 194, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 18, - EndLine: 18, - StartPos: 192, - EndPos: 194, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$a"), - Position: &position.Position{ - StartLine: 18, - EndLine: 18, - StartPos: 192, - EndPos: 194, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte("\n\t\t"), - Position: &position.Position{ - StartLine: 17, - EndLine: 18, - StartPos: 189, - EndPos: 192, - }, - }, - }, - }, - Value: []byte("$a"), - }, - }, - OpTkn: &token.Token{ - ID: token.ID(42), - Value: []byte("*"), - Position: &position.Position{ - StartLine: 18, - EndLine: 18, - StartPos: 195, - EndPos: 196, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 18, - EndLine: 18, - StartPos: 194, - EndPos: 195, - }, - }, - }, - }, - Right: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 18, - EndLine: 18, - StartPos: 197, - EndPos: 199, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 18, - EndLine: 18, - StartPos: 197, - EndPos: 199, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$b"), - Position: &position.Position{ - StartLine: 18, - EndLine: 18, - StartPos: 197, - EndPos: 199, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 18, - EndLine: 18, - StartPos: 196, - EndPos: 197, - }, - }, - }, - }, - Value: []byte("$b"), - }, - }, - }, - SemiColonTkn: &token.Token{ - ID: token.ID(59), - Value: []byte(";"), - Position: &position.Position{ - StartLine: 18, - EndLine: 18, - StartPos: 199, - EndPos: 200, - }, - }, - }, - &ast.StmtExpression{ - Position: &position.Position{ - StartLine: 19, - EndLine: 19, - StartPos: 203, - EndPos: 212, - }, - Expr: &ast.ExprBinaryNotEqual{ - Position: &position.Position{ - StartLine: 19, - EndLine: 19, - StartPos: 203, - EndPos: 211, - }, - Left: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 19, - EndLine: 19, - StartPos: 203, - EndPos: 205, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 19, - EndLine: 19, - StartPos: 203, - EndPos: 205, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$a"), - Position: &position.Position{ - StartLine: 19, - EndLine: 19, - StartPos: 203, - EndPos: 205, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte("\n\t\t"), - Position: &position.Position{ - StartLine: 18, - EndLine: 19, - StartPos: 200, - EndPos: 203, - }, - }, - }, - }, - Value: []byte("$a"), - }, - }, - OpTkn: &token.Token{ - ID: token.T_IS_NOT_EQUAL, - Value: []byte("!="), - Position: &position.Position{ - StartLine: 19, - EndLine: 19, - StartPos: 206, - EndPos: 208, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 19, - EndLine: 19, - StartPos: 205, - EndPos: 206, - }, - }, - }, - }, - Right: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 19, - EndLine: 19, - StartPos: 209, - EndPos: 211, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 19, - EndLine: 19, - StartPos: 209, - EndPos: 211, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$b"), - Position: &position.Position{ - StartLine: 19, - EndLine: 19, - StartPos: 209, - EndPos: 211, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 19, - EndLine: 19, - StartPos: 208, - EndPos: 209, - }, - }, - }, - }, - Value: []byte("$b"), - }, - }, - }, - SemiColonTkn: &token.Token{ - ID: token.ID(59), - Value: []byte(";"), - Position: &position.Position{ - StartLine: 19, - EndLine: 19, - StartPos: 211, - EndPos: 212, - }, - }, - }, - &ast.StmtExpression{ - Position: &position.Position{ - StartLine: 20, - EndLine: 20, - StartPos: 215, - EndPos: 225, - }, - Expr: &ast.ExprBinaryNotIdentical{ - Position: &position.Position{ - StartLine: 20, - EndLine: 20, - StartPos: 215, - EndPos: 224, - }, - Left: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 20, - EndLine: 20, - StartPos: 215, - EndPos: 217, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 20, - EndLine: 20, - StartPos: 215, - EndPos: 217, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$a"), - Position: &position.Position{ - StartLine: 20, - EndLine: 20, - StartPos: 215, - EndPos: 217, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte("\n\t\t"), - Position: &position.Position{ - StartLine: 19, - EndLine: 20, - StartPos: 212, - EndPos: 215, - }, - }, - }, - }, - Value: []byte("$a"), - }, - }, - OpTkn: &token.Token{ - ID: token.T_IS_NOT_IDENTICAL, - Value: []byte("!=="), - Position: &position.Position{ - StartLine: 20, - EndLine: 20, - StartPos: 218, - EndPos: 221, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 20, - EndLine: 20, - StartPos: 217, - EndPos: 218, - }, - }, - }, - }, - Right: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 20, - EndLine: 20, - StartPos: 222, - EndPos: 224, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 20, - EndLine: 20, - StartPos: 222, - EndPos: 224, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$b"), - Position: &position.Position{ - StartLine: 20, - EndLine: 20, - StartPos: 222, - EndPos: 224, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 20, - EndLine: 20, - StartPos: 221, - EndPos: 222, - }, - }, - }, - }, - Value: []byte("$b"), - }, - }, - }, - SemiColonTkn: &token.Token{ - ID: token.ID(59), - Value: []byte(";"), - Position: &position.Position{ - StartLine: 20, - EndLine: 20, - StartPos: 224, - EndPos: 225, - }, - }, - }, - &ast.StmtExpression{ - Position: &position.Position{ - StartLine: 21, - EndLine: 21, - StartPos: 228, - EndPos: 236, - }, - Expr: &ast.ExprBinaryPlus{ - Position: &position.Position{ - StartLine: 21, - EndLine: 21, - StartPos: 228, - EndPos: 235, - }, - Left: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 21, - EndLine: 21, - StartPos: 228, - EndPos: 230, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 21, - EndLine: 21, - StartPos: 228, - EndPos: 230, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$a"), - Position: &position.Position{ - StartLine: 21, - EndLine: 21, - StartPos: 228, - EndPos: 230, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte("\n\t\t"), - Position: &position.Position{ - StartLine: 20, - EndLine: 21, - StartPos: 225, - EndPos: 228, - }, - }, - }, - }, - Value: []byte("$a"), - }, - }, - OpTkn: &token.Token{ - ID: token.ID(43), - Value: []byte("+"), - Position: &position.Position{ - StartLine: 21, - EndLine: 21, - StartPos: 231, - EndPos: 232, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 21, - EndLine: 21, - StartPos: 230, - EndPos: 231, - }, - }, - }, - }, - Right: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 21, - EndLine: 21, - StartPos: 233, - EndPos: 235, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 21, - EndLine: 21, - StartPos: 233, - EndPos: 235, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$b"), - Position: &position.Position{ - StartLine: 21, - EndLine: 21, - StartPos: 233, - EndPos: 235, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 21, - EndLine: 21, - StartPos: 232, - EndPos: 233, - }, - }, - }, - }, - Value: []byte("$b"), - }, - }, - }, - SemiColonTkn: &token.Token{ - ID: token.ID(59), - Value: []byte(";"), - Position: &position.Position{ - StartLine: 21, - EndLine: 21, - StartPos: 235, - EndPos: 236, - }, - }, - }, - &ast.StmtExpression{ - Position: &position.Position{ - StartLine: 22, - EndLine: 22, - StartPos: 239, - EndPos: 248, - }, - Expr: &ast.ExprBinaryPow{ - Position: &position.Position{ - StartLine: 22, - EndLine: 22, - StartPos: 239, - EndPos: 247, - }, - Left: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 22, - EndLine: 22, - StartPos: 239, - EndPos: 241, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 22, - EndLine: 22, - StartPos: 239, - EndPos: 241, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$a"), - Position: &position.Position{ - StartLine: 22, - EndLine: 22, - StartPos: 239, - EndPos: 241, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte("\n\t\t"), - Position: &position.Position{ - StartLine: 21, - EndLine: 22, - StartPos: 236, - EndPos: 239, - }, - }, - }, - }, - Value: []byte("$a"), - }, - }, - OpTkn: &token.Token{ - ID: token.T_POW, - Value: []byte("**"), - Position: &position.Position{ - StartLine: 22, - EndLine: 22, - StartPos: 242, - EndPos: 244, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 22, - EndLine: 22, - StartPos: 241, - EndPos: 242, - }, - }, - }, - }, - Right: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 22, - EndLine: 22, - StartPos: 245, - EndPos: 247, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 22, - EndLine: 22, - StartPos: 245, - EndPos: 247, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$b"), - Position: &position.Position{ - StartLine: 22, - EndLine: 22, - StartPos: 245, - EndPos: 247, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 22, - EndLine: 22, - StartPos: 244, - EndPos: 245, - }, - }, - }, - }, - Value: []byte("$b"), - }, - }, - }, - SemiColonTkn: &token.Token{ - ID: token.ID(59), - Value: []byte(";"), - Position: &position.Position{ - StartLine: 22, - EndLine: 22, - StartPos: 247, - EndPos: 248, - }, - }, - }, - &ast.StmtExpression{ - Position: &position.Position{ - StartLine: 23, - EndLine: 23, - StartPos: 251, - EndPos: 260, - }, - Expr: &ast.ExprBinaryShiftLeft{ - Position: &position.Position{ - StartLine: 23, - EndLine: 23, - StartPos: 251, - EndPos: 259, - }, - Left: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 23, - EndLine: 23, - StartPos: 251, - EndPos: 253, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 23, - EndLine: 23, - StartPos: 251, - EndPos: 253, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$a"), - Position: &position.Position{ - StartLine: 23, - EndLine: 23, - StartPos: 251, - EndPos: 253, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte("\n\t\t"), - Position: &position.Position{ - StartLine: 22, - EndLine: 23, - StartPos: 248, - EndPos: 251, - }, - }, - }, - }, - Value: []byte("$a"), - }, - }, - OpTkn: &token.Token{ - ID: token.T_SL, - Value: []byte("<<"), - Position: &position.Position{ - StartLine: 23, - EndLine: 23, - StartPos: 254, - EndPos: 256, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 23, - EndLine: 23, - StartPos: 253, - EndPos: 254, - }, - }, - }, - }, - Right: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 23, - EndLine: 23, - StartPos: 257, - EndPos: 259, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 23, - EndLine: 23, - StartPos: 257, - EndPos: 259, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$b"), - Position: &position.Position{ - StartLine: 23, - EndLine: 23, - StartPos: 257, - EndPos: 259, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 23, - EndLine: 23, - StartPos: 256, - EndPos: 257, - }, - }, - }, - }, - Value: []byte("$b"), - }, - }, - }, - SemiColonTkn: &token.Token{ - ID: token.ID(59), - Value: []byte(";"), - Position: &position.Position{ - StartLine: 23, - EndLine: 23, - StartPos: 259, - EndPos: 260, - }, - }, - }, - &ast.StmtExpression{ - Position: &position.Position{ - StartLine: 24, - EndLine: 24, - StartPos: 263, - EndPos: 272, - }, - Expr: &ast.ExprBinaryShiftRight{ - Position: &position.Position{ - StartLine: 24, - EndLine: 24, - StartPos: 263, - EndPos: 271, - }, - Left: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 24, - EndLine: 24, - StartPos: 263, - EndPos: 265, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 24, - EndLine: 24, - StartPos: 263, - EndPos: 265, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$a"), - Position: &position.Position{ - StartLine: 24, - EndLine: 24, - StartPos: 263, - EndPos: 265, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte("\n\t\t"), - Position: &position.Position{ - StartLine: 23, - EndLine: 24, - StartPos: 260, - EndPos: 263, - }, - }, - }, - }, - Value: []byte("$a"), - }, - }, - OpTkn: &token.Token{ - ID: token.T_SR, - Value: []byte(">>"), - Position: &position.Position{ - StartLine: 24, - EndLine: 24, - StartPos: 266, - EndPos: 268, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 24, - EndLine: 24, - StartPos: 265, - EndPos: 266, - }, - }, - }, - }, - Right: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 24, - EndLine: 24, - StartPos: 269, - EndPos: 271, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 24, - EndLine: 24, - StartPos: 269, - EndPos: 271, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$b"), - Position: &position.Position{ - StartLine: 24, - EndLine: 24, - StartPos: 269, - EndPos: 271, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 24, - EndLine: 24, - StartPos: 268, - EndPos: 269, - }, - }, - }, - }, - Value: []byte("$b"), - }, - }, - }, - SemiColonTkn: &token.Token{ - ID: token.ID(59), - Value: []byte(";"), - Position: &position.Position{ - StartLine: 24, - EndLine: 24, - StartPos: 271, - EndPos: 272, - }, - }, - }, - &ast.StmtExpression{ - Position: &position.Position{ - StartLine: 25, - EndLine: 25, - StartPos: 275, - EndPos: 284, - }, - Expr: &ast.ExprBinarySmallerOrEqual{ - Position: &position.Position{ - StartLine: 25, - EndLine: 25, - StartPos: 275, - EndPos: 283, - }, - Left: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 25, - EndLine: 25, - StartPos: 275, - EndPos: 277, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 25, - EndLine: 25, - StartPos: 275, - EndPos: 277, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$a"), - Position: &position.Position{ - StartLine: 25, - EndLine: 25, - StartPos: 275, - EndPos: 277, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte("\n\t\t"), - Position: &position.Position{ - StartLine: 24, - EndLine: 25, - StartPos: 272, - EndPos: 275, - }, - }, - }, - }, - Value: []byte("$a"), - }, - }, - OpTkn: &token.Token{ - ID: token.T_IS_SMALLER_OR_EQUAL, - Value: []byte("<="), - Position: &position.Position{ - StartLine: 25, - EndLine: 25, - StartPos: 278, - EndPos: 280, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 25, - EndLine: 25, - StartPos: 277, - EndPos: 278, - }, - }, - }, - }, - Right: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 25, - EndLine: 25, - StartPos: 281, - EndPos: 283, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 25, - EndLine: 25, - StartPos: 281, - EndPos: 283, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$b"), - Position: &position.Position{ - StartLine: 25, - EndLine: 25, - StartPos: 281, - EndPos: 283, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 25, - EndLine: 25, - StartPos: 280, - EndPos: 281, - }, - }, - }, - }, - Value: []byte("$b"), - }, - }, - }, - SemiColonTkn: &token.Token{ - ID: token.ID(59), - Value: []byte(";"), - Position: &position.Position{ - StartLine: 25, - EndLine: 25, - StartPos: 283, - EndPos: 284, - }, - }, - }, - &ast.StmtExpression{ - Position: &position.Position{ - StartLine: 26, - EndLine: 26, - StartPos: 287, - EndPos: 295, - }, - Expr: &ast.ExprBinarySmaller{ - Position: &position.Position{ - StartLine: 26, - EndLine: 26, - StartPos: 287, - EndPos: 294, - }, - Left: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 26, - EndLine: 26, - StartPos: 287, - EndPos: 289, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 26, - EndLine: 26, - StartPos: 287, - EndPos: 289, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$a"), - Position: &position.Position{ - StartLine: 26, - EndLine: 26, - StartPos: 287, - EndPos: 289, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte("\n\t\t"), - Position: &position.Position{ - StartLine: 25, - EndLine: 26, - StartPos: 284, - EndPos: 287, - }, - }, - }, - }, - Value: []byte("$a"), - }, - }, - OpTkn: &token.Token{ - ID: token.ID(60), - Value: []byte("<"), - Position: &position.Position{ - StartLine: 26, - EndLine: 26, - StartPos: 290, - EndPos: 291, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 26, - EndLine: 26, - StartPos: 289, - EndPos: 290, - }, - }, - }, - }, - Right: &ast.ExprVariable{ - Position: &position.Position{ - StartLine: 26, - EndLine: 26, - StartPos: 292, - EndPos: 294, - }, - Name: &ast.Identifier{ - Position: &position.Position{ - StartLine: 26, - EndLine: 26, - StartPos: 292, - EndPos: 294, - }, - IdentifierTkn: &token.Token{ - ID: token.T_VARIABLE, - Value: []byte("$b"), - Position: &position.Position{ - StartLine: 26, - EndLine: 26, - StartPos: 292, - EndPos: 294, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 26, - EndLine: 26, - StartPos: 291, - EndPos: 292, - }, - }, - }, - }, - Value: []byte("$b"), - }, - }, - }, - SemiColonTkn: &token.Token{ - ID: token.ID(59), - Value: []byte(";"), - Position: &position.Position{ - StartLine: 26, - EndLine: 26, - StartPos: 294, - EndPos: 295, - }, - }, - }, - }, - EndTkn: &token.Token{}, - } - - config := conf.Config{ - Version: &version.Version{ - Major: 5, - Minor: 6, - }, - } - lexer := scanner.NewLexer([]byte(src), config) - php5parser := php5.NewParser(lexer, config) - php5parser.Parse() - actual := php5parser.GetRootNode() - assert.DeepEqual(t, expected, actual) -} - -// expr cast - -func TestExprCast_Array(t *testing.T) { - src := ` T_INCLUDE -%token T_INCLUDE_ONCE -%token T_EXIT -%token T_IF -%token T_LNUMBER -%token T_DNUMBER -%token T_STRING -%token T_STRING_VARNAME -%token T_VARIABLE -%token T_NUM_STRING -%token T_INLINE_HTML -%token T_CHARACTER -%token T_BAD_CHARACTER -%token T_ENCAPSED_AND_WHITESPACE -%token T_CONSTANT_ENCAPSED_STRING -%token T_ECHO -%token T_DO -%token T_WHILE -%token T_ENDWHILE -%token T_FOR -%token T_ENDFOR -%token T_FOREACH -%token T_ENDFOREACH -%token T_DECLARE -%token T_ENDDECLARE -%token T_AS -%token T_SWITCH -%token T_ENDSWITCH -%token T_CASE -%token T_DEFAULT -%token T_BREAK -%token T_CONTINUE -%token T_GOTO -%token T_FUNCTION -%token T_FN -%token T_CONST -%token T_RETURN -%token T_TRY -%token T_CATCH -%token T_FINALLY -%token T_THROW -%token T_USE -%token T_INSTEADOF -%token T_GLOBAL -%token T_VAR -%token T_UNSET -%token T_ISSET -%token T_EMPTY -%token T_HALT_COMPILER -%token T_CLASS -%token T_TRAIT -%token T_INTERFACE -%token T_EXTENDS -%token T_IMPLEMENTS -%token T_OBJECT_OPERATOR -%token T_DOUBLE_ARROW -%token T_LIST -%token T_ARRAY -%token T_CALLABLE -%token T_CLASS_C -%token T_TRAIT_C -%token T_METHOD_C -%token T_FUNC_C -%token T_LINE -%token T_FILE -%token T_COMMENT -%token T_DOC_COMMENT -%token T_OPEN_TAG -%token T_OPEN_TAG_WITH_ECHO -%token T_CLOSE_TAG -%token T_WHITESPACE -%token T_START_HEREDOC -%token T_END_HEREDOC -%token T_DOLLAR_OPEN_CURLY_BRACES -%token T_CURLY_OPEN -%token T_PAAMAYIM_NEKUDOTAYIM -%token T_NAMESPACE -%token T_NS_C -%token T_DIR -%token T_NS_SEPARATOR -%token T_ELLIPSIS -%token T_EVAL -%token T_REQUIRE -%token T_REQUIRE_ONCE -%token T_LOGICAL_OR -%token T_LOGICAL_XOR -%token T_LOGICAL_AND -%token T_INSTANCEOF -%token T_NEW -%token T_CLONE -%token T_ELSEIF -%token T_ELSE -%token T_ENDIF -%token T_PRINT -%token T_YIELD -%token T_STATIC -%token T_ABSTRACT -%token T_FINAL -%token T_PRIVATE -%token T_PROTECTED -%token T_PUBLIC -%token T_INC -%token T_DEC -%token T_YIELD_FROM -%token T_INT_CAST -%token T_DOUBLE_CAST -%token T_STRING_CAST -%token T_ARRAY_CAST -%token T_OBJECT_CAST -%token T_BOOL_CAST -%token T_UNSET_CAST -%token T_COALESCE -%token T_SPACESHIP -%token T_NOELSE -%token T_PLUS_EQUAL -%token T_MINUS_EQUAL -%token T_MUL_EQUAL -%token T_POW_EQUAL -%token T_DIV_EQUAL -%token T_CONCAT_EQUAL -%token T_MOD_EQUAL -%token T_AND_EQUAL -%token T_OR_EQUAL -%token T_XOR_EQUAL -%token T_SL_EQUAL -%token T_SR_EQUAL -%token T_COALESCE_EQUAL -%token T_BOOLEAN_OR -%token T_BOOLEAN_AND -%token T_POW -%token T_SL -%token T_SR -%token T_IS_IDENTICAL -%token T_IS_NOT_IDENTICAL -%token T_IS_EQUAL -%token T_IS_NOT_EQUAL -%token T_IS_SMALLER_OR_EQUAL -%token T_IS_GREATER_OR_EQUAL -%token '"' -%token '`' -%token '{' -%token '}' -%token ';' -%token ':' -%token '(' -%token ')' -%token '[' -%token ']' -%token '?' -%token '&' -%token '-' -%token '+' -%token '!' -%token '~' -%token '@' -%token '$' -%token ',' -%token '|' -%token '=' -%token '^' -%token '*' -%token '/' -%token '%' -%token '<' -%token '>' -%token '.' - -%left T_INCLUDE T_INCLUDE_ONCE T_EVAL T_REQUIRE T_REQUIRE_ONCE -%left ',' -%left T_LOGICAL_OR -%left T_LOGICAL_XOR -%left T_LOGICAL_AND -%right T_PRINT -%right T_YIELD -%left '=' T_PLUS_EQUAL T_MINUS_EQUAL T_MUL_EQUAL T_DIV_EQUAL T_CONCAT_EQUAL T_MOD_EQUAL T_AND_EQUAL T_OR_EQUAL T_XOR_EQUAL T_SL_EQUAL T_SR_EQUAL T_POW_EQUAL -%left '?' ':' -%left T_BOOLEAN_OR -%left T_BOOLEAN_AND -%left '|' -%left '^' -%left '&' -%nonassoc T_IS_EQUAL T_IS_NOT_EQUAL T_IS_IDENTICAL T_IS_NOT_IDENTICAL -%nonassoc '<' T_IS_SMALLER_OR_EQUAL '>' T_IS_GREATER_OR_EQUAL -%left T_SL T_SR -%left '+' '-' '.' -%left '*' '/' '%' -%right '!' -%nonassoc T_INSTANCEOF -%right '~' T_INC T_DEC T_INT_CAST T_DOUBLE_CAST T_STRING_CAST T_ARRAY_CAST T_OBJECT_CAST T_BOOL_CAST T_UNSET_CAST '@' -%right T_POW -%right '[' -%nonassoc T_NEW T_CLONE -%left T_ELSEIF -%left T_ELSE -%left T_ENDIF -%right T_STATIC T_ABSTRACT T_FINAL T_PRIVATE T_PROTECTED T_PUBLIC - -%type function interface_entry -%type possible_comma -%type case_separator -%type is_reference is_variadic - -%type top_statement use_declaration use_function_declaration use_const_declaration common_scalar -%type static_class_constant compound_variable reference_variable class_name variable_class_name -%type dim_offset expr expr_without_variable r_variable w_variable rw_variable variable base_variable_with_function_calls -%type base_variable array_function_dereference function_call inner_statement statement unticked_statement -%type statement global_var static_scalar scalar class_constant static_class_name_scalar class_name_scalar -%type encaps_var encaps_var encaps_var_offset general_constant isset_variable internal_functions_in_yacc assignment_list_element -%type variable_name variable_without_objects dynamic_class_name_reference new_expr class_name_reference static_member -%type function_call fully_qualified_class_name combined_scalar combined_scalar_offset general_constant parenthesis_expr -%type exit_expr yield_expr function_declaration_statement class_declaration_statement constant_declaration -%type else_single new_else_single unset_variable declare_statement parameter_list non_empty_parameter_list -%type finally_statement additional_catch unticked_function_declaration_statement unticked_class_declaration_statement -%type optional_class_type parameter class_entry_type class_statement class_constant_declaration -%type trait_use_statement function_call_parameter trait_adaptation_statement trait_precedence trait_alias -%type trait_method_reference_fully_qualified trait_method_reference trait_modifiers member_modifier method -%type static_scalar_value static_operation static_var_list global_var_list -%type ctor_arguments function_call_parameter_list echo_expr_list class_variable_declaration -%type trait_adaptations unset_variables declare_list non_empty_array_pair_list array_pair_list -%type switch_case_list non_empty_function_call_parameter_list assignment_list lexical_var_list -%type method_body trait_reference_list static_array_pair_list non_empty_static_array_pair_list -%type foreach_statement for_statement while_statement isset_variables -%type foreach_variable foreach_optional_arg for_expr non_empty_for_expr -%type extends_from interface_list trait_list namespace_name -%type implements_list use_declarations use_function_declarations use_const_declarations -%type interface_extends_list -%type lexical_vars - -%type top_statement_list -%type inner_statement_list encaps_list -%type elseif_list new_elseif_list -%type case_list catch_statement additional_catches -%type non_empty_additional_catches class_statement_list -%type class_statement_list variable_modifiers method_modifiers -%type trait_adaptation_list non_empty_trait_adaptation_list -%type non_empty_member_modifiers backticks_expr - -%type chaining_dereference chaining_instance_call chaining_method_or_property instance_call variable_property -%type method_or_not array_method_dereference object_property object_dim_list dynamic_class_name_variable_property -%type dynamic_class_name_variable_properties variable_properties - -%type simple_indirect_reference - -%% - -start: - top_statement_list - { - yylex.(*Parser).currentToken.Value = nil - - yylex.(*Parser).rootNode = &ast.Root{ - Position: yylex.(*Parser).builder.NewNodeListPosition($1), - Stmts: $1, - EndTkn: yylex.(*Parser).currentToken, - } - } -; - -top_statement_list: - top_statement_list top_statement - { - if $2 != nil { - $$ = append($1, $2) - } - } - | /* empty */ - { - $$ = []ast.Vertex{} - } -; - -namespace_name: - T_STRING - { - $$ = &ParserSeparatedList{ - Items: []ast.Vertex{ - &ast.NamePart{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - StringTkn: $1, - Value: $1.Value, - }, - }, - } - } - | namespace_name T_NS_SEPARATOR T_STRING - { - part := &ast.NamePart{ - Position: yylex.(*Parser).builder.NewTokenPosition($3), - StringTkn: $3, - Value: $3.Value, - } - - $1.(*ParserSeparatedList).SeparatorTkns = append($1.(*ParserSeparatedList).SeparatorTkns, $2) - $1.(*ParserSeparatedList).Items = append($1.(*ParserSeparatedList).Items, part) - - $$ = $1 - } -; - -top_statement: - error - { - // error - $$ = nil - } - | statement - { - $$ = $1 - } - | function_declaration_statement - { - $$ = $1 - } - | class_declaration_statement - { - $$ = $1 - } - | T_HALT_COMPILER '(' ')' ';' - { - $$ = &ast.StmtHaltCompiler{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $4), - HaltCompilerTkn: $1, - OpenParenthesisTkn: $2, - CloseParenthesisTkn: $3, - SemiColonTkn: $4, - } - } - | T_NAMESPACE namespace_name ';' - { - $$ = &ast.StmtNamespace{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $3), - NsTkn: $1, - Name: &ast.Name{ - Position: yylex.(*Parser).builder.NewNodeListPosition($2.(*ParserSeparatedList).Items), - Parts: $2.(*ParserSeparatedList).Items, - SeparatorTkns: $2.(*ParserSeparatedList).SeparatorTkns, - }, - SemiColonTkn: $3, - } - } - | T_NAMESPACE namespace_name '{' top_statement_list '}' - { - $$ = &ast.StmtNamespace{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $5), - NsTkn: $1, - Name: &ast.Name{ - Position: yylex.(*Parser).builder.NewNodeListPosition($2.(*ParserSeparatedList).Items), - Parts: $2.(*ParserSeparatedList).Items, - SeparatorTkns: $2.(*ParserSeparatedList).SeparatorTkns, - }, - OpenCurlyBracketTkn: $3, - Stmts: $4, - CloseCurlyBracketTkn: $5, - } - } - | T_NAMESPACE '{' top_statement_list '}' - { - $$ = &ast.StmtNamespace{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $4), - NsTkn: $1, - OpenCurlyBracketTkn: $2, - Stmts: $3, - CloseCurlyBracketTkn: $4, - } - } - | T_USE use_declarations ';' - { - $$ = &ast.StmtUseList{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $3), - UseTkn: $1, - Uses: $2.(*ParserSeparatedList).Items, - SeparatorTkns: $2.(*ParserSeparatedList).SeparatorTkns, - SemiColonTkn: $3, - } - } - | T_USE T_FUNCTION use_function_declarations ';' - { - $$ = &ast.StmtUseList{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $4), - UseTkn: $1, - Type: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($2), - IdentifierTkn: $2, - Value: $2.Value, - }, - Uses: $3.(*ParserSeparatedList).Items, - SeparatorTkns: $3.(*ParserSeparatedList).SeparatorTkns, - SemiColonTkn: $4, - } - } - | T_USE T_CONST use_const_declarations ';' - { - $$ = &ast.StmtUseList{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $4), - UseTkn: $1, - Type: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($2), - IdentifierTkn: $2, - Value: $2.Value, - }, - Uses: $3.(*ParserSeparatedList).Items, - SeparatorTkns: $3.(*ParserSeparatedList).SeparatorTkns, - SemiColonTkn: $4, - } - } - | constant_declaration ';' - { - $1.(*ast.StmtConstList).SemiColonTkn = $2 - $1.(*ast.StmtConstList).Position = yylex.(*Parser).builder.NewNodeTokenPosition($1, $2) - $$ = $1 - } -; - -use_declarations: - use_declarations ',' use_declaration - { - $1.(*ParserSeparatedList).SeparatorTkns = append($1.(*ParserSeparatedList).SeparatorTkns, $2) - $1.(*ParserSeparatedList).Items = append($1.(*ParserSeparatedList).Items, $3) - - $$ = $1 - } - | use_declaration - { - $$ = &ParserSeparatedList{ - Items: []ast.Vertex{$1}, - } - } -; - -use_declaration: - namespace_name - { - $$ = &ast.StmtUse{ - Position: yylex.(*Parser).builder.NewNodeListPosition($1.(*ParserSeparatedList).Items), - Use: &ast.Name{ - Position: yylex.(*Parser).builder.NewNodeListPosition($1.(*ParserSeparatedList).Items), - Parts: $1.(*ParserSeparatedList).Items, - SeparatorTkns: $1.(*ParserSeparatedList).SeparatorTkns, - }, - } - } - | namespace_name T_AS T_STRING - { - $$ = &ast.StmtUse{ - Position: yylex.(*Parser).builder.NewNodeListTokenPosition($1.(*ParserSeparatedList).Items, $3), - Use: &ast.Name{ - Position: yylex.(*Parser).builder.NewNodeListPosition($1.(*ParserSeparatedList).Items), - Parts: $1.(*ParserSeparatedList).Items, - SeparatorTkns: $1.(*ParserSeparatedList).SeparatorTkns, - }, - AsTkn: $2, - Alias: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($3), - IdentifierTkn: $3, - Value: $3.Value, - }, - } - } - | T_NS_SEPARATOR namespace_name - { - $$ = &ast.StmtUse{ - Position: yylex.(*Parser).builder.NewTokenNodeListPosition($1, $2.(*ParserSeparatedList).Items), - NsSeparatorTkn: $1, - Use: &ast.Name{ - Position: yylex.(*Parser).builder.NewNodeListPosition($2.(*ParserSeparatedList).Items), - Parts: $2.(*ParserSeparatedList).Items, - SeparatorTkns: $2.(*ParserSeparatedList).SeparatorTkns, - }, - } - } - | T_NS_SEPARATOR namespace_name T_AS T_STRING - { - $$ = &ast.StmtUse{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $4), - NsSeparatorTkn: $1, - Use: &ast.Name{ - Position: yylex.(*Parser).builder.NewNodeListPosition($2.(*ParserSeparatedList).Items), - Parts: $2.(*ParserSeparatedList).Items, - SeparatorTkns: $2.(*ParserSeparatedList).SeparatorTkns, - }, - AsTkn: $3, - Alias: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($4), - IdentifierTkn: $4, - Value: $4.Value, - }, - } - } -; - -use_function_declarations: - use_function_declarations ',' use_function_declaration - { - $1.(*ParserSeparatedList).SeparatorTkns = append($1.(*ParserSeparatedList).SeparatorTkns, $2) - $1.(*ParserSeparatedList).Items = append($1.(*ParserSeparatedList).Items, $3) - - $$ = $1 - } - | use_function_declaration - { - $$ = &ParserSeparatedList{ - Items: []ast.Vertex{$1}, - } - } -; - -use_function_declaration: - namespace_name - { - $$ = &ast.StmtUse{ - Position: yylex.(*Parser).builder.NewNodeListPosition($1.(*ParserSeparatedList).Items), - Use: &ast.Name{ - Position: yylex.(*Parser).builder.NewNodeListPosition($1.(*ParserSeparatedList).Items), - Parts: $1.(*ParserSeparatedList).Items, - SeparatorTkns: $1.(*ParserSeparatedList).SeparatorTkns, - }, - } - } - | namespace_name T_AS T_STRING - { - $$ = &ast.StmtUse{ - Position: yylex.(*Parser).builder.NewNodeListTokenPosition($1.(*ParserSeparatedList).Items, $3), - Use: &ast.Name{ - Position: yylex.(*Parser).builder.NewNodeListPosition($1.(*ParserSeparatedList).Items), - Parts: $1.(*ParserSeparatedList).Items, - SeparatorTkns: $1.(*ParserSeparatedList).SeparatorTkns, - }, - AsTkn: $2, - Alias: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($3), - IdentifierTkn: $3, - Value: $3.Value, - }, - } - } - | T_NS_SEPARATOR namespace_name - { - $$ = &ast.StmtUse{ - Position: yylex.(*Parser).builder.NewTokenNodeListPosition($1, $2.(*ParserSeparatedList).Items), - NsSeparatorTkn: $1, - Use: &ast.Name{ - Position: yylex.(*Parser).builder.NewNodeListPosition($2.(*ParserSeparatedList).Items), - Parts: $2.(*ParserSeparatedList).Items, - SeparatorTkns: $2.(*ParserSeparatedList).SeparatorTkns, - }, - } - } - | T_NS_SEPARATOR namespace_name T_AS T_STRING - { - $$ = &ast.StmtUse{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $4), - NsSeparatorTkn: $1, - Use: &ast.Name{ - Position: yylex.(*Parser).builder.NewNodeListPosition($2.(*ParserSeparatedList).Items), - Parts: $2.(*ParserSeparatedList).Items, - SeparatorTkns: $2.(*ParserSeparatedList).SeparatorTkns, - }, - AsTkn: $3, - Alias: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($4), - IdentifierTkn: $4, - Value: $4.Value, - }, - } - } -; - -use_const_declarations: - use_const_declarations ',' use_const_declaration - { - $1.(*ParserSeparatedList).SeparatorTkns = append($1.(*ParserSeparatedList).SeparatorTkns, $2) - $1.(*ParserSeparatedList).Items = append($1.(*ParserSeparatedList).Items, $3) - - $$ = $1 - } - | use_const_declaration - { - $$ = &ParserSeparatedList{ - Items: []ast.Vertex{$1}, - } - } -; - -use_const_declaration: - namespace_name - { - $$ = &ast.StmtUse{ - Position: yylex.(*Parser).builder.NewNodeListPosition($1.(*ParserSeparatedList).Items), - Use: &ast.Name{ - Position: yylex.(*Parser).builder.NewNodeListPosition($1.(*ParserSeparatedList).Items), - Parts: $1.(*ParserSeparatedList).Items, - SeparatorTkns: $1.(*ParserSeparatedList).SeparatorTkns, - }, - } - } - | namespace_name T_AS T_STRING - { - $$ = &ast.StmtUse{ - Position: yylex.(*Parser).builder.NewNodeListTokenPosition($1.(*ParserSeparatedList).Items, $3), - Use: &ast.Name{ - Position: yylex.(*Parser).builder.NewNodeListPosition($1.(*ParserSeparatedList).Items), - Parts: $1.(*ParserSeparatedList).Items, - SeparatorTkns: $1.(*ParserSeparatedList).SeparatorTkns, - }, - AsTkn: $2, - Alias: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($3), - IdentifierTkn: $3, - Value: $3.Value, - }, - } - } - | T_NS_SEPARATOR namespace_name - { - $$ = &ast.StmtUse{ - Position: yylex.(*Parser).builder.NewTokenNodeListPosition($1, $2.(*ParserSeparatedList).Items), - NsSeparatorTkn: $1, - Use: &ast.Name{ - Position: yylex.(*Parser).builder.NewNodeListPosition($2.(*ParserSeparatedList).Items), - Parts: $2.(*ParserSeparatedList).Items, - SeparatorTkns: $2.(*ParserSeparatedList).SeparatorTkns, - }, - } - } - | T_NS_SEPARATOR namespace_name T_AS T_STRING - { - $$ = &ast.StmtUse{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $4), - NsSeparatorTkn: $1, - Use: &ast.Name{ - Position: yylex.(*Parser).builder.NewNodeListPosition($2.(*ParserSeparatedList).Items), - Parts: $2.(*ParserSeparatedList).Items, - SeparatorTkns: $2.(*ParserSeparatedList).SeparatorTkns, - }, - AsTkn: $3, - Alias: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($4), - IdentifierTkn: $4, - Value: $4.Value, - }, - } - } -; - -constant_declaration: - constant_declaration ',' T_STRING '=' static_scalar - { - constList := $1.(*ast.StmtConstList) - constList.Position = yylex.(*Parser).builder.NewNodesPosition($1, $5) - constList.SeparatorTkns = append(constList.SeparatorTkns, $2) - constList.Consts = append(constList.Consts, &ast.StmtConstant{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($3, $5), - Name: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($3), - IdentifierTkn: $3, - Value: $3.Value, - }, - EqualTkn: $4, - Expr: $5, - }) - - $$ = $1 - } - | T_CONST T_STRING '=' static_scalar - { - $$ = &ast.StmtConstList{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $4), - ConstTkn: $1, - Consts: []ast.Vertex{ - &ast.StmtConstant{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($2, $4), - Name: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($2), - IdentifierTkn: $2, - Value: $2.Value, - }, - EqualTkn: $3, - Expr: $4, - }, - }, - } - } -; - -inner_statement_list: - inner_statement_list inner_statement - { - if $2 != nil { - $$ = append($1, $2) - } - } - | /* empty */ - { - $$ = []ast.Vertex{} - } -; - - -inner_statement: - error - { - // error - $$ = nil - } - | statement - { - $$ = $1 - } - | function_declaration_statement - { - $$ = $1 - } - | class_declaration_statement - { - $$ = $1 - } - | T_HALT_COMPILER '(' ')' ';' - { - $$ = &ast.StmtHaltCompiler{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $4), - HaltCompilerTkn: $1, - OpenParenthesisTkn: $2, - CloseParenthesisTkn: $3, - SemiColonTkn: $4, - } - } -; - - -statement: - unticked_statement - { - $$ = $1 - } - | T_STRING ':' - { - $$ = &ast.StmtLabel{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $2), - Name: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - IdentifierTkn: $1, - Value: $1.Value, - }, - ColonTkn: $2, - } - } -; - -unticked_statement: - '{' inner_statement_list '}' - { - $$ = &ast.StmtStmtList{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $3), - OpenCurlyBracketTkn: $1, - Stmts: $2, - CloseCurlyBracketTkn: $3, - } - } - | T_IF parenthesis_expr statement elseif_list else_single - { - pos := yylex.(*Parser).builder.NewTokenNodePosition($1, $3) - if $5 != nil { - pos = yylex.(*Parser).builder.NewTokenNodePosition($1, $5) - } else if len($4) > 0 { - pos = yylex.(*Parser).builder.NewTokenNodeListPosition($1, $4) - } - - $$ = &ast.StmtIf{ - Position: pos, - IfTkn: $1, - OpenParenthesisTkn: $2.(*ast.ExprBrackets).OpenParenthesisTkn, - Cond: $2.(*ast.ExprBrackets).Expr, - CloseParenthesisTkn: $2.(*ast.ExprBrackets).CloseParenthesisTkn, - Stmt: $3, - ElseIf: $4, - Else: $5, - } - } - | T_IF parenthesis_expr ':' inner_statement_list new_elseif_list new_else_single T_ENDIF ';' - { - $$ = &ast.StmtIf{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $8), - IfTkn: $1, - OpenParenthesisTkn: $2.(*ast.ExprBrackets).OpenParenthesisTkn, - Cond: $2.(*ast.ExprBrackets).Expr, - CloseParenthesisTkn: $2.(*ast.ExprBrackets).CloseParenthesisTkn, - ColonTkn: $3, - Stmt: &ast.StmtStmtList{ - Position: yylex.(*Parser).builder.NewNodeListPosition($4), - Stmts: $4, - }, - ElseIf: $5, - Else: $6, - EndIfTkn: $7, - SemiColonTkn: $8, - } - } - | T_WHILE parenthesis_expr while_statement - { - $3.(*ast.StmtWhile).WhileTkn = $1 - $3.(*ast.StmtWhile).OpenParenthesisTkn = $2.(*ast.ExprBrackets).OpenParenthesisTkn - $3.(*ast.StmtWhile).Cond = $2.(*ast.ExprBrackets).Expr - $3.(*ast.StmtWhile).CloseParenthesisTkn = $2.(*ast.ExprBrackets).CloseParenthesisTkn - $3.(*ast.StmtWhile).Position = yylex.(*Parser).builder.NewTokenNodePosition($1, $3) - - $$ = $3 - } - | T_DO statement T_WHILE parenthesis_expr ';' - { - $$ = &ast.StmtDo{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $5), - DoTkn: $1, - Stmt: $2, - WhileTkn: $3, - OpenParenthesisTkn: $4.(*ast.ExprBrackets).OpenParenthesisTkn, - Cond: $4.(*ast.ExprBrackets).Expr, - CloseParenthesisTkn: $4.(*ast.ExprBrackets).CloseParenthesisTkn, - SemiColonTkn: $5, - } - } - | T_FOR '(' for_expr ';' for_expr ';' for_expr ')' for_statement - { - $9.(*ast.StmtFor).ForTkn = $1 - $9.(*ast.StmtFor).OpenParenthesisTkn = $2 - $9.(*ast.StmtFor).Init = $3.(*ParserSeparatedList).Items - $9.(*ast.StmtFor).InitSeparatorTkns = $3.(*ParserSeparatedList).SeparatorTkns - $9.(*ast.StmtFor).InitSemiColonTkn = $4 - $9.(*ast.StmtFor).Cond = $5.(*ParserSeparatedList).Items - $9.(*ast.StmtFor).CondSeparatorTkns = $5.(*ParserSeparatedList).SeparatorTkns - $9.(*ast.StmtFor).CondSemiColonTkn = $6 - $9.(*ast.StmtFor).Loop = $7.(*ParserSeparatedList).Items - $9.(*ast.StmtFor).LoopSeparatorTkns = $7.(*ParserSeparatedList).SeparatorTkns - $9.(*ast.StmtFor).CloseParenthesisTkn = $8 - $9.(*ast.StmtFor).Position = yylex.(*Parser).builder.NewTokenNodePosition($1, $9) - - $$ = $9 - } - | T_SWITCH parenthesis_expr switch_case_list - { - $3.(*ast.StmtSwitch).SwitchTkn = $1 - $3.(*ast.StmtSwitch).OpenParenthesisTkn = $2.(*ast.ExprBrackets).OpenParenthesisTkn - $3.(*ast.StmtSwitch).Cond = $2.(*ast.ExprBrackets).Expr - $3.(*ast.StmtSwitch).CloseParenthesisTkn = $2.(*ast.ExprBrackets).CloseParenthesisTkn - $3.(*ast.StmtSwitch).Position = yylex.(*Parser).builder.NewTokenNodePosition($1, $3) - - $$ = $3 - } - | T_BREAK ';' - { - $$ = &ast.StmtBreak{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $2), - BreakTkn: $1, - SemiColonTkn: $2, - } - } - | T_BREAK expr ';' - { - $$ = &ast.StmtBreak{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $3), - BreakTkn: $1, - Expr: $2, - SemiColonTkn: $3, - } - } - | T_CONTINUE ';' - { - $$ = &ast.StmtContinue{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $2), - ContinueTkn: $1, - SemiColonTkn: $2, - } - } - | T_CONTINUE expr ';' - { - $$ = &ast.StmtContinue{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $3), - ContinueTkn: $1, - Expr: $2, - SemiColonTkn: $3, - } - } - | T_RETURN ';' - { - $$ = &ast.StmtReturn{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $2), - ReturnTkn: $1, - SemiColonTkn: $2, - } - } - | T_RETURN expr_without_variable ';' - { - $$ = &ast.StmtReturn{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $3), - ReturnTkn: $1, - Expr: $2, - SemiColonTkn: $3, - } - } - | T_RETURN variable ';' - { - $$ = &ast.StmtReturn{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $3), - ReturnTkn: $1, - Expr: $2, - SemiColonTkn: $3, - } - } - | yield_expr ';' - { - $$ = &ast.StmtExpression{ - Position: yylex.(*Parser).builder.NewNodeTokenPosition($1, $2), - Expr: $1, - SemiColonTkn: $2, - } - } - | T_GLOBAL global_var_list ';' - { - $2.(*ast.StmtGlobal).GlobalTkn = $1 - $2.(*ast.StmtGlobal).SemiColonTkn = $3 - $2.(*ast.StmtGlobal).Position = yylex.(*Parser).builder.NewTokensPosition($1, $3) - - $$ = $2 - } - | T_STATIC static_var_list ';' - { - $2.(*ast.StmtStatic).StaticTkn = $1 - $2.(*ast.StmtStatic).SemiColonTkn = $3 - $2.(*ast.StmtStatic).Position = yylex.(*Parser).builder.NewTokensPosition($1, $3) - - $$ = $2 - } - | T_ECHO echo_expr_list ';' - { - $2.(*ast.StmtEcho).EchoTkn = $1 - $2.(*ast.StmtEcho).SemiColonTkn = $3 - $2.(*ast.StmtEcho).Position = yylex.(*Parser).builder.NewTokensPosition($1, $3) - - $$ = $2 - } - | T_INLINE_HTML - { - $$ = &ast.StmtInlineHtml{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - InlineHtmlTkn: $1, - Value: $1.Value, - } - } - | expr ';' - { - $$ = &ast.StmtExpression{ - Position: yylex.(*Parser).builder.NewNodeTokenPosition($1, $2), - Expr: $1, - SemiColonTkn: $2, - } - } - | T_UNSET '(' unset_variables ')' ';' - { - $3.(*ast.StmtUnset).UnsetTkn = $1 - $3.(*ast.StmtUnset).OpenParenthesisTkn = $2 - $3.(*ast.StmtUnset).CloseParenthesisTkn = $4 - $3.(*ast.StmtUnset).SemiColonTkn = $5 - $3.(*ast.StmtUnset).Position = yylex.(*Parser).builder.NewTokensPosition($1, $5) - - $$ = $3 - } - | T_FOREACH '(' variable T_AS foreach_variable foreach_optional_arg ')' foreach_statement - { - foreach := $8.(*ast.StmtForeach) - - foreach.Position = yylex.(*Parser).builder.NewTokenNodePosition($1, $8) - foreach.ForeachTkn = $1 - foreach.OpenParenthesisTkn = $2 - foreach.Expr = $3 - foreach.AsTkn = $4 - foreach.Var = $5 - foreach.CloseParenthesisTkn = $7 - - if $6 != nil { - foreach.Key = foreach.Var - foreach.DoubleArrowTkn = $6.(*ast.StmtForeach).DoubleArrowTkn - foreach.Var = $6.(*ast.StmtForeach).Var - } - - if val, ok := foreach.Key.(*ast.StmtForeach); ok { - yylex.(*Parser).errHandlerFunc(errors.NewError("Key element cannot be a reference", val.AmpersandTkn.Position)) - foreach.Key = val.Var - } - - if val, ok := foreach.Var.(*ast.StmtForeach); ok { - foreach.AmpersandTkn = val.AmpersandTkn - foreach.Var = val.Var - } - - $$ = foreach - } - | T_FOREACH '(' expr_without_variable T_AS foreach_variable foreach_optional_arg ')' foreach_statement - { - foreach := $8.(*ast.StmtForeach) - - foreach.Position = yylex.(*Parser).builder.NewTokenNodePosition($1, $8) - foreach.ForeachTkn = $1 - foreach.OpenParenthesisTkn = $2 - foreach.Expr = $3 - foreach.AsTkn = $4 - foreach.Var = $5 - foreach.CloseParenthesisTkn = $7 - - if $6 != nil { - foreach.Key = foreach.Var - foreach.DoubleArrowTkn = $6.(*ast.StmtForeach).DoubleArrowTkn - foreach.Var = $6.(*ast.StmtForeach).Var - } - - if val, ok := foreach.Key.(*ast.StmtForeach); ok { - yylex.(*Parser).errHandlerFunc(errors.NewError("Key element cannot be a reference", val.AmpersandTkn.Position)) - foreach.Key = val.Var - } - - if val, ok := foreach.Var.(*ast.StmtForeach); ok { - foreach.AmpersandTkn = val.AmpersandTkn - foreach.Var = val.Var - } - - $$ = foreach - } - | T_DECLARE '(' declare_list ')' declare_statement - { - $5.(*ast.StmtDeclare).DeclareTkn = $1 - $5.(*ast.StmtDeclare).OpenParenthesisTkn = $2 - $5.(*ast.StmtDeclare).Consts = $3.(*ParserSeparatedList).Items - $5.(*ast.StmtDeclare).SeparatorTkns = $3.(*ParserSeparatedList).SeparatorTkns - $5.(*ast.StmtDeclare).CloseParenthesisTkn = $4 - $5.(*ast.StmtDeclare).Position = yylex.(*Parser).builder.NewTokenNodePosition($1, $5) - - $$ = $5 - } - | ';' - { - $$ = &ast.StmtNop{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - SemiColonTkn: $1, - } - } - | T_TRY '{' inner_statement_list '}' catch_statement finally_statement - { - pos := yylex.(*Parser).builder.NewTokenNodeListPosition($1, $5) - if $6 != nil { - pos = yylex.(*Parser).builder.NewTokenNodePosition($1, $6) - } - - $$ = &ast.StmtTry{ - Position: pos, - TryTkn: $1, - OpenCurlyBracketTkn: $2, - Stmts: $3, - CloseCurlyBracketTkn: $4, - Catches: $5, - Finally: $6, - } - } - | T_THROW expr ';' - { - $$ = &ast.StmtThrow{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $3), - ThrowTkn: $1, - Expr: $2, - SemiColonTkn: $3, - } - } - | T_GOTO T_STRING ';' - { - $$ = &ast.StmtGoto{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $3), - GotoTkn: $1, - Label: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - IdentifierTkn: $2, - Value: $2.Value, - }, - SemiColonTkn: $3, - } - } -; - -catch_statement: - /* empty */ - { - $$ = []ast.Vertex{} - } - | T_CATCH '(' fully_qualified_class_name T_VARIABLE ')' '{' inner_statement_list '}' additional_catches - { - catch := &ast.StmtCatch{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $8), - CatchTkn: $1, - OpenParenthesisTkn: $2, - Types: []ast.Vertex{$3}, - Var: &ast.ExprVariable{ - Position: yylex.(*Parser).builder.NewTokenPosition($4), - Name: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($4), - IdentifierTkn: $4, - Value: $4.Value, - }, - }, - CloseParenthesisTkn: $5, - OpenCurlyBracketTkn: $6, - Stmts: $7, - CloseCurlyBracketTkn: $8, - } - $$ = append([]ast.Vertex{catch}, $9...) - } -; - -finally_statement: - /* empty */ - { - $$ = nil - } - | T_FINALLY '{' inner_statement_list '}' - { - $$ = &ast.StmtFinally{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $4), - FinallyTkn: $1, - OpenCurlyBracketTkn: $2, - Stmts: $3, - CloseCurlyBracketTkn: $4, - } - } -; - -additional_catches: - non_empty_additional_catches - { - $$ = $1 - } - | /* empty */ - { - $$ = []ast.Vertex{} - } -; - -non_empty_additional_catches: - additional_catch - { - $$ = []ast.Vertex{$1} - } - | non_empty_additional_catches additional_catch - { - $$ = append($1, $2) - } -; - -additional_catch: - T_CATCH '(' fully_qualified_class_name T_VARIABLE ')' '{' inner_statement_list '}' - { - $$ = &ast.StmtCatch{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $8), - CatchTkn: $1, - OpenParenthesisTkn: $2, - Types: []ast.Vertex{$3}, - Var: &ast.ExprVariable{ - Position: yylex.(*Parser).builder.NewTokenPosition($4), - Name: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($4), - IdentifierTkn: $4, - Value: $4.Value, - }, - }, - CloseParenthesisTkn: $5, - OpenCurlyBracketTkn: $6, - Stmts: $7, - CloseCurlyBracketTkn: $8, - } - } -; - -unset_variables: - unset_variable - { - $$ = &ast.StmtUnset{ - Vars: []ast.Vertex{$1}, - } - } - | unset_variables ',' unset_variable - { - $1.(*ast.StmtUnset).Vars = append($1.(*ast.StmtUnset).Vars, $3) - $1.(*ast.StmtUnset).SeparatorTkns = append($1.(*ast.StmtUnset).SeparatorTkns, $2) - - $$ = $1 - } -; - -unset_variable: - variable - { - $$ = $1 - } -; - -function_declaration_statement: - unticked_function_declaration_statement - { - $$ = $1 - } -; - -class_declaration_statement: - unticked_class_declaration_statement - { - $$ = $1 - } -; - -is_reference: - /* empty */ - { - $$ = nil - } - | '&' - { - $$ = $1 - } -; - -is_variadic: - /* empty */ - { - $$ = nil - } - | T_ELLIPSIS - { - $$ = $1 - } -; - -unticked_function_declaration_statement: - function is_reference T_STRING '(' parameter_list ')' '{' inner_statement_list '}' - { - $$ = &ast.StmtFunction{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $9), - FunctionTkn: $1, - AmpersandTkn: $2, - Name: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($3), - IdentifierTkn: $3, - Value: $3.Value, - }, - OpenParenthesisTkn: $4, - Params: $5.(*ParserSeparatedList).Items, - SeparatorTkns: $5.(*ParserSeparatedList).SeparatorTkns, - CloseParenthesisTkn: $6, - OpenCurlyBracketTkn: $7, - Stmts: $8, - CloseCurlyBracketTkn: $9, - } - } -; - -unticked_class_declaration_statement: - class_entry_type T_STRING extends_from implements_list '{' class_statement_list '}' - { - switch n := $1.(type) { - case *ast.StmtClass : - className := &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($2), - IdentifierTkn: $2, - Value: $2.Value, - } - - n.Position = yylex.(*Parser).builder.NewNodeTokenPosition($1, $7) - n.Name = className - n.OpenCurlyBracketTkn = $5 - n.Stmts = $6 - n.CloseCurlyBracketTkn = $7 - - if $3 != nil { - n.ExtendsTkn = $3.(*ast.StmtClass).ExtendsTkn - n.Extends = $3.(*ast.StmtClass).Extends - } - - if $4 != nil { - n.ImplementsTkn = $4.(*ast.StmtClass).ImplementsTkn - n.Implements = $4.(*ast.StmtClass).Implements - n.ImplementsSeparatorTkns = $4.(*ast.StmtClass).ImplementsSeparatorTkns - } - case *ast.StmtTrait : - traitName := &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($2), - IdentifierTkn: $2, - Value: $2.Value, - } - - n.Position = yylex.(*Parser).builder.NewNodeTokenPosition($1, $7) - n.Name = traitName - n.OpenCurlyBracketTkn = $5 - n.Stmts = $6 - n.CloseCurlyBracketTkn = $7 - - if $3 != nil { - yylex.(*Parser).errHandlerFunc(errors.NewError("A trait cannot extend a class. Traits can only be composed from other traits with the 'use' keyword", $3.(*ast.StmtClass).Position)) - } - - if $4 != nil { - yylex.(*Parser).errHandlerFunc(errors.NewError("A trait cannot implement an interface", $4.(*ast.StmtClass).Position)) - } - } - - $$ = $1 - } - | interface_entry T_STRING interface_extends_list '{' class_statement_list '}' - { - iface := &ast.StmtInterface{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $6), - InterfaceTkn: $1, - Name: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($2), - IdentifierTkn: $2, - Value: $2.Value, - }, - OpenCurlyBracketTkn: $4, - Stmts: $5, - CloseCurlyBracketTkn: $6, - } - - if $3 != nil { - iface.ExtendsTkn = $3.(*ast.StmtInterface).ExtendsTkn - iface.Extends = $3.(*ast.StmtInterface).Extends - iface.ExtendsSeparatorTkns = $3.(*ast.StmtInterface).ExtendsSeparatorTkns - } - - $$ = iface - } -; - - -class_entry_type: - T_CLASS - { - $$ = &ast.StmtClass{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - ClassTkn: $1, - } - } - | T_ABSTRACT T_CLASS - { - $$ = &ast.StmtClass{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $2), - Modifiers: []ast.Vertex{ - &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - IdentifierTkn: $1, - Value: $1.Value, - }, - }, - ClassTkn: $2, - } - } - | T_TRAIT - { - $$ = &ast.StmtTrait{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - TraitTkn: $1, - } - } - | T_FINAL T_CLASS - { - $$ = &ast.StmtClass{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $2), - Modifiers: []ast.Vertex{ - &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - IdentifierTkn: $1, - Value: $1.Value, - }, - }, - ClassTkn: $2, - } - } -; - -extends_from: - /* empty */ - { - $$ = nil - } - | T_EXTENDS fully_qualified_class_name - { - $$ = &ast.StmtClass{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), - ExtendsTkn: $1, - Extends: $2, - } - } -; - -interface_entry: - T_INTERFACE - { - $$ = $1 - } -; - -interface_extends_list: - /* empty */ - { - $$ = nil - } - | T_EXTENDS interface_list - { - $$ = &ast.StmtInterface{ - Position: yylex.(*Parser).builder.NewTokenNodeListPosition($1, $2.(*ParserSeparatedList).Items), - ExtendsTkn: $1, - Extends: $2.(*ParserSeparatedList).Items, - ExtendsSeparatorTkns: $2.(*ParserSeparatedList).SeparatorTkns, - }; - } -; - -implements_list: - /* empty */ - { - $$ = nil - } - | T_IMPLEMENTS interface_list - { - $$ = &ast.StmtClass{ - Position: yylex.(*Parser).builder.NewTokenNodeListPosition($1, $2.(*ParserSeparatedList).Items), - ImplementsTkn: $1, - Implements: $2.(*ParserSeparatedList).Items, - ImplementsSeparatorTkns: $2.(*ParserSeparatedList).SeparatorTkns, - }; - } -; - -interface_list: - fully_qualified_class_name - { - $$ = &ParserSeparatedList{ - Items: []ast.Vertex{$1}, - } - } - | interface_list ',' fully_qualified_class_name - { - $1.(*ParserSeparatedList).SeparatorTkns = append($1.(*ParserSeparatedList).SeparatorTkns, $2) - $1.(*ParserSeparatedList).Items = append($1.(*ParserSeparatedList).Items, $3) - - $$ = $1 - } -; - -foreach_optional_arg: - /* empty */ - { - $$ = nil - } - | T_DOUBLE_ARROW foreach_variable - { - $$ = &ast.StmtForeach{ - DoubleArrowTkn: $1, - Var: $2, - } - } -; - -foreach_variable: - variable - { - $$ = $1 - } - | '&' variable - { - $$ = &ast.StmtForeach{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), - AmpersandTkn: $1, - Var: $2, - } - } - | T_LIST '(' assignment_list ')' - { - pairList := $3.(*ParserSeparatedList) - fistPair := pairList.Items[0].(*ast.ExprArrayItem) - - if fistPair.Key == nil && fistPair.Val == nil && len(pairList.Items) == 1 { - pairList.Items = nil - } - - $$ = &ast.ExprList{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $4), - ListTkn: $1, - OpenBracketTkn: $2, - Items: $3.(*ParserSeparatedList).Items, - SeparatorTkns: $3.(*ParserSeparatedList).SeparatorTkns, - CloseBracketTkn: $4, - } - } -; - -for_statement: - statement - { - $$ = &ast.StmtFor{ - Position: yylex.(*Parser).builder.NewNodePosition($1), - Stmt: $1, - } - } - | ':' inner_statement_list T_ENDFOR ';' - { - $$ = &ast.StmtFor{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $4), - ColonTkn: $1, - Stmt: &ast.StmtStmtList{ - Position: yylex.(*Parser).builder.NewNodeListPosition($2), - Stmts: $2, - }, - EndForTkn: $3, - SemiColonTkn: $4, - } - } -; - -foreach_statement: - statement - { - $$ = &ast.StmtForeach{ - Position: yylex.(*Parser).builder.NewNodePosition($1), - Stmt: $1, - } - } - | ':' inner_statement_list T_ENDFOREACH ';' - { - $$ = &ast.StmtForeach{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $4), - ColonTkn: $1, - Stmt: &ast.StmtStmtList{ - Position: yylex.(*Parser).builder.NewNodeListPosition($2), - Stmts: $2, - }, - EndForeachTkn: $3, - SemiColonTkn: $4, - } - } -; - - -declare_statement: - statement - { - $$ = &ast.StmtDeclare{ - Position: yylex.(*Parser).builder.NewNodePosition($1), - Stmt: $1, - } - } - | ':' inner_statement_list T_ENDDECLARE ';' - { - $$ = &ast.StmtDeclare{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $4), - ColonTkn: $1, - Stmt: &ast.StmtStmtList{ - Position: yylex.(*Parser).builder.NewNodeListPosition($2), - Stmts: $2, - }, - EndDeclareTkn: $3, - SemiColonTkn: $4, - } - } -; - - -declare_list: - T_STRING '=' static_scalar - { - $$ = &ParserSeparatedList{ - Items: []ast.Vertex{ - &ast.StmtConstant{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $3), - Name: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - IdentifierTkn: $1, - Value: $1.Value, - }, - EqualTkn: $2, - Expr: $3, - }, - }, - } - } - | declare_list ',' T_STRING '=' static_scalar - { - $1.(*ParserSeparatedList).SeparatorTkns = append($1.(*ParserSeparatedList).SeparatorTkns, $2) - $1.(*ParserSeparatedList).Items = append( - $1.(*ParserSeparatedList).Items, - &ast.StmtConstant{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($3, $5), - Name: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($3), - IdentifierTkn: $3, - Value: $3.Value, - }, - EqualTkn: $4, - Expr: $5, - }, - ) - - $$ = $1 - } -; - - -switch_case_list: - '{' case_list '}' - { - $$ = &ast.StmtSwitch{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $3), - OpenCurlyBracketTkn: $1, - Cases: $2, - CloseCurlyBracketTkn: $3, - } - } - | '{' ';' case_list '}' - { - $$ = &ast.StmtSwitch{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $4), - OpenCurlyBracketTkn: $1, - CaseSeparatorTkn: $2, - Cases: $3, - CloseCurlyBracketTkn: $4, - } - } - | ':' case_list T_ENDSWITCH ';' - { - $$ = &ast.StmtSwitch{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $4), - ColonTkn: $1, - Cases: $2, - EndSwitchTkn: $3, - SemiColonTkn: $4, - } - } - | ':' ';' case_list T_ENDSWITCH ';' - { - $$ = &ast.StmtSwitch{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $5), - ColonTkn: $1, - CaseSeparatorTkn: $2, - Cases: $3, - EndSwitchTkn: $4, - SemiColonTkn: $5, - } - } -; - - -case_list: - /* empty */ - { - $$ = nil - } - | case_list T_CASE expr case_separator inner_statement_list - { - $$ = append($1, &ast.StmtCase{ - Position: yylex.(*Parser).builder.NewTokenNodeListPosition($2, $5), - CaseTkn: $2, - Cond: $3, - CaseSeparatorTkn: $4, - Stmts: $5, - }) - } - | case_list T_DEFAULT case_separator inner_statement_list - { - $$ = append($1, &ast.StmtDefault{ - Position: yylex.(*Parser).builder.NewTokenNodeListPosition($2, $4), - DefaultTkn: $2, - CaseSeparatorTkn: $3, - Stmts: $4, - }) - } -; - - -case_separator: - ':' - { - $$ = $1 - } - | ';' - { - $$ = $1 - } -; - - -while_statement: - statement - { - $$ = &ast.StmtWhile{ - Position: yylex.(*Parser).builder.NewNodePosition($1), - Stmt: $1, - } - } - | ':' inner_statement_list T_ENDWHILE ';' - { - $$ = &ast.StmtWhile{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $4), - ColonTkn: $1, - Stmt: &ast.StmtStmtList{ - Position: yylex.(*Parser).builder.NewNodeListPosition($2), - Stmts: $2, - }, - EndWhileTkn: $3, - SemiColonTkn: $4, - } - } -; - - - -elseif_list: - /* empty */ - { - $$ = nil - } - | elseif_list T_ELSEIF parenthesis_expr statement - { - $$ = append($1, &ast.StmtElseIf{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($2, $4), - ElseIfTkn: $2, - OpenParenthesisTkn: $3.(*ast.ExprBrackets).OpenParenthesisTkn, - Cond: $3.(*ast.ExprBrackets).Expr, - CloseParenthesisTkn: $3.(*ast.ExprBrackets).CloseParenthesisTkn, - Stmt: $4, - }) - } -; - - -new_elseif_list: - /* empty */ - { - $$ = nil - } - | new_elseif_list T_ELSEIF parenthesis_expr ':' inner_statement_list - { - $$ = append($1, &ast.StmtElseIf{ - Position: yylex.(*Parser).builder.NewTokenNodeListPosition($2, $5), - ElseIfTkn: $2, - OpenParenthesisTkn: $3.(*ast.ExprBrackets).OpenParenthesisTkn, - Cond: $3.(*ast.ExprBrackets).Expr, - CloseParenthesisTkn: $3.(*ast.ExprBrackets).CloseParenthesisTkn, - ColonTkn: $4, - Stmt: &ast.StmtStmtList{ - Position: yylex.(*Parser).builder.NewNodeListPosition($5), - Stmts: $5, - }, - }) - } -; - - -else_single: - /* empty */ - { - $$ = nil - } - | T_ELSE statement - { - $$ = &ast.StmtElse{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), - ElseTkn: $1, - Stmt: $2, - } - } -; - - -new_else_single: - /* empty */ - { - $$ = nil - } - | T_ELSE ':' inner_statement_list - { - $$ = &ast.StmtElse{ - Position: yylex.(*Parser).builder.NewTokenNodeListPosition($1, $3), - ElseTkn: $1, - ColonTkn: $2, - Stmt: &ast.StmtStmtList{ - Position: yylex.(*Parser).builder.NewNodeListPosition($3), - Stmts: $3, - }, - } - } -; - - -parameter_list: - non_empty_parameter_list - { - $$ = $1 - } - | /* empty */ - { - $$ = &ParserSeparatedList{} - } -; - -non_empty_parameter_list: - parameter - { - $$ = &ParserSeparatedList{ - Items: []ast.Vertex{$1}, - } - } - | non_empty_parameter_list ',' parameter - { - $1.(*ParserSeparatedList).SeparatorTkns = append($1.(*ParserSeparatedList).SeparatorTkns, $2) - $1.(*ParserSeparatedList).Items = append($1.(*ParserSeparatedList).Items, $3) - - $$ = $1 - } -; - -parameter: - optional_class_type is_reference is_variadic T_VARIABLE - { - pos := yylex.(*Parser).builder.NewTokenPosition($4) - if $1 != nil { - pos = yylex.(*Parser).builder.NewNodeTokenPosition($1, $4) - } else if $2 != nil { - pos = yylex.(*Parser).builder.NewTokensPosition($2, $4) - } else if $3 != nil { - pos = yylex.(*Parser).builder.NewTokensPosition($3, $4) - } - - $$ = &ast.Parameter{ - Position: pos, - Type: $1, - AmpersandTkn: $2, - VariadicTkn: $3, - Var: &ast.ExprVariable{ - Position: yylex.(*Parser).builder.NewTokenPosition($4), - Name: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($4), - IdentifierTkn: $4, - Value: $4.Value, - }, - }, - } - } - | optional_class_type is_reference is_variadic T_VARIABLE '=' expr - { - pos := yylex.(*Parser).builder.NewTokenNodePosition($4, $6) - if $1 != nil { - pos = yylex.(*Parser).builder.NewNodesPosition($1, $6) - } else if $2 != nil { - pos = yylex.(*Parser).builder.NewTokenNodePosition($2, $6) - } else if $3 != nil { - pos = yylex.(*Parser).builder.NewTokenNodePosition($3, $6) - } - - $$ = &ast.Parameter{ - Position: pos, - Type: $1, - AmpersandTkn: $2, - VariadicTkn: $3, - Var: &ast.ExprVariable{ - Position: yylex.(*Parser).builder.NewTokenPosition($4), - Name: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($4), - IdentifierTkn: $4, - Value: $4.Value, - }, - }, - EqualTkn: $5, - DefaultValue: $6, - } - } -; - - -optional_class_type: - /* empty */ - { - $$ = nil - } - | T_ARRAY - { - $$ = &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - IdentifierTkn: $1, - Value: $1.Value, - } - } - | T_CALLABLE - { - $$ = &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - IdentifierTkn: $1, - Value: $1.Value, - } - } - | fully_qualified_class_name - { - $$ = $1 - } -; - - -function_call_parameter_list: - '(' ')' - { - $$ = &ArgumentList{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $2), - OpenParenthesisTkn: $1, - CloseParenthesisTkn: $2, - } - } - | '(' non_empty_function_call_parameter_list ')' - { - argumentList := $2.(*ArgumentList) - argumentList.Position = yylex.(*Parser).builder.NewTokensPosition($1, $3) - argumentList.OpenParenthesisTkn = $1 - argumentList.CloseParenthesisTkn = $3 - - $$ = argumentList - } - | '(' yield_expr ')' - { - $$ = &ArgumentList{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $3), - OpenParenthesisTkn: $1, - Arguments: []ast.Vertex{ - &ast.Argument{ - Position: yylex.(*Parser).builder.NewNodePosition($2), - Expr: $2, - }, - }, - CloseParenthesisTkn: $3, - } - } -; - - -non_empty_function_call_parameter_list: - function_call_parameter - { - $$ = &ArgumentList{ - Arguments: []ast.Vertex{$1}, - } - } - | non_empty_function_call_parameter_list ',' function_call_parameter - { - $1.(*ArgumentList).SeparatorTkns = append($1.(*ArgumentList).SeparatorTkns, $2) - $1.(*ArgumentList).Arguments = append($1.(*ArgumentList).Arguments, $3) - - $$ = $1 - } -; - -function_call_parameter: - expr_without_variable - { - $$ = &ast.Argument{ - Position: yylex.(*Parser).builder.NewNodePosition($1), - Expr: $1, - } - } - | variable - { - $$ = &ast.Argument{ - Position: yylex.(*Parser).builder.NewNodePosition($1), - Expr: $1, - } - } - | '&' w_variable - { - $$ = &ast.Argument{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), - AmpersandTkn: $1, - Expr: $2, - } - } - | T_ELLIPSIS expr - { - $$ = &ast.Argument{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), - VariadicTkn: $1, - Expr: $2, - } - } -; - -global_var_list: - global_var_list ',' global_var - { - $1.(*ast.StmtGlobal).Vars = append($1.(*ast.StmtGlobal).Vars, $3) - $1.(*ast.StmtGlobal).SeparatorTkns = append($1.(*ast.StmtGlobal).SeparatorTkns, $2) - - $$ = $1 - } - | global_var - { - $$ = &ast.StmtGlobal{ - Vars: []ast.Vertex{$1}, - } - } -; - - -global_var: - T_VARIABLE - { - $$ = &ast.ExprVariable{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - Name: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - IdentifierTkn: $1, - Value: $1.Value, - }, - } - } - | '$' r_variable - { - $$ = &ast.ExprVariable{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), - DollarTkn: $1, - Name: $2, - } - } - | '$' '{' expr '}' - { - $$ = &ast.ExprVariable{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $4), - DollarTkn: $1, - OpenCurlyBracketTkn: $2, - Name: $3, - CloseCurlyBracketTkn: $4, - } - } -; - - -static_var_list: - static_var_list ',' T_VARIABLE - { - $1.(*ast.StmtStatic).Vars = append($1.(*ast.StmtStatic).Vars, &ast.StmtStaticVar{ - Position: yylex.(*Parser).builder.NewTokenPosition($3), - Var: &ast.ExprVariable{ - Position: yylex.(*Parser).builder.NewTokenPosition($3), - Name: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($3), - IdentifierTkn: $3, - Value: $3.Value, - }, - }, - }) - $1.(*ast.StmtStatic).SeparatorTkns = append($1.(*ast.StmtStatic).SeparatorTkns, $2) - - $$ = $1 - } - | static_var_list ',' T_VARIABLE '=' static_scalar - { - $1.(*ast.StmtStatic).Vars = append($1.(*ast.StmtStatic).Vars, &ast.StmtStaticVar{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($3, $5), - Var: &ast.ExprVariable{ - Position: yylex.(*Parser).builder.NewTokenPosition($3), - Name: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($3), - IdentifierTkn: $3, - Value: $3.Value, - }, - }, - EqualTkn: $4, - Expr: $5, - }) - $1.(*ast.StmtStatic).SeparatorTkns = append($1.(*ast.StmtStatic).SeparatorTkns, $2) - - $$ = $1 - } - | T_VARIABLE - { - $$ = &ast.StmtStatic{ - Vars: []ast.Vertex{ - &ast.StmtStaticVar{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - Var: &ast.ExprVariable{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - Name: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - IdentifierTkn: $1, - Value: $1.Value, - }, - }, - }, - }, - } - } - | T_VARIABLE '=' static_scalar - { - $$ = &ast.StmtStatic{ - Vars: []ast.Vertex{ - &ast.StmtStaticVar{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $3), - Var: &ast.ExprVariable{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - Name: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - IdentifierTkn: $1, - Value: $1.Value, - }, - }, - EqualTkn: $2, - Expr: $3, - }, - }, - } - } -; - - -class_statement_list: - class_statement_list class_statement - { - $$ = append($1, $2) - } - | /* empty */ - { - $$ = []ast.Vertex{} - } -; - - -class_statement: - variable_modifiers class_variable_declaration ';' - { - $$ = &ast.StmtPropertyList{ - Position: yylex.(*Parser).builder.NewNodeListTokenPosition($1, $3), - Modifiers: $1, - Props: $2.(*ParserSeparatedList).Items, - SeparatorTkns: $2.(*ParserSeparatedList).SeparatorTkns, - SemiColonTkn: $3, - } - } - | class_constant_declaration ';' - { - $1.(*ast.StmtClassConstList).SemiColonTkn = $2 - $1.(*ast.StmtClassConstList).Position = yylex.(*Parser).builder.NewNodeTokenPosition($1, $2) - $$ = $1 - } - | trait_use_statement - { - $$ = $1 - } - | method_modifiers function is_reference T_STRING '(' parameter_list ')' method_body - { - pos := yylex.(*Parser).builder.NewTokenNodePosition($2, $8) - if $1 != nil { - pos = yylex.(*Parser).builder.NewNodeListNodePosition($1, $8) - } - - $$ = &ast.StmtClassMethod{ - Position: pos, - Modifiers: $1, - FunctionTkn: $2, - AmpersandTkn: $3, - Name: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($4), - IdentifierTkn: $4, - Value: $4.Value, - }, - OpenParenthesisTkn: $5, - Params: $6.(*ParserSeparatedList).Items, - SeparatorTkns: $6.(*ParserSeparatedList).SeparatorTkns, - CloseParenthesisTkn: $7, - Stmt: $8, - } - } -; - -trait_use_statement: - T_USE trait_list trait_adaptations - { - traitUse := &ast.StmtTraitUse{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $3), - UseTkn: $1, - Traits: $2.(*ParserSeparatedList).Items, - SeparatorTkns: $2.(*ParserSeparatedList).SeparatorTkns, - } - - switch n := $3.(type) { - case *TraitAdaptationList : - traitUse.OpenCurlyBracketTkn = n.OpenCurlyBracketTkn - traitUse.Adaptations = n.Adaptations - traitUse.CloseCurlyBracketTkn = n.CloseCurlyBracketTkn - case *ast.StmtNop : - traitUse.SemiColonTkn = n.SemiColonTkn - }; - - $$ = traitUse - } -; - -trait_list: - fully_qualified_class_name - { - $$ = &ParserSeparatedList{ - Items: []ast.Vertex{$1}, - } - } - | trait_list ',' fully_qualified_class_name - { - $1.(*ParserSeparatedList).SeparatorTkns = append($1.(*ParserSeparatedList).SeparatorTkns, $2) - $1.(*ParserSeparatedList).Items = append($1.(*ParserSeparatedList).Items, $3) - - $$ = $1 - } -; - -trait_adaptations: - ';' - { - $$ = &ast.StmtNop{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - SemiColonTkn: $1, - } - } - | '{' trait_adaptation_list '}' - { - $$ = &TraitAdaptationList{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $3), - OpenCurlyBracketTkn: $1, - Adaptations: $2, - CloseCurlyBracketTkn: $3, - } - } -; - -trait_adaptation_list: - /* empty */ - { - $$ = nil - } - | non_empty_trait_adaptation_list - { - $$ = $1 - } -; - -non_empty_trait_adaptation_list: - trait_adaptation_statement - { - $$ = []ast.Vertex{$1} - } - | non_empty_trait_adaptation_list trait_adaptation_statement - { - $$ = append($1, $2) - } -; - -trait_adaptation_statement: - trait_precedence ';' - { - $1.(*ast.StmtTraitUsePrecedence).SemiColonTkn = $2 - - $$ = $1; - } - | trait_alias ';' - { - $1.(*ast.StmtTraitUseAlias).SemiColonTkn = $2 - - $$ = $1; - } -; - -trait_precedence: - trait_method_reference_fully_qualified T_INSTEADOF trait_reference_list - { - $$ = &ast.StmtTraitUsePrecedence{ - Position: yylex.(*Parser).builder.NewNodeNodeListPosition($1, $3.(*ParserSeparatedList).Items), - Trait: $1.(*TraitMethodRef).Trait, - DoubleColonTkn: $1.(*TraitMethodRef).DoubleColonTkn, - Method: $1.(*TraitMethodRef).Method, - InsteadofTkn: $2, - Insteadof: $3.(*ParserSeparatedList).Items, - SeparatorTkns: $3.(*ParserSeparatedList).SeparatorTkns, - } - } -; - -trait_reference_list: - fully_qualified_class_name - { - $$ = &ParserSeparatedList{ - Items: []ast.Vertex{$1}, - } - } - | trait_reference_list ',' fully_qualified_class_name - { - $1.(*ParserSeparatedList).SeparatorTkns = append($1.(*ParserSeparatedList).SeparatorTkns, $2) - $1.(*ParserSeparatedList).Items = append($1.(*ParserSeparatedList).Items, $3) - - $$ = $1 - } -; - -trait_method_reference: - T_STRING - { - $$ = &TraitMethodRef{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - Method: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - IdentifierTkn: $1, - Value: $1.Value, - }, - } - } - | trait_method_reference_fully_qualified - { - $$ = $1 - } -; - -trait_method_reference_fully_qualified: - fully_qualified_class_name T_PAAMAYIM_NEKUDOTAYIM T_STRING - { - $$ = &TraitMethodRef{ - Position: yylex.(*Parser).builder.NewNodeTokenPosition($1, $3), - Trait: $1, - DoubleColonTkn: $2, - Method: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($3), - IdentifierTkn: $3, - Value: $3.Value, - }, - } - } -; - -trait_alias: - trait_method_reference T_AS trait_modifiers T_STRING - { - $$ = &ast.StmtTraitUseAlias{ - Position: yylex.(*Parser).builder.NewNodeTokenPosition($1, $4), - Trait: $1.(*TraitMethodRef).Trait, - DoubleColonTkn: $1.(*TraitMethodRef).DoubleColonTkn, - Method: $1.(*TraitMethodRef).Method, - AsTkn: $2, - Modifier: $3, - Alias: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($4), - IdentifierTkn: $4, - Value: $4.Value, - }, - } - } - | trait_method_reference T_AS member_modifier - { - $$ = &ast.StmtTraitUseAlias{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Trait: $1.(*TraitMethodRef).Trait, - DoubleColonTkn: $1.(*TraitMethodRef).DoubleColonTkn, - Method: $1.(*TraitMethodRef).Method, - AsTkn: $2, - Modifier: $3, - } - } -; - -trait_modifiers: - /* empty */ - { - $$ = nil - } - | member_modifier - { - $$ = $1 - } -; - -method_body: - ';' /* abstract method */ - { - $$ = &ast.StmtNop{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - SemiColonTkn: $1, - } - } - | '{' inner_statement_list '}' - { - $$ = &ast.StmtStmtList{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $3), - OpenCurlyBracketTkn: $1, - Stmts: $2, - CloseCurlyBracketTkn: $3, - } - } -; - -variable_modifiers: - non_empty_member_modifiers - { - $$ = $1; - } - | T_VAR - { - $$ = []ast.Vertex{ - &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - IdentifierTkn: $1, - Value: $1.Value, - }, - } - } -; - -method_modifiers: - /* empty */ - { - $$ = nil - } - | non_empty_member_modifiers - { - $$ = $1 - } -; - -non_empty_member_modifiers: - member_modifier - { - $$ = []ast.Vertex{$1} - } - | non_empty_member_modifiers member_modifier - { - $$ = append($1, $2) - } -; - -member_modifier: - T_PUBLIC - { - $$ = &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - IdentifierTkn: $1, - Value: $1.Value, - } - } - | T_PROTECTED - { - $$ = &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - IdentifierTkn: $1, - Value: $1.Value, - } - } - | T_PRIVATE - { - $$ = &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - IdentifierTkn: $1, - Value: $1.Value, - } - } - | T_STATIC - { - $$ = &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - IdentifierTkn: $1, - Value: $1.Value, - } - } - | T_ABSTRACT - { - $$ = &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - IdentifierTkn: $1, - Value: $1.Value, - } - } - | T_FINAL - { - $$ = &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - IdentifierTkn: $1, - Value: $1.Value, - } - } -; - -class_variable_declaration: - class_variable_declaration ',' T_VARIABLE - { - item := &ast.StmtProperty{ - Position: yylex.(*Parser).builder.NewTokenPosition($3), - Var: &ast.ExprVariable{ - Position: yylex.(*Parser).builder.NewTokenPosition($3), - Name: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($3), - IdentifierTkn: $3, - Value: $3.Value, - }, - }, - } - - $1.(*ParserSeparatedList).SeparatorTkns = append($1.(*ParserSeparatedList).SeparatorTkns, $2) - $1.(*ParserSeparatedList).Items = append($1.(*ParserSeparatedList).Items, item) - - $$ = $1 - } - | class_variable_declaration ',' T_VARIABLE '=' static_scalar - { - item := &ast.StmtProperty{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($3, $5), - Var: &ast.ExprVariable{ - Position: yylex.(*Parser).builder.NewTokenPosition($3), - Name: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($3), - IdentifierTkn: $3, - Value: $3.Value, - }, - }, - EqualTkn: $4, - Expr: $5, - } - - $1.(*ParserSeparatedList).SeparatorTkns = append($1.(*ParserSeparatedList).SeparatorTkns, $2) - $1.(*ParserSeparatedList).Items = append($1.(*ParserSeparatedList).Items, item) - - $$ = $1 - } - | T_VARIABLE - { - $$ = &ParserSeparatedList{ - Items: []ast.Vertex{ - &ast.StmtProperty{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - Var: &ast.ExprVariable{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - Name: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - IdentifierTkn: $1, - Value: $1.Value, - }, - }, - Expr: nil, - }, - }, - } - } - | T_VARIABLE '=' static_scalar - { - $$ = &ParserSeparatedList{ - Items: []ast.Vertex{ - &ast.StmtProperty{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $3), - Var: &ast.ExprVariable{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - Name: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - IdentifierTkn: $1, - Value: $1.Value, - }, - }, - EqualTkn: $2, - Expr: $3, - }, - }, - } - } -; - -class_constant_declaration: - class_constant_declaration ',' T_STRING '=' static_scalar - { - constList := $1.(*ast.StmtClassConstList) - constList.Position = yylex.(*Parser).builder.NewNodesPosition($1, $5) - constList.SeparatorTkns = append(constList.SeparatorTkns, $2) - constList.Consts = append(constList.Consts, &ast.StmtConstant{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($3, $5), - Name: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($3), - IdentifierTkn: $3, - Value: $3.Value, - }, - EqualTkn: $4, - Expr: $5, - }) - - $$ = $1 - } - | T_CONST T_STRING '=' static_scalar - { - $$ = &ast.StmtClassConstList{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $4), - ConstTkn: $1, - Consts: []ast.Vertex{ - &ast.StmtConstant{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($2, $4), - Name: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($2), - IdentifierTkn: $2, - Value: $2.Value, - }, - EqualTkn: $3, - Expr: $4, - }, - }, - } - } -; - -echo_expr_list: - echo_expr_list ',' expr - { - $1.(*ast.StmtEcho).Exprs = append($1.(*ast.StmtEcho).Exprs, $3) - $1.(*ast.StmtEcho).SeparatorTkns = append($1.(*ast.StmtEcho).SeparatorTkns, $2) - - $$ = $1 - } - | expr - { - $$ = &ast.StmtEcho{ - Exprs: []ast.Vertex{$1}, - } - } -; - - -for_expr: - /* empty */ - { - $$ = &ParserSeparatedList{} - } - | non_empty_for_expr - { - $$ = $1 - } -; - -non_empty_for_expr: - non_empty_for_expr ',' expr - { - $1.(*ParserSeparatedList).SeparatorTkns = append($1.(*ParserSeparatedList).SeparatorTkns, $2) - $1.(*ParserSeparatedList).Items = append($1.(*ParserSeparatedList).Items, $3) - - $$ = $1 - } - | expr - { - $$ = &ParserSeparatedList{ - Items: []ast.Vertex{$1}, - } - } -; - -chaining_method_or_property: - chaining_method_or_property variable_property - { - $$ = append($1, $2...) - } - | variable_property - { - $$ = $1 - } -; - -chaining_dereference: - chaining_dereference '[' dim_offset ']' - { - fetch := &ast.ExprArrayDimFetch{ - Position: yylex.(*Parser).builder.NewTokensPosition($2, $4), - Var: nil, - OpenBracketTkn: $2, - Dim: $3, - CloseBracketTkn: $4, - } - - $$ = append($1, fetch) - } - | '[' dim_offset ']' - { - fetch := &ast.ExprArrayDimFetch{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $3), - Var: nil, - OpenBracketTkn: $1, - Dim: $2, - CloseBracketTkn: $3, - } - - $$ = []ast.Vertex{fetch} - } -; - -chaining_instance_call: - chaining_dereference chaining_method_or_property - { - $$ = append($1, $2...) - } - | chaining_dereference - { - $$ = $1 - } - | chaining_method_or_property - { - $$ = $1 - } -; - -instance_call: - /* empty */ - { - $$ = nil - } - | chaining_instance_call - { - $$ = $1 - } -; - -new_expr: - T_NEW class_name_reference ctor_arguments - { - if $3 != nil { - $$ = &ast.ExprNew{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $3), - NewTkn: $1, - Class: $2, - OpenParenthesisTkn: $3.(*ArgumentList).OpenParenthesisTkn, - Args: $3.(*ArgumentList).Arguments, - SeparatorTkns: $3.(*ArgumentList).SeparatorTkns, - CloseParenthesisTkn: $3.(*ArgumentList).CloseParenthesisTkn, - } - } else { - $$ = &ast.ExprNew{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), - NewTkn: $1, - Class: $2, - } - } - } -; - -expr_without_variable: - T_LIST '(' assignment_list ')' '=' expr - { - $$ = &ast.ExprAssign{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $6), - Var: &ast.ExprList{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $4), - ListTkn: $1, - OpenBracketTkn: $2, - Items: $3.(*ParserSeparatedList).Items, - SeparatorTkns: $3.(*ParserSeparatedList).SeparatorTkns, - CloseBracketTkn: $4, - }, - EqualTkn: $5, - Expr: $6, - } - } - | variable '=' expr - { - $$ = &ast.ExprAssign{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Var: $1, - EqualTkn: $2, - Expr: $3, - } - } - | variable '=' '&' variable - { - $$ = &ast.ExprAssignReference{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $4), - Var: $1, - EqualTkn: $2, - AmpersandTkn: $3, - Expr: $4, - } - } - | variable '=' '&' T_NEW class_name_reference ctor_arguments - { - var _new *ast.ExprNew - if $6 != nil { - _new = &ast.ExprNew{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($4, $6), - NewTkn: $4, - Class: $5, - OpenParenthesisTkn: $6.(*ArgumentList).OpenParenthesisTkn, - Args: $6.(*ArgumentList).Arguments, - SeparatorTkns: $6.(*ArgumentList).SeparatorTkns, - CloseParenthesisTkn: $6.(*ArgumentList).CloseParenthesisTkn, - } - } else { - _new = &ast.ExprNew{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($4, $5), - NewTkn: $4, - Class: $5, - } - } - - $$ = &ast.ExprAssignReference{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, _new), - Var: $1, - EqualTkn: $2, - AmpersandTkn: $3, - Expr: _new, - } - } - | T_CLONE expr - { - $$ = &ast.ExprClone{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), - CloneTkn: $1, - Expr: $2, - } - } - | variable T_PLUS_EQUAL expr - { - $$ = &ast.ExprAssignPlus{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Var: $1, - EqualTkn: $2, - Expr: $3, - } - } - | variable T_MINUS_EQUAL expr - { - $$ = &ast.ExprAssignMinus{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Var: $1, - EqualTkn: $2, - Expr: $3, - } - } - | variable T_MUL_EQUAL expr - { - $$ = &ast.ExprAssignMul{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Var: $1, - EqualTkn: $2, - Expr: $3, - } - } - | variable T_POW_EQUAL expr - { - $$ = &ast.ExprAssignPow{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Var: $1, - EqualTkn: $2, - Expr: $3, - } - } - | variable T_DIV_EQUAL expr - { - $$ = &ast.ExprAssignDiv{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Var: $1, - EqualTkn: $2, - Expr: $3, - } - } - | variable T_CONCAT_EQUAL expr - { - $$ = &ast.ExprAssignConcat{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Var: $1, - EqualTkn: $2, - Expr: $3, - } - } - | variable T_MOD_EQUAL expr - { - $$ = &ast.ExprAssignMod{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Var: $1, - EqualTkn: $2, - Expr: $3, - } - } - | variable T_AND_EQUAL expr - { - $$ = &ast.ExprAssignBitwiseAnd{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Var: $1, - EqualTkn: $2, - Expr: $3, - } - } - | variable T_OR_EQUAL expr - { - $$ = &ast.ExprAssignBitwiseOr{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Var: $1, - EqualTkn: $2, - Expr: $3, - } - } - | variable T_XOR_EQUAL expr - { - $$ = &ast.ExprAssignBitwiseXor{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Var: $1, - EqualTkn: $2, - Expr: $3, - } - } - | variable T_SL_EQUAL expr - { - $$ = &ast.ExprAssignShiftLeft{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Var: $1, - EqualTkn: $2, - Expr: $3, - } - } - | variable T_SR_EQUAL expr - { - $$ = &ast.ExprAssignShiftRight{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Var: $1, - EqualTkn: $2, - Expr: $3, - } - } - | rw_variable T_INC - { - $$ = &ast.ExprPostInc{ - Position: yylex.(*Parser).builder.NewNodeTokenPosition($1, $2), - Var: $1, - IncTkn: $2, - } - } - | T_INC rw_variable - { - $$ = &ast.ExprPreInc{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), - IncTkn: $1, - Var: $2, - } - } - | rw_variable T_DEC - { - $$ = &ast.ExprPostDec{ - Position: yylex.(*Parser).builder.NewNodeTokenPosition($1, $2), - Var: $1, - DecTkn: $2, - } - } - | T_DEC rw_variable - { - $$ = &ast.ExprPreDec{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), - DecTkn: $1, - Var: $2, - } - } - | expr T_BOOLEAN_OR expr - { - $$ = &ast.ExprBinaryBooleanOr{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | expr T_BOOLEAN_AND expr - { - $$ = &ast.ExprBinaryBooleanAnd{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | expr T_LOGICAL_OR expr - { - $$ = &ast.ExprBinaryLogicalOr{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | expr T_LOGICAL_AND expr - { - $$ = &ast.ExprBinaryLogicalAnd{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | expr T_LOGICAL_XOR expr - { - $$ = &ast.ExprBinaryLogicalXor{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | expr '|' expr - { - $$ = &ast.ExprBinaryBitwiseOr{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | expr '&' expr - { - $$ = &ast.ExprBinaryBitwiseAnd{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | expr '^' expr - { - $$ = &ast.ExprBinaryBitwiseXor{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | expr '.' expr - { - $$ = &ast.ExprBinaryConcat{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | expr '+' expr - { - $$ = &ast.ExprBinaryPlus{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | expr '-' expr - { - $$ = &ast.ExprBinaryMinus{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | expr '*' expr - { - $$ = &ast.ExprBinaryMul{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | expr T_POW expr - { - $$ = &ast.ExprBinaryPow{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | expr '/' expr - { - $$ = &ast.ExprBinaryDiv{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | expr '%' expr - { - $$ = &ast.ExprBinaryMod{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | expr T_SL expr - { - $$ = &ast.ExprBinaryShiftLeft{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | expr T_SR expr - { - $$ = &ast.ExprBinaryShiftRight{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | '+' expr %prec T_INC - { - $$ = &ast.ExprUnaryPlus{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), - PlusTkn: $1, - Expr: $2, - } - } - | '-' expr %prec T_INC - { - $$ = &ast.ExprUnaryMinus{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), - MinusTkn: $1, - Expr: $2, - } - } - | '!' expr - { - $$ = &ast.ExprBooleanNot{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), - ExclamationTkn: $1, - Expr: $2, - } - } - | '~' expr - { - $$ = &ast.ExprBitwiseNot{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), - TildaTkn: $1, - Expr: $2, - } - } - | expr T_IS_IDENTICAL expr - { - $$ = &ast.ExprBinaryIdentical{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | expr T_IS_NOT_IDENTICAL expr - { - $$ = &ast.ExprBinaryNotIdentical{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | expr T_IS_EQUAL expr - { - $$ = &ast.ExprBinaryEqual{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | expr T_IS_NOT_EQUAL expr - { - $$ = &ast.ExprBinaryNotEqual{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | expr '<' expr - { - $$ = &ast.ExprBinarySmaller{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | expr T_IS_SMALLER_OR_EQUAL expr - { - $$ = &ast.ExprBinarySmallerOrEqual{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | expr '>' expr - { - $$ = &ast.ExprBinaryGreater{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | expr T_IS_GREATER_OR_EQUAL expr - { - $$ = &ast.ExprBinaryGreaterOrEqual{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | expr T_INSTANCEOF class_name_reference - { - $$ = &ast.ExprInstanceOf{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Expr: $1, - InstanceOfTkn: $2, - Class: $3, - } - } - | parenthesis_expr - { - $$ = $1 - } - | new_expr - { - $$ = $1 - } - | '(' new_expr ')' instance_call - { - $$ = &ast.ExprBrackets{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $3), - OpenParenthesisTkn: $1, - Expr: $2, - CloseParenthesisTkn: $3, - } - - for _, n := range($4) { - switch nn := n.(type) { - case *ast.ExprFunctionCall: - nn.Function = $$ - nn.Position = yylex.(*Parser).builder.NewNodesPosition($$, nn) - $$ = nn - - case *ast.ExprArrayDimFetch: - nn.Var = $$ - nn.Position = yylex.(*Parser).builder.NewNodesPosition($$, nn) - $$ = nn - - case *ast.ExprPropertyFetch: - nn.Var = $$ - nn.Position = yylex.(*Parser).builder.NewNodesPosition($$, nn) - $$ = nn - - case *ast.ExprMethodCall: - nn.Var = $$ - nn.Position = yylex.(*Parser).builder.NewNodesPosition($$, nn) - $$ = nn - } - } - } - | expr '?' expr ':' expr - { - $$ = &ast.ExprTernary{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $5), - Cond: $1, - QuestionTkn: $2, - IfTrue: $3, - ColonTkn: $4, - IfFalse: $5, - } - } - | expr '?' ':' expr - { - $$ = &ast.ExprTernary{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $4), - Cond: $1, - QuestionTkn: $2, - ColonTkn: $3, - IfFalse: $4, - } - } - | internal_functions_in_yacc - { - $$ = $1 - } - | T_INT_CAST expr - { - $$ = &ast.ExprCastInt{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), - CastTkn: $1, - Expr: $2, - } - } - | T_DOUBLE_CAST expr - { - $$ = &ast.ExprCastDouble{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), - CastTkn: $1, - Expr: $2, - } - } - | T_STRING_CAST expr - { - $$ = &ast.ExprCastString{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), - CastTkn: $1, - Expr: $2, - } - } - | T_ARRAY_CAST expr - { - $$ = &ast.ExprCastArray{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), - CastTkn: $1, - Expr: $2, - } - } - | T_OBJECT_CAST expr - { - $$ = &ast.ExprCastObject{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), - CastTkn: $1, - Expr: $2, - } - } - | T_BOOL_CAST expr - { - $$ = &ast.ExprCastBool{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), - CastTkn: $1, - Expr: $2, - } - } - | T_UNSET_CAST expr - { - $$ = &ast.ExprCastUnset{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), - CastTkn: $1, - Expr: $2, - } - } - | T_EXIT exit_expr - { - exit := &ast.ExprExit{ - ExitTkn: $1, - } - - if $2 == nil { - exit.Position = yylex.(*Parser).builder.NewTokenPosition($1) - } else { - exit.Position = yylex.(*Parser).builder.NewTokenNodePosition($1, $2) - exit.OpenParenthesisTkn = $2.(*ast.ExprBrackets).OpenParenthesisTkn - exit.Expr = $2.(*ast.ExprBrackets).Expr - exit.CloseParenthesisTkn = $2.(*ast.ExprBrackets).CloseParenthesisTkn - } - - $$ = exit - } - | '@' expr - { - $$ = &ast.ExprErrorSuppress{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), - AtTkn: $1, - Expr: $2, - } - } - | scalar - { - $$ = $1 - } - | combined_scalar_offset - { - $$ = $1 - } - | combined_scalar - { - $$ = $1 - } - | '`' backticks_expr '`' - { - $$ = &ast.ExprShellExec{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $3), - OpenBacktickTkn: $1, - Parts: $2, - CloseBacktickTkn: $3, - } - } - | T_PRINT expr - { - $$ = &ast.ExprPrint{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), - PrintTkn: $1, - Expr: $2, - } - } - | T_YIELD - { - $$ = &ast.ExprYield{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - YieldTkn: $1, - } - } - | function is_reference '(' parameter_list ')' lexical_vars '{' inner_statement_list '}' - { - closure := $6.(*ast.ExprClosure) - - closure.Position = yylex.(*Parser).builder.NewTokensPosition($1, $9) - closure.FunctionTkn = $1 - closure.AmpersandTkn = $2 - closure.OpenParenthesisTkn = $3 - closure.Params = $4.(*ParserSeparatedList).Items - closure.SeparatorTkns = $4.(*ParserSeparatedList).SeparatorTkns - closure.CloseParenthesisTkn = $5 - closure.OpenCurlyBracketTkn = $7 - closure.Stmts = $8 - closure.CloseCurlyBracketTkn = $9 - - $$ = closure - } - | T_STATIC function is_reference '(' parameter_list ')' lexical_vars '{' inner_statement_list '}' - { - closure := $7.(*ast.ExprClosure) - - closure.Position = yylex.(*Parser).builder.NewTokensPosition($1, $10) - closure.StaticTkn = $1 - closure.FunctionTkn = $2 - closure.AmpersandTkn = $3 - closure.OpenParenthesisTkn = $4 - closure.Params = $5.(*ParserSeparatedList).Items - closure.SeparatorTkns = $5.(*ParserSeparatedList).SeparatorTkns - closure.CloseParenthesisTkn = $6 - closure.OpenCurlyBracketTkn = $8 - closure.Stmts = $9 - closure.CloseCurlyBracketTkn = $10 - - $$ = closure - } -; - -yield_expr: - T_YIELD expr_without_variable - { - $$ = &ast.ExprYield{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), - YieldTkn: $1, - Val: $2, - } - } - | T_YIELD variable - { - $$ = &ast.ExprYield{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), - YieldTkn: $1, - Val: $2, - } - } - | T_YIELD expr T_DOUBLE_ARROW expr_without_variable - { - $$ = &ast.ExprYield{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $4), - YieldTkn: $1, - Key: $2, - DoubleArrowTkn: $3, - Val: $4, - } - } - | T_YIELD expr T_DOUBLE_ARROW variable - { - $$ = &ast.ExprYield{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $4), - YieldTkn: $1, - Key: $2, - DoubleArrowTkn: $3, - Val: $4, - } - } -; - -combined_scalar_offset: - combined_scalar '[' dim_offset ']' - { - $$ = &ast.ExprArrayDimFetch{ - Position: yylex.(*Parser).builder.NewNodeTokenPosition($1, $4), - Var: $1, - OpenBracketTkn: $2, - Dim: $3, - CloseBracketTkn: $4, - } - } - | combined_scalar_offset '[' dim_offset ']' - { - $$ = &ast.ExprArrayDimFetch{ - Position: yylex.(*Parser).builder.NewNodeTokenPosition($1, $4), - Var: $1, - OpenBracketTkn: $2, - Dim: $3, - CloseBracketTkn: $4, - } - } - | T_CONSTANT_ENCAPSED_STRING '[' dim_offset ']' - { - $$ = &ast.ExprArrayDimFetch{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $4), - Var: &ast.ScalarString{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - StringTkn: $1, - Value: $1.Value, - }, - OpenBracketTkn: $2, - Dim: $3, - CloseBracketTkn: $4, - } - } - | general_constant '[' dim_offset ']' - { - $$ = &ast.ExprArrayDimFetch{ - Position: yylex.(*Parser).builder.NewNodeTokenPosition($1, $4), - Var: $1, - OpenBracketTkn: $2, - Dim: $3, - CloseBracketTkn: $4, - } - } -; - -combined_scalar: - T_ARRAY '(' array_pair_list ')' - { - $$ = &ast.ExprArray{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $4), - ArrayTkn: $1, - OpenBracketTkn: $2, - Items: $3.(*ParserSeparatedList).Items, - SeparatorTkns: $3.(*ParserSeparatedList).SeparatorTkns, - CloseBracketTkn: $4, - } - } - | '[' array_pair_list ']' - { - $$ = &ast.ExprArray{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $3), - OpenBracketTkn: $1, - Items: $2.(*ParserSeparatedList).Items, - SeparatorTkns: $2.(*ParserSeparatedList).SeparatorTkns, - CloseBracketTkn: $3, - } - } -; - -function: - T_FUNCTION - { - $$ = $1 - } -; - -lexical_vars: - /* empty */ - { - $$ = &ast.ExprClosure{} - } - | T_USE '(' lexical_var_list ')' - { - $$ = &ast.ExprClosure{ - UseTkn: $1, - UseOpenParenthesisTkn: $2, - Uses: $3.(*ParserSeparatedList).Items, - UseSeparatorTkns: $3.(*ParserSeparatedList).SeparatorTkns, - UseCloseParenthesisTkn: $4, - } - } -; - -lexical_var_list: - lexical_var_list ',' T_VARIABLE - { - variable := &ast.ExprClosureUse{ - Position: yylex.(*Parser).builder.NewTokenPosition($3), - Var: &ast.ExprVariable{ - Position: yylex.(*Parser).builder.NewTokenPosition($3), - Name: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($3), - IdentifierTkn: $3, - Value: $3.Value, - }, - }, - } - - $1.(*ParserSeparatedList).SeparatorTkns = append($1.(*ParserSeparatedList).SeparatorTkns, $2) - $1.(*ParserSeparatedList).Items = append($1.(*ParserSeparatedList).Items, variable) - - $$ = $1 - } - | lexical_var_list ',' '&' T_VARIABLE - { - variable := &ast.ExprClosureUse{ - Position: yylex.(*Parser).builder.NewTokensPosition($3, $4), - AmpersandTkn: $3, - Var: &ast.ExprVariable{ - Position: yylex.(*Parser).builder.NewTokenPosition($4), - Name: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($4), - IdentifierTkn: $4, - Value: $4.Value, - }, - }, - } - - $1.(*ParserSeparatedList).SeparatorTkns = append($1.(*ParserSeparatedList).SeparatorTkns, $2) - $1.(*ParserSeparatedList).Items = append($1.(*ParserSeparatedList).Items, variable) - - $$ = $1 - } - | T_VARIABLE - { - variable := &ast.ExprClosureUse{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - Var: &ast.ExprVariable{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - Name: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - IdentifierTkn: $1, - Value: $1.Value, - }, - }, - } - - $$ = &ParserSeparatedList{ - Items: []ast.Vertex{ variable }, - } - } - | '&' T_VARIABLE - { - variable := &ast.ExprClosureUse{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $2), - AmpersandTkn: $1, - Var: &ast.ExprVariable{ - Position: yylex.(*Parser).builder.NewTokenPosition($2), - Name: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($2), - IdentifierTkn: $2, - Value: $2.Value, - }, - }, - } - - $$ = &ParserSeparatedList{ - Items: []ast.Vertex{ variable }, - } - } -; - -function_call: - namespace_name function_call_parameter_list - { - $$ = &ast.ExprFunctionCall{ - Position: yylex.(*Parser).builder.NewNodeListNodePosition($1.(*ParserSeparatedList).Items, $2), - Function: &ast.Name{ - Position: yylex.(*Parser).builder.NewNodeListPosition($1.(*ParserSeparatedList).Items), - Parts: $1.(*ParserSeparatedList).Items, - SeparatorTkns: $1.(*ParserSeparatedList).SeparatorTkns, - }, - OpenParenthesisTkn: $2.(*ArgumentList).OpenParenthesisTkn, - Args: $2.(*ArgumentList).Arguments, - SeparatorTkns: $2.(*ArgumentList).SeparatorTkns, - CloseParenthesisTkn: $2.(*ArgumentList).CloseParenthesisTkn, - } - } - | T_NAMESPACE T_NS_SEPARATOR namespace_name function_call_parameter_list - { - $$ = &ast.ExprFunctionCall{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $4), - Function: &ast.NameRelative{ - Position: yylex.(*Parser).builder.NewTokenNodeListPosition($1, $3.(*ParserSeparatedList).Items), - NsTkn: $1, - NsSeparatorTkn: $2, - Parts: $3.(*ParserSeparatedList).Items, - SeparatorTkns: $3.(*ParserSeparatedList).SeparatorTkns, - }, - OpenParenthesisTkn: $4.(*ArgumentList).OpenParenthesisTkn, - Args: $4.(*ArgumentList).Arguments, - SeparatorTkns: $4.(*ArgumentList).SeparatorTkns, - CloseParenthesisTkn: $4.(*ArgumentList).CloseParenthesisTkn, - } - } - | T_NS_SEPARATOR namespace_name function_call_parameter_list - { - $$ = &ast.ExprFunctionCall{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $3), - Function: &ast.NameFullyQualified{ - Position: yylex.(*Parser).builder.NewTokenNodeListPosition($1, $2.(*ParserSeparatedList).Items), - NsSeparatorTkn: $1, - Parts: $2.(*ParserSeparatedList).Items, - SeparatorTkns: $2.(*ParserSeparatedList).SeparatorTkns, - }, - OpenParenthesisTkn: $3.(*ArgumentList).OpenParenthesisTkn, - Args: $3.(*ArgumentList).Arguments, - SeparatorTkns: $3.(*ArgumentList).SeparatorTkns, - CloseParenthesisTkn: $3.(*ArgumentList).CloseParenthesisTkn, - } - } - | class_name T_PAAMAYIM_NEKUDOTAYIM variable_name function_call_parameter_list - { - staticCall := &ast.ExprStaticCall{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $4), - Class: $1, - DoubleColonTkn: $2, - Call: $3, - OpenParenthesisTkn: $4.(*ArgumentList).OpenParenthesisTkn, - Args: $4.(*ArgumentList).Arguments, - SeparatorTkns: $4.(*ArgumentList).SeparatorTkns, - CloseParenthesisTkn: $4.(*ArgumentList).CloseParenthesisTkn, - } - - if brackets, ok := $3.(*ParserBrackets); ok { - staticCall.OpenCurlyBracketTkn = brackets.OpenBracketTkn - staticCall.Call = brackets.Child - staticCall.CloseCurlyBracketTkn = brackets.CloseBracketTkn - } - - $$ = staticCall - } - | class_name T_PAAMAYIM_NEKUDOTAYIM variable_without_objects function_call_parameter_list - { - $$ = &ast.ExprStaticCall{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $4), - Class: $1, - DoubleColonTkn: $2, - Call: $3, - OpenParenthesisTkn: $4.(*ArgumentList).OpenParenthesisTkn, - Args: $4.(*ArgumentList).Arguments, - SeparatorTkns: $4.(*ArgumentList).SeparatorTkns, - CloseParenthesisTkn: $4.(*ArgumentList).CloseParenthesisTkn, - } - } - | variable_class_name T_PAAMAYIM_NEKUDOTAYIM variable_name function_call_parameter_list - { - staticCall := &ast.ExprStaticCall{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $4), - Class: $1, - DoubleColonTkn: $2, - Call: $3, - OpenParenthesisTkn: $4.(*ArgumentList).OpenParenthesisTkn, - Args: $4.(*ArgumentList).Arguments, - SeparatorTkns: $4.(*ArgumentList).SeparatorTkns, - CloseParenthesisTkn: $4.(*ArgumentList).CloseParenthesisTkn, - } - - if brackets, ok := $3.(*ParserBrackets); ok { - staticCall.OpenCurlyBracketTkn = brackets.OpenBracketTkn - staticCall.Call = brackets.Child - staticCall.CloseCurlyBracketTkn = brackets.CloseBracketTkn - } - - $$ = staticCall - } - | variable_class_name T_PAAMAYIM_NEKUDOTAYIM variable_without_objects function_call_parameter_list - { - $$ = &ast.ExprStaticCall{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $4), - Class: $1, - DoubleColonTkn: $2, - Call: $3, - OpenParenthesisTkn: $4.(*ArgumentList).OpenParenthesisTkn, - Args: $4.(*ArgumentList).Arguments, - SeparatorTkns: $4.(*ArgumentList).SeparatorTkns, - CloseParenthesisTkn: $4.(*ArgumentList).CloseParenthesisTkn, - } - } - | variable_without_objects function_call_parameter_list - { - $$ = &ast.ExprFunctionCall{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $2), - Function: $1, - OpenParenthesisTkn: $2.(*ArgumentList).OpenParenthesisTkn, - Args: $2.(*ArgumentList).Arguments, - SeparatorTkns: $2.(*ArgumentList).SeparatorTkns, - CloseParenthesisTkn: $2.(*ArgumentList).CloseParenthesisTkn, - } - } -; - -class_name: - T_STATIC - { - $$ = &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - IdentifierTkn: $1, - Value: $1.Value, - } - } - | namespace_name - { - $$ = &ast.Name{ - Position: yylex.(*Parser).builder.NewNodeListPosition($1.(*ParserSeparatedList).Items), - Parts: $1.(*ParserSeparatedList).Items, - SeparatorTkns: $1.(*ParserSeparatedList).SeparatorTkns, - } - } - | T_NAMESPACE T_NS_SEPARATOR namespace_name - { - $$ = &ast.NameRelative{ - Position: yylex.(*Parser).builder.NewTokenNodeListPosition($1, $3.(*ParserSeparatedList).Items), - NsTkn: $1, - NsSeparatorTkn: $2, - Parts: $3.(*ParserSeparatedList).Items, - SeparatorTkns: $3.(*ParserSeparatedList).SeparatorTkns, - } - } - | T_NS_SEPARATOR namespace_name - { - $$ = &ast.NameFullyQualified{ - Position: yylex.(*Parser).builder.NewTokenNodeListPosition($1, $2.(*ParserSeparatedList).Items), - NsSeparatorTkn: $1, - Parts: $2.(*ParserSeparatedList).Items, - SeparatorTkns: $2.(*ParserSeparatedList).SeparatorTkns, - } - } -; - -fully_qualified_class_name: - namespace_name - { - $$ = &ast.Name{ - Position: yylex.(*Parser).builder.NewNodeListPosition($1.(*ParserSeparatedList).Items), - Parts: $1.(*ParserSeparatedList).Items, - SeparatorTkns: $1.(*ParserSeparatedList).SeparatorTkns, - } - } - | T_NAMESPACE T_NS_SEPARATOR namespace_name - { - $$ = &ast.NameRelative{ - Position: yylex.(*Parser).builder.NewTokenNodeListPosition($1, $3.(*ParserSeparatedList).Items), - NsTkn: $1, - NsSeparatorTkn: $2, - Parts: $3.(*ParserSeparatedList).Items, - SeparatorTkns: $3.(*ParserSeparatedList).SeparatorTkns, - } - } - | T_NS_SEPARATOR namespace_name - { - $$ = &ast.NameFullyQualified{ - Position: yylex.(*Parser).builder.NewTokenNodeListPosition($1, $2.(*ParserSeparatedList).Items), - NsSeparatorTkn: $1, - Parts: $2.(*ParserSeparatedList).Items, - SeparatorTkns: $2.(*ParserSeparatedList).SeparatorTkns, - } - } -; - -class_name_reference: - class_name - { - $$ = $1 - } - | dynamic_class_name_reference - { - $$ = $1 - } -; - -dynamic_class_name_reference: - base_variable T_OBJECT_OPERATOR object_property dynamic_class_name_variable_properties - { - $$ = $1 - - $3[0].(*ast.ExprPropertyFetch).ObjectOperatorTkn = $2 - - for _, n := range($3) { - switch nn := n.(type) { - case *ast.ExprArrayDimFetch: - nn.Var = $$ - *$$.GetPosition() = *yylex.(*Parser).builder.NewNodesPosition($$, nn) - $$ = nn - - case *ast.ExprPropertyFetch: - nn.Var = $$ - *$$.GetPosition() = *yylex.(*Parser).builder.NewNodesPosition($$, nn) - $$ = nn - } - } - - for _, n := range($4) { - switch nn := n.(type) { - case *ast.ExprArrayDimFetch: - nn.Var = $$ - *$$.GetPosition() = *yylex.(*Parser).builder.NewNodesPosition($$, nn) - $$ = nn - - case *ast.ExprPropertyFetch: - nn.Var = $$ - *$$.GetPosition() = *yylex.(*Parser).builder.NewNodesPosition($$, nn) - $$ = nn - } - } - } - | base_variable - { - $$ = $1 - } -; - - -dynamic_class_name_variable_properties: - dynamic_class_name_variable_properties dynamic_class_name_variable_property - { - $$ = append($1, $2...) - } - | /* empty */ - { - $$ = []ast.Vertex{} - } -; - - -dynamic_class_name_variable_property: - T_OBJECT_OPERATOR object_property - { - $2[0].(*ast.ExprPropertyFetch).ObjectOperatorTkn = $1 - - $$ = $2 - } -; - -exit_expr: - /* empty */ - { - $$ = nil - } - | '(' ')' - { - $$ = &ast.ExprBrackets{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $2), - OpenParenthesisTkn: $1, - CloseParenthesisTkn: $2, - } - } - | parenthesis_expr - { - $$ = $1 - } -; - -backticks_expr: - /* empty */ - { - $$ = []ast.Vertex{} - } - | T_ENCAPSED_AND_WHITESPACE - { - $$ = []ast.Vertex{ - &ast.ScalarEncapsedStringPart{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - EncapsedStrTkn: $1, - Value: $1.Value, - }, - } - } - | encaps_list - { - $$ = $1; - } -; - -ctor_arguments: - /* empty */ - { - $$ = nil - } - | function_call_parameter_list - { - $$ = $1 - } -; - -common_scalar: - T_LNUMBER - { - $$ = &ast.ScalarLnumber{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - NumberTkn: $1, - Value: $1.Value, - } - } - | T_DNUMBER - { - $$ = &ast.ScalarDnumber{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - NumberTkn: $1, - Value: $1.Value, - } - } - | T_CONSTANT_ENCAPSED_STRING - { - $$ = &ast.ScalarString{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - StringTkn: $1, - Value: $1.Value, - } - } - | T_LINE - { - $$ = &ast.ScalarMagicConstant{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - MagicConstTkn: $1, - Value: $1.Value, - } - } - | T_FILE - { - $$ = &ast.ScalarMagicConstant{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - MagicConstTkn: $1, - Value: $1.Value, - } - } - | T_DIR - { - $$ = &ast.ScalarMagicConstant{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - MagicConstTkn: $1, - Value: $1.Value, - } - } - | T_TRAIT_C - { - $$ = &ast.ScalarMagicConstant{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - MagicConstTkn: $1, - Value: $1.Value, - } - } - | T_METHOD_C - { - $$ = &ast.ScalarMagicConstant{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - MagicConstTkn: $1, - Value: $1.Value, - } - } - | T_FUNC_C - { - $$ = &ast.ScalarMagicConstant{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - MagicConstTkn: $1, - Value: $1.Value, - } - } - | T_NS_C - { - $$ = &ast.ScalarMagicConstant{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - MagicConstTkn: $1, - Value: $1.Value, - } - } - | T_START_HEREDOC T_ENCAPSED_AND_WHITESPACE T_END_HEREDOC - { - $$ = &ast.ScalarHeredoc{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $3), - OpenHeredocTkn: $1, - Parts: []ast.Vertex{ - &ast.ScalarEncapsedStringPart{ - Position: yylex.(*Parser).builder.NewTokenPosition($2), - EncapsedStrTkn: $2, - Value: $2.Value, - }, - }, - CloseHeredocTkn: $3, - } - } - | T_START_HEREDOC T_END_HEREDOC - { - $$ = &ast.ScalarHeredoc{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $2), - OpenHeredocTkn: $1, - CloseHeredocTkn: $2, - } - } -; - -static_class_constant: - class_name T_PAAMAYIM_NEKUDOTAYIM T_STRING - { - $$ = &ast.ExprClassConstFetch{ - Position: yylex.(*Parser).builder.NewNodeTokenPosition($1, $3), - Class: $1, - DoubleColonTkn: $2, - Const: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($3), - IdentifierTkn: $3, - Value: $3.Value, - }, - } - } -; - -static_scalar: - static_scalar_value - { - $$ = $1 - } -; - -static_scalar_value: - common_scalar - { - $$ = $1 - } - | static_class_name_scalar - { - $$ = $1 - } - | namespace_name - { - $$ = &ast.ExprConstFetch{ - Position: yylex.(*Parser).builder.NewNodeListPosition($1.(*ParserSeparatedList).Items), - Const: &ast.Name{ - Position: yylex.(*Parser).builder.NewNodeListPosition($1.(*ParserSeparatedList).Items), - Parts: $1.(*ParserSeparatedList).Items, - SeparatorTkns: $1.(*ParserSeparatedList).SeparatorTkns, - }, - } - } - | T_NAMESPACE T_NS_SEPARATOR namespace_name - { - $$ = &ast.ExprConstFetch{ - Position: yylex.(*Parser).builder.NewTokenNodeListPosition($1, $3.(*ParserSeparatedList).Items), - Const: &ast.NameRelative{ - Position: yylex.(*Parser).builder.NewTokenNodeListPosition($1, $3.(*ParserSeparatedList).Items), - NsTkn: $1, - NsSeparatorTkn: $2, - Parts: $3.(*ParserSeparatedList).Items, - SeparatorTkns: $3.(*ParserSeparatedList).SeparatorTkns, - }, - } - } - | T_NS_SEPARATOR namespace_name - { - $$ = &ast.ExprConstFetch{ - Position: yylex.(*Parser).builder.NewTokenNodeListPosition($1, $2.(*ParserSeparatedList).Items), - Const: &ast.NameFullyQualified{ - Position: yylex.(*Parser).builder.NewTokenNodeListPosition($1, $2.(*ParserSeparatedList).Items), - NsSeparatorTkn: $1, - Parts: $2.(*ParserSeparatedList).Items, - SeparatorTkns: $2.(*ParserSeparatedList).SeparatorTkns, - }, - } - } - | T_ARRAY '(' static_array_pair_list ')' - { - $$ = &ast.ExprArray{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $4), - ArrayTkn: $1, - OpenBracketTkn: $2, - Items: $3.(*ParserSeparatedList).Items, - SeparatorTkns: $3.(*ParserSeparatedList).SeparatorTkns, - CloseBracketTkn: $4, - } - } - | '[' static_array_pair_list ']' - { - $$ = &ast.ExprArray{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $3), - OpenBracketTkn: $1, - Items: $2.(*ParserSeparatedList).Items, - SeparatorTkns: $2.(*ParserSeparatedList).SeparatorTkns, - CloseBracketTkn: $3, - } - } - | static_class_constant - { - $$ = $1 - } - | T_CLASS_C - { - $$ = &ast.ScalarMagicConstant{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - MagicConstTkn: $1, - Value: $1.Value, - } - } - | static_operation - { - $$ = $1 - } -; - -static_operation: - static_scalar_value '[' static_scalar_value ']' - { - $$ = &ast.ExprArrayDimFetch{ - Position: yylex.(*Parser).builder.NewNodeTokenPosition($1, $4), - Var: $1, - OpenBracketTkn: $2, - Dim: $3, - CloseBracketTkn: $4, - } - } - | static_scalar_value '+' static_scalar_value - { - $$ = &ast.ExprBinaryPlus{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | static_scalar_value '-' static_scalar_value - { - $$ = &ast.ExprBinaryMinus{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | static_scalar_value '*' static_scalar_value - { - $$ = &ast.ExprBinaryMul{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | static_scalar_value T_POW static_scalar_value - { - $$ = &ast.ExprBinaryPow{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | static_scalar_value '/' static_scalar_value - { - $$ = &ast.ExprBinaryDiv{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | static_scalar_value '%' static_scalar_value - { - $$ = &ast.ExprBinaryMod{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | '!' static_scalar_value - { - $$ = &ast.ExprBooleanNot{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), - ExclamationTkn: $1, - Expr: $2, - } - } - | '~' static_scalar_value - { - $$ = &ast.ExprBitwiseNot{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), - TildaTkn: $1, - Expr: $2, - } - } - | static_scalar_value '|' static_scalar_value - { - $$ = &ast.ExprBinaryBitwiseOr{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | static_scalar_value '&' static_scalar_value - { - $$ = &ast.ExprBinaryBitwiseAnd{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | static_scalar_value '^' static_scalar_value - { - $$ = &ast.ExprBinaryBitwiseXor{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | static_scalar_value T_SL static_scalar_value - { - $$ = &ast.ExprBinaryShiftLeft{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | static_scalar_value T_SR static_scalar_value - { - $$ = &ast.ExprBinaryShiftRight{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | static_scalar_value '.' static_scalar_value - { - $$ = &ast.ExprBinaryConcat{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | static_scalar_value T_LOGICAL_XOR static_scalar_value - { - $$ = &ast.ExprBinaryLogicalXor{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | static_scalar_value T_LOGICAL_AND static_scalar_value - { - $$ = &ast.ExprBinaryLogicalAnd{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | static_scalar_value T_LOGICAL_OR static_scalar_value - { - $$ = &ast.ExprBinaryLogicalOr{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | static_scalar_value T_BOOLEAN_AND static_scalar_value - { - $$ = &ast.ExprBinaryBooleanAnd{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | static_scalar_value T_BOOLEAN_OR static_scalar_value - { - $$ = &ast.ExprBinaryBooleanOr{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | static_scalar_value T_IS_IDENTICAL static_scalar_value - { - $$ = &ast.ExprBinaryIdentical{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | static_scalar_value T_IS_NOT_IDENTICAL static_scalar_value - { - $$ = &ast.ExprBinaryNotIdentical{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | static_scalar_value T_IS_EQUAL static_scalar_value - { - $$ = &ast.ExprBinaryEqual{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | static_scalar_value T_IS_NOT_EQUAL static_scalar_value - { - $$ = &ast.ExprBinaryNotEqual{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | static_scalar_value '<' static_scalar_value - { - $$ = &ast.ExprBinarySmaller{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | static_scalar_value '>' static_scalar_value - { - $$ = &ast.ExprBinaryGreater{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | static_scalar_value T_IS_SMALLER_OR_EQUAL static_scalar_value - { - $$ = &ast.ExprBinarySmallerOrEqual{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | static_scalar_value T_IS_GREATER_OR_EQUAL static_scalar_value - { - $$ = &ast.ExprBinaryGreaterOrEqual{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Left: $1, - OpTkn: $2, - Right: $3, - } - } - | static_scalar_value '?' ':' static_scalar_value - { - $$ = &ast.ExprTernary{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $4), - Cond: $1, - QuestionTkn: $2, - ColonTkn: $3, - IfFalse: $4, - } - } - | static_scalar_value '?' static_scalar_value ':' static_scalar_value - { - $$ = &ast.ExprTernary{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $5), - Cond: $1, - QuestionTkn: $2, - IfTrue: $3, - ColonTkn: $4, - IfFalse: $5, - } - } - | '+' static_scalar_value - { - $$ = &ast.ExprUnaryPlus{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), - PlusTkn: $1, - Expr: $2, - } - } - | '-' static_scalar_value - { - $$ = &ast.ExprUnaryMinus{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), - MinusTkn: $1, - Expr: $2, - } - } - | '(' static_scalar_value ')' - { - $$ = &ast.ExprBrackets{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $3), - OpenParenthesisTkn: $1, - Expr: $2, - CloseParenthesisTkn: $3, - } - } -; - -general_constant: - class_constant - { - $$ = $1 - } - | namespace_name - { - $$ = &ast.ExprConstFetch{ - Position: yylex.(*Parser).builder.NewNodeListPosition($1.(*ParserSeparatedList).Items), - Const: &ast.Name{ - Position: yylex.(*Parser).builder.NewNodeListPosition($1.(*ParserSeparatedList).Items), - Parts: $1.(*ParserSeparatedList).Items, - SeparatorTkns: $1.(*ParserSeparatedList).SeparatorTkns, - }, - } - } - | T_NAMESPACE T_NS_SEPARATOR namespace_name - { - $$ = &ast.ExprConstFetch{ - Position: yylex.(*Parser).builder.NewTokenNodeListPosition($1, $3.(*ParserSeparatedList).Items), - Const: &ast.NameRelative{ - Position: yylex.(*Parser).builder.NewTokenNodeListPosition($1, $3.(*ParserSeparatedList).Items), - NsTkn: $1, - NsSeparatorTkn: $2, - Parts: $3.(*ParserSeparatedList).Items, - SeparatorTkns: $3.(*ParserSeparatedList).SeparatorTkns, - }, - } - } - | T_NS_SEPARATOR namespace_name - { - $$ = &ast.ExprConstFetch{ - Position: yylex.(*Parser).builder.NewTokenNodeListPosition($1, $2.(*ParserSeparatedList).Items), - Const: &ast.NameFullyQualified{ - Position: yylex.(*Parser).builder.NewTokenNodeListPosition($1, $2.(*ParserSeparatedList).Items), - NsSeparatorTkn: $1, - Parts: $2.(*ParserSeparatedList).Items, - SeparatorTkns: $2.(*ParserSeparatedList).SeparatorTkns, - }, - } - } -; - -scalar: - T_STRING_VARNAME - { - $$ = &ast.ExprVariable{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - Name: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - IdentifierTkn: $1, - Value: $1.Value, - }, - } - } - | general_constant - { - $$ = $1 - } - | class_name_scalar - { - $$ = $1 - } - | common_scalar - { - $$ = $1 - } - | '"' encaps_list '"' - { - $$ = &ast.ScalarEncapsed{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $3), - OpenQuoteTkn: $1, - Parts: $2, - CloseQuoteTkn: $3, - } - } - | T_START_HEREDOC encaps_list T_END_HEREDOC - { - $$ = &ast.ScalarHeredoc{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $3), - OpenHeredocTkn: $1, - Parts: $2, - CloseHeredocTkn: $3, - } - } - | T_CLASS_C - { - $$ = &ast.ScalarMagicConstant{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - MagicConstTkn: $1, - Value: $1.Value, - } - } -; - -static_array_pair_list: - /* empty */ - { - $$ = &ParserSeparatedList{} - } - | non_empty_static_array_pair_list possible_comma - { - if $2 != nil { - $1.(*ParserSeparatedList).SeparatorTkns = append($1.(*ParserSeparatedList).SeparatorTkns, $2) - $1.(*ParserSeparatedList).Items = append($1.(*ParserSeparatedList).Items, &ast.ExprArrayItem{}) - } - - $$ = $1 - } -; - -possible_comma: - /* empty */ - { - $$ = nil - } - | ',' - { - $$ = $1 - } -; - -non_empty_static_array_pair_list: - non_empty_static_array_pair_list ',' static_scalar_value T_DOUBLE_ARROW static_scalar_value - { - arrayItem := &ast.ExprArrayItem{ - Position: yylex.(*Parser).builder.NewNodesPosition($3, $5), - Key: $3, - DoubleArrowTkn: $4, - Val: $5, - } - - $1.(*ParserSeparatedList).SeparatorTkns = append($1.(*ParserSeparatedList).SeparatorTkns, $2) - $1.(*ParserSeparatedList).Items = append($1.(*ParserSeparatedList).Items, arrayItem) - - $$ = $1 - } - | non_empty_static_array_pair_list ',' static_scalar_value - { - arrayItem := &ast.ExprArrayItem{ - Position: yylex.(*Parser).builder.NewNodePosition($3), - Val: $3, - } - - $1.(*ParserSeparatedList).SeparatorTkns = append($1.(*ParserSeparatedList).SeparatorTkns, $2) - $1.(*ParserSeparatedList).Items = append($1.(*ParserSeparatedList).Items, arrayItem) - - $$ = $1 - } - | static_scalar_value T_DOUBLE_ARROW static_scalar_value - { - $$ = &ParserSeparatedList{ - Items: []ast.Vertex{ - &ast.ExprArrayItem{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Key: $1, - DoubleArrowTkn: $2, - Val: $3, - }, - }, - } - } - | static_scalar_value - { - $$ = &ParserSeparatedList{ - Items: []ast.Vertex{ - &ast.ExprArrayItem{ - Position: yylex.(*Parser).builder.NewNodePosition($1), - Val: $1, - }, - }, - } - } -; - -expr: - r_variable - { - $$ = $1 - } - | expr_without_variable - { - $$ = $1 - } -; - -parenthesis_expr: - '(' expr ')' - { - $$ = &ast.ExprBrackets{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $3), - OpenParenthesisTkn: $1, - Expr: $2, - CloseParenthesisTkn: $3, - } - } - | '(' yield_expr ')' - { - $$ = &ast.ExprBrackets{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $3), - OpenParenthesisTkn: $1, - Expr: $2, - CloseParenthesisTkn: $3, - } - } -; - - -r_variable: - variable - { - $$ = $1 - } -; - - -w_variable: - variable - { - $$ = $1 - } -; - -rw_variable: - variable - { - $$ = $1 - } -; - -variable: - base_variable_with_function_calls T_OBJECT_OPERATOR object_property method_or_not variable_properties - { - $$ = $1 - - $3[0].(*ast.ExprPropertyFetch).ObjectOperatorTkn = $2 - - if $4 != nil { - last := $3[len($3)-1] - switch l := last.(type) { - case *ast.ExprArrayDimFetch: - mc := $4[0].(*ast.ExprMethodCall) - $3 = append($3, &ast.ExprFunctionCall{ - Position: yylex.(*Parser).builder.NewNodePosition(mc), - OpenParenthesisTkn: mc.OpenParenthesisTkn, - Args: mc.Args, - SeparatorTkns: mc.SeparatorTkns, - CloseParenthesisTkn: mc.CloseParenthesisTkn, - }, - ) - $3 = append($3, $4[1:len($4)]...) - case *ast.ExprPropertyFetch: - $4[0].(*ast.ExprMethodCall).OpenCurlyBracketTkn = l.OpenCurlyBracketTkn - $4[0].(*ast.ExprMethodCall).Method = l.Prop - $4[0].(*ast.ExprMethodCall).CloseCurlyBracketTkn = l.CloseCurlyBracketTkn - $4[0].(*ast.ExprMethodCall).ObjectOperatorTkn = l.ObjectOperatorTkn - $3 = append($3[:len($3)-1], $4...) - } - } - - for _, n := range($3) { - switch nn := n.(type) { - case *ast.ExprFunctionCall: - nn.Function = $$ - nn.Position = yylex.(*Parser).builder.NewNodesPosition($$, nn) - $$ = nn - - case *ast.ExprArrayDimFetch: - nn.Var = $$ - nn.Position = yylex.(*Parser).builder.NewNodesPosition($$, nn) - $$ = nn - - case *ast.ExprPropertyFetch: - nn.Var = $$ - nn.Position = yylex.(*Parser).builder.NewNodesPosition($$, nn) - $$ = nn - - case *ast.ExprMethodCall: - nn.Var = $$ - nn.Position = yylex.(*Parser).builder.NewNodesPosition($$, nn) - $$ = nn - } - } - - for _, n := range($5) { - switch nn := n.(type) { - case *ast.ExprFunctionCall: - nn.Function = $$ - nn.Position = yylex.(*Parser).builder.NewNodesPosition($$, nn) - $$ = nn - - case *ast.ExprArrayDimFetch: - nn.Var = $$ - nn.Position = yylex.(*Parser).builder.NewNodesPosition($$, nn) - $$ = nn - - case *ast.ExprPropertyFetch: - nn.Var = $$ - nn.Position = yylex.(*Parser).builder.NewNodesPosition($$, nn) - $$ = nn - - case *ast.ExprMethodCall: - nn.Var = $$ - nn.Position = yylex.(*Parser).builder.NewNodesPosition($$, nn) - $$ = nn - } - } - } - | base_variable_with_function_calls - { - $$ = $1 - } -; - -variable_properties: - variable_properties variable_property - { - $$ = append($1, $2...) - } - | /* empty */ - { - $$ = []ast.Vertex{} - } -; - - -variable_property: - T_OBJECT_OPERATOR object_property method_or_not - { - $2[0].(*ast.ExprPropertyFetch).ObjectOperatorTkn = $1 - - if $3 != nil { - last := $2[len($2)-1] - switch l := last.(type) { - case *ast.ExprArrayDimFetch: - mc := $3[0].(*ast.ExprMethodCall) - $2 = append($2, &ast.ExprFunctionCall{ - Position: yylex.(*Parser).builder.NewNodePosition(mc), - OpenParenthesisTkn: mc.OpenParenthesisTkn, - Args: mc.Args, - SeparatorTkns: mc.SeparatorTkns, - CloseParenthesisTkn: mc.OpenParenthesisTkn, - }, - ) - $2 = append($2, $3[1:len($3)]...) - case *ast.ExprPropertyFetch: - $3[0].(*ast.ExprMethodCall).OpenCurlyBracketTkn = l.OpenCurlyBracketTkn - $3[0].(*ast.ExprMethodCall).Method = l.Prop - $3[0].(*ast.ExprMethodCall).CloseCurlyBracketTkn = l.CloseCurlyBracketTkn - $3[0].(*ast.ExprMethodCall).ObjectOperatorTkn = l.ObjectOperatorTkn - $2 = append($2[:len($2)-1], $3...) - } - } - - $$ = $2 - } -; - -array_method_dereference: - array_method_dereference '[' dim_offset ']' - { - fetch := &ast.ExprArrayDimFetch{ - Position: yylex.(*Parser).builder.NewTokensPosition($2, $4), - Var: nil, - OpenBracketTkn: $2, - Dim: $3, - CloseBracketTkn: $4, - } - - $$ = append($1, fetch) - } - | method '[' dim_offset ']' - { - fetch := &ast.ExprArrayDimFetch{ - Position: yylex.(*Parser).builder.NewTokensPosition($2, $4), - Var: nil, - OpenBracketTkn: $2, - Dim: $3, - CloseBracketTkn: $4, - } - - $$ = []ast.Vertex{$1, fetch} - } -; - -method: - function_call_parameter_list - { - $$ = &ast.ExprMethodCall{ - Position: yylex.(*Parser).builder.NewNodePosition($1), - OpenParenthesisTkn: $1.(*ArgumentList).OpenParenthesisTkn, - Args: $1.(*ArgumentList).Arguments, - SeparatorTkns: $1.(*ArgumentList).SeparatorTkns, - CloseParenthesisTkn: $1.(*ArgumentList).CloseParenthesisTkn, - } - } -; - -method_or_not: - method - { - $$ = []ast.Vertex{$1} - } - | array_method_dereference - { - $$ = $1 - } - | /* empty */ - { - $$ = nil - } -; - -variable_without_objects: - reference_variable - { - $$ = $1 - } - | simple_indirect_reference reference_variable - { - for i := len($1)-1; i>=0; i-- { - $1[i].(*ast.ExprVariable).Name = $2 - $1[i].(*ast.ExprVariable).Position = yylex.(*Parser).builder.NewNodesPosition($1[i], $2) - $2 = $1[i] - } - - $$ = $1[0] - } -; - -static_member: - class_name T_PAAMAYIM_NEKUDOTAYIM variable_without_objects - { - $$ = &ast.ExprStaticPropertyFetch{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Class: $1, - DoubleColonTkn: $2, - Prop: $3, - } - } - | variable_class_name T_PAAMAYIM_NEKUDOTAYIM variable_without_objects - { - $$ = &ast.ExprStaticPropertyFetch{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Class: $1, - DoubleColonTkn: $2, - Prop: $3, - } - } -; - -variable_class_name: - reference_variable - { - $$ = $1 - } -; - -array_function_dereference: - array_function_dereference '[' dim_offset ']' - { - $$ = &ast.ExprArrayDimFetch{ - Position: yylex.(*Parser).builder.NewNodeTokenPosition($1, $4), - Var: $1, - OpenBracketTkn: $2, - Dim: $3, - CloseBracketTkn: $4, - } - } - | function_call '[' dim_offset ']' - { - $$ = &ast.ExprArrayDimFetch{ - Position: yylex.(*Parser).builder.NewNodeTokenPosition($1, $4), - Var: $1, - OpenBracketTkn: $2, - Dim: $3, - CloseBracketTkn: $4, - } - } -; - -base_variable_with_function_calls: - base_variable - { - $$ = $1 - } - | array_function_dereference - { - $$ = $1 - } - | function_call - { - $$ = $1 - } -; - - -base_variable: - reference_variable - { - $$ = $1 - } - | simple_indirect_reference reference_variable - { - for i := len($1)-1; i>=0; i-- { - $1[i].(*ast.ExprVariable).Name = $2 - $1[i].(*ast.ExprVariable).Position = yylex.(*Parser).builder.NewNodesPosition($1[i], $2) - $2 = $1[i] - } - - $$ = $1[0] - } - | static_member - { - $$ = $1 - } -; - -reference_variable: - reference_variable '[' dim_offset ']' - { - $$ = &ast.ExprArrayDimFetch{ - Position: yylex.(*Parser).builder.NewNodeTokenPosition($1, $4), - Var: $1, - OpenBracketTkn: $2, - Dim: $3, - CloseBracketTkn: $4, - } - } - | reference_variable '{' expr '}' - { - $$ = &ast.ExprArrayDimFetch{ - Position: yylex.(*Parser).builder.NewNodeTokenPosition($1, $4), - Var: $1, - OpenBracketTkn: $2, - Dim: $3, - CloseBracketTkn: $4, - } - } - | compound_variable - { - $$ = $1 - } -; - - -compound_variable: - T_VARIABLE - { - $$ = &ast.ExprVariable{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - Name: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - IdentifierTkn: $1, - Value: $1.Value, - }, - } - } - | '$' '{' expr '}' - { - $$ = &ast.ExprVariable{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $4), - DollarTkn: $1, - OpenCurlyBracketTkn: $2, - Name: $3, - CloseCurlyBracketTkn: $4, - } - } -; - -dim_offset: - /* empty */ - { - $$ = nil - } - | expr - { - $$ = $1 - } -; - - -object_property: - object_dim_list - { - $$ = $1 - } - | variable_without_objects - { - $$ = []ast.Vertex{ - &ast.ExprPropertyFetch{ - Position: yylex.(*Parser).builder.NewNodePosition($1), - Prop: $1, - }, - } - } -; - -object_dim_list: - object_dim_list '[' dim_offset ']' - { - fetch := &ast.ExprArrayDimFetch{ - Position: yylex.(*Parser).builder.NewTokensPosition($2, $4), - Var: nil, - OpenBracketTkn: $2, - Dim: $3, - CloseBracketTkn: $4, - } - - $$ = append($1, fetch) - } - | object_dim_list '{' expr '}' - { - fetch := &ast.ExprArrayDimFetch{ - Position: yylex.(*Parser).builder.NewTokensPosition($2, $4), - Var: nil, - OpenBracketTkn: $2, - Dim: $3, - CloseBracketTkn: $4, - } - - $$ = append($1, fetch) - } - | variable_name - { - property := &ast.ExprPropertyFetch{ - Position: yylex.(*Parser).builder.NewNodePosition($1), - Prop: $1, - } - - if brackets, ok := $1.(*ParserBrackets); ok { - property.OpenCurlyBracketTkn = brackets.OpenBracketTkn - property.Prop = brackets.Child - property.CloseCurlyBracketTkn = brackets.CloseBracketTkn - } - - $$ = []ast.Vertex{ property } - } -; - -variable_name: - T_STRING - { - $$ = &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - IdentifierTkn: $1, - Value: $1.Value, - } - } - | '{' expr '}' - { - $$ = &ParserBrackets{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $3), - OpenBracketTkn: $1, - Child: $2, - CloseBracketTkn: $3, - } - } -; - -simple_indirect_reference: - '$' - { - $$ = []ast.Vertex{ - &ast.ExprVariable{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - DollarTkn: $1, - }, - } - } - | simple_indirect_reference '$' - { - $$ = append($1, &ast.ExprVariable{ - Position: yylex.(*Parser).builder.NewTokenPosition($2), - DollarTkn: $2, - }) - } -; - -assignment_list: - assignment_list ',' assignment_list_element - { - $1.(*ParserSeparatedList).SeparatorTkns = append($1.(*ParserSeparatedList).SeparatorTkns, $2) - $1.(*ParserSeparatedList).Items = append($1.(*ParserSeparatedList).Items, $3) - - $$ = $1 - } - | assignment_list_element - { - $$ = &ParserSeparatedList{ - Items: []ast.Vertex{$1}, - } - } -; - - -assignment_list_element: - variable - { - $$ = &ast.ExprArrayItem{ - Position: yylex.(*Parser).builder.NewNodePosition($1), - Val: $1, - } - } - | T_LIST '(' assignment_list ')' - { - pairList := $3.(*ParserSeparatedList) - fistPair := pairList.Items[0].(*ast.ExprArrayItem) - - if fistPair.Key == nil && fistPair.Val == nil && len(pairList.Items) == 1 { - pairList.Items = nil - } - - $$ = &ast.ExprArrayItem{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $4), - Val: &ast.ExprList{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $4), - ListTkn: $1, - OpenBracketTkn: $2, - Items: $3.(*ParserSeparatedList).Items, - SeparatorTkns: $3.(*ParserSeparatedList).SeparatorTkns, - CloseBracketTkn: $4, - }, - } - } - | /* empty */ - { - $$ = &ast.ExprArrayItem{} - } -; - - -array_pair_list: - /* empty */ - { - $$ = &ParserSeparatedList{} - } - | non_empty_array_pair_list possible_comma - { - if $2 != nil { - $1.(*ParserSeparatedList).SeparatorTkns = append($1.(*ParserSeparatedList).SeparatorTkns, $2) - $1.(*ParserSeparatedList).Items = append($1.(*ParserSeparatedList).Items, &ast.ExprArrayItem{}) - } - - $$ = $1 - } -; - -non_empty_array_pair_list: - non_empty_array_pair_list ',' expr T_DOUBLE_ARROW expr - { - arrayItem := &ast.ExprArrayItem{ - Position: yylex.(*Parser).builder.NewNodesPosition($3, $5), - Key: $3, - DoubleArrowTkn: $4, - Val: $5, - } - - $1.(*ParserSeparatedList).SeparatorTkns = append($1.(*ParserSeparatedList).SeparatorTkns, $2) - $1.(*ParserSeparatedList).Items = append($1.(*ParserSeparatedList).Items, arrayItem) - - $$ = $1 - } - | non_empty_array_pair_list ',' expr - { - arrayItem := &ast.ExprArrayItem{ - Position: yylex.(*Parser).builder.NewNodePosition($3), - Val: $3, - } - - $1.(*ParserSeparatedList).SeparatorTkns = append($1.(*ParserSeparatedList).SeparatorTkns, $2) - $1.(*ParserSeparatedList).Items = append($1.(*ParserSeparatedList).Items, arrayItem) - - $$ = $1 - } - | expr T_DOUBLE_ARROW expr - { - $$ = &ParserSeparatedList{ - Items: []ast.Vertex{ - &ast.ExprArrayItem{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), - Key: $1, - DoubleArrowTkn: $2, - Val: $3, - }, - }, - } - } - | expr - { - $$ = &ParserSeparatedList{ - Items: []ast.Vertex{ - &ast.ExprArrayItem{ - Position: yylex.(*Parser).builder.NewNodePosition($1), - Val: $1, - }, - }, - } - } - | non_empty_array_pair_list ',' expr T_DOUBLE_ARROW '&' w_variable - { - arrayItem := &ast.ExprArrayItem{ - Position: yylex.(*Parser).builder.NewNodesPosition($3, $6), - Key: $3, - DoubleArrowTkn: $4, - AmpersandTkn: $5, - Val: $6, - } - - $1.(*ParserSeparatedList).SeparatorTkns = append($1.(*ParserSeparatedList).SeparatorTkns, $2) - $1.(*ParserSeparatedList).Items = append($1.(*ParserSeparatedList).Items, arrayItem) - - $$ = $1 - } - | non_empty_array_pair_list ',' '&' w_variable - { - arrayItem := &ast.ExprArrayItem{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($3, $4), - AmpersandTkn: $3, - Val: $4, - } - - $1.(*ParserSeparatedList).SeparatorTkns = append($1.(*ParserSeparatedList).SeparatorTkns, $2) - $1.(*ParserSeparatedList).Items = append($1.(*ParserSeparatedList).Items, arrayItem) - - $$ = $1 - } - | expr T_DOUBLE_ARROW '&' w_variable - { - $$ = &ParserSeparatedList{ - Items: []ast.Vertex{ - &ast.ExprArrayItem{ - Position: yylex.(*Parser).builder.NewNodesPosition($1, $4), - Key: $1, - DoubleArrowTkn: $2, - AmpersandTkn: $3, - Val: $4, - }, - }, - } - } - | '&' w_variable - { - $$ = &ParserSeparatedList{ - Items: []ast.Vertex{ - &ast.ExprArrayItem{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), - AmpersandTkn: $1, - Val: $2, - }, - }, - } - } -; - -encaps_list: - encaps_list encaps_var - { - $$ = append($1, $2) - } - | encaps_list T_ENCAPSED_AND_WHITESPACE - { - $$ = append( - $1, - &ast.ScalarEncapsedStringPart{ - Position: yylex.(*Parser).builder.NewTokenPosition($2), - EncapsedStrTkn: $2, - Value: $2.Value, - }, - ) - } - | encaps_var - { - $$ = []ast.Vertex{$1} - } - | T_ENCAPSED_AND_WHITESPACE encaps_var - { - $$ = []ast.Vertex{ - &ast.ScalarEncapsedStringPart{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - EncapsedStrTkn: $1, - Value: $1.Value, - }, - $2, - } - } -; - -encaps_var: - T_VARIABLE - { - $$ = &ast.ExprVariable{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - Name: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - IdentifierTkn: $1, - Value: $1.Value, - }, - } - } - | T_VARIABLE '[' encaps_var_offset ']' - { - $$ = &ast.ExprArrayDimFetch{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $4), - Var: &ast.ExprVariable{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - Name: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - IdentifierTkn: $1, - Value: $1.Value, - }, - }, - OpenBracketTkn: $2, - Dim: $3, - CloseBracketTkn: $4, - } - } - | T_VARIABLE T_OBJECT_OPERATOR T_STRING - { - $$ = &ast.ExprPropertyFetch{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $3), - Var: &ast.ExprVariable{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - Name: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - IdentifierTkn: $1, - Value: $1.Value, - }, - }, - ObjectOperatorTkn: $2, - Prop: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($3), - IdentifierTkn: $3, - Value: $3.Value, - }, - } - } - | T_DOLLAR_OPEN_CURLY_BRACES expr '}' - { - $$ = &ast.ScalarEncapsedStringVar{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $3), - DollarOpenCurlyBracketTkn: $1, - Name: $2, - CloseCurlyBracketTkn: $3, - } - } - | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '}' - { - $$ = &ast.ScalarEncapsedStringVar{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $3), - DollarOpenCurlyBracketTkn: $1, - Name: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($2), - IdentifierTkn: $2, - Value: $2.Value, - }, - CloseCurlyBracketTkn: $3, - } - } - | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '[' expr ']' '}' - { - $$ = &ast.ScalarEncapsedStringVar{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $3), - DollarOpenCurlyBracketTkn: $1, - Name: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($2), - IdentifierTkn: $2, - Value: $2.Value, - }, - OpenSquareBracketTkn: $3, - Dim: $4, - CloseSquareBracketTkn: $5, - CloseCurlyBracketTkn: $6, - } - } - | T_CURLY_OPEN variable '}' - { - $$ = &ast.ScalarEncapsedStringBrackets{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $3), - OpenCurlyBracketTkn: $1, - Var: $2, - CloseCurlyBracketTkn: $3, - } - } -; - -encaps_var_offset: - T_STRING - { - $$ = &ast.ScalarString{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - StringTkn: $1, - Value: $1.Value, - } - } - | T_NUM_STRING - { - // TODO: add option to handle 64 bit integer - if _, err := strconv.Atoi(string($1.Value)); err == nil { - $$ = &ast.ScalarLnumber{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - NumberTkn: $1, - Value: $1.Value, - } - } else { - $$ = &ast.ScalarString{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - StringTkn: $1, - Value: $1.Value, - } - } - } - | T_VARIABLE - { - $$ = &ast.ExprVariable{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - Name: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($1), - IdentifierTkn: $1, - Value: $1.Value, - }, - } - } -; - -internal_functions_in_yacc: - T_ISSET '(' isset_variables ')' - { - $$ = &ast.ExprIsset{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $4), - IssetTkn: $1, - OpenParenthesisTkn: $2, - Vars: $3.(*ParserSeparatedList).Items, - SeparatorTkns: $3.(*ParserSeparatedList).SeparatorTkns, - CloseParenthesisTkn: $4, - } - } - | T_EMPTY '(' variable ')' - { - $$ = &ast.ExprEmpty{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $4), - EmptyTkn: $1, - OpenParenthesisTkn: $2, - Expr: $3, - CloseParenthesisTkn: $4, - } - } - | T_EMPTY '(' expr ')' - { - $$ = &ast.ExprEmpty{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $4), - EmptyTkn: $1, - OpenParenthesisTkn: $2, - Expr: $3, - CloseParenthesisTkn: $4, - } - } - | T_INCLUDE expr - { - $$ = &ast.ExprInclude{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), - IncludeTkn: $1, - Expr: $2, - } - } - | T_INCLUDE_ONCE expr - { - $$ = &ast.ExprIncludeOnce{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), - IncludeOnceTkn: $1, - Expr: $2, - } - } - | T_EVAL '(' expr ')' - { - $$ = &ast.ExprEval{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $4), - EvalTkn: $1, - OpenParenthesisTkn: $2, - Expr: $3, - CloseParenthesisTkn: $4, - } - } - | T_REQUIRE expr - { - $$ = &ast.ExprRequire{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), - RequireTkn: $1, - Expr: $2, - } - } - | T_REQUIRE_ONCE expr - { - $$ = &ast.ExprRequireOnce{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), - RequireOnceTkn: $1, - Expr: $2, - } - } -; - -isset_variables: - isset_variable - { - $$ = &ParserSeparatedList{ - Items: []ast.Vertex{$1}, - } - } - | isset_variables ',' isset_variable - { - $1.(*ParserSeparatedList).SeparatorTkns = append($1.(*ParserSeparatedList).SeparatorTkns, $2) - $1.(*ParserSeparatedList).Items = append($1.(*ParserSeparatedList).Items, $3) - - $$ = $1 - } -; - -isset_variable: - variable - { - $$ = $1 - } - | expr_without_variable - { - $$ = $1 - } -; - -class_constant: - class_name T_PAAMAYIM_NEKUDOTAYIM T_STRING - { - $$ = &ast.ExprClassConstFetch{ - Position: yylex.(*Parser).builder.NewNodeTokenPosition($1, $3), - Class: $1, - DoubleColonTkn: $2, - Const: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($3), - IdentifierTkn: $3, - Value: $3.Value, - }, - } - } - | variable_class_name T_PAAMAYIM_NEKUDOTAYIM T_STRING - { - $$ = &ast.ExprClassConstFetch{ - Position: yylex.(*Parser).builder.NewNodeTokenPosition($1, $3), - Class: $1, - DoubleColonTkn: $2, - Const: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($3), - IdentifierTkn: $3, - Value: $3.Value, - }, - } - } -; - -static_class_name_scalar: - class_name T_PAAMAYIM_NEKUDOTAYIM T_CLASS - { - $$ = &ast.ExprClassConstFetch{ - Position: yylex.(*Parser).builder.NewNodeTokenPosition($1, $3), - Class: $1, - DoubleColonTkn: $2, - Const: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($3), - IdentifierTkn: $3, - Value: $3.Value, - }, - } - } -; - -class_name_scalar: - class_name T_PAAMAYIM_NEKUDOTAYIM T_CLASS - { - $$ = &ast.ExprClassConstFetch{ - Position: yylex.(*Parser).builder.NewNodeTokenPosition($1, $3), - Class: $1, - DoubleColonTkn: $2, - Const: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($3), - IdentifierTkn: $3, - Value: $3.Value, - }, - } - } -; - -%% diff --git a/internal/php5/php5_bench_test.go b/internal/php5/php5_bench_test.go deleted file mode 100644 index 42b6917..0000000 --- a/internal/php5/php5_bench_test.go +++ /dev/null @@ -1,30 +0,0 @@ -package php5_test - -import ( - "io/ioutil" - "testing" - - "github.com/VKCOM/php-parser/internal/php5" - "github.com/VKCOM/php-parser/internal/scanner" - "github.com/VKCOM/php-parser/pkg/conf" - "github.com/VKCOM/php-parser/pkg/version" -) - -func BenchmarkPhp5(b *testing.B) { - src, err := ioutil.ReadFile("test.php") - if err != nil { - b.Fatal("can not read test.php: " + err.Error()) - } - - for n := 0; n < b.N; n++ { - config := conf.Config{ - Version: &version.Version{ - Major: 5, - Minor: 6, - }, - } - lexer := scanner.NewLexer(src, config) - php5parser := php5.NewParser(lexer, config) - php5parser.Parse() - } -} diff --git a/internal/php5/test.php b/internal/php5/test.php deleted file mode 100644 index c811eb1..0000000 --- a/internal/php5/test.php +++ /dev/null @@ -1,381 +0,0 @@ -bar($a, ...$b); -foo::bar($a, ...$b); -$foo::bar($a, ...$b); -new foo($a, ...$b); - -function foo(bar $bar=null, baz &...$baz) {} -class foo {public function foo(bar $bar=null, baz &...$baz) {}} -function(bar $bar=null, baz &...$baz) {}; -static function(bar $bar=null, baz &...$baz) {}; - -1234567890123456789; -12345678901234567890; -0.; -0b0111111111111111111111111111111111111111111111111111111111111111; -0b1111111111111111111111111111111111111111111111111111111111111111; -0x007111111111111111; -0x8111111111111111; -__CLASS__; -__DIR__; -__FILE__; -__FUNCTION__; -__LINE__; -__NAMESPACE__; -__METHOD__; -__TRAIT__; - -"test $var"; -"test $var[1]"; -"test $var[1234567890123456789012345678901234567890]"; -"test $var[bar]"; -"test $var[$bar]"; -"$foo $bar"; -"test $foo->bar()"; -"test ${foo}"; -"test ${foo[0]}"; -"test {$foo->bar()}"; - -if ($a) : -endif; -if ($a) : -elseif ($b): -endif; -if ($a) : -else: -endif; -if ($a) : -elseif ($b): -elseif ($c): -else: -endif; - -while (1) { break; } -while (1) { break 2; } -while (1) : break(3); endwhile; -class foo{ const FOO = 1, BAR = 2; } -class foo{ function bar() {} } -class foo{ public static function &bar() {} } -class foo{ final private function bar() {} protected function baz() {} } -abstract class foo{ abstract public function bar(); } -final class foo extends bar { } -final class foo implements bar { } -final class foo implements bar, baz { } - -const FOO = 1, BAR = 2; -while (1) { continue; } -while (1) { continue 2; } -while (1) { continue(3); } -declare(ticks=1); -declare(ticks=1, strict_types=1) {} -declare(ticks=1): enddeclare; -do {} while(1); -echo $a, 1; -echo($a); -for($i = 0; $i < 10; $i++, $i++) {} -for(; $i < 10; $i++) : endfor; -foreach ($a as $v) {} -foreach ([] as $v) {} -foreach ($a as $v) : endforeach; -foreach ($a as $k => $v) {} -foreach ([] as $k => $v) {} -foreach ($a as $k => &$v) {} -foreach ($a as $k => list($v)) {} -function foo() {} - -function foo() { - function bar() {} - class Baz {} - return $a; -} - -function foo(array $a, callable $b) {return;} -function &foo() {return 1;} -function &foo() {} -global $a, $b, $$c, ${foo()}; -a: -goto a; -if ($a) {} -if ($a) {} elseif ($b) {} -if ($a) {} else {} -if ($a) {} elseif ($b) {} elseif ($c) {} else {} -if ($a) {} elseif ($b) {} else if ($c) {} else {} -?>
1, &$b,); -array(3 =>&$b); -array(&$b, 1=>1, 1, 3 =>&$b); -~$a; -!$a; - -Foo::Bar; -clone($a); -clone $a; -function(){}; -function($a, $b) use ($c, &$d) {}; -function($a, $b) use (&$c, $d) {}; -function() {}; -foo; -namespace\foo; -\foo; - -empty($a); -empty(Foo); -@$a; -eval($a); -exit; -exit($a); -die(); -die($a); -foo(); -namespace\foo(&$a); -\foo([]); -$foo(yield $a); - -$a--; -$a++; ---$a; -++$a; - -include $a; -include_once $a; -require $a; -require_once $a; - -$a instanceof Foo; -$a instanceof namespace\Foo; -$a instanceof \Foo; - -isset($a, $b); -isset(Foo); -list() = $b; -list($a, $b) = $b; -list($a[]) = $b; -list(list($a)) = $b; - -$a->foo(); -new Foo; -new namespace\Foo(); -new \Foo(); -print($a); -$a->foo; -$a->foo[1]; -$a->foo->bar->baz()->quux[0]; -$a->foo()[1][1]; -`cmd $a`; -`cmd`; -``; -[]; -[1]; -[1=>1, &$b,]; - -Foo::bar(); -namespace\Foo::bar(); -\Foo::bar(); -Foo::$bar(); -$foo::$bar(); -Foo::$bar; -namespace\Foo::$bar; -\Foo::$bar; -$a ? $b : $c; -$a ? : $c; -$a ? $b ? $c : $d : $e; -$a ? $b : $c ? $d : $e; --$a; -+$a; -$$a; -$$$a; -yield; -yield $a; -yield $a => $b; -yield Foo::class; -yield $a => Foo::class; - -(array)$a; -(boolean)$a; -(bool)$a; -(double)$a; -(float)$a; -(integer)$a; -(int)$a; -(object)$a; -(string)$a; -(unset)$a; - -$a & $b; -$a | $b; -$a ^ $b; -$a && $b; -$a || $b; -$a . $b; -$a / $b; -$a == $b; -$a >= $b; -$a > $b; -$a === $b; -$a and $b; -$a or $b; -$a xor $b; -$a - $b; -$a % $b; -$a * $b; -$a != $b; -$a !== $b; -$a + $b; -$a ** $b; -$a << $b; -$a >> $b; -$a <= $b; -$a < $b; - -$a =& $b; -$a =& new Foo; -$a =& new Foo($b); -$a = $b; -$a &= $b; -$a |= $b; -$a ^= $b; -$a .= $b; -$a /= $b; -$a -= $b; -$a %= $b; -$a *= $b; -$a += $b; -$a **= $b; -$a <<= $b; -$a >>= $b; - - -(new \Foo()); -(new \Foo())->bar()->baz; -(new \Foo())[0][0]; -(new \Foo())[0]->bar(); - -array([0])[0][0]; -"foo"[0]; -foo[0]; -static::foo; - -new $foo; -new $foo::$bar; -new $a->b[0]; -new $a->b{$b ?: null}->$c->d[0];static $a = [1][0]; - -static $a = !1; -static $a = ~1; -static $a = +1; -static $a = -1; -static $a = (1); -static $a = 1 ?: 2; -static $a = 1 ? 2 : 3; -static $a = 1 & 2; -static $a = 1 | 2; -static $a = 1 ^ 2; -static $a = 1 && 2; -static $a = 1 || 2; -static $a = 1 . 2; -static $a = 1 / 2; -static $a = 1 == 2; -static $a = 1 >= 2; -static $a = 1 > 2; -static $a = 1 === 2; -static $a = 1 and 2; -static $a = 1 or 2; -static $a = 1 xor 2; -static $a = 1 - 2; -static $a = 1 % 2; -static $a = 1 * 2; -static $a = 1 != 2; -static $a = 1 !== 2; -static $a = 1 + 2; -static $a = 1 ** 2; -static $a = 1 << 2; -static $a = 1 >> 2; -static $a = 1 <= 2; -static $a = 1 < 2; -static $a = Foo::bar; -static $a = Foo::class; -static $a = __CLASS__; -static $a = Foo; -static $a = namespace\Foo; -static $a = \Foo; -static $a = array(); -static $a = array(1 => 1, 2); -static $a = [1, 2 => 2][0]; - -if (yield 1) {} -Foo::$$bar; - -$foo(); -$foo()[0][0]; -$a{$b}; -${$a}; -$foo::{$bar}(); -$foo::bar; - -__halt_compiler(); - -parsing process must be terminated \ No newline at end of file diff --git a/pkg/parser/parser.go b/pkg/parser/parser.go index 0000eab..5f09633 100644 --- a/pkg/parser/parser.go +++ b/pkg/parser/parser.go @@ -3,10 +3,8 @@ package parser import ( "errors" - "github.com/VKCOM/php-parser/internal/php5" "github.com/VKCOM/php-parser/internal/php7" "github.com/VKCOM/php-parser/internal/php8" - "github.com/VKCOM/php-parser/internal/scanner" "github.com/VKCOM/php-parser/pkg/ast" "github.com/VKCOM/php-parser/pkg/conf" "github.com/VKCOM/php-parser/pkg/version" @@ -16,9 +14,6 @@ var ( // ErrVersionOutOfRange is returned if the version is not supported ErrVersionOutOfRange = errors.New("the version is out of supported range") - php5RangeStart = &version.Version{Major: 5} - php5RangeEnd = &version.Version{Major: 5, Minor: 6} - php7RangeStart = &version.Version{Major: 7} php7RangeEnd = &version.Version{Major: 7, Minor: 4} @@ -39,15 +34,8 @@ func Parse(src []byte, config conf.Config) (ast.Vertex, error) { config.Version = php7RangeEnd } - if config.Version.InRange(php5RangeStart, php5RangeEnd) { - lexer := scanner.NewLexer(src, config) - parser = php5.NewParser(lexer, config) - parser.Parse() - return parser.GetRootNode(), nil - } - if config.Version.InRange(php7RangeStart, php7RangeEnd) { - lexer := scanner.NewLexer(src, config) + lexer := php7.NewLexer(src, config) parser = php7.NewParser(lexer, config) parser.Parse() return parser.GetRootNode(), nil diff --git a/pkg/visitor/printer/printer_php5_test.go b/pkg/visitor/printer/printer_php5_test.go deleted file mode 100644 index 7fffe23..0000000 --- a/pkg/visitor/printer/printer_php5_test.go +++ /dev/null @@ -1,1439 +0,0 @@ -package printer_test - -import ( - "bytes" - "testing" - - "github.com/VKCOM/php-parser/internal/php5" - "github.com/VKCOM/php-parser/internal/scanner" - "github.com/VKCOM/php-parser/pkg/ast" - "github.com/VKCOM/php-parser/pkg/conf" - "github.com/VKCOM/php-parser/pkg/version" - "github.com/VKCOM/php-parser/pkg/visitor/printer" -) - -func parsePhp5(src string) ast.Vertex { - config := conf.Config{ - Version: &version.Version{ - Major: 5, - Minor: 6, - }, - } - lexer := scanner.NewLexer([]byte(src), config) - php5parser := php5.NewParser(lexer, config) - php5parser.Parse() - - return php5parser.GetRootNode() -} - -func printPhp5(n ast.Vertex) string { - o := bytes.NewBufferString("") - - p := printer.NewPrinter(o) - n.Accept(p) - - return o.String() -} - -// test node - -func TestParseAndPrintPhp5Root(t *testing.T) { - - src := `
Hello
- >= $b ; - ` - - actual := printPhp5(parsePhp5(src)) - - if src != actual { - t.Errorf("\nexpected: %s\ngot: %s\n", src, actual) - } -} - -// test binary - -func TestParseAndPrintPhp5Binary(t *testing.T) { - src := `= $b ; - $a > $b ; - $a === $b ; - $a and $b ; - $a or $b ; - $a xor $b ; - $a - $b ; - $a % $b ; - $a * $b ; - $a != $b ; - $a <> $b ; - $a !== $b ; - $a + $b ; - $a ** $b ; - $a << $b ; - $a >> $b ; - $a <= $b ; - $a < $b ; - ` - - actual := printPhp5(parsePhp5(src)) - - if src != actual { - t.Errorf("\nexpected: %s\ngot: %s\n", src, actual) - } -} - -// test cast - -func TestParseAndPrintPhp5Cast(t *testing.T) { - src := ` $world , - ] ; - ` - - actual := printPhp5(parsePhp5(src)) - - if src != actual { - t.Errorf("\nexpected: %s\ngot: %s\n", src, actual) - } -} - -func TestParseAndPrintPhp5Array(t *testing.T) { - src := ` 2 ) ; - ` - - actual := printPhp5(parsePhp5(src)) - - if src != actual { - t.Errorf("\nexpected: %s\ngot: %s\n", src, actual) - } -} - -func TestParseAndPrintPhp5BitwiseNot(t *testing.T) { - src := ` bar ( $arg ) ;` - - actual := printPhp5(parsePhp5(src)) - - if src != actual { - t.Errorf("\nexpected: %s\ngot: %s\n", src, actual) - } -} - -func TestParseAndPrintPhp5New(t *testing.T) { - src := ` b ;` - - actual := printPhp5(parsePhp5(src)) - - if src != actual { - t.Errorf("\nexpected: %s\ngot: %s\n", src, actual) - } -} - -func TestParseAndPrintPhp5Reference(t *testing.T) { - src := ` & $c ] ; - - $a = function ( ) use ( & $b ) { - // do nothing - } ; - - foreach ( $a as & $b ) { - // do nothing - }` - - actual := printPhp5(parsePhp5(src)) - - if src != actual { - t.Errorf("\nexpected: %s\ngot: %s\n", src, actual) - } -} - -func TestParseAndPrintPhp5Require(t *testing.T) { - - src := ` & $b , // one - $c , /* two */ - ] ; - $a = [0, 1, 2] ;` - - actual := printPhp5(parsePhp5(src)) - - if src != actual { - t.Errorf("\nexpected: %s\ngot: %s\n", src, actual) - } -} - -func TestParseAndPrintPhp5StaticCall(t *testing.T) { - src := ` $v ;` - - actual := printPhp5(parsePhp5(src)) - - if src != actual { - t.Errorf("\nexpected: %s\ngot: %s\n", src, actual) - } -} - -// test stmt - -func TestParseAndPrintPhp5AltIf(t *testing.T) { - src := ` & $v ) : - echo $v ; - endforeach ;` - - actual := printPhp5(parsePhp5(src)) - - if src != actual { - t.Errorf("\nexpected: %s\ngot: %s\n", src, actual) - } -} - -func TestParseAndPrintPhp5AltSwitch(t *testing.T) { - src := ` - - - & $v ) { - ; - }` - - actual := printPhp5(parsePhp5(src)) - - if src != actual { - t.Errorf("\nexpected: %s\ngot: %s\n", src, actual) - } -} - -func TestParseAndPrintPhp5Function(t *testing.T) { - - src := `testtest call ( ) ; - $a -> { $b . 'b' } ; - $a -> $b ( ) -> { $c . 'c' } ; - ` - - actual := printPhp5(parsePhp5(src)) - - if src != actual { - t.Errorf("\nexpected: %s\ngot: %s\n", src, actual) - } -} - -func TestParseAndPrintPhp5ComplexString1(t *testing.T) { - src := `bar" ; - ` - - actual := printPhp5(parsePhp5(src)) - - if src != actual { - t.Errorf("\nexpected: %s\ngot: %s\n", src, actual) - } -} - -func TestParseAndPrintPhp5ComplexString2(t *testing.T) { - src := ` bar }" ; - "test ${ $foo -> bar ( ) }" ; - "test ${ $a . '' }" ; - ` - - actual := printPhp5(parsePhp5(src)) - - if src != actual { - t.Errorf("\nexpected: %s\ngot: %s\n", src, actual) - } -} - -func TestParseAndPrintPhp5ComplexString3(t *testing.T) { - src := ` bar }" ; - "test ${$foo -> bar ( ) }" ; - "test ${$a . '' }" ; - ` - - actual := printPhp5(parsePhp5(src)) - - if src != actual { - t.Errorf("\nexpected: %s\ngot: %s\n", src, actual) - } -} - -func TestParseAndPrintPhp5ComplexString4(t *testing.T) { - src := ` bar }" ; - "test {$foo -> bar ( ) }" ; - ` - - actual := printPhp5(parsePhp5(src)) - - if src != actual { - t.Errorf("\nexpected: %s\ngot: %s\n", src, actual) - } -}