<?SBNF-www.vishia.de version="1.0" encoding="iso-8859-1" ?>
$xmlns:topics="http://www.vishia.de/2006/Topics".
$xmlns:xhtml="http://www.w3.org/1999/xhtml".

##yyyy-mm-dd who      what
##2007-12-28 Hartmut  
##2007-12-28 Hartmut  semantic CLASS_C instead ClassDef for CLASS_C sections to differ from class definition


##type::= instead @ident name because construct {<$?name>?::} 
##methodTyp instead @name name because construct {<$?name>?::}
##classDef instead class in CLASS_C to unify the HeaderXml2Xmi for C and C++ 

$keywords=return|if|else|while|do|public|private|protected|inline|static|virtualstatic_cast|struct|class|enum.

Cheader::=
[ #ifndef <$?HeaderEntry>
| #if ! defined ( <$?HeaderEntry> )          ## the test to exclude of double includes is obligate!
]
#define <$>
[/*@PACKAGE <*\ *?package/@name> <*|*/?>*/]
[{ <includeDef?+@> }]    ## includes at begin
[<OutsideHeaderBlock>]
[{                        ##repetition of blocks
  /*@TOPIC <topic>
| <CLASS_CPP>
| <CLASS_C>              ##/*@CLASS_C ....
| <DEFINE_C>             ##/*@DEFINE_C ....
| <ARRAY>                ##/*@ARRAY ....
| <INLINE>               ##/*@INLINE ....
##| <headerBlock>
}]
#endif
[#endSBNF].

##:NOTE: a HeaderBlock may be also inside a condition Block. A Headerblock is the first one information.
##A conditionBlock is only a auxialary wrapper on HeaderBlocks.


##===========================================================================================================
##Block of definition in header. This is the first one information to evaluate a header but also a inner element.
headerBlock::=<?>
[/**<description?-?>*/]
[/*<implementDescription?-?>*/]
[ <invalidBlock?+@>
| <validBlock?>
| <conditionBlock?+conditionBlock>
| extern <variableDecl?+@>;
|<?constDef> const <variableDecl?+@> = [<#?value>|0x<#x?value>|<#f?floatValue>];  ##:TODO: value more variants!
| typedef
  [ <methodPtrTypedef?+@>
  | <methodTypedef?+@>
  | <structDefinition?+@>
  | <unionDefinition?+@>
  | <classDefinition?+@>
  |<?+enumDefinition> enum <enumDefinition?>  <$?@name> ;
  ]
| inline <inlineMethod>
| <includeDef?+@>
| #define CONST<defineDefinition?+const_initializer>
| #define NULL<defineDefinition?+null_initializer>
| #define <defineDefinition?+@>
| <undefDefinition?+@>
| #error <""?compilerError>
| <classDecl?+@>
| <structDecl?+@>
| <classDef?+@>;
| <methodDef?+@>;
| <defineUse?+@>
| ;  ##NOTE: an empty unnecessary semicolon is acceptable in C
].



OutsideHeaderBlock::=<?outside>
{ [?/*@]                                  ##stop repetition if /*@NEWBLOCK is detected
  <headerBlock>
}
.



topic::=<?topics:topic> <$?@ident> <*\n?><*|*/?xhtml:body+>*/.


##CLASS_C::=<?classDef> /*@CLASS_C <$?@name> <*|*/?>*/
CLASS_C::= /*@CLASS_C <$?@name> <*|*/?>*/
{ [?/*@]                                  ##stop repetition if /*@NEWBLOCK is detected
  <headerBlock>
}
[<?virtual> /*@CLASS_C_VIRTUAL <*|*/?>*/  ##it is the block of the c-like virtual methods
  { [?/*@]                                ##stop repetition if /*@ is detected, it is the next block or the end
    <headerBlock>
  }
]
.


##/*@ARRAY ObjectRefvalues_Jc @@@@@@@
##Definition of arrays of types outside the CLASS_C-block:
ARRAY::= /*@ARRAY <$?classIdent> <*|*/?>*/
{ [?/*@]
  <headerBlock>
}
.



DEFINE_C::=/*@DEFINE_C [<$?@name>]<*|*/?>*/
[ /*@ <description>*/]
{ [?/*@]
  <headerBlock>
}
.

INLINE::=/*@INLINE [<$?@name>]<*|*/?>*/
[ /*@ <description>*/]
{ [?/*@]
  <headerBlock>
}
.

CLASS_CPP::=/*@CLASS_CPP <*|*/?>*/
{ [?/*@]
  <headerBlock>
}
.

structDefinition::=struct [<$?@tagname>]
\{ { <structContent?> }
\} [GNU_PACKED] <$?@name>[ \[ <#?@arraySize> \] ] ;.

unionDefinition::=union [<$?@tagname>] 
\{ { [/**<description?-?>*/]
     [ <attribute?+variante> 
     | #define <defineDefinition?+?>
     ]
   } 
\} [GNU_PACKED] <$?@name>;.

classDefinition::=class [<$?@tagname>] \{ { [ <classContent?> | <structContent?> ] } \} <$?@name>;.

enumDefinition::= [<$?@tagname>] 
\{
{ ##note before or behind enumElement there may be several defines, associated to the enum. 
  ##Respect the arrangement of the colon as delimiter between the enumElements 
  [{  [/**<description?-?>*/] #define <defineDefinition?+?>}]
  [/**<description?-?>*/]<enumElement?+?>
  [{  [/**<description?-?>*/] #define <defineDefinition?+?>}]
? ,
}
\}.



implicitStructDefinition::=<structDefinition?><?@implicitStruct>.



methodPtrTypedef::= [METHOD_C|extern "C"|] <type> ( [<$?class> :: ] * <$?name> ) ( [| void |{ <typedParameter> ? ,}] );.

methodTypedef::= [METHOD_C|extern "C"|] <type> [<$?class> :: ] <$?name> ( [| void |{ <typedParameter> ? ,}] );.


##block inside a header with conditional compilation via ifdef
conditionBlock::=
[ #ifdef <$?conditionDef>| #ifndef <$?conditionDefNot>| #if {<?OrCondition> {<?AndCondition> [defined(<$?conditionDef>)
  | ! defined(<$?conditionDefNot>) ] ? && } ? \|\| } ]
[{ <headerBlock> }]
[<?elseConditionBlock> #else
  [{ <headerBlock> }]
]
#endif.



invalidBlock::=
#if 0
[{ <headerBlock> }]
#endif.


validBlock::=
#if 1
[{ <headerBlock> }]
#endif.


includeDef::= #include [<""?file>|\<<*\>?sysfile>\>].

##defineDefinition::=<$NoWhiteSpaces><$?@name>[( { <$?parameter/@name> ? , } )]<![
  \t]*?>[<#-?intvalue>|0x<#x?hexvalue>|<""?stringvalue>|]<![ \t]*?>{<*|\n|\\|\r\n?value>? \\[\r]\n}.
## be carefull: no white spaces between defineDefinition because the white spaces have syntax deterministic functions!
## if whitespaces are overred the line may be left.

defineDefinition::=<$NoWhiteSpaces> <$?@name> [ ( { <$?parameter/@name> ? , } ) ]
                   <![ \t]*?> [ <""?stringvalue>
                            | 0x<#x?hexvalue> 
                            | <#f?floatvalue> 
                            | <#-?intvalue> 
                            | ]
                   <![ \t]*?> 
                   { <*|\n|\\|\r\n?value>
                   ? \\[\r]\n
                   }.

## by value: either until a backslash followed by end of lineor until and of line,
##           repitition if backslash followed by end of line is found.

undefDefinition::= #undef<![ \t]*?><$?@name>[( { <$?parameter/@name> ? , } )].

defineUse::= <$?defineMethod> ( { <$?defineparameter> ? , } ).

classDecl::=class <$?name> ;.

structDecl::=struct <$?name> ;.


type::= [<?@modifier>volatile|const|] [<?@forward>struct|class|] [unsigned<?unsigend>|signed|] {<$?name>?::} 
  [**<?@pointer2> | *<?@pointer>|const **<?@constPointer2>|const *<?@constPointer>|volatile
  *<?@volatilePointer>|&<?cppRef>|].



methodDef::= [METHOD_C|extern "C"|extern|] <type> {<$?name>?::} [( void ) | ( ) | ({ STACKTRCP| <typedParameter> ? ,}
  )].


inlineMethod::=<methodDef> [const] [;|<statementBlock>].


typedParameter::= <type> [<$?@name> [ = <value>] ].


enumElement::= [/**<description>*/] <$?@name> [ = <enumValue?> ].

classDef::=class [<$?@name>] [ : {<superclass> ? ,} ]
\{ { <classVisibilityBlock> | <classContent?> | <structContent?> }
\}.


superclass::= <AccessRight?visibility> [<?isVirtual>virtual] <$?name>.



##attribute::= [/** <*{ *}|*/?!test_description>*/] <type> <$?name> [<arraysize>];. ## | [ = <value> ] ];.
attribute::= [/**<description>*/] <type> <$?@name> [<arraysize>];. ## | [ = <value> ] ];.

description::= <*{ * }|*/?!test_description>.

implementDescription::= <*{ * }|*/?!test_description>.

##The test_desciption syntax is used to parse the inner structure of a description.
test_description::= <*|\e|\@?text>
[{ @return <*@\e?returnDescription>
 | @param <paramDescription>
 | @sizeof = <sizeofDescription>
 | @ <*@\e?auxDescription>
 }].

xxtest_description::=<*|\. |\.\r\n|\.\n|\e|\@?brief> [\.] [<*|\e|\@?rest/xhtml:body+> ]
[{ @return <*@\e?returnDescription/p+>
 | @param <paramDescription>
 | @sizeof = <sizeofDescription>
 | @ <*@\e?auxDescription>
 }].

paramDescription::=<$?@name> <*@\e?text>.

xxparamDescription::=<$?@name> <*|\. |\.\r\n|\.\n|\e|\@?brief> [\.] [<*|\e|\@?rest/xhtml:body+> ].

sizeofDescription::=<?sizeof><#?@sizeof> <*@\e?text>.


structContent::=<?>
[/**<description?-?>*/]
[ <invalidBlock?+>
| <validBlock?+>
| typedef
  [ <methodPtrTypedef?+@>
  | <methodTypedef?+@>
  | <structDefinition?+@>
  | <unionDefinition?+@>
  | <classDefinition?+@>
  |<?+enumDefinition> enum <enumDefinition?> <$?@name>;
  ]
| <unionDefinition?+attribute>
| <implicitStructDefinition?+attribute>
| <attribute?+?>
| #define <defineDefinition?+?>
| <structContentInsideCondition?+?>
].


classContent::=<?>
[ virtual <methodDef?abstractMethod> [const] =0;
| virtual <methodDef?virtualMethod> [const] [;|<statementBlock>]
| static <methodDef?staticMethod> ;
| static <attribute?+staticAttribute>
| friend class <$?friendClass> ;
|<?+enumDefinition> enum <enumDefinition?> [<$?@name>] ;
|<?classForward> class <$?@name> ;
|<?structForward> struct <$?@name> ;
| <classDef>;
##| <structDef?+@>
| <Destructor>
| <operatorDef> [;|<statementBlock>]
| [inline] <methodDef> [const] [;|<statementBlock>]
|<?constructor> <$?@name> ( [| void |{ <typedParameter> ? ,}] ) [ : {<?initialization><$?ident>( <value> )? ,}][ ;|
  <statementBlock>]
| <attribute?+?>
##| <variableDecl>;
].



Destructor::= [virtual] ~<$?className> ( ) [;|<statementBlock>].

operatorDef::= [<type>] operator [<?type>()|<assignOperator?>|<unaryOperator?>|<binaryOperator?>|<type>] ( [| void |{
  <typedParameter> ? ,}] ).

statementBlock::=
\{ [ STACKTRC_ENTRY ( <""?STACKTRC_ENTRY> ) ] 
[{ <statement> }] 
\}.

statement::=
  return <returnAssignment>
| <variabledefinition>
| <simpleMethodCall> ;
| <assignment>
| <if_statement>
| <while_statement>
| <try_statement>
.


variabledefinition::=<$?type> <$?attribute> [ = [<objectAccess>|<value>] ];.



returnAssignment::= [<objectAccess>;|<value>;|<assignment>].

assignment::= [<superAccess>|<externObject>|] <$?variable> <assignOperator> [<objectAccess>;| <value>;|<assignment>].

value::=
[|<unaryOperator>]
  [ <""?simpleStringLiteral>
  | <''?simpleCharLiteral>
  | & <value?referenceAddress>
  | <refCasting> <value>  ##must be arranged before ( <value> ) because confusion with, example (type)value and
    (variable)
  | (<value>)
  | 0x<#x?number>
  | <#f?number>
  | <#-?number>
##  | <simpleMethodCall>
  | <methodCall>
  | <variable>
  ##    | <!'.'?simpleChar>
  ]
  [<binaryOperator> <value>]
.


assignOperator::= = | += | \|= | &= | -= | *= | /= .

unaryOperator::= - | ~ | ! | * | & .

binaryOperator::= + | - | * | / | && | \|\| | & | \| | == | \>= | \<= | \> | \< | != | ^ .



simpleMethodCall::= <$?methodname> [()|<actualParameter>].

actualParameter::= ({ <objectAccess>| <value>? ,} ).


classVisibilityBlock::=[ public | protected | private ] : { <classContent> | <structContent> }.

structContentInsideCondition::=[ #ifdef | #ifndef] <$?conditionDef> { <structContent> }  #endif.

variableDecl::= <type> <$?name> .

AccessRight::=[<?accessRight/@value> public | private | protected | ].


arraysize::=\[ [0x<#x?@value>| <#?@value>| <$?@symbolValue>] \].


## An enum value is a constant. It may be written as term "konst + konst". A konst is a number or a symbolic const.
enumValue::= {0x<#x?hexnumber> | <#-?intnumber> | <$?symbol> ? [<?operation/@value> +|-|*] }.



##A description is tested typically after /** until */.
xxxdescription::=<*|\. |*/|@?brief> [\. <*|*/|@?restToFull> ]
[{ @
  [return <*|*/|@?return>
  |param <*|*/|@param?>
  |<*|*/|@?aux>
  ]
}]
.

xxdescription::=<*|\. |*/|@?brief> [\. <*|*/|@?restToFull> ]
[{ @
  [return <*|*/|@?return>
  |param <*|*/|@param?>
  |<*|*/|@?aux>
  ]
}]
.

methodCall::=[<superAccess>|<externObject>|]<simpleMethodCall>.

variable::=[<superAccess>|<externObject>|] <$?simpleVariable>.

superAccess::=xxx.

externObject::= { [<simpleMethodCall>|<$?association>] [-\>|\.] }.



if_statement::=if ( <condition> ) [<statementBlock>|<statement>] [ else [<statementBlock>|<statement>] ].

while_statement::=while ( <condition> ) [<statementBlock>|<statement>].

try_statement::=try <statementBlock> { catch ( <$?exceptionType> <$?exceptionObj> ) <statementBlock> }.

##objectAccess::=<nullPointer> | <newObject> .

objectAccess::=xxx.

nullPointer::=null.


refCasting::=
  static_cast \< <type> \>   ##C++-safety casting
| ( <type> )                 ##C-like-casting
.