|
Notation: * Characters surrounded by apostophes ("'") are literals; they shall appear in the production exactly as-is. * Items in brackets [...] means zero-or-one of the item. * Items followed by an asterisk (*) means zero-or-more of the item. * Items followed by a plus (+) mean one-or-more of the item. * Parentheses are used to group stuff. When the production calls for a literal parenthesis, we use '(' and ')'. * Words surrounded by angle brackets <> are variable names and reduce to the production "identifier". * := means "is defined as". * a|b|c means "a or b or c". * All nonterminals in this BNF begin with capital letters. * Begin with the "Program" production. * Whitespace rules are explained at the bottom of this file. * Additional semantic rules are listed at the bottom of this file. Program := NoMethodsApproach | MethodsButNoClassApproach | ClassApproach NoMethodsApproach := [ClassDeclarePart] ActionPart MethodsButNoClassApproach := [ClassDeclarePart] MethodPart ClassApproach := [ImportPart] ClassCommand ClassRequiredDocPart [ClassDeclarePart] [Invariant] [Constructor] [MethodPart] EndClassCommand ClassDeclarePart := ConstantCommand* ClassBoxDecl* ConstantCommand := 'Constant' <constantname> '=' Value 'ofType' ScalarPrimitiveType ['is' Visibility] RULE: The word 'is' is required if the Program uses the ClassApproach RULE: The word 'is' is not allowed if the Program does not use the ClassApproach ClassBoxDecl := ClassBoxCommand | ClassBoxesCommand ClassBoxCommand := 'Box' <boxname> Type ['is' Visibility] RULE: The word 'is' is required if the Program uses the ClassApproach RULE: The word 'is' is not allowed if the Program does not use the ClassApproach ClassBoxesCommand := 'Boxes' <boxname> (',' <boxname>)+ Type ['are' Visibility] RULE: The word 'are' is required if the Program uses the ClassApproach RULE: The word 'are' is not allowed if the Program does not use the ClassApproach ImportPart := ImportCommand* ImportCommand := 'Import' ImportLib ImportLib := 'JJIO' | 'JJGUI' | 'JJDBC' | 'JJUtilTime' | 'JJUtil???' ClassCommand := 'Class' <classname> EndClassCommand := 'EndClass' <classname> RULE: The classname shall exactly match the classname supplied on the Class command RULE: The classname shall match exactly the classname supplied on the ClassCommand ClassRequiredDocPart := '-- Name:' <username> | '--Name:' <username> Invariant := InvariantCommand CheckCommand* EndInvariantCommand InvariantCommand := 'Invariant' EndInvariantCommand := 'EndInvariant' RULE: The word 'EndInvariant' shall begin in the same column as its matching 'Invariant'. CheckCommand := 'Check' ScalarBoolExpr 'bounce' StringLiteral Constructor := ConstructorCommand SlotCommand* LocalBoxDecl* [ActionPart] EndConstructorCommand ConstructorCommand := 'Constructor' <classname> '(' SlotDeclList ')' 'is' 'public' RULE: The classname shall match exactly the classname supplied on the ClassCommand EndConstructorCommand := 'EndConstructor' <classname> RULE: The word 'EndConstructor' shall begin in the same column as its matching 'Constructor'. RULE: The classname shall match exactly the classname supplied on the ClassCommand LocalBoxDecl := LocalBoxCommand | LocalBoxesCommand LocalBoxCommand := 'Box' <boxname> Type LocalBoxesCommand := 'Boxes' <boxname> (',' <boxname>)+ Type # routines and functions MethodPart := (Routine | Function)+ Routine := RoutineCommand SlotCommand* LocalBoxDecl* [StartCommand] PreCheckCommand* [ActionPart] PostCheckCommand* EndRoutineCommand RoutineCommand := 'Routine' <routinename> '(' SlotDeclList ')' 'is' Visibility RULE: The word 'is' is required if the Program uses the ClassApproach RULE: The word 'is' is not allowed if the Program does not use the ClassApproach EndRoutineCommand := 'EndRoutine' <routinename> RULE: The word 'EndRoutine' shall begin in the same column as its matching 'Routine'. RULE: The routinename shall match exactly the routinename supplied on the RoutineCommand StartCommand := 'Start' RULE: The Start command can only appear once in a class. RULE: A Start command can only appear in a public routine with no slots. Function := FunctionCommand SlotCommand* ResultBoxDecl* LocalBoxDecl* PreCheckCommand* ActionPart PostCheckCommand* EndFunctionCommand RULE: A function shall set a value in its result box. FunctionCommand := 'Function' <functionname> Type '(' SlotDeclList ')' 'is' Visibility RULE: The word 'is' is required if the Program uses the ClassApproach RULE: The word 'is' is not allowed if the Program does not use the ClassApproach EndFunctionCommand := 'EndFunction' <functionname> RULE: The word 'EndFunction' shall begin in the same column as its matching 'Function'. RULE: The functionname shall match exactly the functionname supplied on the FunctionCommand PreCheckCommand := 'PreCheck' ScalarBoolExpr 'bounce' StringLiteral PostCheckCommand := 'PostCheck' ScalarBoolExpr 'bounce' StringLiteral SlotDeclList := 'none' | <slotname> (',' <slotname>)* SlotCallList := Expr (',' Expr)* SlotCommand := 'Slot' <slotname> Type ResultBoxDecl := 'Box' 'result' Type OfTypeOrClass := 'ofType' PrimitiveTypeCategory | 'ofClass' ClassTypeCategory ScalarOfTypeOrClass := 'ofType' ScalarPrimitiveType | 'ofClass' ScalarClassType PrimitiveTypeCategory := ScalarPrimitiveType | ArrayPrimitiveType ScalarPrimitiveType := 'int' | 'real' | 'bool' ArrayPrimitiveType := 'int[]' | 'real[]' | 'bool[]' ClassTypeCategory := ScalarClassType | ArrayClassType ScalarClassType := 'Str' | <classname> ArrayClassType := 'Str[]' | <classname>'[]' ScalarType := ScalarPrimitiveType | ScalarClassType ArrayType := ArrayPrimitiveType | ArrayClassType Visibility := 'public' | 'private' Value := NumericLiteral | StringLiteral | BoolLiteral StringLiteral := "Char*" Char := any printable character NumericLiteral := IntLiteral | RealLiteral IntLiteral := Digit+ BoolLiteral := 'true' | 'false' RealLiteral := Digit+ '.' Digit+ Identifier := Letter (Alphanumeric | '_')* RULE: An identifier cannot end with a '_' Letter := A-Z | a-z Digit := 0-9 Alphanumeric := Letter | Digit ArrayMember := <arrayname> '[' ScalarIntExpr ']' Expr := Expr BinaryBoolOp Expr | Expr BinaryAddOp Expr | Expr BinaryMinusOp Expr | Expr BinaryMultDivOp Expr | Expr BinaryModOp Expr | '(' Expr BinaryRelOp Expr ')' | UnaryBoolOp Expr | UnaryMinusOp Expr | FunctionReference | ArrayMember | ClassMember | Boxname | Value | '(' Expr ')' RULE: The Expr before and after the BinaryBoolOp shall be of type bool. RULE: The Expr before and after the BinaryAddOp shall be of the same type and of type int, real or Str. RULE: The Expr before and after the BinaryMinusOp shall be of the same type and of type int or real. RULE: The Expr before and after the BinaryMultDivOp shall be of the same type and of type int or real. RULE: The Expr before and after the BinaryModOp shall be of type int. RULE: The Expr before and after the BinaryRelOp shall be of the same type and of type int or real. RULE: The Expr after a UnaryBoolOp shall be of type bool. RULE: The Expr after a UnaryMinusOp shall be of type int or real. ScalarIntExpr := Expr RULE: A ScalarIntExpr shall be of type int ScalarBoolExpr := Expr RULE: A ScalarBoolExpr shall be of type bool ScalarStrExpr := Expr RULE: A ScalarStrExpr shall be of class Str LhsExpr := ArrayMember | Boxname Boxname := <boxname> RULE: Unless being used in a SlotCallList, the type of the boxname shall be of type ScalarType. ClassMember := <classboxname>.<boxname> BinaryBoolOp := 'and' | 'or' BinaryAddOp := '+' BinaryMinusOp := '-' BinaryMultDivOp := '*' | '/' BinaryModOp := '%' BinaryRelOp := '<' | '<=' | '>' | '>=' | '==' | '!=' UnaryBoolOp := 'not' UnaryMinusOp := '-' ActionPart := (Construct | ActionCommand)+ Construct := IfConstruct | LoopConstruct ActionCommand := SetCommand | CallCommand | NewArrayCommand | NewCommand | InputCommand | OutputCommand | OutputlnCommand | DebugCommand | DebuglnCommand | TryCall Command | TrySet Command | CheckCommand IfConstruct := IfPart [ActionPart] ElseIfPart* [ElsePart] EndIfCommand IfPart := IfCommand [ActionPart] IfCommand := 'If' ScalarBoolExpr 'then' RULE: If the IfCommand is nested within an outer IfConstruct, the word 'If' shall not begin in the same column as the word 'If' from the outer IfConstruct EndIfCommand := 'EndIf' RULE: The word 'EndIf' shall begin in the same column as its matching 'If'. ElseIfPart := ElseIfCommand [ActionPart] ElseIfCommand := 'ElseIf' ScalarBoolExpr 'then' RULE: The word 'ElseIf' shall begin in the same column as its matching 'If'. ElsePart := ElseCommand [ActionPart] ElseCommand := 'Else' RULE: The word 'Else' shall begin in the same column as its matching 'If'. LoopConstruct := RepeatCommand [ActionPart] ExitOnCommand [ActionPart] EndRepeatCommand RepeatCommand := 'Repeat' RULE: If the RepeatCommand is nested within an outer RepeatConstruct, the word 'Repeat' shall not begin in the same column as the word 'Repeat' from the outer RepeatConstruct ExitOnCommand := 'ExitOn' ScalarBoolExpr RULE: The word 'ExitOn' shall begin in the same column as its matching 'Repeat'. EndRepeatCommand := 'EndRepeat' RULE: The word 'EndRepeat' shall begin in the same column as its matching 'Repeat'. SetCommand := 'Set' Assignment Assignment := LhsExpr '=' Expr RULE: The LhsExpr and the Expr shall be of the same type. RULE: If the LhsExpr is of type ArrayType, the Expr shall be a FunctionReference (or a FunctionReference inside parentheses) of type ArrayType. CallCommand := 'Call' RoutineReference RoutineReference := LocalRoutineReference | ClassPublicRoutineReference LocalRoutineReference := <routinename> [WithSlots] RULE: If the routinename is declared with any slots, the WithSlots production shall exist. ClassPublicRoutineReference := <classboxname>.<routinename> [WithSlots] RULE: If the routinename is declared with any slots, the WithSlots production shall exist. WithSlots := 'with' '(' SlotCallList ')' FunctionReference := LocalFunctionReference | ClassPublicFunctionReference | IntrinsicFunctionReference LocalFunctionReference := <functionname> '(' [SlotCallList] ')' RULE: If the functionname is declared with any slots, the SlotCallList production shall exist. ClassPublicFunctionReference := <classboxname>.<functionname> '(' [SlotCallList] ')' RULE: If the functionname is declared with any slots, the SlotCallList production shall exist. IntrinsicFunctionReference := <intrinsicfunctionname> '(' SlotCallList ')' NewArrayCommand := 'NewArray' <arrayname> ScalarOfTypeOrClass '[' ScalarIntExpr ']' NewCommand := 'New' LhsExpr 'ofClass' ScalarClassType [WithSlots] RULE: If the constructor for the classname is declared with any slots, the WithSlots production shall exist. InputCommand := 'Input' <varname> OutputCommand := 'Output' Expr RULE: The Expr shall be of type ScalarType OutputlnCommand := 'Outputln' Expr RULE: The Expr shall be of type ScalarType DebugCommand := 'Debug' Expr RULE: The Expr shall be of type ScalarType DebuglnCommand := 'Debugln' Expr RULE: The Expr shall be of type ScalarType TryCallCommand := 'TryCall' FileIORoutineReference 'OnFail' RoutineReferenceOrAssignment FileIORoutineReference := ClassPublicRoutineReference TrySetCommand := 'TrySet' StringConversionAssignment 'OnFail' RoutineReferenceOrAssignment StringConversionAssignment := <boxname> '=' StringConversionFunctionReference RULE: The boxname shall be the same type as the StringConversionFunctionReference. StringConversionFunctionReference := 'StringToInt' '(' ScalarStrExpr ')' | 'StringToReal' '(' ScalarStrExpr ')' RoutineReferenceOrAssignment := RoutineReference | Assignment ----------------------------------------------------------------------------------- Semantic Rules: 1. Types. Jr is a strongly-typed language. No automatic type conversions will be performed. 2. Names. Variable names in Jr shall be alphanumeric, but may not begin with an underscore. There is no built-in limit on how long names may be. 3. StringLiteral. Any printable character may be in a StringLiteral. 4. Whitespace. Whitespace is required between all tokens. The first word of a Command shall be the first word on a line. 5. Initialization. Variables are not automatically initialized. All variables shall be explicitly set before being used in an Expr or a SlotCallList. 6. Operator Precedence. The precedence of operators is the same as the equivalent operators in Java. Highest: Lowest: ----------------------------------------------------------------------------------- Appendix A: Commands, in the order that they appear in this BNF ... ConstantCommand := 'Constant' <constantname> '=' Value 'ofType' ScalarPrimitiveType ['is' Visibility] ClassBoxCommand := 'Box' <boxname> Type ['is' Visibility] ClassBoxesCommand := 'Boxes' <boxname> (',' <boxname>)+ Type ['are' Visibility] ImportCommand := 'Import' ImportLib ClassCommand := 'Class' <classname> EndClassCommand := 'EndClass' <classname> InvariantCommand := 'Invariant' EndInvariantCommand := 'EndInvariant' CheckCommand := 'Check' ScalarBoolExpr 'bounce' StringLiteral ConstructorCommand := 'Constructor' <classname> '(' SlotDeclList ')' 'is' 'public' EndConstructorCommand := 'EndConstructor' <classname> LocalBoxCommand := 'Box' <boxname> Type LocalBoxesCommand := 'Boxes' <boxname> (',' <boxname>)+ Type RoutineCommand := 'Routine' <routinename> '(' SlotDeclList ')' ['is' Visibility] EndRoutineCommand := 'EndRoutine' <routinename> StartCommand := 'Start' FunctionCommand := 'Function' <functionname> Type '(' SlotDeclList ')' ['is' Visibility] EndFunctionCommand := 'EndFunction' <functionname> PreCheckCommand := 'PreCheck' ScalarBoolExpr 'bounce' StringLiteral PostCheckCommand := 'PostCheck' ScalarBoolExpr 'bounce' StringLiteral SlotCommand := 'Slot' <slotname> Type IfCommand := 'If' ScalarBoolExpr 'then' EndIfCommand := 'EndIf' ElseIfCommand := 'ElseIf' ScalarBoolExpr 'then' ElseCommand := 'Else' RepeatCommand := 'Repeat' ExitOnCommand := 'ExitOn' ScalarBoolExpr EndRepeatCommand := 'EndRepeat' SetCommand := 'Set' Assignment CallCommand := 'Call' RoutineReference NewArrayCommand := 'NewArray' <arrayname> ScalarOfTypeOrClass '[' ScalarIntExpr ']' NewCommand := 'New' LhsExpr 'ofClass' ScalarClassType [WithSlots] InputCommand := 'Input' <varname> OutputCommand := 'Output' Expr OutputlnCommand := 'Outputln' Expr DebugCommand := 'Debug' Expr DebuglnCommand := 'Debugln' Expr TryCallCommand := 'TryCall' FileIORoutineReference 'OnFail' RoutineReferenceOrAssignment TrySetCommand := 'TrySet' StringConversionAssignment 'OnFail' RoutineReferenceOrAssignment