# ToExpression processing errors

Is their a way to get a more comprehensive return value when running ToExpression?

For example when I run ToExpression["a[b[c,1],2],3]"] all I get from the output is $Failed when I'm looking for something more like Expression "a[b[c,1],2],3]" has no opening "[". • Look at SyntaxQ and SyntaxLength - in particular, if the latter returns > length of string, it implies the partial expression is correct syntactically but incomplete.... – ciao Aug 5 '15 at 22:49 • @ciao Tell me if I am missing something but it appears that neither return an error message for example Expression "a[b[c,1],2],3]" has no opening "[". ToExpression prints much more descriptive errors. Aug 5 '15 at 22:53 • They will not return an error message for those, nor should they: SyntaxQ will return False, indicating an invalid expression, SyntaxLength will return 11, indicating the expression up to a[b[c,1],2] is valid. If you want to generate messages, you'll need to build that yourself before submitting to ToExpression (and $SyntaxHandler is regrettably not in play, ToExpression does not use it).
– ciao
Aug 5 '15 at 22:57

One way would be to redirect all messages issued by ToExpression to a string-stream. Here is an example of that approach, with minimal error-checking:

Needs["Developer"]

interpret[str_String] :=
Module[{s = StreamToString[], r, m}
, Block[{$Messages = {s}}, r = ToExpression[str, InputForm, HoldComplete]] ; m = StringFromStream[s] ; Close[s] ; <| "result" -> r, "messages" -> m |> ]  It returns an association with the result and any messages returned by the interpretation. The result is held in unevaluated form when the interpretation is successful. Here are some examples: interpret["1+"] (* <| "result" ->$Failed
, "messages" -> "ToExpression::sntxi: Incomplete expression; more input is needed ."
|>
*)

interpret["1+1"]

(* <| "result" -> HoldComplete[1+1], "messages" -> "" |> *)

interpret["a[b[c,1],2],3]"]

(* <| "result" -> $Failed , "messages" -> "ToExpression::sntx: Invalid syntax in or before \"a[b[c,1],2],3]\"." |> *)  The exhibited function makes no attempt to handle abort or other non-local exits from ToExpression. Should one of those occur then the return value and messages will be lost, and the string-stream will not be closed. If a bullet-proof function is required, then more elaborate error-handling will be required (perhaps using CheckAll or the like -- see Resource Management in Mathematica for suggestions). Update As requested in a comment, here is a different version of interpret with better error handling should ToExpression fail catastrophically: interpret2[str_String] := withSetup[ { s = StreamToString[]; Close[s] , r = Block[{$Messages = {s}}, ToExpression[str, InputForm, HoldComplete]]
, m = StringFromStream[s]
}
, <| "result" -> r, "messages" -> m |>
]


It uses the CheckAll-based function withSetup defined in this answer to ensure that the string-stream is released even if ToExpression takes a non-local exit.

• I added a bounty in hopes you might create a more bullet proof solution. It isn't clear to me add 1st glance what you mean by CheckAll` I'm just now reading. Aug 14 '15 at 1:46
• I added an example of what I meant by "more elaborate error-handling". This is probably about as bullet-proof as we can get in high-level Mathematica code, without access to the internal C++ parsing code. Aug 15 '15 at 13:03