Ruby 2.0, 65 76 164 caracteres
eval r="gets p;$<.pos=0;`ruby -c 2>&0`;p$?==0&&$_!='eval r=%p'%r"
Esto utiliza el verificador de sintaxis incorporado de Ruby ( ruby -c) para verificar la sintaxis de la entrada, lo que significa que el código no será evaluado.
Ejemplo de uso básico:
ruby syntax.rb <<< foo
true
ruby syntax.rb <<< "'"
false
ruby syntax.rb < synxtax.rb # assumes the file was saved without trailing newline
false
Explicación
Esta solución está (estaba) basada en el estándar Ruby quine:
q="q=%p;puts q%%q";puts q%q
%pes el especificador de formato para arg.inspect, que se puede comparar con uneval: cuando se evalingresa la cadena devuelta arg.inspect, (generalmente) obtiene el valor original nuevamente. Por lo tanto, al formatear la qcadena consigo misma como argumento, el %pinterior de la cadena se reemplazará con la cadena citada (es decir, obtenemos algo así "q=\"q=%p;puts q%%q\";puts q%q").
Generalizar este tipo de quine lleva a algo como lo siguiente:
prelude;q="prelude;q=%p;postlude";postlude
Sin embargo, este enfoque tiene un gran inconveniente (al menos en code-golf ): todo el código debe duplicarse. Afortunadamente, evalse puede usar para evitar esto:
eval r="some code;'eval r=%p'%r"
Lo que sucede aquí es que el código pasado a eval se almacena dentro r antes de que eval se llame. Como resultado, evalse puede obtener el código fuente completo de la declaración 'eval r=%p'%r. Si hacemos esto dentro del evalcódigo d y nos aseguramos de que el nivel superior de nuestro consiste solo en una evaldeclaración, esa expresión en realidad nos da el código fuente completo de nuestro programa, ya que cualquier código adicional pasado evalya está almacenado dentro r.
Nota al margen: este enfoque en realidad nos permite escribir un quine Ruby en 26 caracteres: eval r="puts'eval r=%p'%r"
Ahora, en esta solución, el código adicional ejecutado en su interior evalconsta de cuatro declaraciones:
gets p
Primero, leemos todas las entradas de STDIN y las guardamos implícitamente en ellas $_.
$<.pos=0
Luego, rebobinamos STDIN para que la entrada esté disponible nuevamente para el subproceso que comenzamos en el siguiente paso.
`ruby -c 2>&0`
Esto inicia Ruby en su modo de verificación de sintaxis incorporado, leyendo el código fuente de stdin. Si la sintaxis del script proporcionado (nombre de archivo o stdin) es correcta, se imprime Syntax OKen su stdout (que es capturado por el proceso principal), pero en caso de un error de sintaxis, se imprime una descripción del error en stderr , lo que ser visible, por lo que redirigimos eso a nirvana ( 2>&0) en su lugar.
p$?==0&&$_!='eval r=%p'%r
Luego, verificamos el código de salida del subproceso $?, que es 0 si la sintaxis era correcta. Por último, la entrada que leemos antes ( $_) se compara con nuestro propio código fuente (que, como describí anteriormente, se puede obtener con 'eval r=%p'%r).
Editar: ¡Salvé 14 caracteres gracias a @histocrat!