我正在尝试创建一种自定义语言,我想将词法分析器规则与解析器规则分开。此外,我的目标是将词法分析器和解析器规则进一步划分为特定文件(例如,公共词法分析器规则和关键字规则)。
\n\n但我似乎无法让它发挥作用。
\n\n.java尽管我在生成解析器(文件) 时没有收到任何错误,grun但失败并显示Exception in thread "main" java.lang.ClassCastException.
我在 Windows7 上运行4.7.2针对 Java 的 ANTLR。
我创建了一组与我想要实现的目标非常相似的文件。下面的示例定义了一种名为 的语言MyLang,并将词法分析器和解析器语法分开。另外,我将词法分析器规则分为四个文件:
// MyLang.g4\nparser grammar MyLang;\n\noptions { tokenVocab = MyLangL; }\n\nprog\n : ( func )* END\n ;\n\nfunc\n : DIR ID L_BRKT (stat)* R_BRKT\n ;\n\nstat\n : expr SEMICOLON\n | ID OP_ASSIGN expr SEMICOLON\n | SEMICOLON\n ;\n\nexpr\n : expr OPERATOR expr\n | NUMBER\n | ID\n | L_PAREN expr R_PAREN\n ;\nRun Code Online (Sandbox Code Playgroud)// MyLangL.g4\nlexer grammar MyLangL;\n\nimport SkipWhitespaceL, CommonL, KeywordL;\n\n@header {\npackage com.invensense.wiggler.lexer;\n}\n\n@lexer::members { // place this class member only in lexer\nMap<String,Integer> keywords = new HashMap<String,Integer>() {{\n put("for", MyLangL.KW_FOR);\n /* add more keywords here */\n}};\n}\n\nID : [a-zA-Z]+\n {\n if ( keywords.containsKey(getText()) ) {\n setType(keywords.get(getText())); // reset token type\n }\n }\n ;\n\nDIR\n : \'in\'\n | \'out\'\n ;\n\nEND : \'end\' ;\nRun Code Online (Sandbox Code Playgroud)// KeywordL.g4\nlexer grammar KeywordL;\n\n@lexer::header { // place this header action only in lexer, not the parser\nimport java.util.*;\n}\n\n// explicitly define keyword token types to avoid implicit def warnings\ntokens {\n KW_FOR\n /* add more keywords here */\n}\nRun Code Online (Sandbox Code Playgroud)// CommonL.g4\nlexer grammar CommonL;\n\nNUMBER\n : FLOAT\n | INT\n | UINT\n ;\n\nFLOAT\n : NEG? DIGIT+ \'.\' DIGIT+ EXP?\n | INT\n ;\n\nINT\n : NEG? UINT+\n ;\n\nUINT\n : DIGIT+ EXP?\n ;\n\nOPERATOR\n : OP_ASSIGN\n | OP_ADD\n | OP_SUB\n ;\n\nOP_ASSIGN : \':=\';\nOP_ADD : POS;\nOP_SUB : NEG;\n\nL_BRKT : \'[\' ;\nR_BRKT : \']\' ;\nL_PAREN : \'(\' ;\nR_PAREN : \')\' ;\nSEMICOLON : \';\' ;\n\nfragment EXP\n : [Ee] SIGN? DIGIT+\n ;\n\nfragment SIGN\n : POS\n | NEG\n ;\n\nfragment POS: \'+\' ;\nfragment NEG : \'-\' ;\nfragment DIGIT : [0-9];\nRun Code Online (Sandbox Code Playgroud)// SkipWhitespaceL.g4\nlexer grammar SkipWhitespaceL;\n\nWS\n : [ \\t\\r\\n]+ -> channel(HIDDEN)\n ;\nRun Code Online (Sandbox Code Playgroud)这是我从上面的代码收到的确切输出:
\n\nussjc-dd9vkc2 | C:\\M\\w\\s\\a\\l\\example\n\xc2\xa7 antlr4.bat .\\MyLangL.g4\n\nussjc-dd9vkc2 | C:\\M\\w\\s\\a\\l\\example\n\xc2\xa7 antlr4.bat .\\MyLang.g4\n\nussjc-dd9vkc2 | C:\\M\\w\\s\\a\\l\\example\n\xc2\xa7 javac *.java\n\nussjc-dd9vkc2 | C:\\M\\w\\s\\a\\l\\example\n\xc2\xa7 grun MyLang prog -tree\nException in thread "main" java.lang.ClassCastException: class MyLang\n at java.lang.Class.asSubclass(Unknown Source)\n at org.antlr.v4.gui.TestRig.process(TestRig.java:135)\n at org.antlr.v4.gui.TestRig.main(TestRig.java:119)\n\nussjc-dd9vkc2 | C:\\M\\w\\s\\a\\l\\example\n\xc2\xa7\nRun Code Online (Sandbox Code Playgroud)\n