Research Article

SPOT: A DSL for Extending Fortran Programs with Metaprogramming

Algorithm 4

Primary EBNF grammar of SPOT.
programFile
:Transformer’   ID ‘{’   transformBody (;’   transformBody)*   ‘}’
-> (TRANSFORMER_ND ID transformBody+);
transformBody
:transformScope ‘{’   transformStatement+ ‘}’
-> (TFBODY_ND transformScope transformStatement+)
|IncludeCode   ‘{’   statement+ ‘}’   (into’   fileName)
-> (SOURCE_CODE statement+);
transformScope
: Within   (’   scopeIndicator ID )
-> (Within’   scopeIndicator ID);
scopeIndicator
:Function
|Module
|Project
|Statement;
pointIndicator
:FunctionCall
|VariableRead
|VariableWrite
| statementTypeName //collect all statements of a type
| "’   statement ";//collect all statements with original source code, e.g. "a=b+c"
transformStatement
: operation
| subTransform
| spotCondition;
spotCondition
:IF’  ‘('   condition )’‘{’   transformStatement ‘}’
-> (IF’   condition transformStatement+)
|ELSE IF   (’   condition )’‘{’   transformStatement+ ‘}’
-> ELSE IF’   condition transformStatement+
|ELSE’   ‘{’   transformStatement+ ‘}’
-> ELSE’   transformStatement+;
operation
:actionVariable ;
-> (ACTION_ND actionVariable)
|actionStatement ;
-> (ACTION_ND actionStatement)
|actionFunction ;
-> (ACTION_ND actionFunction)
|scopeIndicator %? ID =’   actionRetrieve ;
-> (RETRIEVE_ND scopeIndicator %? ID =’   actionRetrieve);
subTransform
:transformLocation ‘{’   operation+ ‘}’
-> (SUB_TRANSFORMER transformLocation operation+);
transformLocation
: locationKeyword (’   pointIndicator (ID|*|%’   ID)?)
-> (TRANS_LOCATION locationKeyword pointIndicator (ID|*|%   ID))
| ForAll   (’   ‘Procedure’   (*|%’   ID) )’   // ForAll (Procedure %procs)
-> (ForAll_ND Procedure’   (*|%   ID))
| ForAll’   ‘(’   ‘Module’   (*|%’   ID))
-> (ForAll_ND Module’   (*|%   ID))
| ForAll’   ‘(’   pointIndicator ID? (*|%’   ID))
-> (ForAll_ND pointIndicator ID? (*|%   ID));
actionVariable
:AddVariable   (’   typeName ,’   ID (,’   initializedVal)? )
-> (AddVariable’   typeName ID initializedVal?)
|DeleteVariable’   ‘(’   ID )
-> (DeleteVariable’   ID)
|RenameVariable’   ‘(’   oldName=ID ,’   newName=ID )
-> (RenameVariable’   $oldName $newName);
actionStatement
:AddCallStatement’   ‘(locationKeyword ,’   spotCurrentStatement ,
ID (,callArgumentList)?)
-> (AddCallStatement’   locationKeyword spotCurrentStatement ID callArgumentList? )
|AddDirectiveStatement’‘(’   directive )
-> (AddDirectiveStatement’   directive)
|AddIncludeStatement’   ‘(’   ID )
-> (AddIncludeStatement’   ID)
|ReplaceStatement’   ‘(’   oldStmt=statementType ,’   newStmt=statementType )
-> (ReplaceStatement’   $oldStmt $newStmt)
|DeleteStatement’   ‘(’   statementType )
-> (DeleteStatement’   statementType);