ANTLR生成C#代码编译报错求助:TokenNames与SerializedAtn问题
ANTLR生成C#代码编译报错:TokenNames无法重写、SerializedAtn类型不匹配
问题背景
刚接触ANTLR数日,使用JetBrains Rider的ANTLR插件开发自定义语法(CubeScript.g4),语法树能正常解析代码,但生成C#源代码后编译失败。
语法文件(CubeScript.g4)
CubeScript; program: line* EOF; line: statement | ifBlock | whileBlock; statement : assignment #assignmentexpr | functionCall ';'#functioncallstatement // defining string should end with ; | 'def' IDENTIFIER '=' STRING ';' #definingstringexpr // using statement should end with ; | 'using' IDENTIFIER ';' #usingstringexpr //using statement with the . | 'using' '.' IDENTIFIER ';' #usingstringexpr //print(varible) should end with ; //string | 'string' IDENTIFIER '=' STRING ';' #stringexpr // defining blocks of code should end with ; | ENTRY IDENTIFIER '(' (IDENTIFIER (',' IDENTIFIER)*)? ')' block #definingfunctionexpr // namespace should end with ; | 'House' ':' IDENTIFIER ';' #namespaceexpr // math operations should end with ; | expression ';' #expressionstatement // math operations | INTEGER '+' INTEGER #expressionexpr // int operations | INTEGER '-' INTEGER #expressionexpr // int operations | INTEGER '*' INTEGER #expressionexpr // int define | 'int' IDENTIFIER '=' INTEGER ';' #intexpr // float define | 'float' IDENTIFIER '=' FLOAT ';' #floatexpr // float operations | FLOAT '+' FLOAT #expressionexpr // float operations | FLOAT '-' FLOAT #expressionexpr // string array, string{int} identifier = //say io.read(); | 'string' IDENTIFIER? '{' IDENTIFIER? '}' IDENTIFIER? '=' functionCall';' #stringarrayexpr //foreach | 'foreach' '(' IDENTIFIER 'in' IDENTIFIER ')'block #foreachexpr //print with math operations | 'print' '(' expression ')' ';' #printexpr //print with identifire | 'print' '(' IDENTIFIER ')' ';' #printexpr ; ifBlock: 'if' expression block ('else' elseifBlock)?; elseifBlock: block | ifBlock; whileBlock: WHILE expression block ('else' elseifBlock)?; WHILE: 'while' | 'until'; assignment: IDENTIFIER '=' expression; //function call with support for . functionCall: IDENTIFIER '(' (expression (',' expression)*)? ')' #functioncallexprs | IDENTIFIER '.' IDENTIFIER '(' (expression (',' expression)*)? ')' #functioncallexprs ; block: '{' line* '}'; expression : constant #constantexpr | IDENTIFIER #identifierexpr | functionCall #functioncallexpr | '(' expression ')' #parenthesisexpr | '!' expression #notexpr | expression multOp expression #multexpr | expression addOp expression #addexpr | expression cmpOp expression #cmpexpr | expression boolOp expression #boolexpr ; Comment : ('//' ~( '\r' | '\n' )* | '/*' .*? '*/' | '#' ~( '\r' | '\n' )*) -> skip ; multOp: '*' | '/' | '%'; addOp: '+' | '-'; cmpOp: '<' | '>' | '<=' | '>=' | '==' | '!='; boolOp: BOOL_OPERATOR; BOOL_OPERATOR: 'and' | 'or' | 'xor'; constant : INTEGER | FLOAT | STRING | BOOL | NULL; INTEGER: [0-9]+; FLOAT: [0-9]* '.' [0-9]+; fragment ESC: '\\' ([\"\\/bfnrt] | UNICODE); fragment UNICODE: 'u' HEX HEX HEX HEX; fragment HEX: [0-9a-fA-F]; fragment SAFE: ~[\"\\\u0000-\u001F]; STRING: '"' (ESC | SAFE)* '"'; BOOL: 'true' | 'false'; NULL: 'null'; WS: [ \t\r\n]+ -> skip; ENTRY: 'struct' | 'class' ; IDENTIFIER: [a-zA-Z_][a-zA-Z0-9_]*;
编译错误信息
0>CubeScriptLexer.cs(94,27): Error CS0115 : 'CubeScriptLexer.TokenNames': no suitable method found to override 0>CubeScriptLexer.cs(117,25): Error CS1715 : 'CubeScriptLexer.SerializedAtn': type must be 'int[]' to match overridden member 'Recognizer<int, LexerATNSimulator>.SerializedAtn' 0>CubeScriptParser.cs(87,27): Error CS0115 : 'CubeScriptParser.TokenNames': no suitable method found to override 0>CubeScriptParser.cs(108,25): Error CS1715 : 'CubeScriptParser.SerializedAtn': type must be 'int[]' to match overridden member 'Recognizer<IToken, ParserATNSimulator>.SerializedAtn' 0>------- Finished building project: ProtoGram. Succeeded: False. Errors: 4. Warnings: 0
已尝试使用NuGet最新版antlr4.runtime和antlr4包,未解决问题。
解决方案
1. 统一ANTLR工具与Runtime版本
这类错误核心原因是ANTLR插件生成代码的版本与项目引用的NuGet runtime版本不一致。需确保两者版本完全匹配:
- 打开Rider的Settings(File → Settings),找到Tools → ANTLR,查看插件默认使用的ANTLR版本。
- 对比项目NuGet包中
antlr4.runtime的版本,确保两者版本号完全相同(如均为4.13.1)。
2. 重新生成代码
- 先删除项目中已生成的
CubeScriptLexer.cs、CubeScriptParser.cs等文件,避免旧代码干扰。 - 在Rider中右键点击
CubeScript.g4文件,选择Generate ANTLR Recognizer。 - 在生成选项中,确认目标语言为C#,并指定与NuGet版本一致的ANTLR版本。
3. 检查NuGet包安装
- 确保项目中仅安装了对应版本的
antlr4.runtime(运行时核心包),无需重复安装antlr4工具包(若已安装,需确认版本一致)。 - 清理NuGet缓存(Tools → NuGet Package Manager → Package Manager Settings → Clear All NuGet Cache(s)),重新安装对应版本的包。
4. 验证生成代码设置
- 右键
CubeScript.g4→ Properties,检查ANTLR设置中的Output directory是否正确,生成的代码是否被放入项目的正确目录中,且未被旧文件覆盖。
内容的提问来源于stack exchange,提问作者Charlie-sans
相关产品推荐
相关产品推荐

