Содержание
| Предыдущая | СледующаяГЛАВА 2
В этой главе описываются контекстно-свободные грамматики, используемые в данной спецификации для определения лексической и синтаксической структур программы, написанной на языке Ява.
Контекстно-свободная грамматика состоит из множества продукций. В левой части каждой продукции стоит абстрактный символ, называемый нетерминальным, в правой - последовательность, состоящая из одного или более нетерминальных и терминальных символов. Для каждой грамматики, терминальные символы - это символы определенного алфавита.
Начиная с предложения, состоящего из одного нетерминального символа, называемого начальным символом, данная контекстно-свободная грамматика определяет язык, который представляет собой бесконечный набор всевозможных последовательностей терминальных символов. Этот набор получается в результате замены (возможно неоднократной) любого нетерминального символа последовательностью, которая представляет собой правую часть продукции, для которой этот нетерминальный символ является левой частью.
2.2 Лексическая грамматикаПонятие - лексическая грамматика для языка Ява дается в § 3. Unicode - символы являются терминальными символами этой грамматики. Они определяют набор продукций, начинающихся с начального символа Ввод (§ 3.5), которые описывают каким образом последовательности Unicode -символов (§ 3.1) переводятся в последовательность элементов ввода (§ 3.5).
Эти элементы ввода, с незначащими символами (§ 3.6) и комментариями (§ 3.7), образуют терминальные символы синтаксической грамматики для языка Ява и называются лексемами языка Ява (§ 3.5). Лексемами являются идентификаторы (§ 3.8), ключевые слова (§ 3.9), литералы (§ 3.10), разделители (§ 3.11) и знаки операций (§ 3.11) языка Ява.
Синтаксическая грамматика для языка Ява описывается в главах 4, 6-10, 14 и 15. Терминальными символами этой грамматики являются лексемы языка Ява, определенные лексической грамматикой. Она определяется набором продукций, начинающихся с начального символа CompilationUnit (§ 7.3), которые описывают, каким образом последовательности символов могут формировать синтаксически корректные программы на языке Ява.
LALR (1) версия синтаксической грамматики представлена в главе 19. Грамматика в данной спецификации очень похожа на LALR (1) грамматику, но более читабельна.
В этой спецификации терминальные символы в продукциях лексической и синтаксической грамматик всегда записываются равноширинным шрифтом. В программе они имеют точно такое написание, как в данных продукциях.
Нетерминальные символы написаны курсивом. Определение нетерминального символа представлено именем, за которым следует двоеточие. Одна или более альтернативных правых частей для нетерминального символа записываются с новой строки. Например, синтаксическое определение:
IfThenStatement:if (
Expression)
Statement
показывает, что нетерминал IfThenStatement представляет символ if, за которым следует символ левой круглой скобки, за которым следует нетерминал Expression, за которым следует символ правой круглой скобки, за которым следует нетерминал Statement. Другой пример, синтаксическое определение:
ArgumentList:
Argument
ArgumentList ,
Argument
показывает, что ArgumentList может представлять либо просто нетерминал Argument, либо нетерминал ArgumentList, за которым следует запятая, за которой следует Argument. Данное определение нетерминала ArgumentList рекурсивно, то есть в определении понятия используется оно же само. В результате нетерминал ArgumentList может содержать любое положительное число нетерминалов Argument. Такое рекурсивное определение нетерминалов является обычным.
Подстрочный cуффикс "opt", который может появляться после терминала или нетерминала, показывает, что символ необязательный. Присутствие необязательного символа фактически определяет два варианта правой части: первый не содержит необязательный элемент, а второй - включает его. Это означает что:
BreakStatement:break
Identifieropt;
является удобным сокращением для:
BreakStatement:break ;
break
Identifier;
и что:
ForStatement:for (
ForInitopt;
Expressionopt;
ForUpdateopt)
Statement
является удобным сокращением для:
ForStatement:for ( ;
Expressionopt;
ForUpdateopt)
Statementfor (
ForInit;
Expressionopt;
ForUpdateopt)
Statement
которое в свою очередь является сокращением для:
ForStatement:for ( ; ;
ForUpdateopt)
Statementfor ( ;
Expression;
ForUpdateopt)
Statementfor (
ForInit; ;
ForUpdateopt)
Statementfor (
ForInit;
Expression;
ForUpdateopt)
Statement
которое в свою очередь является сокращением для:
ForStatement:for ( ; ; )
Statementfor ( ; ;
ForUpdate)
Statementfor ( ;
Expression; )
Statementfor ( ;
Expression;
ForUpdate)
Statementfor (
ForInit; ; )
Statementfor (
ForInit; ;
ForUpdate)
Statementfor (
ForInit;
Expression; )
Statementfor (
ForInit;
Expression;
ForUpdate)
Statement
Так что нетерминальный символ ForStatement имеет справа по такому определению фактически восемь альтернативных значений.
Очень длинное определение нетерминала может быть продолжено на второй строке с отступом относительно первой строки, например:
ConstructorDeclaration: ConstructorModifiersoptConstructorDeclarator Throwsopt
ConstructorBody
Эта конструкция определяет одну правую часть для нетерминального символа ConstructorDeclaration. (Эта правая часть - сокращение для четырех альтернативных правых частей, из-за двух употреблений суффикса "opt".)
Когда в грамматическом определении за двоеточием следуют слова " one of ", они показывают, что каждый из терминальных символов следующей строки или строк - альтернативное определение. Например, лексическая грамматика языка Ява содержит конструкцию:
ZeroToThree: one of
0 1 2 3
Которая просто является удобным сокращением для продукций:
ZeroToThree:0
1
2
3
Когда альтернатива в лексической продукции представляется лексемами, то она определяет последовательность знаков, из которых состоит эта лексема. Таким образом, определение:
BooleanLiteral: one of
true false
в лексической грамматике имеет то же значение, что и конструкция:
BooleanLiteral:
t r u e
f a l s e
В правой части лексической конструкции можно указать, что некоторые варианты не разрешаются, используя фразу " but not " и затем перечисляются варианты, которые будут исключены, как в констукциях InputCharacter (§ 3.4) и Identifier (§ 3.8):
InputCharacter: UnicodeInputCharacter but not CR or LF Identifier: IdentifierName but not a Keyword or BooleanLiteral or NullLiteral
Наконец, некоторые нетерминальные символы описываются наглядной фразой, напечатанной шрифтом roman, в случаях, где было бы нерационально вносить в список все альтернативы:
RawInputCharacter: any Unicode character