Как выглядит синтаксический анализ компилятора Java?
Простое выражение типа
(x) - y
интерпретируется по-разному в зависимости от того, является ли x
именем типа или нет. Если x
не является именем типа, (x) - y
просто вычитает y
из x
. Но если x
- это имя типа, (x) - y
вычисляет отрицание y
и выводит результирующее значение на тип x
.
В типичном компиляторе C или С++ вопрос о том, является ли тип x
типом или нет, отвечает, потому что парсер передает эту информацию в лексер, как только он обрабатывает объявление typedef или struct. (Я думаю, что такое требуемое нарушение уровней было самой противной частью дизайна C.)
Но в Java x
не может быть определен до конца в исходном коде. Как компилятор Java рассогласовывает такое выражение?
Ясно, что компилятору Java требуется несколько проходов, поскольку Java не требует объявления перед использованием. Но это, по-видимому, означает, что первый проход должен выполнять очень неряшливое задание при разборе выражений, а затем в более позднем прохождении делать другой, более точный разбор выражений. Это кажется расточительным.
Есть ли лучший способ?
Ответы
Ответ 1
Я думаю, что нашел решение, которое меня удовлетворяет. Благодаря mmyers я понял, что мне нужно проверить формальную спецификацию синтаксиса для тиков.
Неоднозначность вызвана тем, что +
и -
являются как унарными, так и двоичными операторами. Java решает проблему этой грамматикой:
CastExpression:
( PrimitiveType Dimsopt ) UnaryExpression
( ReferenceType ) UnaryExpressionNotPlusMinus
(см. http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#238146)
Итак, '+'
и '-'
явно запрещены сразу после ')'
приведения, если только cast не использует примитивный тип - который известен априорно компилятору.
Ответ 2
Я только что проверил это, и этот код:
Double y = new Double(0.1);
System.out.println((Double)-y);
дает ошибку компиляции:
operator - cannot be applied to Double, java.lang.Double
.
Помещение круглых скобок вокруг -y делает его компилируемым. Таким образом, очевидно, что Java решает эту проблему, просто не допуская ее в грамматике (если это правильная терминология, я не эксперт по компиляторам).