2

I am trying to generate a CPP Parser using ANTLR4 grammar and

org.antlr.v4.Tool

is giving me the NullPointerException. I don't get it. If there is a problem with my grammar, then it should have stated it with a meaningful error message. One more strange thing is, although I created this grammar in vim, when I opened it in ANTLRWorks 2.1, its Navigator pane shows "Please Wait..." and nothing else. Here is my grammar given below:-

grammar CppGrammar;

cpp: (INCLUDE_STAT | funcDefinition)*;

INCLUDE_STAT: '#' 'include' (LT ID+ '.h'? GT | '"' ID+ '.h'? '"');

expr: assignmentExpr
    | expr COMMA assignmentExpr;

assignmentExpr: conditionalExpr
              | logicalOrExpr ASSIGNMENTOP assignmentExpr
              | throwExpr;

conditionalExpr: logicalOrExpr
               | logicalOrExpr QMARK expr COLON assignmentExpr;

logicalOrExpr: logicalAndExpr
             | logicalOrExpr OR_OP logicalAndExpr;

ASSIGNMENTOP: EQ
            | MULT_EQ
            | DIV_EQ
            | MOD_EQ
        | PLUS_EQ
        | MINUS_EQ
        | GT_GT_EQ
        | LT_LT_EQ
        | AND_EQ
        | EXP_EQ
        | EXC_EQ;

throwExpr: THROW assignmentExpr?;

logicalAndExpr: inclusiveOrExpr
              | logicalAndExpr AND_OP inclusiveOrExpr;

inclusiveOrExpr: exclusiveOrExpr
               | inclusiveOrExpr INC_OR_OP exclusiveOrExpr;

exclusiveOrExpr: andExpr
               | exclusiveOrExpr EX_OR_OP andExpr;

andExpr: equalityExpr
       | andExpr AND equalityExpr;

equalityExpr: relationalExpr
            | equalityExpr EQUALITY relationalExpr
        | equalityExpr EXC_EQ relationalExpr;

relationalExpr: shiftExpr
              | relationalExpr LT shiftExpr
          | relationalExpr GT shiftExpr
          | relationalExpr LT_EQ shiftExpr
          | relationalExpr GT_EQ shiftExpr;

shiftExpr: additiveExpr
         | shiftExpr LT_LT additiveExpr
     | shiftExpr GT_GT additiveExpr;

additiveExpr: multiplicativeExpr
            | additiveExpr PLUS multiplicativeExpr
        | additiveExpr MINUS multiplicativeExpr;

multiplicativeExpr: pmExpr
                  | multiplicativeExpr MULT pmExpr
          | multiplicativeExpr DIV pmExpr
          | multiplicativeExpr MOD pmExpr;

pmExpr: castExpr
      | pmExpr DOT_MULT castExpr
      | pmExpr MINUS_GT_MULT castExpr;

castExpr: unaryExpr
        | LPARAN typeId RPARAN castExpr;

unaryExpr: postfixExpr
         | PLUS_PLUS castExpr
     | MINUS_MINUS castExpr
     | UNARYOP castExpr
     | SIZEOF unaryExpr
     | SIZEOF LPARAN typeId RPARAN
     | newExpr
     | delExpr;

typeId: typeSpecifierSeq abstractDeclarator?;

postfixExpr: primaryExpr
           | postfixExpr LSQRBRAC expr RSQRBRAC
       | postfixExpr LPARAN exprList? RPARAN
       | simpleTypeSpecifier LPARAN exprList? RPARAN
       | TYPENAME COLON_COLON? nestedNameSpecifier ID LPARAN exprList? RPARAN
       | TYPENAME COLON_COLON? nestedNameSpecifier TEMPLATE? templateId LPARAN exprList RPARAN
       | postfixExpr DOT TEMPLATE? idExpr
       | postfixExpr MINUS_GT TEMPLATE? idExpr
       | postfixExpr DOT pseudoDestructorName
       | postfixExpr MINUS_GT pseudoDestructorName
       | postfixExpr PLUS_PLUS
       | postfixExpr MINUS_MINUS
       | DYNAMIC_CAST LT typeId GT LPARAN expr RPARAN
       | STATIC_CAST LT typeId GT LPARAN expr RPARAN
       | REINTERPRET_CAST LT typeId GT LPARAN expr RPARAN
       | CONST_CAST LT typeId GT LPARAN expr RPARAN
       | TYPEID LPARAN expr RPARAN
       | TYPEID LPARAN typeId RPARAN;

