-- This grammar for the BON textual notation was extracted from the
-- text of the book "Seamless Object-Oriented Software Architecture"
-- and turned into plain Ascii format for easy use by anyone
-- interested in building a parser for the language.
--
-- For a general description of this notation and examples of its use,
-- see appendix A and B of the book, pp. 349-380.
--
-- The book text is freely available at http://www.bon-method.com.


-- BON SPECIFICATION
Bon_specification	::= {Specification_element ...}+
Specification_element	::= Informal_chart | Class_dictionary | Static_diagram |
			    Dynamic_diagram | Notational_tuning

-- INFORMAL CHARTS
Informal_chart		::= System_chart | Cluster_chart | Class_chart |
			    Event_chart | Scenario_chart | Creation_chart
Class_dictionary	::= 'dictionary' System_name
			    {Dictionary_entry ...}+
			    'end'
Dictionary_entry	::= 'class' Class_name 'cluster' Cluster_name
			    'description' Manifest_textblock
--
System_chart		::= 'system_chart' System_name
			    ['indexing' Index_list]
			    ['explanation' Manifest_string]
			    ['part' Manifest_string]
			    [Cluster_entries]
			    'end'
Cluster_entries		::= {Cluster_entry ...}+
Cluster_entry		::= 'cluster' Cluster_name
			    'description' Manifest_textblock
System_name		::= Identifier
--
Index_list		::= {Index_clause ";" ...}+
Index_clause		::= Identifier ":" Index_term_list
Index_term_list		::= {Index_string "," ...}+
Index_string		::= Manifest_string
--
Cluster_chart		::= 'cluster_chart' Cluster_name
			    ['indexing' Index_list]
			    ['explanation' Manifest_string]
			    ['part' Manifest_string]
			    [Class_entries]
			    [Cluster_entries]
			    'end'
Class_entries		::= {Class_entry ...}+
Class_entry		::= 'class' Class_name
			    'description' Manifest_textblock
Cluster_name		::= Identifier
--
Class_chart		::= 'class_chart' Class_name
			    ['indexing' Index_list]
			    ['explanation' Manifest_string]
			    ['part' Manifest_string]
			    ['inherit' Class_name_list]
			    ['query' Query_list]
			    ['command' Command_list]
			    ['constraint' Constraint_list]
			    'end'
Query_list		::= {Manifest_string "," ...}+
Command_list		::= {Manifest_string "," ...}+
Constraint_list		::= {Manifest_string "," ...}+
Class_name_list		::= {Class_name "," ...}+
Class_name		::= Identifier
--
Event_chart		::= 'event_chart' System_name
			    ['incoming' | 'outgoing']
			    ['indexing' Index_list]
			    ['explanation' Manifest_string]
			    ['part' Manifest_string]
			    [Event_entries]
			    'end'
Event_entries		::= {Event_entry ...}+
Event_entry		::= 'event' Manifest_string 'involves' Class_name_list
--
Scenario_chart		::= 'scenario_chart' System_name
			    ['indexing' Index_list]
			    ['explanation' Manifest_string]
			    ['part' Manifest_string]
			    [Scenario_entries]
			    'end'
Scenario_entries	::= {Scenario_entry ...}+
Scenario_entry		::= 'scenario' Manifest_string
			    'description' Manifest_textblock
--
Creation_chart		::= 'creation_chart' System_name
			    ['indexing' Index_list]
			    ['explanation' Manifest_string]
			    ['part' Manifest_string]
			    [Creation_entries]
			    'end'
Creation_entries	::= {Creation_entry ...}+
Creation_entry		::= 'creator' Class_name 'creates' Class_name_list

-- STATIC DIAGRAMS
Static_diagram		::= 'static_diagram' [Extended_id] [Comment]
			    'component' Static_block 'end'
Extended_id		::= Identifier | Integer
Comment			::= {Line_comment New_line ...}+
Line_comment		::= "--" Simple_string
Static_block		::= {Static_component ...}
Static_component	::= Cluster | Class | Static_relation
--
Cluster			::= 'cluster' Cluster_name 
			    ['reused'] [Comment]
			    [Cluster_components]
