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.
SyntaxQandSyntaxLength- in particular, if the latter returns > length of string, it implies the partial expression is correct syntactically but incomplete.... – ciao Aug 05 '15 at 22:49Expression "a[b[c,1],2],3]" has no opening "[".ToExpressionprints much more descriptive errors. – William Aug 05 '15 at 22:53SyntaxQwill returnFalse, indicating an invalid expression,SyntaxLengthwill return11, indicating the expression up toa[b[c,1],2]is valid. If you want to generate messages, you'll need to build that yourself before submitting toToExpression(and$SyntaxHandleris regrettably not in play,ToExpressiondoes not use it). – ciao Aug 05 '15 at 22:57