2011-03-05 10 views
11

Se pueden escribir scripts en Scala. Así que usted puede poner esto en Hello.scala¿Cómo puedo verificar la sintaxis de un script de Scala sin ejecutar el script y generar ningún archivo de clase?

#!/bin/sh 
exec scala $0 [email protected] 
!# 

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

y que sea ejecutable en Unix por

chmod u+x Hello.scala 

A continuación, puede ejecutar el script simplemente

./Hello.scala 

Esto compila el guión y lo ejecuta si no hay errores de sintaxis. Sin embargo, esto no tiene en cuenta la situación cuando solo quiero verificar la sintaxis sin ejecutar el script. No quiero modificar el script (es decir, eliminando la directiva #!) Y no quiero que se generen archivos * .class.

¿Cómo puedo verificar la sintaxis de un script de Scala?

+0

La comprobación de la sintaxis solo es probablemente más fácil si se crea un analizador básico con herramientas como ANTLR usando la gramática dada en la especificación del lenguaje. ¿Desea verificar el nombre y el tipo también? Si es así, las cosas se complican y es probable que desee trabajar con (partes de) scalac directamente. – Raphael

+0

No fui precisa en mi pregunta. Deseo realizar la verificación de la sintaxis y la verificación de tipos y quiero usar el compilador/infraestructura de Scala. La respuesta de Miles a continuación está justo en el botón. – midinastasurazz

Respuesta

22

Espero que realmente desee algo más que comprobar la sintaxis correcta ... presumiblemente, lo que desea saber es que su archivo se compilaría correctamente si realmente lo compiló. Eso implica verificación de tipos y verificación de sintaxis.

Para los archivos fuente Scala (es decir, no scripts) puede especificar el argumento -Ystop: refchecks command line para hacer que el compilador se detenga antes de iniciar la generación de código (si realmente está interesado en la corrección sintáctica puede especificarlo) Ystop: analizador). Si hay errores, se mostrarán en la consola exactamente de la misma manera que si compiló completamente las fuentes.

Para los scripts de Scala también puede especificar el argumento -Ystop: refchecks. Si lo hace, entonces usted va a ver ya sea compilar errores reportados en la consola o, si no hay errores en la secuencia de comandos, verá lo siguiente,

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

El ClassNotFoundException lo que indica que no hay archivos de clase se han generado y que su script no se ha ejecutado.

+0

Buena respuesta: aprendí algunos trucos nuevos hoy. Gracias. – Janx

+0

Excelente respuesta. Tu interpretación es correcta Quiero saber si el archivo se compilaría correctamente si realmente lo compilé. Gracias. – midinastasurazz

+0

¿Esto todavía es válido? No parece funcionar con scala 2.9. No se puede encontrar información sobre esto en una búsqueda. Gracias. –

0

Si se quiere cortar las líneas de tu archivo para pasar al intérprete, puede crear un script llamado CutScala.scala (o lo que usted prefiera):

#!/bin/sh 
exec scala $0 [email protected] 
!# 

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 
} 

y luego llamar así

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

para soltar las primeras 4 líneas y simplemente analizar el resto. La respuesta de Miles te dice cómo hacer la otra mitad (más difícil) de no producir ninguna salida y no ejecutar nada.

+1

¡Guau! Tanto scala fuss en lugar de algo tan simple como 'awk 'NR> 4'' ... –

+1

@Elazar Leibovich - O' tail -n + 4'. El problema es que AFAICT, el intérprete de scripts de Scala, no tomará stdin, y que no se puede evitar robustos tokenizar un reemplazo de comando, por lo que los intentos relativamente triviales de rellenar el texto en '-e' no funcionan. –

+0

'cat $ 1 | awk 'NR> 4'> /tmp/tmp.$1 && scalac /tmp/tmp.$1; rm/tmp/tmp. $ 1' o una forma un poco más sofisticada de generar un nombre de archivo único en aras de la integridad. Pero tanto código para tareas triviales me demuestra que esta es la herramienta incorrecta para el trabajo. Además, tenga en cuenta que debe sufrir los tiempos de inicio de JVM dos veces, para el script y para 'scala'. –

Cuestiones relacionadas