如何在不执行脚本并生成任何类文件的情况下检查 Scala 脚本的语法?

发布于 2024-10-20 05:02:47 字数 414 浏览 1 评论 0原文

人们可以用 Scala 编写脚本。因此,您可以将其放入 Hello.scala

#!/bin/sh
exec scala $0 $@
!#

println("You supplied " + args.length + " arguments!")

并使其在 Unix 中可执行

chmod u+x Hello.scala

然后您可以简单地运行该脚本

./Hello.scala

如果没有语法错误,则编译脚本并运行它。但是,这并没有考虑到我只想进行语法检查而不执行脚本的情况。我不想修改脚本(即通过删除 #! 指令)并且不想生成任何 *.class 文件。

如何检查 Scala 脚本的语法?

One can write scripts in Scala. So you can put this into Hello.scala

#!/bin/sh
exec scala $0 $@
!#

println("You supplied " + args.length + " arguments!")

and make it executable in Unix by

chmod u+x Hello.scala

Then you can run the script simply by

./Hello.scala

This compiles the script and runs it if there are no syntax errors. However, this does not account for situation when I only want to syntax check without executing the script. I do not want to modify the script (i.e. by removing the #! directive) and I do not want any *.class files to be generated.

How can I syntax check a Scala script?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

谎言 2024-10-27 05:02:47

我希望您实际上想要的不仅仅是检查正确的语法……大概您想知道的是,如果您确实编译了文件,那么它会正确编译。这涉及类型检查和语法检查。

对于 Scala 源文件(即不是脚本),您可以指定 -Ystop:refchecks 命令行参数,以使编译器在开始代码生成之前停止(如果您确实只对语法正确性感兴趣,则可以指定 -Ystop:parser) 。如果存在错误,它们将以与完全编译源代码完全相同的方式显示在控制台上。

对于 Scala 脚本,您还可以指定 -Ystop:refchecks 参数。如果执行此操作,那么您将看到控制台上报告的编译错误,或者如果脚本中没有错误,您将看到以下内容:

$ scala -Ystop:refchecks Hello.scala 
java.lang.ClassNotFoundException: Main

ClassNotFoundException 指示未生成任何类文件并且您的脚本尚未执行。

I expect that you actually want a little more than just checking for correct syntax ... presumably what you want to know is that your file would compile correctly if you did actually compile it. That involves type checking as well as syntax checking.

For Scala source files (ie. not scripts) you can specify the -Ystop:refchecks command line argument to cause the compiler to stop before it starts code generation (if you really are only interested in syntactic correctness you could specify -Ystop:parser). If there are errors they will be shown on the console in exactly the same way as if you fully compiled the sources.

For Scala scripts you can also specify the -Ystop:refchecks argument. If you do this, then you will either see compile errors reported on the console or, if there are no errors in the script, you will see the following,

$ scala -Ystop:refchecks Hello.scala 
java.lang.ClassNotFoundException: Main

The ClassNotFoundException indicating that no classfiles have been generated and that your script has not been executed.

浮生未歇 2024-10-27 05:02:47

如果您想从文件中删除行以传递给解释器,您可以创建一个名为 CutScala.scala 的脚本(或您喜欢的任何内容):

#!/bin/sh
exec scala $0 $@
!#

import scala.collection.JavaConversions._
import java.io._

val p = new ProcessBuilder(
  List(
    "scala",
    "-e",
    io.Source.fromFile(args(1)).getLines().drop(args(0).toInt).mkString("\n")
  ) :::
  args.drop(2).toList
).start()

p.waitFor

val output = List(p.getInputStream,p.getErrorStream).map(
  x => new BufferedReader(new InputStreamReader(x))
)

println("Exit code = " + p.exitValue)
for ((reader,title) <- (output zip List("Output:","Errors:"))) {
  println(title);
  Iterator.continually(reader.readLine).takeWhile(_!=null).foreach(println)
  println
}

然后调用它,就像

./CutScala.scala 4 Hello.scala a b c

删除前 4 行 一样只需解析其余部分即可。迈尔斯的答案告诉您如何做另一半(更困难的),即不产生任何输出并且不运行任何东西。

If you want to cut lines off your file to pass to the interpreter, you can create a script called CutScala.scala (or whatever you prefer):

#!/bin/sh
exec scala $0 $@
!#

import scala.collection.JavaConversions._
import java.io._

val p = new ProcessBuilder(
  List(
    "scala",
    "-e",
    io.Source.fromFile(args(1)).getLines().drop(args(0).toInt).mkString("\n")
  ) :::
  args.drop(2).toList
).start()

p.waitFor

val output = List(p.getInputStream,p.getErrorStream).map(
  x => new BufferedReader(new InputStreamReader(x))
)

println("Exit code = " + p.exitValue)
for ((reader,title) <- (output zip List("Output:","Errors:"))) {
  println(title);
  Iterator.continually(reader.readLine).takeWhile(_!=null).foreach(println)
  println
}

and then call it like

./CutScala.scala 4 Hello.scala a b c

to drop the first 4 lines and just parse the rest. Miles' answer tells you how to do the other (more difficult) half of not producing any output and not running anything.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文