Spec-Zone .ru
спецификации, руководства, описания, API
Содержание | Предыдущий | Следующий | Индекс

ГЛАВА 19

LALR (1) Грамматика


Эта глава представляет грамматику для Java. Грамматика была механически проверена, чтобы обеспечить, чтобы это был LALR (1).

Грамматика для Java, представленного по частям в предыдущих главах, намного лучше для выставки, но это не может быть проанализировано слева направо с одним маркером предвидения из-за определенных синтаксических особенностей, некоторые из них наследованный от C и C++. Эти проблемы и решения, принятые для LALR (1) грамматика, представляются ниже, сопровождаются грамматикой непосредственно.

19.1 Грамматические Трудности

Есть пять проблем с грамматикой, представленной в предыдущих главах.

19.1.1 Проблема #1: Слишком Определенные Имена

Рассмотрите две группы производства:

и:

Теперь рассмотрите частичный ввод:

class Problem1 { int m() { hayden.
Когда синтаксический анализатор рассматривает маркер hayden, с предвидением с одним маркером к символу".", это еще не может сказать ли hayden должен быть PackageName, который квалифицирует имя типа, как в:

hayden.Dinosaur rex = new hayden.Dinosaur(2);
или AmbiguousName, который квалифицирует имя метода, как в:

hayden.print("Dinosaur Rex!");
Поэтому, производство, показанное выше результата в грамматике, которая не является LALR (1). Есть также другие проблемы с рисованием различий среди различных видов имен в грамматике.

Решение состоит в том, чтобы устранить нетерминалы PackageName, TypeName, ExpressionName, MethodName, и AmbiguousName, заменяя их всех единственным нетерминальным Именем:

Более поздний этап компиляторного анализа тогда разбирается в точной роли каждого имени или спецификатора имени.

По связанным причинам, этому производству в §4.3:

были изменены на:

19.1.2 Проблема #2: Слишком Определенные Модификаторы

Рассмотрите две группы производства:

и:

Теперь рассмотрите частичный ввод:

class Problem2 { public static int
Когда синтаксический анализатор рассматривает маркер static, с предвидением с одним маркером к символу int- или, хуже все же, рассматривая маркер public с предвидением к static- это еще не может сказать, будет ли это полевым объявлением, таким как:

public static int maddie = 0;
или объявление метода, такое как:

public static int maddie(String art) { return art.length(); }
Поэтому, синтаксический анализатор не может сказать с только предвидением с одним маркером ли static (или, точно так же public) должен быть уменьшен до FieldModifier или MethodModifier. Поэтому, производство, показанное выше результата в грамматике, которая не является LALR (1). Есть также другие проблемы с рисованием различий среди различных видов модификаторов в грамматике.

В то время как не все контексты вызывают проблему, самое простое решение состоит в том, чтобы объединить все контексты, в которых такие модификаторы используются, устраняя все шесть из нетерминалов ClassModifiers (§8.1.2), FieldModifiers (§8.3.1), MethodModifiers (§8.4.3), ConstructorModifiers (§8.6.3), InterfaceModifiers (§9.1.2), и ConstantModifiers (§9.3) от грамматики, заменяя их всех с синглом нетерминальные Модификаторы:

Более поздний этап компиляторного анализа тогда разбирается в точной роли каждого модификатора и разрешается ли это в данном контексте.

19.1.3 Проблема #3: Полевое Объявление против Объявления метода

Рассмотрите эти два производства (показанный после того, как проблема #2 была исправлена):

и:

где ResultType определяется как:

Теперь рассмотрите частичный ввод:

class Problem3 { int julie
Отметьте, что в этом простом примере никакие Модификаторы не присутствуют. Когда синтаксический анализатор рассматривает маркер int, с предвидением с одним маркером к символу julie, это еще не может сказать, будет ли это полевым объявлением, таким как:

int julie = 14;
или объявление метода, такое как:

int julie(String art) { return art.length(); }
Поэтому, после того, как синтаксический анализатор уменьшает int к нетерминальному Типу это не может сказать с только предвидением с одним маркером, должен ли Тип быть далее уменьшен до ResultType (для объявления метода) или оставлен в покое (для полевого объявления). Поэтому, производство, показанное выше результата в грамматике, которая не является LALR (1).

Решение состоит в том, чтобы устранить производство ResultType и иметь отдельные альтернативы для MethodHeader:

Это позволяет синтаксическому анализатору уменьшать int Ввести и затем оставить это, как, задерживая решение относительно того, происходят ли полевое объявление или объявление метода.

19.1.4 Проблема #4: Тип Массива против Доступа Массива

Рассмотрите производство (показанный после того, как проблема #1 была исправлена):

и:

Теперь рассмотрите частичный ввод:

class Problem4 { Problem4() { peter[
Когда синтаксический анализатор рассматривает маркер peter, с предвидением с одним маркером к символу [, это еще не может сказать ли peter будет часть имени типа, как в:

peter[] team;
или часть доступа массива, как в:

peter[3] = 12;
Поэтому, после того, как синтаксический анализатор уменьшает peter к нетерминальному Имени это не может сказать с только предвидением с одним маркером, должно ли Имя быть уменьшено в конечном счете, чтобы Ввести (для типа массива) или оставлено в покое (для доступа массива). Поэтому, производство, показанное выше результата в грамматике, которая не является LALR (1).

Решение состоит в том, чтобы иметь отдельные альтернативы для ArrayType:

Это позволяет синтаксическому анализатору уменьшать peter Назвать и затем оставить это, как, задерживая решение относительно того, происходят ли тип массива или доступ массива.

19.1.5 Проблема #5: Бросок против Заключенного в скобки Выражения

Рассмотрите производство:

Теперь рассмотрите частичный ввод:

class Problem5 { Problem5() { super((matthew)
Когда синтаксический анализатор рассматривает маркер matthew, с предвидением с одним маркером к символу ), это еще не может сказать ли (matthew) будет заключенное в скобки выражение, как в:

super((matthew), 9);
или бросок, как в:

super((matthew)baz, 9);
Поэтому, после того, как синтаксический анализатор уменьшает matthew к нетерминальному Имени это не может сказать с только предвидением с одним маркером, должно ли Имя быть далее уменьшено до PostfixExpression и в конечном счете до Выражения (для заключенного в скобки выражения) или к ClassOrInterfaceType и затем к ReferenceType (для броска). Поэтому, производство, показанное выше результата в грамматике, которая не является LALR (1).

Решение состоит в том, чтобы устранить использование нетерминального ReferenceType в определении CastExpression, который требует, чтобы некоторая переделка обеих альтернатив избежала других неоднозначностей:

Это позволяет синтаксическому анализатору уменьшать matthew к Выражению и затем оставляют это там, задерживая решение относительно того, происходят ли заключенное в скобки выражение или бросок. Несоответствующие разновидности, такие как:

(int[])+3
и:

(matthew+1)baz
должен тогда быть избавлен и отклонен более поздним этапом компиляторного анализа.

Остающиеся разделы этой главы составляют LALR (1) грамматика для синтаксиса Java, в котором выше были решены эти пять проблем, описанных.

19.2 Производство от §2.3: Синтаксическая Грамматика

19.3 Производство от §3: Лексическая Структура

19.4 Производство от §4: Типы, Значения, и Переменные

19.5 Производство от §6: Имена

19.6 Производство от §7: Пакеты

19.7 Производство, Используемое Только в LALR (1) Грамматика

19.8 Производство от §8: Классы

19.8.1 Производство от §8.1: Объявление Класса

19.8.2 Производство от §8.3: Полевые Объявления

19.8.3 Производство от §8.4: Объявления метода

19.8.4 Производство от §8.5: Статические Инициализаторы

19.8.5 Производство от §8.6: Объявления Конструктора

19.9 Производство от §9: Интерфейсы

19.9.1 Производство от §9.1: Интерфейсные Объявления

19.10 Производства от §10: Массивы

19.11 Производства от §14: Блоки и Операторы

19.12 Производства от §15: Выражения


Содержание | Предыдущий | Следующий | Индекс

Спецификация языка Java (HTML, сгенерированный Блинчиком "сюзет" Pelouch 24 февраля 1998)
Авторское право © Sun Microsystems, Inc 1996 года. Все права защищены
Пожалуйста, отправьте любые комментарии или исправления к doug.kramer@sun.com

free hit counter