newExpr: COLON_COLON? NEW newPlacement? newTypeId newInitializer?
       | COLON_COLON? NEW newPlacement? LPARAN typeId RPARAN newInitializer?;

delExpr: COLON_COLON? DELETE castExpr
       | COLON_COLON? DELETE LSQRBRAC RSQRBRAC castExpr;

typeSpecifierSeq: typeSpecifier typeSpecifierSeq?;

abstractDeclarator: ptrOp abstractDeclarator?
                  | directAbstractDeclarator;

primaryExpr: LITERAL
           | THIS
       | LPARAN expr RPARAN
       | idExpr;

exprList: assignmentExpr
        | exprList COMMA assignmentExpr;

simpleTypeSpecifier: COLON_COLON? nestedNameSpecifier? typeName
                   | COLON_COLON? nestedNameSpecifier TEMPLATE templateId
           | CHAR
           | WCHAR_T
           | BOOL
           | SHORT
           | INT
           | LONG
           | SIGNED
           | UNSIGNED
           | FLOAT
           | DOUBLE
           | VOID;

nestedNameSpecifier: classOrNamespaceName COLON_COLON nestedNameSpecifier?
                   | classOrNamespaceName COLON_COLON TEMPLATE nestedNameSpecifier;

templateId: templateName LT templateArgumentList? GT;

templateName: ID;

idExpr: unqualifiedId
      | qualifiedId;

pseudoDestructorName: COLON_COLON? nestedNameSpecifier? typeName COLON_COLON NEG typeName
                    | COLON_COLON? nestedNameSpecifier TEMPLATE templateId COLON_COLON NEG typeName
            | COLON_COLON? nestedNameSpecifier? NEG typeName;

newPlacement: LPARAN exprList RPARAN;

newTypeId: typeSpecifierSeq newDeclarator?;

newInitializer: LPARAN exprList? RPARAN;

typeSpecifier: simpleTypeSpecifier
             | classSpecifier
         | enumSpecifier
         | elaboratedTypeSpecifier
         | cvQualifier;

//directAbstractDeclarator: directAbstractDeclarator? LPARAN parameterDeclarationClause RPARAN cvQualifierSeq? exceptionSpecification?
//                        | directAbstractDeclarator? LSQRBRAC constantExpr RSQRBRAC
//          | LPARAN abstractDeclarator RPARAN;

directAbstractDeclarator
   :   directAbstractDeclarator LPARAN parameterDeclarationClause RPARAN cvQualifierSeq? exceptionSpecification?
   |   directAbstractDeclarator LSQRBRAC constantExpr? RSQRBRAC
   |   LPARAN parameterDeclarationClause RPARAN cvQualifierSeq? exceptionSpecification?
   |   LSQRBRAC constantExpr? RSQRBRAC
   |   LPARAN abstractDeclarator RPARAN
;    

typeName: className
        | enumName
    | typedefName;

classOrNamespaceName: className
                    | namespaceName;

templateArgumentList: templateArgument
                    | templateArgumentList COMMA templateArgument;

unqualifiedId: ID
             | operatorFuncId
         | conversionFuncId
         | NEG className
         | templateId;

qualifiedId: COLON_COLON? nestedNameSpecifier TEMPLATE? unqualifiedId
           | COLON_COLON ID
       | COLON_COLON operatorFuncId
       | COLON_COLON templateId;

newDeclarator: ptrOp newDeclarator?
             | directNewDeclarator;

classSpecifier: classHead LBRACKET memberSpecification? RBRACKET;

enumSpecifier: ENUM ID? LBRACKET enumList? RBRACKET;

elaboratedTypeSpecifier: CLASS_KEY COLON_COLON nestedNameSpecifier? ID
                       | ENUM COLON_COLON? nestedNameSpecifier? ID
               | TYPENAME COLON_COLON? nestedNameSpecifier ID
               | TYPENAME COLON_COLON? nestedNameSpecifier TEMPLATE? templateId;

cvQualifier: CONST
           | VOLATILE;

