MenuBNF.tioga, written by R. Pausch
NOTE: examples can be found at the bottom of the file, below the BNF
This in an informal BNF description of the Syntax of Cedar Viewer Menus, as parsed by Menus.ParseDescription. BNF notation: anything in single quotes (also shown in BOLD) means I need that exact String, although I don't care about the case of the characters. Parens (), OR bars | and stars * are part of the BNF notation. NOTE: You may find this thing easier to read if you use one very wide viewer.
Last Edited by: Pausch, August 26, 1983 7:17 pm
Last Edited by: Wyatt, October 7, 1983 2:26 pm
Item ::= ReLabel | Menu
ReLabel ::= 'ReLabel' '[' SpecificMenu Old New ']' | 'ReLabel' '[' Old New ']'
three String are MenuName, oldentryname, newentryname — using only two strings implies that ALL entries in all menus that have first String as their name should be ReLabel with the second String. Note that this doesn't change the 'name' field of the data structure, rather, it changes the 'displayData' field (which is why it is called 'ReLabel', not 'Rename')
SpecificMenu ::= Identifier
Old ::= Identifier
New ::= Identifier
Menu ::= '[' MenuName MenuParms* Entry* ']'
MenuName ::= Identifier
MenuParms ::= 'breakBefore' ':' Bool | 'breakAfter' ':' Bool | 'beginsActive' ':' Bool | 'notifyProc' ':' Proc
Entry ::= '[' EntryName EntryParms* '=>' WhatToDoWhenHit ']'
EntryName ::= Identifier
EntryParms ::= 'guarded' ':' Bool | 'display' ':' StringOrProc
WhatToDoWhenHit ::= NotifyProcData | TriggerAndResults*
TriggerAndResults ::= '[' ( SimpleTrigger | TriggerList ) TriggerParms* '=>' NotifyProcData ']'
complexity: if an Entry is to have different functionality for different triggers, i.e. left-clicking does something different than right-clicking, it is harder to specify. To wit, EACH trigger or combination of triggers must have things specified for it.
TriggerList ::= '[' SimpleTrigger* ']'
SimpleTrigger ::= 'none' | 'all' | 'leftUp' | 'middleUp' | 'rightUp' | 'shiftLeftUp' | 'shiftMiddleUp' | 'shiftRightUp' | 'allNonShifts' | 'allShifts' | 'allLeft' | 'allMiddle' | 'allRight'
TriggerParms :== 'popUpDoc' ':' String | 'guardResponse' ':' StringOrProc | 'makeActive' ':' String | 'makeInactive' ':' String | 'toggle' ':' String
Identifier ::= whatever CedarScanner thinks is an Identifier
NotifyProcData ::= ListOfRefAny -- this stuff gets passed to your notify proc
Proc ::= '{' ModuleName '.' ProcedureName ListOfRefAny '}'
StringOrProc ::= String | Proc
ModuleName ::= String
ProcedureName ::= String
String ::= a quoted String that CedarScanner gets for me
Bool ::= 'true' | 'false'
ListOfRefAny ::= list of things until I hit a ']' or '}'
Examples:
The following description is for a simple menu with four entries, each of which sends a single atom when the button is pressed:
[HouseCleaningMenu
[Dust => $Dust]
[Sweep => $UseBroom]
[Vacuum => $Vacuum]
[Mop => $MopFloors]
]
The next example provides the same functionality, but with only two menu entries. It does this by "overloading" the second entry. This means the entry will cause different things to happen depending on whether it is invoked with the left, middle, or right mouse button.
[HouseCleaningMenu
[Dust => $Dust]
[CleanFloors =>
[allleft => $UseBroom ]
[allmiddle => $Vacuum ]
[allright => $MopFloors ]
]
]


The next example provides the same functionality in yet a third way: The second menu entry is used to "bring up" a secondary menu for the user to click at. The secondary menu is designed to provide three buttons, each of which will cause the menu to disappear after one of the options is invoked.
[HouseCleaningMenu
[Dust => $Dust]
[Places => [all toggle: "FloorCleaningMenu" => ] ] -- note that nothing follows the '=>'
]
[FloorCleaningMenu
[Sweep => [all makeInactive: "FloorCleaningMenu" => $UseBroom ] ]
[Vacuum => [all makeInactive: "FloorCleaningMenu" => $Vacuum ] ]
[Mop => [all makeInactive: "FloorCleaningMenu" => $MopFloors ] ]
]