Appendix D. PDL Syntax

This chapter introduces the syntax for the Persistence Definition Language.

D.1. PDL Grammar

The following is an Extended Backus-Naur Form (EBNF) grammar that defines the current PDL language. EBNF is a standard notation for formally defining a language that extends BNF (they are functionally equivalent -- EBNF simply introduces some elements for better readability).

In this grammar, items within angle braces <ITEM> are terminals (tokens), while those not within angle brackets are non-terminals. If you are unfamiliar with EBNF, http://www.garshol.priv.no/download/text/bnf.html is a good starting point.

/** Top level constructs. */

 file :=
     model <SEMI>
     ( pdl_import <SEMI> )*
     ( object_type | association | data_operation )*
     <EOF>

 model := <MODEL> idpath

 pdl_import := <IMPORT> idpath ( <DOT> <STAR> )?

 object_type :=
    ( <VERSIONED> )?
    ( <QUERY> | <OBJECTTYPE> ) id
    ( ( <EXTENDS> type |
        <CLASS> javaClass <ADAPTER> javaClass |
        <RETURNS> <INT> <DOT> <DOT> ( id | <INT> ) ) )?
    <LBRACE> ( statement )* <RBRACE>

 association :=
     <ASSOCIATION> <LBRACE> property <SEMI> property <SEMI>
     ( property <SEMI> )*
     ( option_block )?
     ( event )* <RBRACE>

 data_operation :=
     <DATA_OPERATION> id <LBRACE> ( option_block )? sql_block <RBRACE>


/** First level constructs. */

 statement := ( simple_statement <SEMI> | compound_statement )
 simple_statement :=
     ( property_stmt | object_key | reference_key |
       unique_key | aggressive_load | join_stmt )

 compound_statement :=      ( event | option_block )


/** Simple statements */

 property_stmt := property

 property :=
     ( <IMMEDIATE> )?
     ( ( <VERSIONED> | <UNVERSIONED> ) )?
     ( <UNIQUE> )?
     ( ( <COMPONENT> | <COMPOSITE> ) )?
     type ( multiplicity )? id
     ( <EQ> ( column | join_path ) )?

 multiplicity := <LBRACKET> integer <DOT> <DOT> ( id | integer ) <RBRACKET>

 object_key := <OBJECTKEY> <LPAREN> id ( <COMMA> id )* <RPAREN>

 reference_key := <REFERENCEKEY> <LPAREN> column <RPAREN>

 unique_key := <UNIQUE> <LPAREN> id ( <COMMA> id )* <RPAREN>

 aggressive_load := <AGGRESSIVE> <LPAREN> path ( <COMMA> path )* <RPAREN>

 join_stmt := join_path


/** Compound statements */

 event :=
     ( ( ( <INSERT> | <UPDATE> | <DELETE> ) |
       ( ( <ADD> | <REMOVE> | <CLEAR> ) ( id )? ) |
       ( <RETRIEVE> ( <ALL> | <ATTRIBUTES> | id )? ) )
       <LBRACE> ( sql_block | <SUPER> <SEMI> )*
       <RBRACE> | sql_block )

 sql_block :=
     ( <CALL> | <DO> ) <SQL>
     ( <MAP> <LBRACE> ( mapStatement <SEMI> )+ <RBRACE> )?

 mapStatement := ( binding | mapping )

 binding := path <COLON> db_type

 mapping := path <EQ> path

 option_block := <OPTIONS> <LBRACE> ( option <SEMI> )+ <RBRACE>

 option := id <EQ> optionValue

 optionValue := <TRUE> | <FALSE> | <STRINGLIT>

/** Shared definitions */

 join_path := join ( <COMMA> join )*

 join := <JOIN> column <TO> column

 column := id <DOT> id ( db_type )?

 db_type := id ( <LPAREN> integer ( <COMMA> integer )? <RPAREN> )?

 type := idpath

 path := idpath

 javaClass := idpath

 idpath := id ( <DOT> id )*

 id := <ID>
 integer := <INT>