ANTLR4 TestRig(grun)引发java.lang.NoClassDefFoundError异常



我正在努力学习ANTLR 4,我正在遵循最终ANTLR 4参考中给出的示例。遗憾的是,我被第一个例子卡住了。


系统:
Windows 10(1703)
Java 8,更新151
ANTLR 4,v4.7

我的%CLASSPATH%被设置为系统变量(.;"D:Program FilesJavalibsantlr-4.7-complete.jar";)
我的%PATH%中有可用的antlr4.batgrun.bat,并且我可以从命令行运行antlr4

antlr4.bat:java -cp %CLASSPATH% org.antlr.v4.Tool %*
grun.bat:java -cp %CLASSPATH% org.antlr.v4.gui.TestRig %*

我明确使用-cp %CLASSPATH%,因为我看到其他一些人在不使用-cp选项时遇到问题。


我的问题是:
当我在示例语法Hello(grun Hello r -tokens)上运行grun时,我得到了错误消息

Exception in thread "main" java.lang.NoClassDefFoundError: HelloLexer (wrong name: main/resource/hello/HelloLexer)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$100(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at org.antlr.v4.gui.TestRig.process(TestRig.java:129)
at org.antlr.v4.gui.TestRig.main(TestRig.java:119)

你知道我做错了什么吗
非常感谢!


编辑:
我以为我找到了答案。通过cd进入编译文件所在的文件夹(而不是从根项目文件夹调用grun),我成功地完成了有问题的示例。

但当我试图建立自己的项目时,我遇到了同样的问题,并出现了与上面相同的错误消息。

这一次,在我使用-package选项运行了antlr4之后,grun似乎在抱怨。

有人知道为什么会这样吗?

我遇到了和你一样的问题
@DoTheGenes提醒我,这可能是由.g4文件中的@header {package com.blahblah.antlr4.hello;}引起的。Grun在包重定位命令中有一些未修复的错误。当我用@header删除这一行时,问题解决了,我可以用生成和编译的文件运行grun gui、tree和任何其他命令
希望这能有所帮助。

哇。。。当然,这个解决方案很简单。。。我的问题是,我把cd'd放在测试项目的根文件夹中,而我只需要把cd放在编译文件所在的目录中(并从中调用grun)

编辑:
我似乎仍然对grun有问题。请参阅编辑后的问题

Edit2:
据我所知,grunantlr4-package选项配合得不太好
所以我的解决方案是,我必须将我的项目设置为Gradle项目,因为显然这样效果更好。

尝试将语法名称与其所属的包完全限定,例如。com.demo.pl.Grammar。似乎适用于ANTLR 4.7.2

我使用的是ANTLR 4.9.1,我遇到了完全相同的问题。我的项目布局有一个独特而独立的位置:

  • 语法
  • 生成的源文件(@header块在语法中指定的位置)

这使得grun总是失败(因为所有东西都必须在同一个文件夹中)。解决方法是制作另一个脚本来修复这2个grun错误,例如:

  1. 将所有内容移动到1个文件夹(修复第一个错误)
  2. 从语法中删除@header{...}(修复第二个错误)
  3. (可选)如果类路径中没有antlr,则添加它
  4. 编译所有.java文件
  5. 运行antlr4(或手动运行org.antlr.v4.Tool)以生成解析器.java文件
  6. 编译所有解析器.java文件
  7. 使用所需的任何选项运行grun(或手动运行org.antlr.v4.gui.TestRig)

下面的PowerShell脚本显示了我是如何做到这一点的(请记住,您的路径可能不同),在我的情况下,语言和项目被称为Nameless,我使用了.g4test扩展来测试脚本(因此相应地调整您的Bash/Batch/PowerShell脚本)

# Script name : run.ps1
# Script arguments
param ($Target="-tokens")
# Options
$lang = "Nameless"
$startRule = "file"
# Paths
$antlr = "D:DesktopWorkspacesJavaANTLRv4antlr-4.9.1-complete.jar"
$project = "D:DesktopWorkspacesJavaEclipse Workspace 2020Nameless"
$javas = "$projecttargetgenerated-sourcesantlr4generated"
$script = "$projectscriptsLiteralsTest.g4test"
$classes = "$projectbuildclassesgenerated"
# Fix weird bug of TestRig needing all in 1 folder lol
Write-Host "Moving project files.." -NoNewLine
Copy-Item "$project$lang.g4" -Destination $classes
Copy-Item -Path "$javas*" -Destination $classes
cd $classes
Write-Host " done."
# Fix other framework bug that makes '@header' lines not run lol..
Write-Host "Removing package header line from grammar.." -NoNewline
(Get-Content -Path "$lang.g4" -Raw) -replace "(?sm)^@header`{.*?`}$" | Out-File -FilePath ".$lang.g4" -Encoding ASCII
Write-Host " done."
# All should be good now, do the usual
Write-Host "Adding to classpath temporarily.." -NoNewLine
$env:CLASSPATH = ".;$antlr;$env:CLASSPATH"
Write-Host " done."
Write-Host "Generating Java files from grammar.." -NoNewLine
java -cp ".;$antlr" org.antlr.v4.Tool "$lang.g4" -listener -visitor
Write-Host " done."
Write-Host "Compiling java files.." -NoNewLine
javac -cp ".;$antlr" *.java
Write-Host " done."
Write-Host "Running.."
java -Xmx500M -cp ".:$env:CLASSPATH" org.antlr.v4.gui.TestRig $lang $startRule $Target $script

相关内容

  • 没有找到相关文章

最新更新