parameterDeclarationClause: parameterDeclarationList? DOT_DOT_DOT?
                          | parameterDeclarationList COMMA DOT_DOT_DOT;

cvQualifierSeq: cvQualifier cvQualifierSeq?;

exceptionSpecification: THROW LPARAN typeIdList RPARAN;

constantExpr: conditionalExpr;

className: ID
         | templateId;

typedefName: ID;

enumName: ID;

namespaceName: originalNamespaceName
             | namespaceAlias;

templateArgument: assignmentExpr
                | typeId
        | idExpr;

operatorFuncId: OPERATOR OP;

conversionFuncId: OPERATOR conversionTypeId;

directNewDeclarator: LSQRBRAC expr RSQRBRAC
                   | directNewDeclarator LSQRBRAC constantExpr RSQRBRAC;

classHead: CLASS_KEY ID? baseClause?
         | CLASS_KEY nestedNameSpecifier ID baseClause?
     | CLASS_KEY nestedNameSpecifier? templateId baseClause?;

CLASS_KEY: CLASS
        | 'struct'
    | 'union';

memberSpecification: memberDeclaration memberSpecification?
                   | ACCESS_SPECIFIER COLON memberSpecification?;

memberDeclaration: declSpecifierSeq? memberDeclaratorList? SEMI_COLON
                 | funcDefinition SEMI_COLON?
         | COLON_COLON? nestedNameSpecifier TEMPLATE? unqualifiedId SEMI_COLON
         | usingDeclaration
         | templateDeclaration;

enumList: enumDefinition
        | enumList COMMA enumDefinition;

enumDefinition: enum
              | enum EQ constantExpr;

enum: ID;

parameterDeclarationList: parameterDeclaration
                        | parameterDeclarationList COMMA parameterDeclaration;

parameterDeclaration: declSpecifierSeq declarator
                    | declSpecifierSeq declarator EQ assignmentExpr
            | declSpecifierSeq abstractDeclarator?
            | declSpecifierSeq abstractDeclarator? EQ assignmentExpr;

typeIdList: typeId
          | typeIdList COMMA typeId;

originalNamespaceName: ID;

namespaceAlias: ID;

conversionTypeId: typeSpecifierSeq conversionDeclarator?;

conversionDeclarator: ptrOp conversionDeclarator?;

baseClause: COLON baseSpecifierList;

baseSpecifierList: baseSpecifier
                 | baseSpecifierList COMMA baseSpecifier;

baseSpecifier: COLON_COLON? nestedNameSpecifier? className
             | VIRTUAL ACCESS_SPECIFIER? COLON_COLON? nestedNameSpecifier? className
         | ACCESS_SPECIFIER VIRTUAL? COLON_COLON? nestedNameSpecifier? className;

ACCESS_SPECIFIER: 'private'
               | 'protected'
           | 'public';

declSpecifierSeq: declSpecifierSeq? declSpecifier;

declSpecifier: STORAGE_CLASS_SPECIFIER
             | typeSpecifier
         | FUNC_SPECIFIER
         | FRIEND
         | TYPEDEF;

memberDeclaratorList: memberDeclarator
                    | memberDeclaratorList COMMA memberDeclarator;

memberDeclarator: declarator PURE_SPECIFIER?
                | declarator constantInitializer?
        | ID? COLON constantExpr;

funcDefinition: declSpecifierSeq? declarator ctorInitializer? funcBody
              | declSpecifierSeq? declarator funcTryBlock;

funcBody: compoundStatement;

funcTryBlock: TRY ctorInitializer? funcBody handlerSeq;

usingDeclaration: USING TYPENAME? COLON_COLON? nestedNameSpecifier unqualifiedId SEMI_COLON
                | USING COLON_COLON unqualifiedId SEMI_COLON;

templateDeclaration: EXPORT? TEMPLATE LT templateParameterList GT declaration;

templateParameterList: templateParameter
                     | templateParameterList COMMA templateParameter;

templateParameter: typeParameter
                 | parameterDeclaration;

typeParameter: CLASS ID?
             | CLASS ID? EQ typeId
         | TYPENAME ID?
         | TYPENAME ID? EQ typeId
         | TEMPLATE LT templateParameterList GT CLASS ID?
         | TEMPLATE LT templateParameterList GT CLASS ID? EQ idExpr;

declarator: directDeclarator
          | ptrOp declarator;

