# Number literal with unary plus operator

class A {+1;}

==>

Specification(
    ClassDeclaration(
        class
        Whitespace
        Identifier
        Whitespace
        OpenBrace
        ExpressionStatement(
            UnaryExpression(
                UnaryPlus
                UnaryExpression(
                    IntegerLiteral
                )
            )
            Semicolon
        )
        CloseBrace
    )
)

# Identifier with unary negation operator

class A {-i;}

==>

Specification(
    ClassDeclaration(
        class
        Whitespace
        Identifier
        Whitespace
        OpenBrace
        ExpressionStatement(
            UnaryExpression(
                UnaryNegation
                UnaryExpression(
                    Identifier
                )
            )
            Semicolon
        )
        CloseBrace
    )
)

# Lengthof operator with unary negation

class A {-lengthof(i);}

==>

Specification(
    ClassDeclaration(
        class
        Whitespace
        Identifier
        Whitespace
        OpenBrace
        ExpressionStatement(
            UnaryExpression(
                UnaryNegation
                UnaryExpression(
                    LengthofExpression(
                        lengthof
                        OpenParenthesis
                        UnaryExpression(
                            Identifier
                        )
                        CloseParenthesis
                    )
                )
            )
            Semicolon
        )
        CloseBrace
    )
)

# Postfix operator

class A {i++;}

==>

Specification(
    ClassDeclaration(
        class
        Whitespace
        Identifier
        Whitespace
        OpenBrace
        ExpressionStatement(
            UnaryExpression(
                UnaryExpression(
                    Identifier
                )
                PostfixIncrement
            )
            Semicolon
        )
        CloseBrace
    )
)

# Class member access expression

class A {a.b;}

==>

Specification(
    ClassDeclaration(
        class
        Whitespace
        Identifier
        Whitespace
        OpenBrace
        ExpressionStatement(
            UnaryExpression(
                UnaryExpression(
                    Identifier
                )
                ClassMemberAccess(
                    Period
                    Identifier
                )
            )
            Semicolon
        )
        CloseBrace
    )
)

# Class member access expression - multiple

class A {a.b.c;}

==>

Specification(
    ClassDeclaration(
        class
        Whitespace
        Identifier
        Whitespace
        OpenBrace
        ExpressionStatement(
            UnaryExpression(
                UnaryExpression(
                    UnaryExpression(
                        Identifier
                    )
                    ClassMemberAccess(
                        Period
                        Identifier
                    )
                )
                ClassMemberAccess(
                    Period
                    Identifier
                )
            )
            Semicolon
        )
        CloseBrace
    )
)

# Array element access expression

class A {a[1];}

==>

Specification(
    ClassDeclaration(
        class
        Whitespace
        Identifier
        Whitespace
        OpenBrace
        ExpressionStatement(
            UnaryExpression(
                UnaryExpression(
                    Identifier
                )
                ArrayElementAccess(
                    OpenBracket
                    UnaryExpression(
                        IntegerLiteral
                    )
                    CloseBracket
                )
            )
            Semicolon
        )
        CloseBrace
    )
)

# Array element access expression multiple

class A {a[1][2];}

==>

Specification(
    ClassDeclaration(
        class
        Whitespace
        Identifier
        Whitespace
        OpenBrace
        ExpressionStatement(
            UnaryExpression(
                UnaryExpression(
                    UnaryExpression(
                        Identifier
                    )
                    ArrayElementAccess(
                        OpenBracket
                        UnaryExpression(
                            IntegerLiteral
                        )
                        CloseBracket
                    )
                )
                ArrayElementAccess(
                    OpenBracket
                    UnaryExpression(
                        IntegerLiteral
                    )
                    CloseBracket
                )
            )
            Semicolon
        )
        CloseBrace
    )
)

# Class member access expression with postfix operator

class A {a.b++;}

==>

