Class Parser

    • Field Detail

      • scanner

        private final Scanner scanner
      • MODIFIER_NAMES

        private static final java.lang.String[] MODIFIER_NAMES
      • MODIFIER_CODES

        private static final short[] MODIFIER_CODES
      • MUTUALLY_EXCLUSIVE_MODIFIER_CODES

        private static final short[] MUTUALLY_EXCLUSIVE_MODIFIER_CODES
      • BASIC_TYPE_NAMES

        private static final java.lang.String[] BASIC_TYPE_NAMES
      • BASIC_TYPE_CODES

        private static final int[] BASIC_TYPE_CODES
      • optionalWarningHandler

        private WarningHandler optionalWarningHandler
    • Constructor Detail

      • Parser

        public Parser​(Scanner scanner)
    • Method Detail

      • getScanner

        public Scanner getScanner()
        Returns:
        The scanner that produces the tokens for this parser.
      • parseQualifiedIdentifier

        public java.lang.String[] parseQualifiedIdentifier()
                                                    throws CompileException,
                                                           java.io.IOException
           QualifiedIdentifier := Identifier { '.' Identifier }
         
        Throws:
        CompileException
        java.io.IOException
      • parsePackageMemberTypeDeclaration

        public Java.PackageMemberTypeDeclaration parsePackageMemberTypeDeclaration()
                                                                            throws CompileException,
                                                                                   java.io.IOException
           PackageMemberTypeDeclaration :=
                     ModifiersOpt 'class' ClassDeclarationRest |
                     ModifiersOpt 'interface' InterfaceDeclarationRest
         
        Throws:
        CompileException
        java.io.IOException
      • parseModifiers

        public Java.Modifiers parseModifiers()
                                      throws CompileException,
                                             java.io.IOException
           ModifiersAndAnnotations := { 'public' | 'protected' | 'private' | 'static' | 'abstract' | 'final' | 'native'
                   | 'synchronized' | 'transient' | 'volatile' | 'strictfp' | Annotation }
         
        Throws:
        CompileException
        java.io.IOException
      • parseAnnotation

        private Java.Annotation parseAnnotation()
                                         throws CompileException,
                                                java.io.IOException
           Annotation :=
                   MarkerAnnotation             // JLS7 9.7.2
                   | SingleElementAnnotation    // JLS7 9.7.3
                   | NormalAnnotation           // JLS7 9.7.1
        
           MarkerAnnotation        := '@' Identifier
        
           SingleElementAnnotation := '@' Identifier '(' ElementValue ')'
        
           NormalAnnotation        := '@' TypeName '(' ElementValuePairsOpt ')'
        
           ElementValuePairsOpt    := [ ElementValuePair { ',' ElementValuePair } ]
         
        Throws:
        CompileException
        java.io.IOException
      • parseElementValueArrayInitializer

        private Java.ElementValue parseElementValueArrayInitializer()
                                                             throws CompileException,
                                                                    java.io.IOException
           ElementValueArrayInitializer := '{' { ElementValue | ',' } '}'
         
        Throws:
        CompileException
        java.io.IOException
      • parseClassBodyDeclaration

        public void parseClassBodyDeclaration​(Java.ClassDeclaration classDeclaration)
                                       throws CompileException,
                                              java.io.IOException
           ClassBodyDeclaration :=
             ';' |
             ModifiersOpt (
               Block |                                    // Instance (JLS7 8.6) or static initializer (JLS7 8.7)
               'void' Identifier MethodDeclarationRest |
               'class' ClassDeclarationRest |
               'interface' InterfaceDeclarationRest |
               ConstructorDeclarator |
               Type Identifier (
                 MethodDeclarationRest |
                 FieldDeclarationRest ';'
               )
             )
        
         
        Throws:
        CompileException
        java.io.IOException
      • parseInterfaceBody

        public void parseInterfaceBody​(Java.InterfaceDeclaration interfaceDeclaration)
                                throws CompileException,
                                       java.io.IOException
           InterfaceBody := '{' {
             ';' |
             ModifiersOpt (
               'void' Identifier MethodDeclarationRest |
               'class' ClassDeclarationRest |
               'interface' InterfaceDeclarationRest |
               Type Identifier (
                 MethodDeclarationRest |
                 FieldDeclarationRest
               )
             )
           } '}'
         
        Throws:
        CompileException
        java.io.IOException
      • parseConstructorDeclarator

        public Java.ConstructorDeclarator parseConstructorDeclarator​(java.lang.String optionalDocComment,
                                                                     Java.Modifiers modifiers)
                                                              throws CompileException,
                                                                     java.io.IOException
           ConstructorDeclarator :=
             Identifier
             FormalParameters
             [ 'throws' ReferenceTypeList ]
             '{'
               [ 'this' Arguments ';' | 'super' Arguments ';' | Primary '.' 'super' Arguments ';' ]
               BlockStatements
             '}'
         
        Throws:
        CompileException
        java.io.IOException
      • parseMethodDeclarationRest

        public Java.MethodDeclarator parseMethodDeclarationRest​(java.lang.String optionalDocComment,
                                                                Java.Modifiers modifiers,
                                                                Java.Type type,
                                                                java.lang.String name)
                                                         throws CompileException,
                                                                java.io.IOException
           MethodDeclarationRest :=
             FormalParameters
             { '[' ']' }
             [ 'throws' ReferenceTypeList ]
             ( ';' | MethodBody )
         
        Throws:
        CompileException
        java.io.IOException
      • parseBlockStatement

        public Java.BlockStatement parseBlockStatement()
                                                throws CompileException,
                                                       java.io.IOException
           BlockStatement := { Identifier ':' } (
             ( Modifiers Type | ModifiersOpt BasicType ) VariableDeclarators ';' |
             'class' ... |
             Statement |
             'final' Type VariableDeclarators ';' |
             Expression ';' |
             Expression VariableDeclarators ';'   (1)
           )
         
        (1) "Expression" must pose a type, and has optional trailing brackets.
        Throws:
        CompileException
        java.io.IOException
      • parseFieldDeclarationRest

        public Java.VariableDeclarator[] parseFieldDeclarationRest​(java.lang.String name)
                                                            throws CompileException,
                                                                   java.io.IOException
           FieldDeclarationRest :=
             VariableDeclaratorRest
             { ',' VariableDeclarator }
         
        Throws:
        CompileException
        java.io.IOException
      • parseVariableDeclaratorRest

        public Java.VariableDeclarator parseVariableDeclaratorRest​(java.lang.String name)
                                                            throws CompileException,
                                                                   java.io.IOException
           VariableDeclaratorRest := { '[' ']' } [ '=' VariableInitializer ]
         
        Used by field declarations and local variable declarations.
        Throws:
        CompileException
        java.io.IOException
      • parseStatement

        public Java.Statement parseStatement()
                                      throws CompileException,
                                             java.io.IOException
           Statement :=
             LabeledStatement |
             Block |
             IfStatement |
             ForStatement |
             WhileStatement |
             DoStatement |
             TryStatement |
             'switch' ... |
             'synchronized' ... |
             ReturnStatement |
             ThrowStatement |
             BreakStatement |
             ContinueStatement |
             EmptyStatement |
             ExpressionStatement
         
        Throws:
        CompileException
        java.io.IOException
      • parseForStatement

        public Java.Statement parseForStatement()
                                         throws CompileException,
                                                java.io.IOException
           ForStatement :=
             'for' '(' [ ForInit ] ';' [ Expression ] ';' [ ExpressionList ] ')' Statement
             | 'for' '(' FormalParameter ':' Expression ')' Statement
        
           ForInit :=
             Modifiers Type VariableDeclarators
             | ModifiersOpt BasicType VariableDeclarators
             | Expression VariableDeclarators              (1)
             | Expression { ',' Expression }
         
        (1) "Expression" must pose a type.
        Throws:
        CompileException
        java.io.IOException
      • parseTryStatement

        public Java.Statement parseTryStatement()
                                         throws CompileException,
                                                java.io.IOException
           TryStatement :=
             'try' Block Catches [ Finally ] |
             'try' Block Finally
        
           Catches := CatchClause { CatchClause }
        
           CatchClause := 'catch' '(' FormalParameter ')' Block
        
           Finally := 'finally' Block
         
        Throws:
        CompileException
        java.io.IOException
      • parseSwitchStatement

        public Java.Statement parseSwitchStatement()
                                            throws CompileException,
                                                   java.io.IOException
           SwitchStatement :=
             'switch' '(' Expression ')' '{' { SwitchLabels BlockStatements } '}'
        
           SwitchLabels := SwitchLabels { SwitchLabels }
        
           SwitchLabel := 'case' Expression ':' | 'default' ':'
         
        Throws:
        CompileException
        java.io.IOException
      • parseSynchronizedStatement

        public Java.Statement parseSynchronizedStatement()
                                                  throws CompileException,
                                                         java.io.IOException
           SynchronizedStatement :=
             'synchronized' '(' expression ')' Block
         
        Throws:
        CompileException
        java.io.IOException
      • parseType

        public Java.Type parseType()
                            throws CompileException,
                                   java.io.IOException
           Type := (
             'byte' | 'short' | 'char' | 'int' | 'long' |
             'float' | 'double' | 'boolean' |
             ReferenceType
           ) { '[' ']' }
         
        Throws:
        CompileException
        java.io.IOException
      • parseTypeParameter

        private Java.TypeParameter parseTypeParameter()
                                               throws CompileException,
                                                      java.io.IOException
           TypeParameter := identifier [ 'extends' ( identifier | ReferenceType { '&' ReferenceType }
         
        Throws:
        CompileException
        java.io.IOException
      • parseTypeArgument

        private Java.TypeArgument parseTypeArgument()
                                             throws CompileException,
                                                    java.io.IOException
           TypeArgument :=
             ReferenceType { '[' ']' }    <= The optional brackets are mising in JLS7, section 18!?
             | BasicType '[' ']' { '[' ']' }
             | '?' extends ReferenceType
             | '?' super ReferenceType
         
        Throws:
        CompileException
        java.io.IOException
      • parseAssignmentExpression

        public Java.Atom parseAssignmentExpression()
                                            throws CompileException,
                                                   java.io.IOException
           AssignmentExpression :=
             ConditionalExpression [ AssignmentOperator AssignmentExpression ]
        
           AssignmentOperator :=
             '=' | '*=' | '/=' | '%=' | '+=' | '-=' | '<<=' |
             '>>=' | '>>>=' | '&=' | '^=' | '|='
         
        Throws:
        CompileException
        java.io.IOException
      • parseConditionalExpression

        public Java.Atom parseConditionalExpression()
                                             throws CompileException,
                                                    java.io.IOException
           ConditionalExpression :=
             ConditionalOrExpression [ '?' Expression ':' ConditionalExpression ]
         
        Throws:
        CompileException
        java.io.IOException
      • parseConditionalOrExpression

        public Java.Atom parseConditionalOrExpression()
                                               throws CompileException,
                                                      java.io.IOException
           ConditionalOrExpression :=
             ConditionalAndExpression { '||' ConditionalAndExpression ]
         
        Throws:
        CompileException
        java.io.IOException
      • parseConditionalAndExpression

        public Java.Atom parseConditionalAndExpression()
                                                throws CompileException,
                                                       java.io.IOException
           ConditionalAndExpression :=
             InclusiveOrExpression { '&&' InclusiveOrExpression }
         
        Throws:
        CompileException
        java.io.IOException
      • parseInclusiveOrExpression

        public Java.Atom parseInclusiveOrExpression()
                                             throws CompileException,
                                                    java.io.IOException
           InclusiveOrExpression :=
             ExclusiveOrExpression { '|' ExclusiveOrExpression }
         
        Throws:
        CompileException
        java.io.IOException
      • parseExclusiveOrExpression

        public Java.Atom parseExclusiveOrExpression()
                                             throws CompileException,
                                                    java.io.IOException
           ExclusiveOrExpression :=
             AndExpression { '^' AndExpression }
         
        Throws:
        CompileException
        java.io.IOException
      • parseAndExpression

        public Java.Atom parseAndExpression()
                                     throws CompileException,
                                            java.io.IOException
           AndExpression :=
             EqualityExpression { '&' EqualityExpression }
         
        Throws:
        CompileException
        java.io.IOException
      • parseEqualityExpression

        public Java.Atom parseEqualityExpression()
                                          throws CompileException,
                                                 java.io.IOException
           EqualityExpression :=
             RelationalExpression { ( '==' | '!=' ) RelationalExpression }
         
        Throws:
        CompileException
        java.io.IOException
      • parseRelationalExpression

        public Java.Atom parseRelationalExpression()
                                            throws CompileException,
                                                   java.io.IOException
           RelationalExpression :=
             ShiftExpression {
               'instanceof' ReferenceType
               | '<' ShiftExpression [ { ',' TypeArgument } '>' ]
               | '<' TypeArgument [ { ',' TypeArgument } '>' ]
               | ( '>' | '<=' | '>=' ) ShiftExpression
             }
         
        Throws:
        CompileException
        java.io.IOException
      • parseShiftExpression

        public Java.Atom parseShiftExpression()
                                       throws CompileException,
                                              java.io.IOException
           ShiftExpression :=
             AdditiveExpression { ( '<<' | '>>' | '>>>' ) AdditiveExpression }
         
        Throws:
        CompileException
        java.io.IOException
      • parseAdditiveExpression

        public Java.Atom parseAdditiveExpression()
                                          throws CompileException,
                                                 java.io.IOException
           AdditiveExpression :=
             MultiplicativeExpression { ( '+' | '-' ) MultiplicativeExpression }
         
        Throws:
        CompileException
        java.io.IOException
      • parseMultiplicativeExpression

        public Java.Atom parseMultiplicativeExpression()
                                                throws CompileException,
                                                       java.io.IOException
           MultiplicativeExpression :=
             UnaryExpression { ( '*' | '/' | '%' ) UnaryExpression }
         
        Throws:
        CompileException
        java.io.IOException
      • parseUnaryExpression

        public Java.Atom parseUnaryExpression()
                                       throws CompileException,
                                              java.io.IOException
           UnaryExpression :=
             { PrefixOperator } Primary { Selector } { PostfixOperator }
        
           PrefixOperator := '++' | '--' | '+' | '-' | '~' | '!'
        
           PostfixOperator := '++' | '--'
         
        Throws:
        CompileException
        java.io.IOException
      • parsePrimary

        public Java.Atom parsePrimary()
                               throws CompileException,
                                      java.io.IOException
           Primary :=
             CastExpression |                        // CastExpression 15.16
             '(' Expression ')' |                    // ParenthesizedExpression 15.8.5
             Literal |                               // Literal 15.8.1
             Name |                                  // AmbiguousName
             Name Arguments |                        // MethodInvocation
             Name '[]' { '[]' } |                    // ArrayType 10.1
             Name '[]' { '[]' } '.' 'class' |        // ClassLiteral 15.8.2
             'this' |                                // This 15.8.3
             'this' Arguments |                      // Alternate constructor invocation 8.8.5.1
             'super' Arguments |                     // Unqualified superclass constructor invocation 8.8.5.1
             'super' '.' Identifier |                // SuperclassFieldAccess 15.11.2
             'super' '.' Identifier Arguments |      // SuperclassMethodInvocation 15.12.4.9
             NewClassInstance |
             NewAnonymousClassInstance |             // ClassInstanceCreationExpression 15.9
             NewArray |                              // ArrayCreationExpression 15.10
             NewInitializedArray |                   // ArrayInitializer 10.6
             BasicType { '[]' } |                    // Type
             BasicType { '[]' } '.' 'class' |        // ClassLiteral 15.8.2
             'void' '.' 'class'                      // ClassLiteral 15.8.2
        
           CastExpression :=
             '(' PrimitiveType { '[]' } ')' UnaryExpression |
             '(' Expression ')' UnaryExpression
        
           NewClassInstance := 'new' ReferenceType Arguments
        
           NewAnonymousClassInstance := 'new' ReferenceType Arguments [ ClassBody ]
        
           NewArray := 'new' Type DimExprs { '[]' }
        
           NewInitializedArray := 'new' ArrayType ArrayInitializer
         
        Throws:
        CompileException
        java.io.IOException
      • parseSelector

        public Java.Atom parseSelector​(Java.Atom atom)
                                throws CompileException,
                                       java.io.IOException
           Selector :=
             '.' Identifier |                               // FieldAccess 15.11.1
             '.' Identifier Arguments |                     // MethodInvocation
             '.' 'this'                                     // QualifiedThis 15.8.4
             '.' 'super' Arguments                          // Qualified superclass constructor invocation (JLS7 8.8.7.1)
             '.' 'super' '.' Identifier |                   // SuperclassFieldReference (JLS7 15.11.2)
             '.' 'super' '.' Identifier Arguments |         // SuperclassMethodInvocation (JLS7 15.12.3)
             '.' 'new' Identifier Arguments [ ClassBody ] | // QualifiedClassInstanceCreationExpression  15.9
             '.' 'class'
             '[' Expression ']'                             // ArrayAccessExpression 15.13
         
        Throws:
        CompileException
        java.io.IOException
      • parseLiteral

        public Java.Rvalue parseLiteral()
                                 throws CompileException,
                                        java.io.IOException
           Literal :=
             IntegerLiteral
             | FloatingPointLiteral
             | BooleanLiteral
             | CharacterLiteral
             | StringLiteral
             | NullLiteral
         
        Throws:
        CompileException
        java.io.IOException
      • location

        public Location location()
        Returns:
        The location of the first character of the previously peek()ed or read() token
      • peekNextButOne

        public Scanner.Token peekNextButOne()
                                     throws CompileException,
                                            java.io.IOException
        Returns:
        The next-but-one token, but consumes neither the next nor the next-but-one token
        Throws:
        CompileException
        java.io.IOException
      • peek

        public boolean peek​(java.lang.String suspected)
                     throws CompileException,
                            java.io.IOException
        Returns:
        Whether the value of the next token equals suspected; does not consume the next token
        Throws:
        CompileException
        java.io.IOException
      • peek

        public int peek​(java.lang.String[] suspected)
                 throws CompileException,
                        java.io.IOException
        Checks whether the value of the next token equals any of the suspected; does not consume the next token.
        Returns:
        The index of the first of the suspected that equals the value of the next token, or -1 if the value of the next token equals none of the suspected
        Throws:
        CompileException
        java.io.IOException
      • peek

        public int peek​(int[] suspected)
                 throws CompileException,
                        java.io.IOException
        Checks whether the type of the next token is any of the suspected; does not consume the next token.
        Returns:
        The index of the first of the suspected types that is the next token's type, or -1 if the type of the next token is none of the suspected types
        Throws:
        CompileException
        java.io.IOException
      • peekNextButOne

        public boolean peekNextButOne​(java.lang.String suspected)
                               throws CompileException,
                                      java.io.IOException
        Returns:
        Whether the value of the next-but-one token equals the suspected; consumes neither the next nor the next-but-one token
        Throws:
        CompileException
        java.io.IOException
      • read

        public void read​(java.lang.String expected)
                  throws CompileException,
                         java.io.IOException
        Verifies that the value of the next token equals expected, and consumes the token.
        Throws:
        CompileException - The value of the next token does not equal expected (this includes the case that the scanner is at end-of-input)
        java.io.IOException
      • read

        public int read​(java.lang.String[] expected)
                 throws CompileException,
                        java.io.IOException
        Verifies that the value of the next token equals one of the expected, and consumes the token.
        Returns:
        The index of the consumed token within expected
        Throws:
        CompileException - The value of the next token does not equal any of the expected (this includes the case where the scanner is at end-of-input)
        java.io.IOException
      • peekRead

        public boolean peekRead​(java.lang.String suspected)
                         throws CompileException,
                                java.io.IOException
        Returns:
        Whether the value of the next token equals the suspected; if so, it consumes the next token
        Throws:
        CompileException
        java.io.IOException
      • peekRead

        public int peekRead​(java.lang.String[] values)
                     throws CompileException,
                            java.io.IOException
        Returns:
        -1 iff the next token is none of values
        Throws:
        CompileException
        java.io.IOException
      • peekEof

        public boolean peekEof()
                        throws CompileException,
                               java.io.IOException
        Returns:
        Whether the scanner is at end-of-input
        Throws:
        CompileException
        java.io.IOException
      • peekIdentifier

        public java.lang.String peekIdentifier()
                                        throws CompileException,
                                               java.io.IOException
        Returns:
        null iff the next token is not an identifier, otherwise the value of the identifier token
        Throws:
        CompileException
        java.io.IOException
      • peekLiteral

        public boolean peekLiteral()
                            throws CompileException,
                                   java.io.IOException
        Returns:
        Whether the next token is a literal
        Throws:
        CompileException
        java.io.IOException
      • readIdentifier

        public java.lang.String readIdentifier()
                                        throws CompileException,
                                               java.io.IOException
        Returns:
        The value of the next token, which is an indentifier
        Throws:
        CompileException - The next token is not an identifier
        java.io.IOException
      • readOperator

        public java.lang.String readOperator()
                                      throws CompileException,
                                             java.io.IOException
        Returns:
        The value of the next token, which is an operator
        Throws:
        CompileException - The next token is not an operator
        java.io.IOException
      • indexOf

        private static int indexOf​(java.lang.String[] strings,
                                   java.lang.String subject)
      • indexOf

        private static int indexOf​(int[] values,
                                   int subject)
      • verifyStringIsConventionalPackageName

        private void verifyStringIsConventionalPackageName​(java.lang.String s,
                                                           Location loc)
                                                    throws CompileException
        Issue a warning if the given string does not comply with the package naming conventions.
        Throws:
        CompileException
      • verifyIdentifierIsConventionalClassOrInterfaceName

        private void verifyIdentifierIsConventionalClassOrInterfaceName​(java.lang.String id,
                                                                        Location loc)
                                                                 throws CompileException
        Issue a warning if the given identifier does not comply with the class and interface type naming conventions (JLS7 6.8.2).
        Throws:
        CompileException
      • verifyIdentifierIsConventionalMethodName

        private void verifyIdentifierIsConventionalMethodName​(java.lang.String id,
                                                              Location loc)
                                                       throws CompileException
        Issue a warning if the given identifier does not comply with the method naming conventions (JLS7 6.8.3).
        Throws:
        CompileException
      • verifyIdentifierIsConventionalFieldName

        private void verifyIdentifierIsConventionalFieldName​(java.lang.String id,
                                                             Location loc)
                                                      throws CompileException
        Issue a warning if the given identifier does not comply with the field naming conventions (JLS7 6.8.4) and constant naming conventions (JLS7 6.8.5).
        Throws:
        CompileException
      • verifyIdentifierIsConventionalLocalVariableOrParameterName

        private void verifyIdentifierIsConventionalLocalVariableOrParameterName​(java.lang.String id,
                                                                                Location loc)
                                                                         throws CompileException
        Issue a warning if the given identifier does not comply with the local variable and parameter naming conventions (JLS7 6.8.6).
        Throws:
        CompileException
      • setWarningHandler

        public void setWarningHandler​(WarningHandler optionalWarningHandler)
        By default, warnings are discarded, but an application my install a WarningHandler.

        Notice that there is no Parser.setErrorHandler() method, but parse errors always throw a CompileException. The reason being is that there is no reasonable way to recover from parse errors and continue parsing, so there is no need to install a custom parse error handler.

        Parameters:
        optionalWarningHandler - null to indicate that no warnings be issued
      • join

        private static java.lang.String join​(java.lang.String[] sa,
                                             java.lang.String separator)