APPENDIX A: BON textual grammar (from BON text and included for easy reference). A.1 INTRODUCTION This appendix presents a formal syntax specification of the BON textual notation, which is useful for automatic processing and for maintenance of BON designs where no case tool is available. The specification gives a comprehensive overview of all notational concepts in BON, facilitating the construction of parsers for translating BON charts and diagrams into other desired formats. Communicating BON designs from either case tools or text files to other tools with well-defined interfaces is thus straightforward. Interesting possibilities in this respect include configuration management tools, commercial DBMS environments, and widely available document processors and desktop publishing tools. For example, it is not very difficult to create templates for the informal BON charts, using some of the more advanced word processors. With textual BON it is then possible to mix the interactive input of charts with automatic generation from information stored elsewhere. The formal description also gives the reader a second chance to resolve possible unclarities that always lurk in natural language descriptions. Nothing can compensate for the precision of a formal notation when it comes to communicating the difficult cases unambiguously. On the other hand, a language grammar is much harder to read to get a general overview of a notation than are typical examples of language usage. For this reason, and since a fair portion of the BON textual notation has not been shown elsewhere in the book, the next appendix will provide the interested reader with textual equivalents to some of the graphical BON diagrams presented earlier. The textual version of BON does not include any means for describing the layout of diagrams. This would require an independent set of concepts largely orthogonal to the BON structural elements. Such a language may emerge later as a result of experience with case tools supporting BON. A.2 THE SYNTAX NOTATION We will present the BON textual grammar in an extended BNF (Backus Naur Form), where the extensions are very close to the ones used in [Meyer 1992a]. The syntax notation is based on the following concepts. Any syntactically meaningful part of a BON textual specification, such as a cluster, a class, or an assertion, is called a component. The structure of all components of a certain category is described by a construct, and an individual component conforming to this description is called a specimen of the construct. Each construct has a unique construct name, which is a single word in roman font starting with a capital letter. For example, Class_chart, Feature_clause, and Object_group are construct names, and the corresponding specimens are any individual class chart, feature clause, etc., that may be built according to the rules specified by the grammar. Every construct is either terminal or non-terminal. A specimen of a terminal construct is called a lexical element or a token. The set of tokens make up the basic vocabulary which may be used to construct sentences in the language, and their internal structure is not described by the grammar. The set of tokens are either considered known a priori, or else described separately (usually through regular expressions applied to sequences of individual characters, or by informal language). Non-terminals, on the other hand, are described in terms of other constructs, either terminal or non-terminal. Such a description is called a production for the construct, and has the following form: Construct = right-hand-side By convention, every non-terminal construct appears (through its construct name) as the left-hand side of exactly one production. Terminal constructs, on the other hand, may only appear on the right-hand side (by definition). The symbol = means "is defined as". The right-hand side of a production specifies the structure of the left-hand construct, and since every non-terminal construct has a production attached, the corresponding specimen can always be recursively decomposed into sequences of tokens. It is not always possible to tell whether a construct is terminal or non-terminal without checking if it occurs as the left-hand side of a production or not. However, two common token types are written using different typography for easy identification: keywords (in lower case boldface) and fixed operators (enclosed in double quotes). There are three basic types of production, which have the following forms. Aggregate Defines the construct as a fixed sequence of construct parts. One or more elements in the sequence may be marked as optional by enclosing them in square brackets. For example: Parenthesized = "(" Expression ")" Inheritance_relation = Child inherit [ "{" Multiplicity "}" ] Parent [ Semantic_label ] defines Parenthesized as a left parenthesis followed by an Expression followed by a right parenthesis, and Inheritance_relation as a Child construct followed by the keyword inherit, then an optional multiplicity part (Multiplicity enclosed in braces), then a Parent construct, then an optional Semantic_label. Choice Defines the construct as one of a fixed number of alternative constructs. It is written as a non-empty sequence of constructs separated by vertical bar. The production Expression = Quantification | Call | Operator_expression | Constant therefore means that an Expression is a Quantification, or a Call, or an Operator_expression, or a Constant. Repetition Defines the construct as a variable length sequence of specimens of another construct, possibly separated (if more than one element) by a given separator. The separator (if any) may be either terminal or non-terminal. A repetition right-hand side is written in one of the two forms below: { Element_construct Separator_construct ...} { Element_construct Separator_construct ...} + The first form signals that the sequence may be empty, while the second requires at least one element. Omitting the separator construct means that multiple elements are concatenated without separators in this type of sequence. Below are some examples. The first production defines an Index_list as a sequence of one or more Index_clause, separated by a semicolon. The second defines Features as a sequence of one or more Feature_clause without any separator. The third production defines a Dynamic_ref as zero or more Group_prefix followed by a Dynamic_component_name. Index_list = { Index_clause ";" ...} + Features = { Feature_clause ...} + Dynamic_ref = { Group_prefix ...} Dynamic_component_name With these preliminaries, we are now ready to give the full syntax specification of the BON textual notation. The grammar is defined in the following sections and then concluded by a discussion of the lexical components, summing up the keywords and operators used. A.3 BON SPECIFICATION Bon_specification = { Specification_element ...} + Specification_element = Informal_chart | Class_dictionary | Static_diagram | Dynamic_diagram | Notational_tuning A.4 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 "," ...} + -- @design kiniry - Aug, 2001 - Class_name_list likely has to be -- extended for referral to clusters (e.g. "(CLUSTER_NAME)") as a -- shortcut for referring to all classes of the cluster. See -- MONITORING_SYSTEM event charts for an example. 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 A.5 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 A.6 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 = "+" | "-" | "*" | "/" | "<" | ">" | "<=" | ">=" | "=" | "/=" | "//" | "\\" | "^" | or | xor | and | "->" | "<->" | member_of | ":" A.7 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 A.8 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_name = Class_name [ "." Extended_id ] Group_name = Extended_id Message_label = Manifest_string A.9 NOTATIONAL TUNING This will be explained in the next section. 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 A.10 LEXICAL COMPONENTS We conclude this chapter with a discussion of the lexical components, which are used to form BON textual descriptions in accordance with the grammar defined in the preceding sections. These components are the terminal constructs that do not appear as the left-hand side of any production in the grammar, and therefore need to be described separately. Identifiers The Identifier construct is defined as a sequence of alphanumeric characters including underscore. An identifier must begin with an alphanumeric character and must not end with an underscore (whose purpose really is to mimic word separation). Letter case is not significant, but using consistent style rules is important. The recommended BON standard is to use all upper case names for class and cluster names, all lower case for feature names, and lower case beginning with a capital for object groups and constants values. We also strongly recommend using underscore for word separation rather than, for example, in-word capitalization, since this greatly enhances readability. Free operators The Free_operator construct represents feature names used as infix and prefix operations. Such operations may be textual keywords, such as the boolean "and" and "or", but are more often composed of special characters, like "+", "**", "=>", etc. The purpose is usually to make object-oriented expressions (which are always feature calls in the end) look very similar to the formalisms used in some discipline thus providing a more compact and readable notation for the problem at hand. Since it is difficult to foresee exactly what operator combinations may be needed, BON only defines the Free_operator construct as a sequence of non-spacing printable characters that does not conflict with any of the predefined ones. However, in practice, more restrictions are added by each development environment. Comments Major analysis and design elements, such as static diagrams, clusters, classes, object groups, etc., often need to have comments attached to them in order to explain overall modeling aspects that have no natural place among the constituent parts at lower levels. Therefore, the BON textual notation recognizes comments to major specification elements as part of the grammar, thereby encouraging the standard placement of them. This also provides a parser with the possibility to check and possibly enforce certain strategic descriptions. However, besides the places recognized by the grammar, comments may be inserted anywhere in a BON textual description, except inside strings. Strings The construct Simple_string is defined as any string of characters not containing a New_line character. The non-terminal construct Manifest_string is a Simple_string enclosed in the pair of terminals String_begin and String_end. Similarly, the non-terminal Manifest_textblock is a sequence of Simple_string separated by New_line and enclosed by the same pair of terminal constructs (see the grammar above). These delimiters are defined by default as a string containing one double quote character. The character sequence "show some class, don't treat me like an object" is then interpreted as a Manifest_string. However, to facilitate the accommodation of double quotes inside strings without having to insert escape characters, the delimiting strings may be changed (often to some control characters in connection with automatic processing). BON also defines a lexical Concatenator construct. If a Concatenator is found inside a Simple_string, it is removed along with all characters (including New_line) up to and including the next Concatenator construct. This makes it possible to embed formatting white space into strings for readability, without making the formatting characters part of the strings. The Concatenator construct is defined as a single backslash by default, but may be changed by the user. It must not conflict with the string delimiters. An example of its use is shown below. "This is a long simple string, which has been broken into\ \ two lines for readability" The basic constructs Integer, New_line, Character, and Real are not further specified, since they may need different definitions depending on the development environment. Reserved words Reserved words are terminal constructs which are predefined sequences of letters only, and which cannot be used as identifiers by the user, since this might lead to language ambiguities. The reserved words in BON consist of keywords and predefined names. There are only three of the latter type: Current, Result,and Void. The full list is shown in figure A.1. Figure A.1 BON reserved words action creator false not reused and Current feature object root calls deferred for_all object_group scenario class delta incoming object_stack scenario_chart class_chart description indexing old static_diagram client dictionary infix or string_marks cluster dynamic_diagram inherit outgoing such_that cluster_chart effective interfaced part system_chart command end invariant persistent true component ensure involves prefix Void concatenator event it_holds query xor constraint event_chart keyword_prefix redefined creates exists member_of require creation_chart explanation nameless Result In a sizable language, there is always the risk that some keywords steal valuable name space from the user, and textual BON, being fairly expressive, is no exception. To counter this disadvantage, BON defines a terminal construct Keyword_prefix, which is empty by default. By defining Keyword_prefix as the string "$", for example, we may change the syntax of BON so all keywords now need to be prefixed by a dollar sign, thus freeing all the corresponding normal words for use in specification of the system under development. Special symbols Finally, we collect the complete set of special symbols used in BON with an overview of their meaning (figure A.2). Each of them has been described earlier in the book. The ones marked as operators (except for the type operator ":") can be viewed as class features of infix form that may be redefined by descendant classes. Conclusion The BON textual notation is a full specification language for object-oriented system designs, whose purpose is threefold: o It can be used to communicate exact specifications between various tools and environments, thus taking advantage of the advances in many independent areas of presentation. " o It can be used for better understanding of the concepts underlying the graphical notation and for settling ambiguities. With today s widely available parser generator utilities, the task of writing a parser for the language becomes easy. " o It provides a means of storing and updating a specification in a simple way, using standard text editors, which can serve as an alternative to a dedicated case tool. It may be feasible to copy small whiteboard diagrams with pencil on paper in connection with design sessions, but maintaining larger specifications requires more. Anybody who has experienced the pain of trying to keep evolving graphical figures up to date without strong automatic support knows only too well what we are talking about. Finally, regarding the different presentations that may be generated from a BON textual description, we have not tried to cover graphical layout in the textual language. The basic graphical appearance of each textual concept has been defined earlier in this book, along with validity constraints and rules for how relational arrows may be combined, labels be positioned, etc. But what valid alternative to choose is left to the strategies of the individual case tool. Figure A.2 BON special symbols SYMBOL NAME USE ====================================================================== -- double dash Introduces comments ' single quote Encloses character constants " double quote Encloses prefix and infix operator names , comma General element separator ; semicolon Separator for parent lists, assertion clauses, and indexing clauses ( ) parentheses Grouping of expressions, multiplicity [ ] square brackets Encloses generic parameters { } braces Encloses restricted export lists, renaming, enumerated sets + - * / plus, minus, Arithmetic operators times, division // \\ double slash, Integer division, modulo operators double backslash ^ up arrow Power operator, renaming < > less than, Relational operators greater than <= >= less than or equal, Relational operators greater than or equal = /= equal, not equal Equality and non-equality -> right arrow, implies Feature arguments, constrained genericity, logical implication <-> equivalence Logical equivalence . dot Feature calls, renaming, relational references, object_id .. double dot Interval marker : colon Type mark, type operator, index separator :{ aggregate mark Indicates aggregate supplier The following assertion elements must be supported (from figure 3.13, page 46, of WaldenNerson94): Graphical BON (TeX) Textual BON Explanation ====================================================================== \Delta name delta name Attribute changed old expr old expr Old return value ---------------------------------------------------------------------- Result Result Current query result @ Current Current object \emptyset Void Void reference + - * / + - * / Basic numeric operators ^ ^ Power operator // // Integer division \\ \\ Modulo = = Equal \neq /= Not equal < < Less than \leq <= Less than or equal > > Greater than \geq >= Greater than or equal \arrow -> Implies (semi-strict) \ <-> Equivalent to \neg not Not and and And (semi-strict) or or Or (semi-strict) xor xor Exclusive or \exists exists There exists \forall for_all For all | such_that Such that \dot it_holds It holds \in member_of Is in set \nin not member_of Is not in set : type : type Is of type {} {} Enumerated set .. .. Closed range
We note the various problems, corrections, additions, etc. that we made to the BON grammar here.
Static_component: Cluster_rule | Class_rule | Static_relation | ELLIPSES_TOKEN ;
See the scanner design documentation for details on how errors during scanning are gracefuly handled.