Specification(
    ClassDeclaration(
        class
        Whitespace
        Identifier
        Whitespace
        OpenBrace
        ExpressionStatement(
            UnaryExpression(
                UnaryExpression(
                    UnaryExpression(
                        Identifier
                    )
                    ClassMemberAccess(
                        Period
                        Identifier
                    )
                )
                PostfixIncrement
            )
            Semicolon
        )
        CloseBrace
    )
)

# Array element access expression with postfix operator

class A {a[1]++;}

==>

Specification(
    ClassDeclaration(
        class
        Whitespace
        Identifier
        Whitespace
        OpenBrace
        ExpressionStatement(
            UnaryExpression(
                UnaryExpression(
                    UnaryExpression(
                        Identifier
                    )
                    ArrayElementAccess(
                        OpenBracket
                        UnaryExpression(
                            IntegerLiteral
                        )
                        CloseBracket
                    )
                )
                PostfixIncrement
            )
            Semicolon
        )
        CloseBrace
    )
)

# Class member and array element access expression - multiple mixed

class A {a[1][2].b.c[3];}

==>

Specification(
    ClassDeclaration(
        class
        Whitespace
        Identifier
        Whitespace
        OpenBrace
        ExpressionStatement(
            UnaryExpression(
                UnaryExpression(
                    UnaryExpression(
                        UnaryExpression(
                            UnaryExpression(
                                UnaryExpression(
                                    Identifier
                                )
                                ArrayElementAccess(
                                    OpenBracket
                                    UnaryExpression(
                                        IntegerLiteral
                                    )
                                    CloseBracket
                                )
                            )
                            ArrayElementAccess(
                                OpenBracket
                                UnaryExpression(
                                    IntegerLiteral
                                )
                                CloseBracket
                            )
                        )
                        ClassMemberAccess(
                            Period
                            Identifier
                        )
                    )
                    ClassMemberAccess(
                        Period
                        Identifier
                    )
                )
                ArrayElementAccess(
                    OpenBracket
                    UnaryExpression(
                        IntegerLiteral
                    )
                    CloseBracket
                )
            )
            Semicolon
        )
        CloseBrace
    )
)

# Expression in parenthesis with postfix operator and whitespace

class A {( i ) ++;}

==>

Specification(
    ClassDeclaration(
        class
        Whitespace
        Identifier
        Whitespace
        OpenBrace
        ExpressionStatement(
            UnaryExpression(
                UnaryExpression(
                    OpenParenthesis
                    Whitespace
                    UnaryExpression(
                        Identifier
                    )
                    Whitespace
                    CloseParenthesis
                )
                Whitespace
                PostfixIncrement
            )
            Semicolon
        )
        CloseBrace
    )
)

# Multiplication of two literals

class A {1*2;}

==>

Specification(
    ClassDeclaration(
        class
        Whitespace
        Identifier
        Whitespace
        OpenBrace
        ExpressionStatement(
            BinaryExpression(
                UnaryExpression(
                    IntegerLiteral
                )
                Multiplication
                UnaryExpression(
                    IntegerLiteral
                )
            )
            Semicolon
        )
        CloseBrace
    )
)

# Multiplication of two literals with unary operators

class A {+1*-2;}

==>

Specification(
    ClassDeclaration(
        class
        Whitespace
        Identifier
        Whitespace
        OpenBrace
        ExpressionStatement(
            BinaryExpression(
                UnaryExpression(
                    UnaryPlus
                    UnaryExpression(
                        IntegerLiteral
                    )
                )
                Multiplication
                UnaryExpression(
                    UnaryNegation
                    UnaryExpression(
                        IntegerLiteral
                    )
                )
            )
            Semicolon
        )
        CloseBrace
    )
)

# Multiplication of three literals

class A {1*2*3;}

==>

Specification(
    ClassDeclaration(
        class
        Whitespace
        Identifier
        Whitespace
        OpenBrace
        ExpressionStatement(
            BinaryExpression(
                BinaryExpression(
                    UnaryExpression(
                        IntegerLiteral
                    )
                    Multiplication
                    UnaryExpression(
                        IntegerLiteral
                    )
                )
                Multiplication
                UnaryExpression(
                    IntegerLiteral
                )
            )
            Semicolon
        )
        CloseBrace
    )
)

