c++ - ANTLR4 cpp 语法无法生成解析器;空指针异常

标签 c++ parsing antlr4

我正在尝试使用 ANTLR4 语法

生成 CPP 解析器

org.antlr.v4.Tool

给我 NullPointerException。我不明白。如果我的语法有问题,那么它应该用有意义的错误消息来说明它。更奇怪的是,虽然我在 vim 中创建了这个语法,但当我在 ANTLRWorks 2.1 中打开它时,它的 Navigator Pane 显示“Please Wait...”,没有其他任何内容。下面是我的语法:-

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';

我遇到异常:

 [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)

如果有人知道我的语法有什么问题,请告诉我。

感谢和问候, 普拉哈米什拉

最佳答案

这听起来可能很刺耳,但如果您想要一个有用的结果,那么尝试构建您自己的 C++ 语法就有点疯狂了。

首先,正确使用语法真的很难。你会弄清楚 C++(98?2011?2014?)标准实际上说的是什么,将其转换为解析器生成器 (ANTLR4) 术语,然后找出编译器真正接受的内容(总是不同的,并且真的很神秘)。您将不得不与模棱两可的解析作斗争,ANTLR4 对此有一些帮助,但没有符号表就无法完全解决(见下文)。

要处理真正的程序,您需要一个完整的 C++ 预处理器。同样的警告。

要用这样的语法做任何有用的事情,您将需要构建符号表。同样的注意事项,但难度增加十倍,因为您没有任何正式语法,只有 600 页标准中的非正式词汇(以及实际编译器的未记录行为)。

我有一个小型工程师团队致力于此,我们认为我们的支持工具非常好。我们投入了大约 15 人年,并认为我们取得了相当不错的结果;我不认为你可以做得更快。 Clang 团队是分布式的,而且可能比我们的大得多。

如果您只是出于教育目的这样做,那么,好吧,请参阅 280Z28 的回答。预计会受伤。

关于c++ - ANTLR4 cpp 语法无法生成解析器;空指针异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20439255/

相关文章:

c++ - 在 C++ 中作为货币输出

c# - 比 decimal.Parse 更快的替代方法

java - 你能分享一个 URL 解析实现的链接吗?

php - 如何通过cURL 获取带有POST 方法的表单响应?

java - 我可以更改antlr4中context的父类吗

parsing - 如何将 ANTLR 语法文件拆分为多个文件

gradle - 我怎么知道任务从哪里来的?

c++ - 处理对象组的设计模式

c++ - 对 RGB 图像使用特征数组

c++ - 随机双C++11