directDeclarator: declaratorId
                | directDeclarator LPARAN parameterDeclarationClause RPARAN cvQualifierSeq? exceptionSpecification?
        | directDeclarator LSQRBRAC constantExpr RSQRBRAC
        | LPARAN declarator RPARAN;

declaratorId: idExpr
            | COLON_COLON? nestedNameSpecifier? typeName;

STORAGE_CLASS_SPECIFIER: 'auto'
                     | 'register'
             | 'static'
             | EXTERN
             | 'mutable';

FUNC_SPECIFIER: 'inline'
             | VIRTUAL
         | 'explicit';

PURE_SPECIFIER: EQ '0';

constantInitializer: EQ constantExpr;

ctorInitializer: COLON memInitializerList;

memInitializerList: memInitializer
                  | memInitializer COMMA memInitializerList;

memInitializer: memInitializerId LPARAN exprList RPARAN;

memInitializerId: COLON_COLON? nestedNameSpecifier? className
                | ID;

compoundStatement: LBRACKET statementSeq? RBRACKET;

statementSeq: statement
            | statementSeq statement;

statement: labeledStatement
         | exprStatement
     | compoundStatement
     | selectionStatement
     | iterationStatement
     | jumpStatement
     | declarationStatement
     | tryBlock;

labeledStatement: ID COLON statement
                | CASE constantExpr COLON statement
        | DEFAULT COLON statement;

exprStatement: expr? SEMI_COLON;

selectionStatement: IF LPARAN condition RPARAN statement
                  | IF LPARAN condition RPARAN statement ELSE statement
          | SWITCH LPARAN condition RPARAN statement;

iterationStatement: WHILE LPARAN condition RPARAN statement
                  | DO statement WHILE LPARAN expr RPARAN SEMI_COLON
          | FOR LPARAN forInitStatement condition? SEMI_COLON expr? RPARAN statement;

jumpStatement: BREAK SEMI_COLON
             | CONTINUE SEMI_COLON
         | RETURN expr? SEMI_COLON
         | GOTO ID SEMI_COLON;

declarationStatement: blockDeclaration;

tryBlock: TRY compoundStatement handlerSeq;

condition: expr
         | typeSpecifierSeq declarator EQ assignmentExpr;

forInitStatement: exprStatement
                | simpleDeclaration;

simpleDeclaration: declSpecifierSeq? initDeclaratorList? SEMI_COLON;

initDeclaratorList: initDeclarator
                  | initDeclaratorList COMMA initDeclarator;

initDeclarator: declarator initializer?;

initializer: EQ initializerClause
           | LPARAN exprList RPARAN;

initializerClause: assignmentExpr
                 | LBRACKET initializerList COMMA? RBRACKET
         | LBRACKET RBRACKET;

initializerList: initializerClause
               | initializerList COMMA initializerClause;

blockDeclaration: simpleDeclaration
                | ASM_DEFINITION
        | namespaceAliasDefinition
        | usingDeclaration
        | usingDirective;

ASM_DEFINITION: 'asm' LPARAN STRING RPARAN SEMI_COLON;

namespaceAliasDefinition: NAMESPACE ID EQ qualifiedNamespaceSpecifier SEMI_COLON;

qualifiedNamespaceSpecifier: COLON_COLON? nestedNameSpecifier? namespaceName; 

usingDirective: USING NAMESPACE COLON_COLON? nestedNameSpecifier? namespaceName SEMI_COLON;

handlerSeq: handler handlerSeq?;

handler: CATCH LPARAN exceptionDeclaration RPARAN compoundStatement;

exceptionDeclaration: typeSpecifierSeq declarator
                    | typeSpecifierSeq abstractDeclarator
            | typeSpecifierSeq
            | DOT_DOT_DOT;

declaration: blockDeclaration
           | funcDefinition
       | templateDeclaration
       | explicitInstantiation
       | explicitSpecialization
       | linkageSpecification
       | namespaceDefinition;

explicitInstantiation: TEMPLATE declaration;

explicitSpecialization: TEMPLATE LT GT declaration;

linkageSpecification: EXTERN STRING LBRACKET declarationSeq RBRACKET
                    | EXTERN STRING declaration;

declarationSeq: declaration
              | declarationSeq declaration;