# Binary expression in parenthesis

class A {(1*2);}

==>

Specification(
    ClassDeclaration(
        class
        Whitespace
        Identifier
        Whitespace
        OpenBrace
        ExpressionStatement(
            UnaryExpression(
                OpenParenthesis
                BinaryExpression(
                    UnaryExpression(
                        IntegerLiteral
                    )
                    Multiplication
                    UnaryExpression(
                        IntegerLiteral
                    )
                )
                CloseParenthesis
            )
            Semicolon
        )
        CloseBrace
    )
)

# Binary expression in parenthesis with postfix operator - invalid syntax!

class A {(1*2)++;}

==>

Specification(
    ClassDeclaration(
        class
        Whitespace
        Identifier
        Whitespace
        OpenBrace
        ExpressionStatement(
            UnaryExpression(
                UnaryExpression(
                    OpenParenthesis
                    BinaryExpression(
                        UnaryExpression(
                            IntegerLiteral
                        )
                        Multiplication
                        UnaryExpression(
                            IntegerLiteral
                        )
                    )
                    CloseParenthesis
                )
                PostfixIncrement
            )
            Semicolon
        )
        CloseBrace
    )
)

# Multiplicative operators - left-to-right associativity

class A {1/2*3;}

==>

Specification(
    ClassDeclaration(
        class
        Whitespace
        Identifier
        Whitespace
        OpenBrace
        ExpressionStatement(
            BinaryExpression(
                BinaryExpression(
                    UnaryExpression(
                        IntegerLiteral
                    )
                    Division
                    UnaryExpression(
                        IntegerLiteral
                    )
                )
                Multiplication
                UnaryExpression(
                    IntegerLiteral
                )
            )
            Semicolon
        )
        CloseBrace
    )
)

# Multiplicative and additive operators - precedence

class A {1+2*3;}

==>

Specification(
    ClassDeclaration(
        class
        Whitespace
        Identifier
        Whitespace
        OpenBrace
        ExpressionStatement(
            BinaryExpression(
                UnaryExpression(
                    IntegerLiteral
                )
                Addition
                BinaryExpression(
                    UnaryExpression(
                        IntegerLiteral
                    )
                    Multiplication
                    UnaryExpression(
                        IntegerLiteral
                    )
                )
            )
            Semicolon
        )
        CloseBrace
    )
)

# Multiplicative and additive operators - precedence overridden by parenthesis

class A {(1+2)*3;}

==>

Specification(
    ClassDeclaration(
        class
        Whitespace
        Identifier
        Whitespace
        OpenBrace
        ExpressionStatement(
            BinaryExpression(
                UnaryExpression(
                    OpenParenthesis
                    BinaryExpression(
                        UnaryExpression(
                            IntegerLiteral
                        )
                        Addition
                        UnaryExpression(
                            IntegerLiteral
                        )
                    )
                    CloseParenthesis
                )
                Multiplication
                UnaryExpression(
                    IntegerLiteral
                )
            )
            Semicolon
        )
        CloseBrace
    )
)

# Logical operators

class A {i||j && k;}

==>

Specification(
    ClassDeclaration(
        class
        Whitespace
        Identifier
        Whitespace
        OpenBrace
        ExpressionStatement(
            BinaryExpression(
                BinaryExpression(
                    UnaryExpression(
                        Identifier
                    )
                    LogicalOr
                    UnaryExpression(
                        Identifier
                    )
                )
                Whitespace
                LogicalAnd
                Whitespace
                UnaryExpression(
                    Identifier
                )
            )
            Semicolon
        )
        CloseBrace
    )
)

# Additive operators

class A {i+j - k;}

==>

