133 Source Files and Declarations
Predica has two top-level file grammars. _component_.predica is a component manifest: it marks
the component root and has an optional component declaration followed by an optional releases
block. Each release entry has a fixed name field and date field, followed by zero or more
component release dependencies.
An ordinary .predica source file has a prologue followed by declarations and then optional
program statements. Its prologue consists of an optional component declaration, an optional
@dynamic directive, and zero or more file-scoped using declarations, in that order.
A using declaration belongs to an ordinary source-file prologue. Once a program variable, update
statement, procedure call, or expression statement appears, no further declarations may appear in that
file.
Grammar in EBNF
(************** Program **************)
Program =
ComponentManifestFile
| SourceFile;
ComponentManifestFile =
[ ComponentDeclaration ],
[ ComponentReleasesBlock ];
SourceFile =
SourceFilePrologue,
TypeDefinitions,
{ Statement };
SourceFilePrologue =
[ ComponentDeclaration ],
[ DynamicModeDeclaration ],
{ UsingDeclaration };
(* ComponentManifestFile is the grammar for _component_.predica.
SourceFile is the grammar for ordinary .predica source files.
UsingDeclaration is permitted only in SourceFilePrologue, not inside a namespace. *)
ComponentDeclaration =
"component", QualifiedComponentName, ";";
ComponentReleasesBlock =
"releases",
"{",
{ ComponentReleaseEntry, [ "," ] },
"}";
ComponentReleaseEntry =
IntegerLiteral,
":",
"{",
"name", ":", StringLiteral,
",",
"date", ":", ComponentReleaseDate,
{ ",", ComponentReleaseDependency },
[ "," ],
"}";
ComponentReleaseDate =
"(", IntegerLiteral, ",", Identifier, ",", IntegerLiteral, ")";
ComponentReleaseDependency =
QualifiedComponentName,
":",
IntegerLiteral;
DynamicModeDeclaration =
"@", "dynamic", "=", BooleanLiteral, ";";
UsingDeclaration =
"using",
QualifiedComponentName,
[ ( "as", ComponentName ) | SelectedImportList ],
";";
SelectedImportList =
"{",
SelectedImport, { ",", SelectedImport },
"}";
SelectedImport =
QualifiedImportName, [ "as", Identifier ];
QualifiedImportName =
Identifier, { ".", Identifier };
(************** Metadata **************)
MetaData =
MetaDataItem, { MetaDataItem };
MetaDataItem =
"@", Identifier, [ "(", [ ExpressionList ], ")" ];
(************** Names **************)
(* Qualified names used in references *)
QualifiedNamespaceName = NamespaceName, { ".", NamespaceName };
QualifiedComponentName = QualifiedNamespaceName;
QualifiedTypeName = [ComponentName, "."], TypeName;
(* Unqualified names, typically used in definitions. These are also used for aliases *)
NamespaceName = Identifier;
TypeName = Identifier;
AttributeName = Identifier;
GlobalVarName = Identifier;
ComponentName = Identifier;