JJ BNF

Notation:
 o  Characters surrounded by apostophes (') are literals;
    they shall appear in the production exactly as-is.

 o  Items followed by a question mark (?) means zero-or-one of the item.

 o  Items followed by an asterisk (*) means zero-or-more of the item.

 o  Items followed by a plus (+) mean one-or-more of the item.

 o  a | b | c means "a or b or c".

 o  Words surrounded by angle brackets <> are categories of either
    names or expressions.  This allows for a specific link between an
    error message and this BNF.  For example, instead of using <Name>
    in various productions, more specific terms are used such as
    <ClassName>, <ConstantName>, and <VoidMethodName>.
    Similarly, instead of using <Expr>, there are more specific terms
    used such as <ConditionExpr>, <ArrayIndexExpr>, and <RhsExpr>.

 o  All nonterminals in this BNF begin with capital letters.

 o  Begin with the "Program" production.

 o  Whitespace rules are explained at the bottom of this file.

 o  Additional semantic rules are listed at the bottom of this file.

Productions:
Program is
 ClassApproach |
 NoClassButHasMethodsApproach |
 NoClassNoMethodsApproach

NoClassNoMethodsApproach is
 MethodBody

NoClassButHasMethodsApproach is
 ClassConstantsAndBoxesDeclPart? 
 MethodConstruct+

ClassApproach is
 ClassRequiredCommentPart
 ImportCommand*
 ClassConstruct

ClassConstruct is
 ClassDeclCommand
 ClassConstantsAndBoxesDeclPart?
 InvariantConstruct?
 ConstructorConstruct?
 MethodConstruct*
 EndConstructCommand

ClassConstantsAndBoxesDeclPart is
 ClassConstantDeclCommand* 
 ClassBoxDeclCommand*

InvariantConstruct is
 InvariantCommand
 CheckCommand*
 EndConstructCommand

ConstructorConstruct is
 ConstructorDeclCommand
 MethodBody
 EndConstructCommand

 RULE: For rules on constructors, see rules under the ConstructorDeclCommand production.

MethodConstruct is
 MethodDeclCommand
 MethodBody
 EndConstructCommand

 RULE: For rules on methods, see rules under the MethodDeclCommand production.

MethodBody is
 MethodConstantDeclCommand*
 MethodBoxDeclCommand*
 ActionOrActionConstruct*

ActionOrActionConstruct is
 Action | 
 ActionConstruct

Action is
 StartCommand |
 PreCheckCommand |
 CheckCommand |
 CallVoidMethodCommand |
 NewArraySizeCommand |
 NewInstanceCommand |
 SetBoxCommand |
 IncCommand |
 DecCommand |
 IOCommands |
 ExitLoopCommand |
 PostCheckCommand |
 ReturnResultCommand

 RULE: An ExitLoopCommand shall only be used inside a LoopingConstruct.  See rules
 under the WhileConstruct and ForConstruct productions.

 RULE: A ReturnResultCommand shall only be used as the final command
 in the MethodBody of a TypeMethod.  See rule under the MethodDeclCommand
 production.

IOCommands is
 InputCommand |
 OutputCommand |
 OutputlnCommand |
 JavaSystemOutPrintCommand |
 JavaSystemOutPrintlnCommand |
 DebugCommand |
 DebuglnCommand

ActionConstruct is
 IfConstruct | LoopingConstruct

LoopingConstruct is
 WhileConstruct | ForConstruct

IfConstruct is
 IfPart
 ElseIfPart*
 ElsePart?
 EndConstructCommand

IfPart is
 IfCommand
 ActionOrActionConstruct*

ElseIfPart is
 ElseIfCommand
 ActionOrActionConstruct*

ElsePart is
 ElseCommand
 ActionOrActionConstruct*

WhileConstruct is
 WhileCommand
 ActionOrActionConstruct+
 EndConstructCommand

 RULE: If the ConditionExpr in the WhileCommand is the word "true", there
 shall be exactly one ExitLoopCommand; otherwise, the ConditionExpr is used
 to specify the exit and ExitLoopCommand is not allowed.

ForConstruct is
 ForCommand
 ActionOrActionConstruct+
 EndConstructCommand

 RULE: There can be at most one ExitLoopCommand in the ForConstruct.

-----------------------------------------------------------------------------------
Command Productions
-----------------------------------------------------------------------------------

ClassRequiredCommentPart is
 '// Name:' <username> |
 '// Name' <username>  |
 '//Name:' <username>  |
 '//Name' <username>

ImportCommand is
 'import' ImportLib ';'

ImportLib is
 tbd

ClassConstantDeclCommand is
 Visibility? 'static' 'final' Type <ConstantName> '=' Value ';'

 RULE: Inside a ClassConstruct, Visibility is required.

 RULE: If not inside a ClassConstruct, Visibility is not allowed.

 RULE: Type shall be int, double, boolean or String (it shall not be a className other than String
       and it shall not be an array).

 RULE: Type shall be the same type as the Value.

 RULE: UNR1 (Unique Name Rule #1): The name used as the ConstantName shall not appear
 previously as a ConstantName or the ClassName.

ClassBoxDeclCommand is
 Visibility? Type <ClassBoxName> ';'

 RULE: Inside a ClassConstruct, Visibility is required.

 RULE: If not inside a ClassConstruct, Visibility is not allowed.

 RULE: UNR2 (Unique Name Rule #2): The name used as the ClassBoxName shall not appear
 previously as a ClassBoxName, ConstantName or the ClassName.

ClassDeclCommand is
 'class' <ClassName> '{'

EndConstructCommand is
 '}' EndConstructComment?

EndConstructComment? is

 '//' 'end' ConstructWord |
 '//' 'end' ConstructName |
 '//' 'end' ConstructWord ConstructName

ConstructWord is
 'class' |
 'method' |
 'void method' |
 'type method' |
 Type 'method' |
 'if' |
 'for' |
 'while'

ConstructName is
 Name

 RULE: The Name shall exactly match the name of the class or method.

InvariantCommand is
 'private' 'void' 'invariant' '(' ')' '{'

 NOTE: The InvariantCommand is an example of the MethodDeclCommand where the
 Visibility is private and the methodName is invariant.

CheckCommand is
 'JJS' '.' 'check' '(' <ConditionExpr> ',' StringLiteral ')' ';'

 NOTE: The CheckCommand is an example of the CallVoidMethodCommand where the
 className is JJS, the methodName is check, and the ExprList has two expressions.

ConstructorCommand is
 'public' <ClassName> '(' SlotDeclList? ')' '{'

 RULE: The classname shall match exactly the classname supplied on the ClassCommand

 NOTE: The ConstructorCommand is similar to the MethodDeclCommand, except the
 Visibility is always public, there is no TypeOrVoid, and the name shall match the className.

MethodDeclCommand is
 Visibility? TypeOrVoid <MethodName> '(' SlotDeclList? ')' '{'

 RULE: Inside a ClassConstruct, Visibility is required.

 RULE: If not inside a ClassConstruct, Visibility is not allowed.

 RULE: UNR3 (Unique Name Rule #3): The name used as the MethodName shall not appear
 previously as a MethodName, ClassBoxName, ConstantName or the ClassName.

 NOTE: If TypeOrVoid is void, the method is referred to as a voidMethod in the
 below rules; otherwise the method is referred to as a typeMethod.
 
 RULE: A voidMethod shall not be called in an Expr.

 RULE: A typeMethod shall only be referenced in an Expr.

 RULE: A typeMethod shall declare a local box named "result" (result box).

 RULE: The Type of the typeMethod shall match the Type of the result box.

 RULE: The result box shall have its own box declaration command.

 RULE: The result box shall be declared before any method box declarations.

 RULE: A typeMethod shall set a value for a result box.

 RULE: Inside a ClassConstruct, at most one voidMethod shall contain a StartCommand.

 RULE: If not inside a ClassConstruct and the program contains methods, exactly one
 voidMethod shall contain a StartCommand.

SlotDecl is
 Type <SlotName>

 RULE: UNR4 (Unique Name Rule #4): The name used as a SlotName shall not appear
 previously as a SlotName, ClassBoxName, ConstantName or the ClassName.

 NOTE: It is highly recommended that each slot declaration start on a new line.

MethodConstantDeclCommand is
 'static' 'final' Type <MethodConstantName> '=' Value ';'

 RULE: Type shall be int, double, boolean or String (it shall not be a className other than String
       and it shall not be an array).

 RULE: Type shall be the same type as the Value.

 RULE: UNR5 (Unique Name Rule #5): The name used as a MethodConstantName shall not appear
 previously as a MethodConstantName, SlotName, ClassBoxName, ConstantName or the ClassName.

MethodBoxDeclCommand is
 Type <MethodBoxNameList> ';'

 RULE: UNR6 (Unique Name Rule #6): The name used as a MethodBoxName shall not appear
 previously as a MethodBoxName, MethodConstantName, SlotName, ClassBoxName, ConstantName or the ClassName.

StartCommand is
 'JJS' '.' 'start' '(' ')' ';'

 RULE: The one StartCommand shall appear before any other Actions or ActionConstructs.

 NOTE: The StartCommand is an example of the CallVoidMethodCommand where the
 className is JJS, the methodName is start, and the ExprList does not exist.

PreCheckCommand is
 'JJS' '.' 'preCheck' '(' <ConditionExpr> ',' StringLiteral ')' ';'

 RULE: All PreCheckCommands shall appear before any other Actions or ActionConstructs
 with the exception of a StartCommand.

 NOTE: The PreCheckCommand is an example of the CallVoidMethodCommand where the
 className is JJS, the methodName is preCheck, and the ExprList has two expressions.

PostCheckCommand is
 'JJS' '.' 'postCheck' '(' <ConditionExpr> ',' StringLiteral ')' ';'

 RULE: All PostCheckCommands shall appear after any other Actions or ActionConstructs,
 with the exception of the ReturnResultCommand (see next rule).

 RULE: All PostCheckCommands shall appear before the ReturnResultCommand of a
 TypeMethod.

 NOTE: The PostCheckCommand is an example of the CallVoidMethodCommand where the
 className is JJS, the methodName is postCheck, and the ExprList has two expressions.

SetBoxCommand is
 Lhs '=' <RhsExpr> ';'

 RULE: The Lhs and the RhsExpr shall be of the same type.

 RULE: If the Lhs is of type ArrayType, the Expr shall be a reference to a
 TypeMethod of type ArrayType.

CallVoidMethodCommand is
 CallLocalVoidMethodCommand |
 CallClassPublicVoidMethodCommand

CallLocalVoidMethodCommand is
 <VoidMethodName> '(' <ArgExprList>? ')' ';'

 RULE: The VoidMethodName shall be declared in the same program as this command

 RULE: The number of Exprs in the ArgExprList shall match the number of slots
 declared for the method.

 RULE: The Type of each Exprs in the ArgExprList shall match the Type of the
 corresponding slot for the method.

CallClassPublicVoidMethodCommand is
 <BoxName> '.' <VoidMethodName> '(' <ArgExprList>? ')' ';'

 RULE: The BoxName shall be declared with a type of a class.

 RULE: The VoidMethodName shall be declared as a public in the
 class specified by the type of the BoxName

 RULE: For rules on ArgExprList, see rules under the CallLocalVoidMethodCommand production.

NewArraySizeCommand is
 <ArrayBoxName> '=' 'new' Type '[' <SizeExpr> ']' ';'

 RULE:

NewInstanceCommand is
 <LhsExpr> '=' 'new' <ClassName> '(' <ArgExprList> ')' ';'

 RULE:

InputCommand is
 <LhsExpr> '=' 'JJS' '.' 'inputInt' '(' ')' ';' |
 <LhsExpr> '=' 'JJS' '.' 'inputDouble' '(' ')' ';' |
 <LhsExpr> '=' 'JJS' '.' 'inputBoolean' '(' ')' ';' |
 <LhsExpr> '=' 'JJS' '.' 'inputString' '(' ')' ';'

 RULE:

OutputCommand is
 'JJS' '.' 'outputInt' '(' <OutputIntExpr> ')' ';' |
 'JJS' '.' 'outputDouble' '(' <OutputDoubleExpr> ')' ';' |
 'JJS' '.' 'outputBoolean' '(' <OutputBooleanExpr> ')' ';' |
 'JJS' '.' 'outputString' '(' <OutputStringExpr> ')' ';'

 RULE: The Expr shall be of type ScalarType

OutputlnCommand is
 'JJS' '.' 'outputlnInt' '(' <OutputIntExpr> ')' ';' |
 'JJS' '.' 'outputlnDouble' '(' <OutputDoubleExpr> ')' ';' |
 'JJS' '.' 'outputlnBoolean' '(' <OutputBooleanExpr> ')' ';' |
 'JJS' '.' 'outputlnString' '(' <OutputStringExpr> ')' ';'

 RULE: The Expr shall be of type ScalarType

JavaSystemOutPrintCommand is
 'System' '.' 'out' '.' 'print' '(' <SystemOutPrintExpr> ')' ';' |

JavaSystemOutPrintlnCommand is
 'System' '.' 'out' '.' 'println' '(' <SystemOutPrintlnExpr> ')' ';' |

DebugCommand is
 'JJS' '.' 'debug' '(' <DebugExpr> ')' ';'

 RULE: The Expr shall be of type ScalarType

DebuglnCommand is
 'JJS' '.' 'debugln' '(' <DebugExpr> ')' ';'

 RULE: The Expr shall be of type ScalarType

TryCallCommand is
FileIORoutineReference is
TrySetCommand is
StringConversionAssignment is
StringConversionTypeMethodReference is
RoutineReferenceOrAssignment is

Type is
 PrimitiveType |
 ClassType

PrimitiveType is
 ScalarPrimitiveType |
 ArrayPrimitiveType

ScalarPrimitiveType is
 'int' | 'double' | 'boolean'

ArrayPrimitiveType is
 'int[]' | 'double[]' | 'boolean[]'

NumericType is
 'int' | 'double'

ClassType is
 ScalarClassType | ArrayClassType

ScalarClassType is
 'Str' | <ClassName>

ArrayClassType is
 'Str[]' | <ClassName>'[]'

ScalarType is
 ScalarPrimitiveType | ScalarClassType

ArrayType is
 ArrayPrimitiveType | ArrayClassType

Visibility is
 'public' | 'private'

Value is
 NumericLiteral | StringLiteral | BoolLiteral

StringLiteral is
 '"' CharOrSpecialChar* '"'

CharOrSpecialChar is
 Char |
 SpecialChar

Char is
 any printable character

SpecialChar is
 '\n' | '\"' |'\\' |'\t' (whatever is listed in APlist plus the \t)

NumericLiteral is
 IntLiteral | RealLiteral

IntLiteral is
 Digit+

BoolLiteral is
 'true' | 'false'

RealLiteral is
 Digit+ '.' Digit+

 NOTE: There is at least one Digit both before and after the decimal point ('.').

Name is
 Letter LetterDigitOrUnderscore*

RULE: A Name, ignoring the case, shall not be the same as a reserved word.

RULE: A Name, ignoring the case, shall not be the same as any other name.

RULE: A Name shall not end with an Underscore.

LetterDigitOrUnderscore is
 Letter |
 Digit |
 Underscore

Letter is
 'A'-'Z' | 'a'-'z'

 NOTE: 'A'-'Z' means all the characters between A and Z inclusive and
 'a'-'z' means all the characters between a and z inclusive.

Digit is
 '0'-'9'

 NOTE: '0'-'9' means all the characters between 0 and 9 inclusive.

Underscore is
 '_'

LocalArrayMember is
 <ArrayName> '[' <ArrayIndexExpr> ']'

 RULE: The ArrayIndexExpr shall be of type ScalarType.

 RULE: The type of the ArrayIndexExpr shall be int.

 RULE:

PublicClassArrayMember is
 <BoxName> '.' <PublicArrayName> '[' <ArrayIndexExpr> ']'

 RULE: The ArrayIndexExpr shall be of type ScalarType.

 RULE: The type of the ArrayIndexExpr shall be int.

 RULE: 

Expr is
 Expr BinaryBoolOp Expr | 
 Expr BinaryAddOp Expr | 
 Expr BinaryMinusOp Expr | 
 Expr BinaryMultDivOp Expr | 
 Expr BinaryModOp Expr | 
 '(' Expr BinaryRelOp Expr ')' | 
 UnaryNotOp Expr | 
 UnaryMinusOp Expr | 
 TypeMethodReference | 
 ArrayMember |
 PublicClassBox |
 BoxOrSlotName |
 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,
 either NumericType or String.

 RULE: The Expr before and after the BinaryMinusOp shall be of the same type.

 RULE: The Expr before and after the BinaryMinusOp shall be NumericType.

 RULE: The Expr before and after the BinaryMultDivOp shall be of the same type.

 RULE: The Expr before and after the BinaryMultDivOp shall be NumericType.

 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.

 RULE: The Expr before and after the BinaryRelOp shall be NumericType.

 RULE: The Expr after a UnaryBoolOp shall be of type bool.

 RULE: The Expr after a UnaryMinusOp shall be NumericType.

 RULE: All boxes shall be set before being used in an Expr.

Lhs is
 LocalArrayMember |
 BoxName

 NOTE: Unlike Java, a public class box cannot be the Lhs.

BoxOrSlotName is
 Name

 RULE: Unless being used in an ArgExprList, the type of the BoxOrSlotName shall be 
 of type ScalarType.

 NOTE: If inside a class, a BoxOrSlotName can be the name of a ClassBox, a MethodBox
 for the current method, or a Slot name for the current method.
 If inside a method but not inside a class, a BoxOrSlotName can be the name of a MethodBox
 for the current method, or a Slot name for the current method.
 If not inside a method (thus not inside a class), a BoxOrSlotName can be the name of a Box.

PublicClassBox is
 <BoxName> '.' <PublicClassBoxName>

TypeMethodReference is
 LocalTypeMethodReference |
 ClassPublicTypeMethodReference |
 IntrinsicStaticTypeMethodReference

LocalTypeMethodReference is
 <TypeMethodName> '(' <ArgExprList>? ')'

 RULE: The TypeMethodName shall be declared in the same program as this reference

 RULE: For rules on ArgExprList, see rules under the CallLocalVoidMethodCommand production.

ClassPublicTypeMethodReference is
 <BoxName> '.' <TypeMethodName> '(' <ArgExprList>? ')'

 RULE: The BoxName shall be declared with a type of a class.

 RULE: The TypeMethodName shall be declared as public in the
 class specified by the type of the BoxName

 RULE: For rules on ArgExprList, see rules under the CallLocalVoidMethodCommand production.

IntrinsicStaticTypeMethodReference is
 <ClassName> '.' <StaticTypeMethodName> '(' <ArgExprList>? ')'

 RULE: For rules on ArgExprList, see rules under the CallLocalVoidMethodCommand production.

BinaryBoolOp is
 '&&' | '||'

BinaryAddOp is
 '+'

BinaryMinusOp is
 '-'

BinaryMultDivOp is
 '*' | '/'

BinaryModOp is
 '%'

BinaryRelOp is
 '<' | '<=' | '>' | '>=' | '==' | '!='

UnaryNotOp is
 'not'

UnaryMinusOp is '-'

IfCommand is
 'if' '(' <ConditionExpr> ')' '{'

 RULE: The type of the ConditionExpr shall be boolean.

 RULE: The ConditionExpr shall be of type ScalarType.

ElseIfCommand is
 '}' 'else' 'if' '(' <ConditionExpr> ')' '{'

 RULE: The type of the ConditionExpr shall be boolean.

 RULE: The ConditionExpr shall be of type ScalarType.

 NOTE: The '}' shall start a new line, and as with all commands the command
 can span as many lines as the author desires.

ElseCommand is
 '}' 'else' '{'

 NOTE: The '}' shall start a new line, and as with all commands the command
 can span as many lines as the author desires.

-----------------------------------------------------------------------------------
Semantic Rules:
1. Types.
  JJ is a strongly-typed language.  No automatic type conversions will be 
  performed.  For example, converting an integer to a double can be
  accomplished by referencing the intrinsic static typed method intToDouble
  as in

   double1 = JJS.intToDouble(int1);

2. Whitespace.
  The first word of a Command shall be the first word on a line.  All other
  whitespace rules follow those of Java (look these up and put them here).

3. Initialization.
  Scalar boxes are not automatically initialized.  Array boxes are initialized
  according to the rules of Java (look these up and put them here).
  All variables shall be explicitly set before being used in an expression.

4. Operator Precedence.
  The precedence of operators is the same as the those in Java.