Antlr4 cpp грамматика неспособна генерировать синтаксический анализатор; NullPointereException
Я пытаюсь сгенерировать cpp-парсер, используя грамматику ANTLR4 и
Орг.антлр.v4.Инструмент
Дает мне исключение NullPointerException. Я ничего не понимаю. Если есть проблема с моей грамматикой, то она должна была заявить об этом с содержательным сообщением об ошибке. Еще одна странная вещь заключается в том, что, хотя я создал эту грамматику в vim, когда я открыл ее в ANTLRWorks 2.1, ее навигационная панель показывает "Пожалуйста, подождите... " и больше ничего. Вот моя грамматика дана ниже: -
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: [ trn]+ -> 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)
Если кто-нибудь знает, что так неправильно в моей грамматике, пожалуйста, дайте мне знать об этом.
Спасибо и с уважением, Пракхар Мишра
3 ответа:
На первый взгляд, в вашей грамматике очень много ошибок. Я не уверен, что вызывает
Ниже приведен неполный список основных проблем, которые я замечаю при первом взгляде на грамматику.NullPointerException
, но вам определенно нужно решить их, прежде чем это сработает для вас.Грамматика должна быть разделена таким образом, чтобы все правила синтаксического анализатора (которые начинаются со строчной буквы) появлялись перед всеми правилами лексера (которые начинаются с прописной буквы).
- ваш лексер будет никогда не создавайте маркер
PLUS
, потому что ПравилоOP
лексера совпадает с правилом+
и ПравилоOP
появляется перед правиломPLUS
в грамматике. Токенам присваивается ровно один тип токена, поэтому вы никогда не сможете иметь токен, который является одновременноOP
иPLUS
. Это относится ко многим, если не ко всем, другим элементам, перечисленным в правилеOP
.- правило
INCLUDE_STAT
не позволяет пробелам появляться в любом месте директивы#include
.- идентификатор
f
никогда не будетID
, потому чтоFLOAT_SUFFIX
правило совпадает сf
и появляется перед правиломID
. Я полагаю, вы хотели отметить правилоFLOAT_SUFFIX
Как правилоfragment
. Эта концептуальная ошибка встречается в грамматике много раз.- ключевое слово
else
никогда не будетELSE
, потому что ПравилоID
также совпадает с правиломelse
и появляется перед правиломELSE
в грамматике. Эта концептуальная ошибка относится ко всем ключевым словам, перечисленным после ПравилаID
в грамматике.
Это может показаться грубым, но вы немного сумасшедший, чтобы попытаться построить свою собственную грамматику C++, если вы хотите получить полезный результат.
Во-первых, получить правильную грамматикудействительно трудно. Вы получите, чтобы выяснить, что C++ (98? 2011 год? 2014 год?) стандарт фактически говорит, бросьте его в генератор синтаксического анализа (ANTLR4) термины, а затем выясните, что компиляторы действительно принимают (неизменно разные и действительно тайные). Вам придется бороться с неоднозначными парсами, для которых ANTLR4 имеет некоторую помощь, но полностью решить проблему без таблиц символов невозможно (см.
Для обработки реальных программ вам понадобится полный препроцессор C++. Те же предостережения.
Чтобы сделать что-нибудь полезное с такой грамматикой, вам понадобится построить таблицы символов. Те же предостережения, но в десять раз сложнее, потому что у вас нет никакого формального синтаксиса, только неформальные слова в стандарте 600 страниц (и недокументированное поведение реальных компиляторов).
У меня есть небольшая команда инженеров работая над этим, мы думаем, что у нас довольно хорошие вспомогательные инструменты. Мы инвестировали около 15 человеко-лет и считаем, что у нас есть довольно хороший результат; я не думаю, что вы можете сделать это намного быстрее. Команда лязга распределена и, вероятно, намного больше, чем наша.
Если вы делаете это только для образовательных целей, что ж, прекрасно, смотрите ответ 280Z28. Ожидать, чтобы быть в синяках.
Это не грамматика бросает его. Реальная проблема, которая вызывает исключение, заключается в следующем: - "у". Замена на '\ \ u ' останавливает бросок NullPointerException.
Строки 605:
UNIVERSAL_CHARACTER_NAME: '\\u' HEX_QUAD
Теперь следующая ошибка и предупреждения. Выходные данные после замены:
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]