Robert H
Robert H

Reputation: 1663

How to find syntax error

When I evaluate a function in one cell, Mathematica says

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. >>

And the cell right edge turns red.

How do I find the error location?

Upvotes: 6

Views: 5611

Answers (3)

Alexey Popkov
Alexey Popkov

Reputation: 9425

In reality, the kernel always sends the position of first syntax error in the input string to the FrontEnd (if this input string contains an error). It can be demonstrated with the following MathLink code:

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]

The integer in SyntaxPacket "indicates the position at which a syntax error was detected in the input line" according to the documentation. What is confusing at first is that this position in the case of the input line "2+" is obviously beyond the end of the input line. But it seems that in reality this position is counted for the InputForm of the input line which in this case is: "2+\n\n".

We can check how it works with $SyntaxHandler defined as follows:

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]:= ]

One can see an inconsistency between the positions of the same syntax error reported by SyntaxPacket and by $SyntaxHandler. But it seems possible to understand how they count the position: both use InputForm of the input line and the position before the input line has number 0 for $SyntaxHandler and number 1 in the case of SyntaxPacket. In this way we can define $SyntaxHandler for getting exact visual representation of the position of the syntax error inside of the input string (the input Cell must have "RawInputForm" style) as follows:

$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];

I will stress again that input cell MUST have the "RawInputForm" style! Such cell may be created by creating ordinary empty input cell and then converting it to the "RawInputForm" cell by the appropriate command in the Cell -> Convert To menu.

Lets see how it works:

screenshot

The reason why we must use "RawInputForm" cell is probably that $SyntaxHandler is applied ony when the input is sent to the kernel in the form of a String, not in the form of Boxes as it happens with default StandardForm input cells.

Upvotes: 9

Sjoerd C. de Vries
Sjoerd C. de Vries

Reputation: 16232

Syntax errors such as unbalanced function brackets, are usually indicated by means of character coloring, an unmatched bracket turning pink or so. In this case, there has been an input type error. Apparently, you called (or a function you used did) ToExpression using the result of another function that failed. First step would be finding this ToExpression and finding out what function providing its input returns $Failed.

Mathematica has a bare-bones debugger, which you can find in the Evaluation menu. A better debugger may be found in Matimatica Workbench which is free if you have a Premier Service license.

If your code is not too large I'd suggest posting it as part of your question. We're not a code review site, though.

Upvotes: 4

Michael Pilat
Michael Pilat

Reputation: 6520

Are you calling ToExpression yourself on a string? The function SyntaxLength will give you the character offset of the first syntax error when applied to a string, for example:

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

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

Note that as indicated in the docs, when SyntaxLength returns a position beyond the end of the input string, that means the expression is syntactically correct so far, but incomplete. Otherwise, SyntaxLength effectively returns the position of the first syntax error.

If you're not explicitly invoking ToExpression on something, it will probably help to see the cell in question.

Upvotes: 6

Related Questions