Specification(
    ClassDeclaration(
        class
        Whitespace
        Identifier
        Whitespace
        OpenBrace
        ExpressionStatement(
            BinaryExpression(
                BinaryExpression(
                    UnaryExpression(
                        Identifier
                    )
                    Addition
                    UnaryExpression(
                        Identifier
                    )
                )
                Whitespace
                Subtraction
                Whitespace
                UnaryExpression(
                    Identifier
                )
            )
            Semicolon
        )
        CloseBrace
    )
)

# Shift operators

class A {i<<j >> k;}

==>

Specification(
    ClassDeclaration(
        class
        Whitespace
        Identifier
        Whitespace
        OpenBrace
        ExpressionStatement(
            BinaryExpression(
                BinaryExpression(
                    UnaryExpression(
                        Identifier
                    )
                    BitwiseShiftLeft
                    UnaryExpression(
                        Identifier
                    )
                )
                Whitespace
                BitwiseShiftRight
                Whitespace
                UnaryExpression(
                    Identifier
                )
            )
            Semicolon
        )
        CloseBrace
    )
)

# Relational operators

class A {i<j<=k>l>=m;}

==>

Specification(
    ClassDeclaration(
        class
        Whitespace
        Identifier
        Whitespace
        OpenBrace
        ExpressionStatement(
            BinaryExpression(
                BinaryExpression(
                    BinaryExpression(
                        BinaryExpression(
                            UnaryExpression(
                                Identifier
                            )
                            RelationalLessThan
                            UnaryExpression(
                                Identifier
                            )
                        )
                        RelationalLessThanOrEqual
                        UnaryExpression(
                            Identifier
                        )
                    )
                    RelationalGreaterThan
                    UnaryExpression(
                        Identifier
                    )
                )
                RelationalGreaterThanOrEqual
                UnaryExpression(
                    Identifier
                )
            )
            Semicolon
        )
        CloseBrace
    )
)

# Equality operators

class A {i==j != k;}

==>

Specification(
    ClassDeclaration(
        class
        Whitespace
        Identifier
        Whitespace
        OpenBrace
        ExpressionStatement(
            BinaryExpression(
                BinaryExpression(
                    UnaryExpression(
                        Identifier
                    )
                    RelationalEqual
                    UnaryExpression(
                        Identifier
                    )
                )
                Whitespace
                RelationalNotEqual
                Whitespace
                UnaryExpression(
                    Identifier
                )
            )
            Semicolon
        )
        CloseBrace
    )
)

# Bitwise operators

class A {i&j | k;}

==>

Specification(
    ClassDeclaration(
        class
        Whitespace
        Identifier
        Whitespace
        OpenBrace
        ExpressionStatement(
            BinaryExpression(
                BinaryExpression(
                    UnaryExpression(
                        Identifier
                    )
                    BitwiseAnd
                    UnaryExpression(
                        Identifier
                    )
                )
                Whitespace
                BitwiseOr
                Whitespace
                UnaryExpression(
                    Identifier
                )
            )
            Semicolon
        )
        CloseBrace
    )
)

# All precedence rules

class A {8&&7|6==5>4>>3+2*1;}

==>

Specification(
    ClassDeclaration(
        class
        Whitespace
        Identifier
        Whitespace
        OpenBrace
        ExpressionStatement(
            BinaryExpression(
                UnaryExpression(
                    IntegerLiteral
                )
                LogicalAnd
                BinaryExpression(
                    UnaryExpression(
                        IntegerLiteral
                    )
                    BitwiseOr
                    BinaryExpression(
                        UnaryExpression(
                            IntegerLiteral
                        )
                        RelationalEqual
                        BinaryExpression(
                            UnaryExpression(
                                IntegerLiteral
                            )
                            RelationalGreaterThan
                            BinaryExpression(
                                UnaryExpression(
                                    IntegerLiteral
                                )
                                BitwiseShiftRight
                                BinaryExpression(
                                    UnaryExpression(
                                        IntegerLiteral
                                    )
                                    Addition
                                    BinaryExpression(
                                        UnaryExpression(
                                            IntegerLiteral
                                        )
                                        Multiplication
                                        UnaryExpression(
                                            IntegerLiteral
                                        )
                                    )
                                )
                            )
                        )
                    )
                )
            )
            Semicolon
        )
        CloseBrace
    )
)

