If a hex literal has an 'd' of 'f' in it, such as '0xf' or '0xd', the compiler fails with illegal tree structure.

The other hex literals work.  The issue is probably related to using `f` and `d` in float and double literals.

```
    public void testHexCollisionDouble() {
        assertEquals(13, exec("return 0xd"));
    }

    public void testHexCollisionFloat() {
        assertEquals(15, exec("return 0xf"));
    }

    public void testHex() throws Exception {
        for (int i = 0; i <= 15; i++) {
            String hex = Integer.toHexString(i);
            if ("d".equals(hex) || "f".equals(hex)) {
                continue;
            }
            assertEquals(i, exec("return 0x" + hex));
            assertEquals(i, exec("return 0x" + hex.toUpperCase(Locale.ROOT)));
            assertEquals(i, exec("return 0X" + hex));
            assertEquals(i, exec("return 0X" + hex.toUpperCase(Locale.ROOT)));
        }
    }
```
modules/lang-painless/src/main/java/org/elasticsearch/painless/phase/DefaultSemanticAnalysisPhase.java
}
            semanticScope.putDecoration(userSymbolNode, new StaticType(staticType));
        } else if (semanticScope.isVariableDefined(symbol)) {
            if (read == false && write == false) {
                throw userSymbolNode.createError(new IllegalArgumentException("not a statement: variable [" + symbol + "] not used"));
            }
            Location location = userSymbolNode.getLocation();
            Variable variable = semanticScope.getVariable(location, symbol);
            if (write && variable.isFinal()) {
                throw userSymbolNode.createError(new IllegalArgumentException("Variable [" + variable.name() + "] is read-only."));
            }
            Class<?> valueType = variable.type();
            semanticScope.putDecoration(userSymbolNode, new ValueType(valueType));
        } else {
            semanticScope.putDecoration(userSymbolNode, new PartialCanonicalTypeName(symbol));
        }
    }
    /**
     * Visits a dot expression which is a field index with a qualifier (prefix) and
     * may resolve to a static type, a partial canonical type, a field, a shortcut to a
     * getter/setter method on a type, or a getter/setter for a Map or List.
     * Checks: type validation, method resolution, field resolution
     */
    @Override
    public void visitDot(EDot userDotNode, SemanticScope semanticScope) {
        boolean read = semanticScope.getCondition(userDotNode, Read.class);
        boolean write = semanticScope.getCondition(userDotNode, Write.class);
        if (read == false && write == false) {
            throw userDotNode.createError(new IllegalArgumentException("not a statement: result of dot operator [.] not used"));
        }