2011-06-22 11 views
6

Cuando evalúo una función en una celda, Mathematica diceCómo encontrar error de sintaxis

 
ToExpression::notstrbox: {At Line = 6, the input was:,$Failed,InString[6]} 
is not a string or a box. ToExpression can only interpret strings or boxes 
as Mathematica input. >> 

Y el borde de la celda derecha se vuelve rojo.

¿Cómo puedo encontrar la ubicación del error?

+0

Encontré el error de sintaxis: he elevado una x a la segunda potencia, pero en lugar de escribir x^2 utilicé la notación matemática 2D y escribí x CTRL^2. Parece que esto a veces causa un problema al introducir algún personaje oculto. Cuando lo cambié a x^2, el error desapareció. Esto no sucede todo el tiempo y parece ser aleatorio y raro. Para estar seguro, dejaré de utilizar la notación matemática 2D en el código a partir de ahora, aunque hizo que el código se vea mejor, pero me parece un error. –

+0

No he visto ese tipo de errores desde la versión 2 o 3. Como recuerdo, fue principalmente la edición de citas coincidentes que podrían causar havok. Uso notación 2D todo el tiempo. Tal vez su instalación está corrupta o así? –

+0

Mi instalación está bien. Como dije, este error es raro. También uso matemáticas 2D todo el tiempo y vi este problema una vez. porque usted no vio el error por algún tiempo usted mismo no significa mucho, y eso no significa que el problema se haya solucionado. –

Respuesta

9

En realidad, el kernel siempre envía la posición del primer error de sintaxis en la cadena de entrada al FrontEnd (si esta cadena de entrada contiene un error). Se puede demostrar con el siguiente código MathLink:

In[32]:= link = LinkLaunch[First[$CommandLine] <> " -mathlink"]; 
LinkRead[link]; 
LinkWrite[link, EnterTextPacket["2+"]] 
LinkRead[link] 
LinkRead[link] 
LinkRead[link] 

Out[35]= MessagePacket[Syntax, "sntxi"]  
Out[36]= TextPacket["Syntax::sntxi: Incomplete expression; more input is needed. 
"]  
Out[37]= SyntaxPacket[5] 

El número entero en SyntaxPacket "indica la posición en la que se ha detectado un error de sintaxis en la línea de entrada", de acuerdo a la documentación. Lo que es confuso al principio es que esta posición en el caso de la línea de entrada "2+" obviamente está más allá del final de la línea de entrada. Pero parece que en realidad esta posición se cuenta para el InputForm de la línea de entrada que en este caso es: "2+\n\n".

Podemos comprobar cómo funciona con $SyntaxHandler define como sigue:

In[41]:= link = LinkLaunch[First[$CommandLine] <> " -mathlink"]; 
LinkRead[link] 
LinkWrite[link, 
EnterTextPacket[ 
    "$SyntaxHandler= 
     Function[{str,pos}, 
       Print["Input string: ",ToString[str,InputForm]]; 
       Print["Position of syntax error: ",pos]; 
       $Failed 
     ]; 
    "]] 
LinkRead[link] 
LinkWrite[link, EnterTextPacket["2+"]] 
While[Head[packet = LinkRead[link]] =!= InputNamePacket, 
Print[packet]]; Print[packet] 

Out[42]= InputNamePacket["In[1]:= "]  
Out[44]= InputNamePacket["In[2]:= "]  
During evaluation of In[41]:= MessagePacket[Syntax,sntxi]  
During evaluation of In[41]:= TextPacket[Syntax::sntxi: Incomplete expression; more input is needed. 
]  
During evaluation of In[41]:= TextPacket[Input string: "2+\n\n" 
]  
During evaluation of In[41]:= TextPacket[Position of syntax error: 6 
]  
During evaluation of In[41]:= SyntaxPacket[5]  
During evaluation of In[41]:= InputNamePacket[In[2]:= ] 

Uno puede ver una inconsistencia entre las posiciones de un mismo error de sintaxis informado por SyntaxPacket y por $SyntaxHandler. Pero parece posible entender cómo cuentan la posición: ambos usan InputForm de la línea de entrada y la posición antes de la línea de entrada tiene el número 0 para $SyntaxHandler y el número 1 en el caso de SyntaxPacket.De esta manera podemos definir $SyntaxHandler para conseguir representación visual exacta de la posición del error de sintaxis en el interior de la cadena de entrada (la entrada Cell debe tener "RawInputForm" estilo) de la siguiente manera:

$SyntaxHandler = 
    Function[{str, pos}, 
    Print["Input string: ", ToString[str, InputForm], "\n", 
    "Position of syntax error: ", pos, "\n", 
    StringInsert[ToString[str, InputForm], 
    ToString[Style["\[DownArrowBar]", Red, Background -> Yellow], 
     StandardForm], pos + 2]]; $Failed]; 

Subrayaré ¡nuevamente esa celda de entrada DEBE tener el estilo "RawInputForm"! Dicha celda se puede crear creando una celda de entrada vacía común y luego convirtiéndola en la celda "RawInputForm" con el comando apropiado en el menú Cell -> Convert To.

Veamos como funciona:

screenshot

La razón por la que debemos utilizar los teléfonos "RawInputForm" es probable que $SyntaxHandler se aplica ony cuando la entrada se envía al núcleo en forma de un String , no en la forma de Boxes como ocurre con las celdas de entrada StandardForm predeterminadas.

6

¿Está llamando al ToExpression usted mismo en una cadena? La función SyntaxLength le dará el carácter de compensación del primer error de sintaxis cuando se aplica a una cadena, por ejemplo:

In[26]:= SyntaxLength["2+"] 
Out[26]= 4 

In[27]:= SyntaxLength["x[1]+x[2]]"] 
Out[27]= 9 

Tenga en cuenta que, como se indica en la documentación, cuando SyntaxLength devuelve una posición más allá del final de la cadena de entrada , eso significa que la expresión es sintácticamente correcta hasta ahora, pero incompleta. De lo contrario, SyntaxLength devuelve efectivamente la posición del primer error de sintaxis.

Si no está invocando explícitamente ToExpression en algo, probablemente le ayude a ver la celda en cuestión.

+0

No estoy llamando a ToExpression. No sé para qué sirve eso. Me pregunto si hay una herramienta o método para encontrar las ubicaciones reales de los errores de sintaxis en un cuaderno. Claramente debe haber una forma automatizada de decirle a Mathematica que informe tal información, simplemente generando un mensaje que diga que un error de sintaxis ocurrió en alguna parte. –

+1

¿Qué versión de Mathematica estás usando? –

+0

Versión 8 de Mathematica –

4

Los errores de sintaxis, como los corchetes de funciones no balanceadas, generalmente se indican mediante el color de los caracteres, un corchete sin igual que se vuelve rosa o algo así. En este caso, ha habido un error de tipo de entrada. Aparentemente, usted llamó (o una función que utilizó) ToExpression usando el resultado de otra función que falló. El primer paso sería encontrar este ToExpression y descubrir qué función proporciona su entrada devuelve $ Failed.

Mathematica tiene un depurador bare-bones, que puede encontrar en el menú de Evaluación. Puede encontrar un mejor depurador en Matimatica Workbench, que es gratuito si tiene una licencia Premier Service.

Si su código no es demasiado grande, le sugiero que lo publique como parte de su pregunta. Sin embargo, no somos un sitio de revisión de código.