# Mixed unary and binary expressions

class A {i++ * lengthof(j);}

==>

Specification(
    ClassDeclaration(
        class
        Whitespace
        Identifier
        Whitespace
        OpenBrace
        ExpressionStatement(
            BinaryExpression(
                UnaryExpression(
                    UnaryExpression(
                        Identifier
                    )
                    PostfixIncrement
                )
                Whitespace
                Multiplication
                Whitespace
                UnaryExpression(
                    LengthofExpression(
                        lengthof
                        OpenParenthesis
                        UnaryExpression(
                            Identifier
                        )
                        CloseParenthesis
                    )
                )
            )
            Semicolon
        )
        CloseBrace
    )
)

# Nested parenthesis

class A {((1*2)+3)/(2*3);}

==>

Specification(
    ClassDeclaration(
        class
        Whitespace
        Identifier
        Whitespace
        OpenBrace
        ExpressionStatement(
            BinaryExpression(
                UnaryExpression(
                    OpenParenthesis
                    BinaryExpression(
                        UnaryExpression(
                            OpenParenthesis
                            BinaryExpression(
                                UnaryExpression(
                                    IntegerLiteral
                                )
                                Multiplication
                                UnaryExpression(
                                    IntegerLiteral
                                )
                            )
                            CloseParenthesis
                        )
                        Addition
                        UnaryExpression(
                            IntegerLiteral
                        )
                    )
                    CloseParenthesis
                )
                Division
                UnaryExpression(
                    OpenParenthesis
                    BinaryExpression(
                        UnaryExpression(
                            IntegerLiteral
                        )
                        Multiplication
                        UnaryExpression(
                            IntegerLiteral
                        )
                    )
                    CloseParenthesis
                )
            )
            Semicolon
        )
        CloseBrace
    )
)

# Three levels of precedence

class A {1+2*3<<2;}

==>

Specification(
    ClassDeclaration(
        class
        Whitespace
        Identifier
        Whitespace
        OpenBrace
        ExpressionStatement(
            BinaryExpression(
                BinaryExpression(
                    UnaryExpression(
                        IntegerLiteral
                    )
                    Addition
                    BinaryExpression(
                        UnaryExpression(
                            IntegerLiteral
                        )
                        Multiplication
                        UnaryExpression(
                            IntegerLiteral
                        )
                    )
                )
                BitwiseShiftLeft
                UnaryExpression(
                    IntegerLiteral
                )
            )
            Semicolon
        )
        CloseBrace
    )
)

# Assignment expression

class A {i=1*2;}

==>

Specification(
    ClassDeclaration(
        class
        Whitespace
        Identifier
        Whitespace
        OpenBrace
        ExpressionStatement(
            AssignmentExpression(
                UnaryExpression(
                    Identifier
                )
                Assignment
                BinaryExpression(
                    UnaryExpression(
                        IntegerLiteral
                    )
                    Multiplication
                    UnaryExpression(
                        IntegerLiteral
                    )
                )
            )
            Semicolon
        )
        CloseBrace
    )
)

# Assignment with class member and array element access expressions

class A {a.b=c[1];}

==>

Specification(
    ClassDeclaration(
        class
        Whitespace
        Identifier
        Whitespace
        OpenBrace
        ExpressionStatement(
            AssignmentExpression(
                UnaryExpression(
                    UnaryExpression(
                        Identifier
                    )
                    ClassMemberAccess(
                        Period
                        Identifier
                    )
                )
                Assignment
                UnaryExpression(
                    UnaryExpression(
                        Identifier
                    )
                    ArrayElementAccess(
                        OpenBracket
                        UnaryExpression(
                            IntegerLiteral
                        )
                        CloseBracket
                    )
                )
            )
            Semicolon
        )
        CloseBrace
    )
)
