ANTLR4:使用单独语法时出现 grun 错误 (ClassCastException)

mba*_*i23 5 antlr4

描述

\n\n

我正在尝试创建一种自定义语言,我想将词法分析器规则与解析器规则分开。此外,我的目标是将词法分析器和解析器规则进一步划分为特定文件(例如,公共词法分析器规则和关键字规则)。

\n\n

但我似乎无法让它发挥作用。

\n\n

.java尽管我在生成解析器(文件) 时没有收到任何错误,grun但失败并显示Exception in thread "main" java.lang.ClassCastException.

\n\n

笔记

\n\n

我在 Windows7 上运行4.7.2针对 Java 的 ANTLR。

\n\n

代码

\n\n

我创建了一组与我想要实现的目标非常相似的文件。下面的示例定义了一种名为 的语言MyLang,并将词法分析器和解析器语法分开。另外,我将词法分析器规则分为四个文件:

\n\n
    \n
  1. // 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    ;\n
    Run Code Online (Sandbox Code Playgroud)
  2. \n
  3. // 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\' ;\n
    Run Code Online (Sandbox Code Playgroud)
  4. \n
  5. // 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}\n
    Run Code Online (Sandbox Code Playgroud)
  6. \n
  7. // 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];\n
    Run Code Online (Sandbox Code Playgroud)
  8. \n
  9. // SkipWhitespaceL.g4\nlexer grammar SkipWhitespaceL;\n\nWS\n    :   [ \\t\\r\\n]+ -> channel(HIDDEN)\n    ;\n
    Run Code Online (Sandbox Code Playgroud)
  10. \n
\n\n

输出

\n\n

这是我从上面的代码收到的确切输出:

\n\n
ussjc-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\n
Run Code Online (Sandbox Code Playgroud)\n

Nul*_*ble 4

使用 MyLangParser 和 MyLangLexer 重命名两个文件,然后运行grun MyLang prog -tree