namespaceDefinition: namedNamespaceDefinition
                   | unnamedNamespaceDefinition;

namedNamespaceDefinition: originalNamespaceDefinition
                        | extensionNamespaceDefinition;

originalNamespaceDefinition: NAMESPACE ID LBRACKET namespaceBody RBRACKET; 

extensionNamespaceDefinition: NAMESPACE originalNamespaceName LBRACKET namespaceBody RBRACKET;

unnamedNamespaceDefinition: NAMESPACE LBRACKET namespaceBody RBRACKET;

namespaceBody: declarationSeq?;

UNARYOP: MULT
       | AND
       | PLUS
       | MINUS
       | EXC
       | NEG;

ptrOp: MULT cvQualifierSeq?
     | AND
     | COLON_COLON? nestedNameSpecifier MULT cvQualifierSeq;

LITERAL: INT_L
       | CHAR_L
       | FLOAT_L
       | STRING
       | BOOL_L;

INT_L: DECIMAL INT_SUFFIX?
   | OCTAL INT_SUFFIX?
   | HEXADECIMAL INT_SUFFIX?;

DECIMAL: NONZERO_DIGIT
       | DECIMAL DIGIT;

NONZERO_DIGIT: '1'
             | '2'
         | '3'
         | '4'
         | '5'
         | '6'
         | '7'
         | '8'
         | '9';

OCTAL: '0'
     | OCTAL OCTAL_DIGIT;

HEXADECIMAL: '0x' HEXADECIMAL_DIGIT
           | '0X' HEXADECIMAL_DIGIT
       | HEXADECIMAL HEXADECIMAL_DIGIT;

INT_SUFFIX: UNSIGNED_SUFFIX LONG_SUFFIX?
          | LONG_SUFFIX UNSIGNED_SUFFIX?;

UNSIGNED_SUFFIX: 'u'
               | 'U';

LONG_SUFFIX: 'l'
           | 'L';

CHAR_L: '\'' C_CHAR_SEQUENCE '\''
    | 'L\'' C_CHAR_SEQUENCE '\'';

C_CHAR_SEQUENCE: C_CHAR
               | C_CHAR_SEQUENCE C_CHAR;

C_CHAR: ~('\n' | '\\' | '\'')
      | ESCAPE_SEQUENCE
      | UNIVERSAL_CHARACTER_NAME;

ESCAPE_SEQUENCE: SIMPLE_ESCAPE_SEQUENCE
               | OCTAL_ESCAPE_SEQUENCE
           | HEXADECIMAL_ESCAPE_SEQUENCE;

SIMPLE_ESCAPE_SEQUENCE: '\\\''
                      | '\\"'
              | '\\?'
              | '\\\\'
              | '\\a'
              | '\\b'
              | '\\f'
              | '\\n'
              | '\\r'
              | '\\t'
              | '\\v';

OCTAL_ESCAPE_SEQUENCE: '\\' OCTAL_DIGIT
                     | '\\' OCTAL_DIGIT OCTAL_DIGIT
             | '\\' OCTAL_DIGIT OCTAL_DIGIT OCTAL_DIGIT;

OCTAL_DIGIT: '0'
           | '1'
       | '2'
       | '3'
       | '4'
       | '5'
       | '6'
       | '7';

HEXADECIMAL_ESCAPE_SEQUENCE: '\x' HEXADECIMAL_DIGIT
                           | HEXADECIMAL_ESCAPE_SEQUENCE HEXADECIMAL_DIGIT;

HEXADECIMAL_DIGIT: '0'
                 | '1'
         | '2'
         | '3'
         | '4'
         | '5'
         | '6'
         | '7'
         | '8'
         | '9'
         | 'a'
         | 'b'
         | 'c'
         | 'd'
         | 'e'
         | 'f'
         | 'A'
         | 'B'
         | 'C'
         | 'D'
         | 'E'
         | 'F';

UNIVERSAL_CHARACTER_NAME: '\u' HEX_QUAD
                        | '\U' HEX_QUAD HEX_QUAD;

HEX_QUAD: HEXADECIMAL_DIGIT HEXADECIMAL_DIGIT HEXADECIMAL_DIGIT HEXADECIMAL_DIGIT;