Cluster_components	::= 'component' Static_block 'end'
Class			::= ['root' | 'deferred' | 'effective']
			    'class' Class_name [Formal_generics]
			    ['reused'] ['persistent'] ['interfaced'] [Comment]
			    [Class_interface]
Static_relation		::= Inheritance_relation | Client_relation
--
Inheritance_relation	::= Child 'inherit' ["{" Multiplicity "}"]
			    Parent [Semantic_label]
Client_relation		::= Client 'client' [Client_entities] [Type_mark]
			    Supplier [Semantic_label]
Client_entities		::= "{" Client_entity_expression "}"
Client_entity_expression ::= Client_entity_list | Multiplicity
Client_entity_list	::= {Client_entity "," ...}+
Client_entity		::= Feature_name | Supplier_indirection |
			    Parent_indirection
Supplier_indirection	::= [Indirection_feature_part ":"] Generic_indirection
Indirection_feature_part ::= Feature_name | Indirection_feature_list
Indirection_feature_list ::= "(" Feature_name_list ")"
Parent_indirection	::= "->" Generic_indirection
--
Generic_indirection	::= Formal_generic_name | Named_indirection
Named_indirection	::= Class_name "[" Indirection_list "]"
Indirection_list	::= {Indirection_element "," ...}+
Indirection_element	::= "..." | Named_indirection
Type_mark		::= ":" | ":{" | Shared_mark
Shared_mark		::= ":" "(" Multiplicity ")"
--
Child			::= Static_ref
Parent			::= Static_ref
Client			::= Static_ref
Supplier		::= Static_ref
Static_ref		::= {Cluster_prefix ...} Static_component_name
Cluster_prefix		::= Cluster_name "."
Static_component_name	::= Class_name | Cluster_name
Multiplicity		::= Integer
Semantic_label		::= Manifest_string

-- CLASS INTERFACE DESCRIPTION
Class_interface		::= ['indexing' Index_list]
			    ['inherit' Parent_class_list]
			    Features
			    ['invariant' Class_invariant]
			    'end'
Class_invariant		::= Assertion
Parent_class_list	::= {Class_type ";" ...}+
Features		::= {Feature_clause ...}+
--
Feature_clause		::= 'feature' [Selective_export]
			    [Comment]
			    Feature_specifications
Feature_specifications	::= {Feature_specification ...}+
Feature_specification	::= ['deferred' | 'effective' | 'redefined']
			    Feature_name_list [Type_mark Type]
			    [Rename_clause] 
			    [Comment]
			    [Feature_arguments]
			    [Contract_clause]
--
Contract_clause		::= Contracting_conditions 'end'
Contracting_conditions	::= Precondition | Postcondition | Pre_and_post
Precondition		::= 'require' Assertion
Postcondition		::= 'ensure' Assertion
Pre_and_post		::= Precondition Postcondition
--
Selective_export	::= "{" Class_name_list "}"
Feature_name_list	::= {Feature_name "," ...}+
Feature_name		::= Identifier | Prefix | Infix
Rename_clause		::= "{" Renaming "}"
Renaming		::= "^" Class_name "." Feature_name 
Feature_arguments	::= {Feature_argument ...}+
Feature_argument	::= "->" [Identifier_list ":"] Type
Identifier_list		::= {Identifier "," ...}+
Prefix			::= 'prefix' '"' Prefix_operator '"'
Infix			::= 'infix' '"' Infix_operator '"'
Prefix_operator		::= Unary | Free_operator
Infix_operator		::= Binary | Free_operator
--
Formal_generics		::= "[" Formal_generic_list "]"
Formal_generic_list	::= {Formal_generic "," ...}+
Formal_generic		::= Formal_generic_name ["->" Class_type]
Formal_generic_name	::= Identifier
Class_type		::= Class_name [Actual_generics]
Actual_generics		::= "[" Type_list "]"
Type_list		::= {Type "," ...}+
Type			::= Class_type | Formal_generic_name
--
Unary			::= 'delta' | 'old' | 'not' | "+" | "-"
Binary			::= "+" | "-" | "*" | "/" |
			    "<" | ">" | "<=" | ">=" | 
			    "\(eq" | "/=" | "/" | "\\" | "^" |
			    'or' | 'xor' | 'and' | '"->"' | '"<->"' |
			    'member_of' | ":"

