Ad/2010-08-01 Concrete Syntax for a uml action Language for Foundational uml (Alf) Second Revised Submission



Download 1.74 Mb.
Page7/62
Date28.01.2017
Size1.74 Mb.
#9041
1   2   3   4   5   6   7   8   9   10   ...   62

6.3Lexical Structure


The lexical structure of Alf defines how the string of characters in an Alf input text is divided into a set of input elements. Such input elements can be categorized as whitespace, comments or tokens.

Lexical analysis is the process of converting an Alf input text into a corresponding stream of input elements. After lexical analysis, whitespace and comments are discarded and only tokens are retained for the subsequent step of parsing. Lexical analysis for Alf is thus essentially the same as is done for the processing of any typical textual programming language.

The Alf lexical structure is specified by a lexical grammar in which characters are terminal elements and the input elements resulting from lexical analysis are non-terminal elements. The lexical grammar is defined using an Extended Backus-Naur Form (EBNF) notation, whose conventions are given in Table 6 -1.

Table 6 1 EBNF Notation Conventions

Terminal element*

"terminal"

Non-terminal element

NonterminalElement

Sequential elements

Element1 Element2

Alternative elements

Element1 | Element2

Optional element (zero or one)

[ Element ]

Repeated element (zero or more)

{ Element }

Production definition

NonterminalElement = …

* The escape sequences given in Table 7 -3 are also used to represent the corresponding special characters within terminal elements in the EBNF notation.

6.4Concrete Syntax


The concrete syntax of Alf defines how lexical tokens are grouped into an abstract syntax tree. Parsing is the process of constructing an abstract syntax tree from the tokens produced by the lexical analysis of an Alf text. The parsing of an Alf input text is thus essentially the same as is done for the processing of any typical textual programming language.

The Alf concrete syntax is specified by a syntactic grammar whose definition is also based on the EBNF notation given in Table 6 -1. However, elements of the productions in the syntactic grammar are further annotated to indicate how an abstract syntax tree is to be constructed during parsing. The EBNF specification of Alf syntax provides the basis for the context-free parsing of an Alf input text. Context-dependent constraints are then enforced on the abstract syntax representation.

As described further below in Subclause 6.5, the abstract syntax for Alf is specified as a UML class model. A production in the syntactic grammar results in the synthesis of an instance of a class in the abstract syntax. The production definition defines a name for the instance being synthesized, which is used in the body of the production, and declares the class of the instance.

For example, the production

LocalNameDeclarationStatement(s: LocalNameDeclarationStatement)
= NameDeclaration(s) "=" InitializationExpression(s.expression) ";"

declares that it synthesizes an object called s of class LocalNameDeclarationStatement. Note the name of the class of the synthesized object is often the same as the non-terminal defined by the production, as in this example, but this is not always the case.

Annotations are parenthesized in the body of a production. There are several forms of annotation, as shown in Table 6 -2. For example, the body of the production given above may be read as follows: a LocalNameDeclarationStatement consists of a NameDeclaration (which is parsed into the object s), followed by “=”, followed by an InitializationExpression (the abstract syntax representation of which is assigned to the expression attribute of object s), followed by a “;”

Table 6 2 Abstract Syntax Synthesis Notation



Non-terminal object constraint

NonterminalElement(x)

The object x is constrained to be the same as the object synthesized for the immediately preceding non-terminal element.

Non-terminal property constraint

NonterminalElement(x.p)

The object synthesized for the immediately preceding non-terminal element is added to the list of values of property p of object x. If the non-terminal element is a lexical token, then the string image of the token is added to the property.

Terminal string constraint

"terminal"(x)

The synthesized “object” x, which must have the primitive type String, is constrained to have the string image of the immediately preceding terminal element as it’s value.

Terminal property constraint

"terminal"(x.p)

The string image of the immediately preceding terminal element is added to the list of values of property p of object x.

General constraint

(expr)

The OCL constraint expression expr must be true.

If an annotation appears in an alternative or optional element group, then it only applies if the content of that group actually applies during parsing. If an annotation appears in a repeating group, then it applies during each repeated application of the content of that group.

For example, the following is the production for the non-terminal NameDeclaration used in the body of the production for LocalNameDeclarationStatement above.

NameDeclaration(s: LocalNameDeclarationStatement)
= "let" Name(s.name) ":" TypeName(s.typeName)
[ MultiplicityIndicator (s.hasMultiplicity=true) ]
| TypeName(s.typeName)
[ MultiplicityIndicator (s.hasMultiplicity=true) ] Name(s.name)

According to this production, a NameDeclaration may have one of two alternative forms:



  • The terminal element “let”, followed by a Name (a lexical token whose string image is assigned to the name property of object s), followed by a “:”, followed by a TypeName (whose value is assigned to s.typeName), optionally followed by a MultiplicityIndicator (if there is a MultiplicityIndicator, then s.hasMultiplicity must be true).

  • A TypeName (whose value is assigned to s.typeName) optionally followed by a MultiplicityIndicator (if there is a MultiplicityIndicator, then s.hasMultiplicity must be true), followed by a Name (whose string image is assigned to s.name).

Finally, consider the production

ColonQualifiedName(q: QualifiedName)


= Name(q.name) "::" { Name(q.name) "::" } Name(q.name)

In this case, the first name is assigned to the property q.name, and then subsequent names, if any, are appended as additional values of that same property. Clearly, for this to be valid, the property QualifiedName::name must have a multiplicity upper bound of *.

Technically, the Alf concrete syntax is specified (as described above) using a simplified form of an attributive grammar. Each production has a single synthesized attribute. In an attributive grammar, the values for synthesized attributes are passed upwards in the parse tree. The Alf concrete grammar does not include any inherited attributes, however. Inherited attributes are passed downwards in the parse tree in order to enforce context-sensitive constraints. For Alf, such constraints are instead specified on the abstract syntax representation after parsing.



Download 1.74 Mb.

Share with your friends:
1   2   3   4   5   6   7   8   9   10   ...   62




The database is protected by copyright ©ininet.org 2024
send message

    Main page