FLOAT_L: FRACTIONAL_CONSTANT EXPONENT_PART? FLOAT_SUFFIX?
     | DIGIT_SEQUENCE EXPONENT_PART FLOAT_SUFFIX?;

FRACTIONAL_CONSTANT: DIGIT_SEQUENCE? DOT DIGIT_SEQUENCE
                   | DIGIT_SEQUENCE DOT;

EXPONENT_PART: 'e' SIGN? DIGIT_SEQUENCE
             | 'E' SIGN? DIGIT_SEQUENCE;

SIGN: PLUS
    | MINUS;

DIGIT_SEQUENCE: DIGIT
              | DIGIT_SEQUENCE DIGIT;

DIGIT: '0'
     | '1'
     | '2'
     | '3'
     | '4'
     | '5'
     | '6'
     | '7'
     | '8'
     | '9';

FLOAT_SUFFIX: 'f'
            | 'l'
        | 'F'
        | 'L';

BOOL_L: 'false'
    | 'true';

OP: NEW
  | DELETE
  | 'new[]'
  | 'delete[]'
  | PLUS
  | MINUS
  | MULT
  | DIV
  | MOD
  | EXP
  | AND
  | OR
  | NEG
  | EXC
  | EQ
  | LT
  | GT
  | PLUS_EQ
  | MINUS_EQ
  | MULT_EQ
  | DIV_EQ
  | MOD_EQ
  | EXP_EQ
  | AND_EQ
  | OR_EQ
  | LT_LT
  | GT_GT
  | GT_GT_EQ
  | LT_LT_EQ
  | EQ_EQ
  | EXC_EQ
  | LT_EQ
  | GT_EQ
  | AND_AND
  | OR_OR
  | PLUS_PLUS
  | MINUS_MINUS
  | COMMA
  | MINUS_GT_MULT
  | MINUS_GT
  | LP_RP
  | LB_RB;

NEW: 'new';
DELETE: 'delete';
PLUS: '+';
MINUS: '-';
MULT: '*';
DIV: '/';
MOD: '%';
EXP: '^';
AND: '&';
OR: '|';
NEG: '~';
EXC: '!';
EQ: '=';
LT: '<';
GT: '>';
PLUS_EQ: '+=';
MINUS_EQ: '-=';
MULT_EQ: '*=';
DIV_EQ: '/=';
MOD_EQ: '%=';
EXP_EQ: '^=';
AND_EQ: '&=';
OR_EQ: '|=';
LT_LT: '<<';
GT_GT: '>>';
GT_GT_EQ: '>>=';
LT_LT_EQ: '<<=';
EQ_EQ: '==';
EXC_EQ: '!=';
LT_EQ: '<=';
GT_EQ: '>=';
AND_AND: '&&';
OR_OR: '||';
PLUS_PLUS: '++';
MINUS_MINUS: '--';
COMMA: ',';
MINUS_GT_MULT: '->*';
MINUS_GT: '->';
LP_RP: '()';
LB_RB: '[]';

ID: [a-zA-Z0-9_$]+;

COMMENT: ('/*' .*? '*/' | '//' .*? '\r'? '\n') -> skip;

WS: [ \t\r\n]+ -> skip;

STRING: '"' ( '\\"' | . )*? '"';

QMARK: '?';

CHAR: 'char';

WCHAR_T: 'wchar_t';

BOOL: 'bool';

SHORT: 'short';

INT: 'int';

LONG: 'long';

SIGNED: 'signed';

UNSIGNED: 'unsigned';

FLOAT: 'float';

DOUBLE: 'double';

VOID: 'void';

DOT_MULT: '.*';

LPARAN: '(';

RPARAN: ')';

COLON_COLON: '::';

LBRACKET: '{';

RBRACKET: '}';

LSQRBRAC: '[';

RSQRBRAC: ']';

COLON: ':';

SEMI_COLON: ';';

DOT: '.';

DOT_DOT_DOT: '...';

SIZEOF: 'sizeof';

TYPENAME: 'typename';

TEMPLATE: 'template';

DYNAMIC_CAST: 'dynamic_cast';

STATIC_CAST: 'static_cast';

REINTERPRET_CAST: 'reinterpret_cast';

CONST_CAST: 'const_cast';

TYPEID: 'typeid';      

THIS: 'this';

ENUM: 'enum';

CONST: 'const';