-- FORMAL ASSERTIONS
Assertion		::= {Assertion_clause ";" ...}+
Assertion_clause	::= Boolean_expression | Comment
Boolean_expression	::= Expression
Expression		::= Quantification | Call |
			    Operator_expression | Constant
Quantification		::= Quantifier Range_expression 
			    [Restriction] Proposition
Quantifier		::= 'for_all' | 'exists'
Range_expression	::= {Variable_range ";" ...}+
Restriction		::= 'such_that' Boolean_expression
Proposition		::= 'it_holds' Boolean_expression
Variable_range		::= Member_range | Type_range
Member_range		::= Identifier_list 'member_of' Set_expression
Type_range		::= Identifier_list ":" Type
--
Call			::= [Parenthesized_qualifier] Call_chain
Parenthesized_qualifier ::= Parenthesized "."
Call_chain		::= {Unqualified_call "." ...}+
Unqualified_call	::= Identifier [Actual_arguments]
Actual_arguments	::= "(" Expression_list ")"
Expression_list		::= {Expression "," ...}+
Operator_expression	::= Parenthesized | Unary_expression | Binary_expression
Parenthesized		::= "(" Expression ")"
--
Unary_expression	::= Prefix_operator Expression
Binary_expression	::= Expression Infix_operator Expression
Set_expression		::= Enumerated_set | Call | Operator_expression
Enumerated_set		::= "{" Enumeration_list "}"
Enumeration_list	::= {Enumeration_element "," ...}+
Enumeration_element	::= Expression | Interval
Interval		::= Integer_interval | Character_interval
Integer_interval	::= Integer_constant ".." Integer_constant
Character_interval	::= Character_constant ".." Character_constant
--
Constant		::= Manifest_constant | 'Current' | 'Void'
Manifest_constant	::= Boolean_constant | Character_constant |
			    Integer_constant | Real_constant |
		´	    Manifest_string
Sign			::= "+" | "-"
Boolean_constant	::= 'true' | 'false'
Character_constant	::= "'" Character "'"
Integer_constant	::= [Sign] Integer
Real_constant		::= [Sign] Real
Manifest_textblock	::= String_begin String String_end
String			::= {Simple_string New_line ...}+
Manifest_string		::= String_begin Simple_string String_end
--
--DYNAMIC DIAGRAMS
Dynamic_diagram		::= 'dynamic_diagram' [Extended_id] [Comment]
			    'component' Dynamic_block 'end'
Dynamic_block		::= {Dynamic_component ...}
Dynamic_component	::= Scenario_description |
			    Object_group |
			    Object_stack |
			    Object |
			    Message_relation
--
Scenario_description	::= 'scenario' Scenario_name [Comment]
			    'action' Labeled_actions 'end'
Labeled_actions		::= {Labeled_action ...}+
Labeled_action		::= Action_label Action_description
Action_label		::= Manifest_string
Action_description	::= Manifest_textblock
Scenario_name		::= Manifest_string
--
Object_group		::= ['nameless'] 'object_group' Group_name [Comment]
			    [Group_components]
Group_components	::= 'component' Dynamic_block 'end'
Object_stack		::= 'object_stack' Object_name [Comment]
Object			::= 'object' Object_name [Comment]
--
Message_relation	::= Caller 'calls' Receiver [Message_label]
Caller			::= Dynamic_ref
Receiver		::= Dynamic_ref
Dynamic_ref		::= {Group_prefix ...} Dynamic_component_name
Group_prefix		::= Group_name "."
Dynamic_component_name	::= Object_name | Group_name
Object_nam		::= Class_name ["." Extended_id]
Group_name		::= Extended_id
Message_label		::= Manifest_string

-- NOTAIONAL TUNING
Notational_tuning	::= Change_string_marks |
			    Change_concatenator |
			    Change_prefix
Change_string_marks	::= 'string_marks' Manifest_string Manifest_string
Change_concatenator	::= 'concatenator' Manifest_string
Change_prefix		::= 'keyword_prefix' Manifest_string
