Ruby 2.0, 65 76 164 personagens
eval r="gets p;$<.pos=0;`ruby -c 2>&0`;p$?==0&&$_!='eval r=%p'%r"
Isso usa o verificador de sintaxe interno do Ruby ( ruby -c) para verificar a sintaxe da entrada, o que significa que o código não será avaliado.
Exemplo 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
Explicação
Esta solução é (foi) baseada no padrão Ruby quine:
q="q=%p;puts q%%q";puts q%q
%pé o especificador de formato para o arg.inspectqual pode ser comparado uneval: ao evalinserir a string retornada por arg.inspect, você (normalmente) obtém o valor original novamente. Assim, ao formatar a qstring como argumento, o %pinterior da string será substituído pela própria string citada (ou seja, obtemos algo parecido "q=\"q=%p;puts q%%q\";puts q%q").
A generalização desse tipo de quine leva a algo como o seguinte:
prelude;q="prelude;q=%p;postlude";postlude
Essa abordagem tem uma enorme desvantagem (pelo menos no código-golfe ): Todo o código precisa ser duplicado. Felizmente, evalpode ser usado para contornar isso:
eval r="some code;'eval r=%p'%r"
O que acontece aqui é que o código passado para eval é armazenado dentro r antes de eval ser chamado. Como resultado, o código fonte completo da evalinstrução pode ser obtido com 'eval r=%p'%r. Se fizermos isso dentro do evalcódigo d e garantirmos que o nível superior de nosso consistir apenas em uma evalinstrução, essa expressão realmente nos fornecerá o código fonte completo do nosso programa, pois qualquer código adicional passado evaljá está armazenado r.
Nota lateral: Essa abordagem nos permite escrever um Ruby Quine em 26 caracteres: eval r="puts'eval r=%p'%r"
Agora, nesta solução, o código adicional executado dentro evalconsiste em quatro instruções:
gets p
Primeiro, lemos toda a entrada do STDIN e a salvamos implicitamente $_.
$<.pos=0
Em seguida, rebobinamos o STDIN para que a entrada fique novamente disponível para o subprocesso que iniciaremos na próxima etapa.
`ruby -c 2>&0`
Isso inicia o Ruby no modo de verificação de sintaxe embutido, lendo o código fonte do stdin. Se a sintaxe do script fornecido (nome do arquivo ou stdin) estiver correta, ela será impressa Syntax OKno seu stdout (que é capturado pelo processo pai), mas no caso de um erro de sintaxe, uma descrição do erro será impressa no stderr - o que seria fique visível, então redirecionamos isso para o nirvana ( 2>&0).
p$?==0&&$_!='eval r=%p'%r
Depois, verificamos o código de saída do subprocesso $?, que é 0 se a sintaxe estiver correta. Por fim, a entrada que lemos anteriormente ( $_) é comparada com nosso próprio código-fonte (que, como descrevi anteriormente, pode ser obtido com 'eval r=%p'%r).
Editar: salvou 14 caracteres graças a @histocrat!