VOLATILE: 'volatile';

THROW: 'throw';

OPERATOR: 'operator';

VIRTUAL: 'virtual';

CLASS: 'class';

NAMESPACE: 'namespace';

FRIEND: 'friend';

TYPEDEF: 'typedef';

IF: 'if';

SWITCH: 'switch';

WHILE: 'while';

DO: 'do';

FOR: 'for';

BREAK: 'break';

CONTINUE: 'continue';

RETURN: 'return';

GOTO: 'goto';

TRY: 'try';

USING: 'using';

EXPORT: 'export';

CASE: 'case';

DEFAULT: 'default';

ELSE: 'else';

CATCH: 'catch';

EXTERN: 'extern';

I am getting an exception:

 [java] Exception in thread "main" java.lang.NullPointerException
 [java]     at org.antlr.v4.automata.ParserATNFactory.elemList(ParserATNFactory.java:452)
 [java]     at org.antlr.v4.automata.ParserATNFactory.alt(ParserATNFactory.java:439)
 [java]     at org.antlr.v4.parse.ATNBuilder.alternative(ATNBuilder.java:567)
 [java]     at org.antlr.v4.parse.ATNBuilder.ruleBlock(ATNBuilder.java:289)
 [java]     at org.antlr.v4.automata.ParserATNFactory._createATN(ParserATNFactory.java:177)
 [java]     at org.antlr.v4.automata.LexerATNFactory.createATN(LexerATNFactory.java:94)
 [java]     at org.antlr.v4.Tool.processNonCombinedGrammar(Tool.java:407)
 [java]     at org.antlr.v4.Tool.process(Tool.java:376)
 [java]     at org.antlr.v4.Tool.processGrammarsOnCommandLine(Tool.java:343)
 [java]     at org.antlr.v4.Tool.main(Tool.java:190)

If anybody knows whats so wrong about my grammar, please let me know about it.

Thanks and Regards, Prakhar Mishra

