MGrammar Language Specification
MGrammar Language Specification
1 Introduction ..................................................................................................................................3
1.1 Language Basics ......................................................................................................................3
1.2 Character Processing.............................................................................................................. 5
1.3 Output ..................................................................................................................................... 7
1.4 Modularity ............................................................................................................................ 10
2 Lexical Structure ........................................................................................................................ 12
2.1 Programs ............................................................................................................................... 12
2.2 Grammars............................................................................................................................. 12
2.2.1 Grammar notation ........................................................................................................ 12
2.2.2 Lexical grammar ........................................................................................................... 13
2.2.3 Syntactic grammar ....................................................................................................... 14
2.3 Lexical analysis .................................................................................................................... 14
2.3.1 Line terminators ........................................................................................................... 14
2.3.2 Comments ..................................................................................................................... 15
2.3.3 Whitespace.................................................................................................................... 16
2.4 Tokens .................................................................................................................................. 16
2.4.1 Identifiers ...................................................................................................................... 17
2.4.2 Keywords....................................................................................................................... 17
2.4.3 Literals .......................................................................................................................... 18
2.4.3.1 Decimal literals ...................................................................................................... 18
2.4.3.2 Integer literals........................................................................................................ 18
2.4.3.3 Logical literals........................................................................................................ 18
2.4.3.4 Text literals ............................................................................................................ 19
2.4.3.5 Null literal .............................................................................................................. 21
2.4.4 Operators and punctuators .......................................................................................... 21
2.5 Pre-processing directives.................................................................................................... 22
2.5.1 Conditional compilation symbols ................................................................................23
2.5.2 Pre-processing expressions..........................................................................................23
2.5.3 Declaration directives.................................................................................................. 24
2.5.4 Conditional compilation directives ............................................................................ 24
3 Text Pattern Expressions .......................................................................................................... 28
3.1 Primary Expressions ........................................................................................................... 28
3.1.1 Character Class ............................................................................................................. 28
3.1.2 References .................................................................................................................... 28
3.1.3 Repetition operators .................................................................................................... 29
3.1.4 Inline Rules .................................................................................................................. 29
3.1.5 Any ................................................................................................................................ 30
3.1.6 Error ............................................................................................................................. 30
3.2 Term Operators .................................................................................................................... 31
4 Productions.................................................................................................................................32
4.1 Pattern Declaration ..............................................................................................................32
4.2 Term Declaration .................................................................................................................32
4.3 Constructors .........................................................................................................................33
4.3.1 Constructor operators...................................................................................................35
4.3.2 Default Constructor ..................................................................................................... 36
4.4 Precedence ........................................................................................................................... 37
4.4.1 Production Precedence ................................................................................................. 37
4.4.2 Term Precedence ......................................................................................................... 38
5 Rules........................................................................................................................................... 40
5.1 Token Rules ......................................................................................................................... 40
5.1.1 Final Modifier ................................................................................................................ 41
5.1.2 Identifier Modifier ........................................................................................................ 41
5.2 Syntax Rules ......................................................................................................................... 41
5.3 Interleave Rules ................................................................................................................... 41
5.4 Inline Rules ......................................................................................................................... 42
5.5 Rule Parameters .................................................................................................................. 42
6 Languages .................................................................................................................................. 44
6.1 Main Rule............................................................................................................................. 44
6.2 Cross-language rule references ...........................................................................................45
7 Modules...................................................................................................................................... 46
7.1 Compilation Unit ................................................................................................................. 46
7.2 Module Declaration............................................................................................................. 46
7.3 Inter-Module Dependencies ................................................................................................ 47
8 Attributes ....................................................................................................................................52
8.1 Case Sensitive .......................................................................................................................52
1 Introduction
Text is often the most natural way to represent information for presentation and editing by
people. However, the ability to extract that information for use by software has been an
arcane art practiced only by the most advanced developers. The success of XML is evidence
that there is significant demand for using text to represent information – this evidence is even
more compelling considering the relatively poor readability of XML syntax and the decade-
long challenge to make XML-based information easily accessible to programs and stores. The
emergence of simpler technologies like JSON and the growing use of meta-programming
facilities in Ruby to build textual domain specific languages (DSLs) such as Ruby on Rails or
Rake speak to the desire for natural textual representations of information. However, even
these technologies limit the expressiveness of the representation by relying on fixed formats
to encode all information uniformly, resulting in text that has very few visual cues from the
problem domain (much like XML).
The MGrammar Language (Mg) was created to enable information to be represented in a
textual form that is tuned for both the problem domain and the target audience. The Mg
language provides simple constructs for describing the shape of a textual language – that
shape includes the input syntax as well as the structure and contents of the underlying
information. To that end, Mg acts as both a schema language that can validate that textual
input conforms to a given language as well as a transformation language that projects textual
input into data structures that are amenable to further processing or storage. The data that
results from Mg processing is compatible with Mg‟s sister language, The "Oslo" Modeling
Language, "M", which provides a SQL-compatible schema and query language that can be
used to further process the underlying information.
1.3 Output
Mg processing transforms text into structured data. The shape and content of that data is
determined by the syntax rules of the language being processed. Each syntax rule consists of a
set of productions, each of which consists of a pattern and an optional projection. Patterns
were discussed in the previous sections and describe a set of legal character sequences that
are valid input. Projections describe how the information represented by that input should be
produced.
Each production is like a function from text to structured data. The primary way to write
projections is to use a simple construction syntax that produces graph-structured data
suitable for programs and stores. For example, consider this rule:
syntax Rock =
"Rock" => Item { Heavy { true }, Solid { true } } ;
This rule has one production that has a pattern that matches "Rock" and a projection that
produces the following value (using a notation known as D graphs):
Item {
Heavy { true },
Solid { true }
}
Rules can contain more than one production in order to allow different input to produce very
different output. Here‟s an example of a rule that contains three productions with very
different projections:
syntax Contents
= "Rock" => Item { Heavy { true }, Solid { true } }
| "Water" => Item { Consumable { true }, Solid { false } }
| "Hamster" => Pet { Small { true }, Legs { 4 } } ;
When a rule with more than one production is processed, the input text is tested against all of
the productions in the rule to determine whether the rule applies. If the input text matches
the pattern from exactly one of the rule‟s productions, then the corresponding projection is
used to produce the result. In this example, when presented with the input text "Hamster", the
rule would yield:
Pet {
Small { true },
Legs { 4 }
}
as a result.
To allow a syntax rule to match no matter what input it is presented with, a syntax rule may
specify a production that uses the empty pattern, which will be selected if and only if none of
the other productions in the rule match:
syntax Contents
= "Rock" => Item { Heavy { true }, Solid { true } }
| "Water" => Item { Consumable { true }, Solid { false } }
| "Hamster" => Pet { Small { true }, Legs { 4 } }
| empty => NoContent { } ;
When the production with the empty pattern is chosen, no input is consumed as part of the
match.
To allow projections to use the input text that was used during pattern matching, pattern
terms associate a variable name with individual pattern terms by prefixing the pattern with an
identifier separated by a colon. These variable names are then made available to the
projection. For example, consider this language:
language GradientLang {
syntax Main
= from:Color ", " to:Color => Gradient { Start { from }, End { to } } ;
token Color
= "Red" | "Green" | "Blue";
}
Given this input value:
Red, Blue
The Mg processor would produce this output:
Gradient {
Start { "Red" },
End { "Blue" }
}
Like all projection expressions we‟ve looked at, literal values may appear in the output graph.
The set of literal types supported by Mg and a couple examples follow:
Text literals – "ABC", 'ABC'
Integer literals – 25, -34
Real literals – 0.0, -5.0E15
Logical literals – true, false
Null literal – null
The projections we‟ve seen so far all attach a label to each graph node in the output (e.g.,
Gradient, Start, etc.). The label is optional and can be omitted:
syntax Naked = t1:First t2:Second => { t1, t2 };
The label can be an arbitrary string – to allow labels to be escaped, one uses the id operator:
syntax Fancy = t1:First t2:Second => id("Label with Spaces!"){ t1, t2 };
The id operator works with either literal strings or with variables that are bound to input text:
syntax Fancy = name:Name t1:First t2:Second => id(name){ t1, t2 };
Using id with variables allows the labeling of the output data to be driven dynamically from
input text rather than statically defined in the language. This example works when the
variable name is bound to a literal value. If the variable was bound to a structured node that
was returned by another rule, that node‟s label can be accessed using the labelof operator:
syntax Fancier p:Point => id(labelof(p)) { 1, 2, 3 };
The labelof operator returns a string that can be used both in the id operator as well as a
node value.
The projection expressions shown so far have no notion of order. That is, this projection
expression:
A { X { 100 }, Y { 200 } }
is semantically equivalent to this:
A { Y { 200 }, X { 100 } }
and implementations of Mg are not required to preserve the order specified by the projection.
To indicate that order is significant and must be preserved, brackets are used rather than
braces. This means that this projection expression:
A [ X { 100 }, Y { 200 } ]
is not semantically equivalent to this:
A [ Y { 200 }, X { 100 } ]
The use of brackets is common when the sequential nature of information is important and
positional access is desired in downstream processing.
Sometimes it is useful to splice the nodes of a value together into a single collection. The
valuesof operator will return the values of a node (labeled or unlabeled) as top-level values
that are then combinable with other values as values of new node.
syntax ListOfA
= a:A => [a]
| list:ListOfA "," a:A => [ valuesof(list), a ];
Here, valuesof(list) returns the all the values of the list node, combinable with a to form a
new list.
Productions that do not specify a projection get the default projection.
For example, consider this simple language that does not specify productions:
language GradientLanguage {
syntax Main = Gradient | Color;
syntax Gradient = from:Color " on " to:Color;
token Color = "Red" | "Green" | "Blue";
}
When presented with the input "Blue on Green” the language processor returns the following
output:
Main[ Gradient [ "Red", " on ", "Green" ] ] ]
These default semantics allows grammars to be authored rapidly while still yielding
understandable output. However, in practice explicit projection expressions provide language
designers complete control over the shape and contents of the output.
1.4 Modularity
All of the examples shown so far have been “loose Mg” that is taken out of context. To write a
legal Mg document, all source text must appear in the context of a module definition. A
module defines a top-level namespace for any languages that are defined.
Here is a simple module definition:
module Literals {
// declare a language
language Number {
syntax Main = ('0'..'9')+;
}
}
In this example, the module defines one language named Literals.Number.
Modules may refer to declarations in other modules by using an import directive to name the
module containing the referenced declarations. For a declaration to be referenced by other
modules, the declaration must be explicitly exported using an export directive.
Consider this module:
module MyModule {
import HerModule; // declares HerType
export MyLanguage1;
language MyLanguage1 {
syntax Main = HerLanguage.Options;
}
language MyLanguage2 {
syntax Main = "x"+;
}
}
Note that only MyLanguage1 is visible to other modules. This makes the following definition of
HerModule legal:
module HerModule {
import MyModule; // declares MyLanguage1
export HerLanguage;
language HerLanguage {
syntax Options = (('a'..'z')+ ('on'|'off'))*;
}
language Private { }
}
As this example shows, modules may have circular dependencies.
2 Lexical Structure
2.1 Programs
An Mg program consists of one or more source files, known formally as compilation units. A
compilation unit file is an ordered sequence of Unicode characters. Compilation units
typically have a one-to-one correspondence with files in a file system, but this correspondence
is not required. For maximal portability, it is recommended that files in a file system be
encoded with the UTF-8 encoding.
Conceptually speaking, a program is compiled using four steps:
1. Lexical analysis, which translates a stream of Unicode input characters into a stream of
tokens. Lexical analysis evaluates and executes pre-processing directives.
2. Syntactic analysis, which translates the stream of tokens into an abstract syntax tree.
3. Semantic analysis, which resolves all symbols in the abstract syntax tree, type checks the
structure and generates a semantic graph.
4. Code generation, which generates instructions from the semantic graph for some target
runtime, producing an image.
Further tools may link images and load them into a runtime.
2.2 Grammars
This specification presents the syntax of the Mg programming language using two grammars.
The lexical grammar defines how Unicode characters are combined to form line terminators,
white space, comments, tokens, and pre-processing directives. The syntactic grammar defines
how the tokens resulting from the lexical grammar are combined to form Mg programs.
2.3.2 Comments
Two forms of comments are supported: single-line comments and delimited comments.
Single-line comments start with the characters // and extend to the end of the source line.
Delimited comments start with the characters /* and end with the characters */. Delimited
comments may span multiple lines.
Comment:
CommentDelimited
CommentLine
CommentDelimited:
/* CommentDelimitedContentsopt */
CommentDelimitedContent:
* none of /
CommentDelimitedContents:
CommentDelimitedContent
CommentDelimitedContents CommentDelimitedContent
CommentLine:
// CommentLineContentsopt
CommentLineContent: none of
NewLineCharacter
CommentLineContents:
CommentLineContent
CommentLineContents CommentLineContent
Comments do not nest. The character sequences /* and */ have no special meaning within a
// comment, and the character sequences // and /* have no special meaning within a
delimited comment.
Comments are not processed within text literals.
The example
// This defines a
// Logical literal
//
syntax LogicalLiteral
= "true"
| "false" ;
shows three single-line comments.
The example
/* This defines a
Logical literal
*/
syntax LogicalLiteral
= "true"
| "false" ;
includes one delimited comment.
2.3.3 Whitespace
Whitespace is defined as any character with Unicode class Zs (which includes the space
character) as well as the horizontal tab character, the vertical tab character, and the form feed
character.
Whitespace:
WhitespaceCharacters
WhitespaceCharacter:
U+0009 // Horizontal Tab
U+000B // Vertical Tab
U+000C // Form Feed
U+0020 // Space
NewLineCharacter
WhitespaceCharacters:
WhitespaceCharacter
WhitespaceCharacters WhitespaceCharacter
2.4 Tokens
There are several kinds of tokens: identifiers, keywords, literals, operators, and punctuators.
White space and comments are not tokens, though they act as separators for tokens.
Token:
Identifier
Keyword
Literal
OperatorOrPunctuator
2.4.1 Identifiers
A regular identifier begins with a letter or underscore and then any sequence of letter,
underscore, dollar sign, or digit. An escaped identifier is enclosed in square brackets. It
contains any sequence of Text literal characters.
Identifier:
IdentifierBegin IdentifierCharactersopt
IdentifierVerbatim
IdentifierBegin:
_
Letter
IdentifierCharacter:
IdentifierBegin
$
DecimalDigit
IdentifierCharacters:
IdentifierCharacter
IdentifierCharacters IdentifierCharacter
IdentifierVerbatim:
[ IdentifierVerbatimCharacters ]
IdentifierVerbatimCharacter:
none of ]
IdentifierVerbatimEscape
IdentifierVerbatimCharacters:
IdentifierVerbatimCharacter
IdentifierVerbatimCharacters IdentifierVerbatimCharacter
IdentifierVerbatimEscape:
\\
\]
Letter:
a..z
A..Z
DecimalDigit:
0..9
DecimalDigits:
DecimalDigit
DecimalDigits DecimalDigit
2.4.2 Keywords
A keyword is an identifier-like sequence of characters that is reserved, and cannot be used as
an identifier except when escaped with square brackets [].
Keyword: oneof:
any empty error export false final id import interleave language
labelof left module null precedence right syntax token true valuesof
The following keywords are reserved for future use:
checkpoint identifier nest override new virtual partial
2.4.3 Literals
A literal is a source code representation of a value.
Literal:
DecimalLiteral
IntegerLiteral
LogicalLiteral
NullLiteral
TextLiteral
Literals may be ascribed with a type to override the default type ascription.
Since Mg uses a 16-bit encoding of Unicode code points in Text values, a Unicode character in
the range U+10000 to U+10FFFF is not considered a Text literal of length one (a single
character), but is represented using a Unicode surrogate pair in a Text literal.
Unicode characters with code points above 0x10FFFF are not supported.
Multiple translations are not performed. For instance, the text literal \u005Cu005C is
equivalent to \u005C rather than \. The Unicode value U+005C is the character \.
A hexadecimal escape sequence represents a single Unicode character, with the value formed
by the hexadecimal number following the prefix.
TextLiteral:
' SingleQuotedCharacters '
" DoubleQuotedCharacters "
@ ' SingleQuotedVerbatimCharactersopt '
@ " DoubleQuotedVerbatimCharactersopt "
SingleQuotedCharacters:
SingleQuotedCharacter
SingleQuotedCharacters SingleQuotedCharacter
SingleQuotedCharacter:
SingleQuotedCharacterSimple
CharacterEscapeSimple
CharacterEscapeUnicode
SingleQuotedCharacterSimple: none of
'
\
NewLineCharacter
SingleQuotedVerbatimCharacters:
SingleQuotedVerbatimCharacter
SingleQuotedVerbatimCharacters SingleQuotedVerbatimCharacter
SingleQuotedVerbatimCharacter:
none of '
SingleQuotedVerbatimCharacterEscape
SingleQuotedVerbatimCharacterEscape:
""
DoubleQuotedCharacter:
DoubleQuotedCharacterSimple
CharacterEscape
DoubleQuotedCharacters:
DoubleQuotedCharacter
DoubleQuotedCharacters DoubleQuotedCharacter
DoubleQuotedCharacterSimple: none of
"
\
NewLineCharacter
DoubleQuotedVerbatimCharacter:
none of "
DoubleQuotedVerbatimCharacterEscape
DoubleQuotedVerbatimCharacters:
DoubleQuotedVerbatimCharacter
DoubleQuotedVerbatimCharacters DoubleQuotedVerbatimCharacter
DoubleQuotedVerbatimCharacterEscape:
""
CharacterEscape:
CharacterEscapeSimple
CharacterEscapeUnicode
CharacterEscapeSimple:
\ CharacterEscapeSimpleCharacter
CharacterEscapeSimpleCharacter: one of
' " \ 0 a b f n r t v
CharacterEscapeUnicode:
\u HexDigit HexDigit HexDigit HexDigit
\U HexDigit HexDigit HexDigit HexDigit HexDigit HexDigit HexDigit HexDigit
Examples of text literals follow:
'a'
'\u2323'
'\x2323'
'2323'
"Hello World"
@"""Hello,
World"""
"\u2323"
Text pattern expressions perform operations on the sets of possible text values that one or
more terms recognize.
3.1.2 References
A reference primary is the name of another rule possibly with arguments for parameterized
rules. All rules defined within the same language can be accessed without qualification. The
protocol to access rules defined in a different language within the same module are defined in
§6.2. The protocol to access rules defined in a different module are defined in §7.3.
ReferencePrimary:
GrammarReference
GrammarReference:
Identifier
GrammarReference . Identifier
GrammarReference . Identifier ( TypeArguments )
Identifier ( TypeArguments )
TypeArguments:
PrimaryExpression
TypeArguments , PrimaryExpression
Note that whitespace between a rule name and its arguments list is significant to discriminate
between a reference to a parameterized rule and a reference without parameters and an inline
rule. In a reference to a parameterized rule, no whitespace is permitted between the identifier
and the arguments.
3.1.5 Any
The any term is a wildcard that matches any text value of length 1.
Any:
any
"1", "z", and "*" all match any.
3.1.6 Error
The error production enables error recover. Consider the following example:
module HelloWorld {
language HelloWorld {
syntax Main
= HelloList;
token Hello
= "Hello";
checkpoint syntax HelloList
= Hello
| HelloList "," Hello
| HelloList "," error;
}
}
The language recognizes the text "Hello,Hello,Hello" as expected and produces the
following default output:
Main[
HelloList[
HelloList[
HelloList[
Hello
],
,,
Hello
],
,,
Hello
]
]
The text "Hello,hello,Hello" is not in the language because the second "h" is not capitalized
(and case sensitivity is true). However, rather than stop at "h", the language processor
matches "h" to the error token, then matches "e" to the error token, etc. Until it reaches the
comma. At this point the text conforms to the language and normal processing can continue.
The language process reports the position of the errors and produces the following output:
Main[
HelloList[
HelloList[
HelloList[
Hello
],
error["hello"],
],
,,
Hello
]
]
Hello occurs twice instead of three times as above and the text the error token matched is
returned as error["hello"].
4.4 Precedence
The Mg language processor is tolerant of such ambiguity as it is recognizing subsequences of
text. However, it is an error to produce more than one output for an entire text value.
Precedence qualifiers on productions or terms determine which of the several outputs should
be returned.
A rule is a named collection of alternative productions. There are three kinds of rules: syntax,
token, and interleave. A text value conforms to a rule if it conforms to any one of the
productions in the rule. If a text value conforms to more than one production in the rule, then
the rule is ambiguous. The three different kinds of rules differ in how they treat ambiguity
and how they handle their output.
RuleDeclaration:
Attributesopt MemberModifiersopt Kind Name RuleParametersopt RuleBodyopt ;
Kind:
token
syntax
interleave
MemberModifiers:
MemberModifier
MemberModifiers MemberModifer
MemberModifier:
final
identifier
RuleBody:
= ProductionDeclarations
ProductionDeclarations:
ProductionDeclaration
ProductionDeclarations | ProductionDeclaration
The rule Main below recognizes the two text values "Hello" and "Goodbye".
module HelloGoodby {
language HelloGoodbye {
syntax Main
= "Hello"
| "Goodbye";
}
}
syntax AppleOrOrange
= "Apple" => Apple{}
| "Orange" => Orange{};
}
language Example2 {
syntax Main
= aos:("Apple" => Apple{} | "Orange" => Orange{})*
=> aos;
}
}
language Words {
token Hello
= "Hello";
token World
= "World";
}
language HelloWorld {
syntax Main
= Words.Hello Whitespace Words.World;
token Whitespace =
= " ";
}
}
All rules defined within the same module are accessible in this way. Rules defined in other
modules must be exported and imported as defined in §7.
7 Modules
language Internal {
token Digit = '0'..'9';
token Letter = 'A'..'Z' | 'a'..'z';
}
language Base {
token Identifier = Letter (Letter | Digit)*;
}
}
The definition Language.Core.Internal may only be referenced from within the module
Language.Core. The definition Language.Core.Base may be referenced in any module that has
an ImportDirective for module Language.Core, as shown in this example:
module Language.Extensions {
import Language.Core;
language Names {
syntax QualifiedIdentifier
= Language.Core.Base.Identifier '.' Language.Core.Base.Identifier;
}
}
The example above uses the fully qualified name to refer to Language.Core.Base. An
ImportDirective may also specify an ImportAlias that provides a replacement Identifier for
the imported declaration:
module Language.Extensions {
import Language.Core as lc;
language Names {
syntax QualifiedIdentifier
= lc.Base.Identifier '.' lc.Base.Identifier;
}
}
An ImportAlias replaces the name of the imported declaration. That means that the following
is an error:
module Language.Extensions {
import Language.Core as lc;
language Names {
syntax QualifiedIdentifier
= Language.Core.Base.Identifier '.' Language.Core.Base.Identifier;
}
}
It is legal for two or more ImportDirectives to import the same declaration, provided they
specify distinct aliases. For a given compilation episode, at most one ImportDirective may use
a given alias.
If an ImportDirective imports a module without specifying an alias, the declarations in the
imported module may be referenced without the qualification of the module name.
That means the following is also legal.
module Language.Extensions {
import Language.Core;
language Names {
syntax QualifiedIdentifier = Base.Identifier '.' Base.Identifier;
}
}
When two modules contain same-named declarations, there is a potential for ambiguity. The
potential for ambiguity is not an error – ambiguity errors are detected lazily as part of
resolving references.
Consider the following two modules:
module A {
export L;
language L {
token X = '1';
}
}
module B {
export L;
language L {
token X = '2';
}
}
It is legal to import both modules either with or without providing an alias:
module C {
import A, B;
language M {
token Y = '3';
}
}
This is legal because ambiguity is only an error for references, not declarations. That means
that the following is a compile-time error:
module C {
import A, B;
language M {
token Y = L.X | '3';
}
}
This example can be made legal either by fully qualifying the reference to L:
module C {
import A, B;
language M {
token Y = A.L.X | '3'; // no error
}
}
or by adding an alias to one or both of the ImportDirectives:
module C {
import A;
import B as bb;
language M {
token Y = L.X | '3'; // no error, refers to A.L
token Z = bb.L.X | '3'; // no error, refers to B.L
}
}
An ImportDirective may either import all exported declarations from a module or only a
selected subset of them. The latter is enabled by specifying ImportMembers as part of the
directive. For example, Module Plot2D imports only Point2D and PointPolar from the Module
Geometry:
module Geometry {
import Algebra;
export Geo2D, Geo3D;
language Geo2D {
syntax Point = '(' Numbers.Number ',' Numbers.Number ')';
syntax PointPolar = '<' Numbers.Number ',' Numbers.Number '>';
}
language Geo3D {
syntax Point =
'(' Numbers.Number ',' Numbers.Number ',' Numbers.Number ')';
}
}
module Plot2D {
import Geometry {Geo2D};
language Paths {
syntax Path = '(' Geo2D.Point* ')';
syntax PathPolar = '(' Geo2D.PointPolar* ')';
}
}
An ImportDirective that contains an ImportMember only imports the named declarations
from that module. This means that the following is a compilation error because module
Plot3D references Geo3D which is not imported from module Geometry:
module Plot3D {
import Geometry {Geo2D};
language Paths {
syntax Path = '(' Geo3D.Point* ')';
}
}
An ImportDirective that contains an ImportAlias on a selected imported member assigns the
replacement name to the imported declaration, hiding the original export name.
module Plot3D {
import Geometry {Geo3D as geo};
language Paths {
syntax Path = '(' geo.Point* ')';
}
}
Aliasing an individual imported member is useful to resolve occasional conflicts between
imports. Aliasing an entire imported module is useful to resolve a systemic conflict. For
example, when importing two modules, where one is a different version of the other, it is
likely to get many conflicts. Aliasing at member level would lead to a correspondingly long list
of alias declarations.
8 Attributes
Attributes provide metadata which can be used to interpret the language feature they modify.
AttributeSections:
AttributeSection
AttributeSections AttributeSection
AttributeSection:
@{ Nodes }