3

我正在尝试学习 ANTLR 4,并且正在遵循The Definitive ANTLR 4 Reference中给出的示例。可悲的是,我被困在第一个例子中。


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

My%CLASSPATH%设置为系统变量 ( .;"D:\Program Files\Java\libs\antlr-4.7-complete.jar";)。
我有antlr4.bat并且grun.bat可以在我的 中使用%PATH%,并且可以从命令行运行antlr4

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

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


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

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从根项目文件夹调用),我设法通过了有问题的示例。

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

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

有人知道为什么吗?

4

4 回答 4

1

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

于 2020-01-20T06:59:28.023 回答
0

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

于 2019-04-08T09:40:00.250 回答
0

哇...解决方案当然是一个简单的解决方案...我的问题是我已经cd进入了我的测试项目的根文件夹,我只需要cd(并从中调用grun)编译的目录文件是。

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

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

于 2017-11-06T10:11:17.320 回答
0

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

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

grun总是失败(因为一切都必须在同一个文件夹中)。解决方法是制作另一个脚本来修复这两个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脚本)BatchPowerShell

# Script name : run.ps1
# Script arguments
param ($Target="-tokens")
# Options
$lang = "Nameless"
$startRule = "file"

# Paths
$antlr = "D:\Desktop\Workspaces\Java\ANTLRv4\antlr-4.9.1-complete.jar"
$project = "D:\Desktop\Workspaces\Java\Eclipse Workspace 2020\Nameless"
$javas = "$project\target\generated-sources\antlr4\generated"
$script = "$project\scripts\LiteralsTest.g4test"
$classes = "$project\build\classes\generated"

# 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
于 2021-04-08T09:49:09.373 回答