Prakhar Mishra
  • 1,586
  • 4
  • 28
  • 52
  • If you want a bug fixed, you have to put it on the project's issue tracker: https://github.com/antlr/antlr4/issues – Sam Harwell Dec 07 '13 at 19:30
  • @280Z28 Ok, here it is [Issue](https://github.com/antlr/antlr4/issues/367). I was counting on ANTLR folks here for declaring my grammar buggy instead. Looks like I won't be able to use ANTLR4 for parsing stuff. – Prakhar Mishra Dec 07 '13 at 20:19

3 Answers3

1

This may sound harsh, but you are a little crazy to try and build your own C++ grammar, if you want a useful result.

First, getting the grammar right is really hard. You get to figure out what the C++ (98? 2011? 2014?) standard actually says, cast it into parser generator (ANTLR4) terms, then find out what the compilers really accept (invariably different, and really arcane). You'll have to fight with ambiguous parses, which ANTLR4 has some help for, but can't resolve entirely without symbol tables (see below).

To process real programs, you'll need a full C++ preprocessor. Same caveats.

To do anything useful with such a grammar, you're going to need to build symbol tables. Same caveats, but ten times as difficult because you don't have any formal syntax, just the informal words in the 600 page standard (and the undocumented behavior of the actual compilers).

I have a small team of engineers working on this and we think we pretty good supporting tools. We have about 15 man-years invested and think we have a pretty good result; I don't think you can do it a lot faster. The Clang team is distributed and probably way bigger than ours.

If you are just doing this for educational purposes, well, then, fine, see 280Z28's answer. Expect to be bruised.

Ira Baxter
  • 93,541
  • 22
  • 172
  • 341
  • 1
    Of course, there are many useful things an imperfect subset of a "real" c++ grammar can do. Although, if I was 15 man-years into a parser, I probably would have trouble imagining them too. :-) – Ron Burk Dec 09 '13 at 23:05
  • I'm open to suggestions. Mostly if you can't parse the source code, you can't do anything real. If you can parse it sloppily, you can only do sloppy reasoning. That works up to about 100 lines and then rapidly goes useless. Our problem imagining things is that the code bases we apply such tools are simply not small. – Ira Baxter Dec 09 '13 at 23:07
  • Isn't there a C++ grammar that you could use as a starting point? – vonbrand Jan 24 '14 at 18:08
  • Maybe the one in Elsa. AFAIK, it is out of date (in particular, doesn't handle C++11) and certainly isn't compatible with ANTLR4. And if it were ideal, you face the huge problem of building symbol tables (and other basic facts about the code). So the practical answer is, NO. – Ira Baxter Jan 24 '14 at 20:54
0

At first glance, your grammar has many, many bugs. I'm not sure what's causing the NullPointerException, but you'll definitely need to resolve these before it works for you.

The following is an incomplete list of major issues I notice on a first look through the grammar.

  1. The grammar should be separated such that all parser rules (which start with a lowercase letter) appear before all the lexer rules (which start with an uppercase letter).
  2. Your lexer will never create a PLUS token because the OP lexer rule matches + and the OP rule appears before the PLUS rule in the grammar. Tokens are assigned exactly one token type, so you can never have a token that is both OP and PLUS. This applies to many, if not all, of the other items listed in the OP rule.
  3. The INCLUDE_STAT rule does not allow any whitespace to appear anywhere in a #include directive.
  4. The identifier f will never be an ID, because the FLOAT_SUFFIX rule matches f and appears before the ID rule. I believe you meant to mark the FLOAT_SUFFIX rule as a fragment rule. This conceptual error appears many other times in the grammar.
  5. The keyword else will never be an ELSE, because the ID rule also matches else and appears before the ELSE rule in the grammar. This conceptual error applies to every keyword listed after the ID rule in the grammar.
Sam Harwell
  • 97,721
  • 20
  • 209
  • 280
  • You did pointed out some serious flaws in my grammar. Guess I have to look into the ANTLR for more details. Thanks for your help. But it doesn't guarantees that after corrections, ANTLR4 will parse it without giving any exception. Should I go for **clang**? Or, should I rely on **ANTLR**? I am confused. – Prakhar Mishra Dec 09 '13 at 05:25
  • ANTLR is a parser generator, clang is a C compiler. Different species (even kindoms)... – vonbrand Jan 24 '14 at 18:06
-1

It is not the grammar that throws it. The real issue that throws the Exception is: '\u'. Replacing with '\\u' stops the NullPointerException throw.

lines 605:

UNIVERSAL_CHARACTER_NAME: '\\u' HEX_QUAD

Now, the following error, and warnings. The output after replacing:

error(119): \CppGrammar.g4::: The following sets of rules are mutually left-recursive [DECIMAL] and [OCTAL] and [HEXADECIMAL] and [DIGIT_SEQUENCE] and [HEXADECIMAL_ESCAPE_SEQUENCE] and [C_CHAR_SEQUENCE]
warning(125): \CppGrammar.g4:5:22: implicit definition of token 'OR_OP' in parser
warning(125): \CppGrammar.g4:5:22: implicit definition of token 'AND_OP' in parser
warning(125): \CppGrammar.g4:5:22: implicit definition of token 'INC_OR_OP' in parser
warning(125): \CppGrammar.g4:5:22: implicit definition of token 'EX_OR_OP' in parser
warning(125): \CppGrammar.g4:5:22: implicit definition of token 'EQUALITY' in parser
error(119): \CppGrammar.g4::: The following sets of rules are mutually left-recursive [declSpecifierSeq]
Rabamirezzan
  • 87
  • 1
  • 5
  • If this does not answer the question, is not an answer (by definition) , so remove it. – Manu343726 Jan 24 '14 at 21:37
  • Why is this downvoted? Surely (i) the original issue is that antlr, instead of providing meaningful error messages is blowing up in a way that is not helpful and (ii) fixing the \\u and getting meaningful error messages is exactly what the OP wanted? I have had exactly the same issue with antlr blowing up and throwing this exception, and had the same problem with a backslash that was not escaped. The exception stack led me to this SE question, and the answer here is what fixed the problem (my grammar was otherwise error free). Therefore I say this DOES ANSWER THE QUESTION! – Graham Wheeler Jan 27 '14 at 22:23
  • Hi @Graham Wheeler, I recently started to posting here. The first downvoted was correct, I wrote a bad answer. The second downvoted, perhaps because I left the wrong answer with an update part (at the bottom) that explained this current answer. Was my fault as novice. Or my grammar (Non-english speaker), So, thanks. – Rabamirezzan Jan 28 '14 at 00:06