start= program | unit | library | package .
identifier_list= ID_NAME { ',' ID_NAME } .
unit_qualified_identifier= ID_NAME { '.' ID_NAME } .
type_name= TYPE_NAME | STRING | FILE .
unit_qualified_type_name= type_name [ '.' type_name ] .
function_result_type= type_name .
constant_expression= F .
string_expression= ( STRING_NAME | STRING_LITTERAL )
{ '+' ( STRING_NAME | STRING_LITTERAL ) } .
variable_access= ( ACCESS_NAME | STRING ) { end_access_ } .
end_access_= { array_access_ | record_access_ | '^' | function_parameters_ } .
array_access_= '[' constant_expression { ',' constant_expression } ']' .
record_access_= '.' variable_access .
function_parameters_= '(' [ constant_expression { ',' constant_expression } ] ')' .
set_factor= '[' [ set_element { ',' set_element } ] ']' .
set_element= constant_expression [ '..' constant_expression ] .
constant_expression= simple_expression__ [ ('=' | '<>' | '<' | '<=' | '>' | '>=' | IN )
simple_expression__ ] .
simple_expression__= [ '+' | '-' ] term__ { ('+' | '-' | OR | XOR ) term__ } .
term__= factor__ { ('*' | '/' | DIV | MOD | AND | SHR | SHL ) factor__ } .
factor__= NUMBER | STRING_LITTERAL | NIL
| variable_access
| NOT factor__ | '@' factor__ | set_factor
| '^' NAME
| '(' constant_expression ')'.
typed_constant= simple_expression_ [ ('=' | '<>' | '<' | '<=' | '>' | '>=' | IN )
simple_expression_ ] .
simple_expression_= [ '+' | '-' ] term_ { ('+' | '-' | OR | XOR ) term_ } .
term_= factor_ { ('*' | '/' | DIV | MOD | AND | SHR | SHL ) factor_ } .
factor_= NUMBER | STRING_LITTERAL | NIL
// -- id or field "(f1: v1; f2: v2)"
| variable_access [ ':' typed_constant
{ ';' variable_access ':' typed_constant } ]
| NOT factor_ | '@' factor_
| '^' NAME
| '(' [ typed_constant_] ')'
| set_factor .
// -- array "(1, 2, 3)" or "fn(p1, p2")
typed_constant_= typed_constant { ',' typed_constant } .
formal_parameters= '(' formal_parameter { ';' formal_parameter } ')' .
formal_parameter= [ parameter | var_parameter
| const_parameter | out_parameter | in_parameter ] .
parameter_name_list= PARAMETER_NAME { ',' PARAMETER_NAME } .
array_or_name_type= ARRAY OF ( CONST | unit_qualified_type_name )
| unit_qualified_type_name .
parameter= parameter_name_list ':' array_or_name_type
['=' constant_expression ] .
var_parameter= VAR parameter_name_list [ ':' array_or_name_type ] .
const_parameter= CONST parameter_name_list
[ ':' array_or_name_type ['=' constant_expression ] ] .
out_parameter= OUT parameter_name_list [ ':' array_or_name_type ] .
in_parameter= IN parameter .
dos_directives= NEAR | FAR | EXPORT | ASSEMBLER .
calling_directives= CDECL | PASCAL | REGISTER | SAFECALL | STDCALL .
overload_directive= OVERLOAD .
method_directives= ABSTRACT | VIRTUAL | DYNAMIC
| OVERRIDE | REINTRODUCE | MESSAGE constant_expression .
const_type_var_declarations= constant_definitions | resource_defintions
| type_definitions | variable_declarations .
type= keyed_types | type_0 .
// -- called by i_type
enumeration_type= '(' identifier_list ')' .
expression_t= simple_expression_t
[ ( ('=' | '<>' | '<' | '<=' | '>' | '>=' | IN ) simple_expression_t
| '..' end_range_type ) ] .
simple_expression_t= [ '+' | '-' ] term_t { ('+' | '-' | OR | XOR ) term_t } .
term_t= factor_t { ('*' | '/' | DIV | MOD | AND | SHR | SHL ) factor_t } .
factor_t= NUMBER | STRING_LITTERAL | NIL
| variable_access
| NOT factor_t | '@' factor_t
| '^' NAME
| '(' expression_t ')'
| set_factor .
end_range_type= simple_expression_t .
type_0= ( NUMBER | STRING_LITTERAL | NIL | NOT | '+' | '-' | '@' | '(' | '[' | NAME )
$i_type .
keyed_types= string_type | structured_type | pointer_type | procedural_type .
// -- handle STRING as array[index_type]
string_type= STRING [ '[' constant_expression ']' ] .
structured_type= [ PACKED ] ( array_type | record_type | set_type | file_type ) .
array_type= ARRAY [ '[' index_type { ',' index_type } ']' ] OF type .
index_type= constant_expression [ '..' constant_expression ] .
record_type= RECORD field_list END .
field_list= { common_field ';' } [ variant_fields ] .
common_field= identifier_list ':' type .
variant_fields= CASE tag OF cases { cases } .
tag= VARIANT_TAG_NAME [ ':' unit_qualified_type_name ] .
cases= constant_expression { ',' constant_expression }
':' one_case .
one_case= '(' [ common_field { ';' [ ( common_field | variant_fields ) ] }
| variant_fields ]
')' [ ';' ] .
set_type= SET OF type .
file_type= FILE [ OF type ] .
pointer_type= '^' POINTED_NAME .
procedural_type= ( PROCEDURE [ formal_parameters ]
| FUNCTION [ formal_parameters ] ':' function_result_type )
$
dir .
procedural_type_directives= calling_directives .
i_procedural_type_directives= ( ';'
| CDECL | PASCAL | REGISTER | SAFECALL | STDCALL ) $i_directives .
constant_definitions= CONST constant_definition { constant_definition } .
constant_definition= CONST_NAME [ ':' type ] '=' typed_constant ';' .
resource_defintions= RESOURCESTRING resource_definition { resource_definition } .
resource_definition= RESOURCE_NAME '=' string_expression ';' .
type_definitions= TYPE type_definition { type_definition } .
type_definition= TYPE_NAME '=' [ TYPE ] ( class_type | interface_type | type ) ';' .
// -- used in INTERFACE also
property= PROPERTY $>priv PROPERTY_NAME [ property_type ] property_specifiers .
property_type= [ property_indexes ] ':' unit_qualified_type_name .
property_indexes= '[' property_index { ';' property_index } ']' .
property_index= [ CONST ] INDEX_NAME { ',' INDEX_NAME }
':' unit_qualified_type_name .
property_specifiers= $prop
// -- "READ FTabSize.Y"
$prop
// -- some params called "dispid"
$prop
$prop
[ IMPLEMENTS unit_qualified_identifier { ',' unit_qualified_identifier } ';' ] .
storage_specifier= storage_stored | storage_default | storage_no_default .
storage_stored= STORED [ constant_expression ] .
storage_default= DEFAULT [ constant_expression ] .
storage_no_default= NODEFAULT .
// -- the ; is in the type_definitions
class_type= CLASS [ class_reference | class_definition ] .
class_reference= OF unit_qualified_type_name .
// -- class_definition : can be foward with inheritance
class_definition= [ inheritance ] [ class_body ] .
inheritance= '(' unit_qualified_type_name { ',' unit_qualified_type_name } ')' .
class_body= fields_and_procs_section { fields_and_procs_section } END .
fields_and_procs_section= $priv .
protection= [ PRIVATE | PROTECTED | PUBLIC | PUBLISHED ] .
fields_and_procs= { class_field } { class_methods | property $priv ':' type ';' $dir .
// -- if interfaces : "FUNCTION i_xxx.yyy = zzz;"
rename_method= '.' NAME '=' NAME ';' .
constructor= CONSTRUCTOR $>priv PR_NAME [ formal_parameters ] ';'
method_directives_ $priv PR_NAME [ formal_parameters ] ';'
method_directives_ $priv PR_NAME
( rename_method | [ formal_parameters ] ';'
method_directives_ ) $priv FN_NAME
( rename_method | [ formal_parameters ] ':' function_result_type ';'
method_directives_ ) $dir .
dispid= DISPID constant_expression .
// -- redefinition "PROCEDURE x.y= z;" (axctrls)
class_procedure_= ( PROCEDURE | CONSTRUCTOR | DESTRUCTOR )
PR_NAME [ formal_parameters ] ';' interface_directives_ .
class_function_= FUNCTION FN_NAME [ formal_parameters ] ':' function_result_type ';'
interface_directives_ .
variable_declarations= (THREADVAR | VAR) variable_declaration { variable_declaration } .
// -- has separated in 2 because of initialization
// -- absolute can be after a list, but not with initialization
variable_declaration= ID_NAME
( ':' type [ '=' typed_constant | absolute ] ';'
| { ',' ID_NAME } ':' type [ absolute ] ';' ) .
absolute= ABSOLUTE OTHER_VAR_NAME .
// -- code
expression= simple_expression [ ('=' | '<>' | '<' | '<=' | '>' | '>=' | IN | IS )
simple_expression ] .
simple_expression= [ '+' | '-' ] term { ('+' | '-' | OR | XOR ) term } .
term= factor { ('*' | '/' | DIV | MOD | AND | SHR | SHL ) factor } .
// -- called by $i_access_or_expression
// -- can be empty if fn call "fn()"
parenthized_expression= '(' [ expression { ',' expression } ] ')' .
factor= NUMBER | STRING_LITTERAL | NIL
| NOT factor | '@' factor | INHERITED [ factor ]
| '^' NAME
| set_factor
// -- x= (Sender AS tButton).Caption
// -- the AS is only for the level 0
| ( NAME | STRING ) { parenthized_expression | end_access }
| parenthized_expression { end_access } .
end_access= { array_access | record_access | '^' | as_access } .
array_access= '[' expression { ',' expression } ']' .
record_access= '.' expression .
as_access= AS NAME .
// -- instructions
asm= ASM { asm_statement } END .
// -- for pasting in i_asm
asm_statement_= { NAME | NUMBER | STRING_LITTERAL
| '[' | ']' | '.' | ','
| ':'
| '+' | '-' | '*' | '/'
| NOT | AND | OR | XOR | SHR | SHL | DIV } .
label_= '@' [ '@'] ( ALL_NAME | NUMBER ) .
asm_statement= ( NAME | NUMBER | STRING_LITTERAL
| '[' | ']' | '.' | ','
| '@'
| ':'
| '+' | '-' | '*' | '/'
| NOT | AND | OR | XOR | SHR | SHL | DIV ) $i_asm .
composed_instruction= F .
// -- allows empty ";" instruction
instruction_list= [ instruction ] { ';' [ instruction ] } .
instruction= { assignment_or_call | structured_instruction } .
// -- this covers "x[3].z:= u;" or "my_proc(3+ zz)";
// -- acces or (pchar+ 1)^ := ...
assignment_or_call= expression [ end_assignment ] .
// -- "(Sender As tButton).Caption:= xxx"
end_assignment= ':=' expression .
structured_instruction= composed_instruction | test | repetition | with
| try | inherited_call | raise_statement | asm .
test= if | case .
if= IF expression THEN instruction [ ELSE instruction ] .
// -- D5: ';' after last instr or before ELSE optional !
case= CASE expression OF case_element
{ ';' [ ELSE $NOREAD | END $NOREAD | case_element ] }
[ ELSE instruction_list ] END .
case_element= case_label ':' instruction .
// -- a general constant constant_expression, but no set [],
// -- unless in a function call
case_label= constant_expression
{ ( ',' constant_expression | '..' constant_expression ) } .
repetition= while | repeat | for .
while= WHILE expression DO instruction .
repeat= REPEAT instruction_list UNTIL expression .
for= FOR unit_qualified_identifier ':=' expression [ TO | DOWNTO ]
expression DO instruction .
// -- "with xxx AS"
with= WITH expression { ',' expression } DO instruction .
try= TRY instruction_list
( EXCEPT except_block | FINALLY instruction_list ) END .
except_block= on [ ELSE instruction_list ] | instruction_list .
// -- can have "ON ezero DO ELSE xxx ;" or "ON xxx DO ;"
on= handle_instruction { ';' [ handle_instruction ] } .
exception_identifier= unit_qualified_identifier [ ':' unit_qualified_identifier ] .
handle_instruction= ON exception_identifier DO [ instruction ';' ] .
// -- "Inherited Items[Index]:= "
inherited_call= INHERITED [ instruction ] .
// inline_statement= INLINE '(' INTEGERCONST {'/' INTEGERCONST } ')' .
raise_statement= $at .
composed_instruction= BEGIN instruction_list END .
// -- bloc
// -- VIRTUAL etc only in CLASS
routine_header= class_methods_header | constructor_header | destructor_header
| procedure_header | function_header .
// -- methods have no directives in implementation
class_methods_header= CLASS (class_procedure_method | class_function_method ) .
class_procedure_method= PROCEDURE CLASS_NAME '.' PR_NAME [ formal_parameters ] ';' .
// -- repeating the result is optional
class_function_method= FUNCTION CLASS_NAME [ '.' FN_NAME ]
[ formal_parameters ] [ ':' function_result_type ] ';' .
constructor_header= CONSTRUCTOR CLASS_NAME '.' PR_NAME [ formal_parameters ] ';' .
destructor_header= DESTRUCTOR CLASS_NAME '.' PR_NAME [ formal_parameters ] ';' .
// -- always ; before directives (for procedural cdecl is without ? )
code_procedure_directives= $dir .
procedure_header= PROCEDURE
CLASS_OR_PR_NAME [ '.' PR_NAME ] [ formal_parameters ] ';'
code_procedure_directives .
// -- for the functions, STDCALL does not require ; "fn xxx: yyy STDCALL;"
function_header= FUNCTION CLASS_OR_FN_NAME [ '.' FN_NAME ]
[ formal_parameters ] [ ':' function_result_type ]
[ ';' ] code_procedure_directives [ ';' ] .
bloc= F .
main_declarations= const_type_var_declarations | procedure_declarations_and_body .
procedure_declarations_and_body= { procedure_declaration } .
procedure_declaration= routine_header
$dir | EXTERNAL $>dir end_external | $>dir bloc ) ';' .
// "procedure xxx; external;"
// "procedure xxx; external 'xxx';"
// "procedure xxx; external xxx;"
// "procedure xxx; external xxx NAME 'MessageBoxA';"
// "procedure xxx; external xxx 'MessageBoxA' INDEX 31;"
end_external= [ constant_expression $index ] '.' .
index= INDEX constant_expression .
bloc= { main_declarations } ( composed_instruction | asm ) .
main_uses= USES uses_in { ',' uses_in } ';' .
uses_in= UNIT_NAME [ IN constant_expression ] .
// -- program / units / library / packages
program= PROGRAM NAME ';' [ main_uses ] bloc '.' .
unit= UNIT UNIT_NAME ';' unit_interface unit_implementation unit_end '.' .
uses= USES identifier_list ';' .
unit_interface= INTERFACE [ uses ] { const_type_var_declarations | routine_header } .
unit_implementation= IMPLEMENTATION [ uses ] { main_declarations } .
unit_end= ( BEGIN instruction_list | initialization ) END .
initialization= [ INITIALIZATION instruction_list [ FINALIZATION instruction_list ]] .
library= LIBRARY LIBRARY_NAME main_uses bloc '.' .
package= PACKAGE PACKAGE_NAME ';'
$pack END '.' .
requires_clause= REQUIRES REQUIRES_NAME {',' REQUIRES_NAME } ';' .
contains_clause= CONTAINS contains_statement {',' contains_statement } ';' .
contains_statement= CONTAINS_NAME [ IN constant_expression ] .
.