13
$\begingroup$

Consider the following conversion from String to Mathematica Expression:

n = 10;
ToExpression[Table["{", {n}] <> Table["}", {n}]]
{{{{{{{{{{}}}}}}}}}}

Everything is fine.

However, when the string is longer:

n = 510;
ToExpression[Table["{", {n}] <> Table["}", {n}]]
ToExpression::sntx: Invalid syntax in or before "                                                                               

                         <<182>>                                                                                                
               ^".
$Failed

My actual string that I'm trying to convert is much longer, about 2 million characters. How can I convert it to a Mathematica expression? A short example is:

"{"GAME", {"version", "0.23.5"}, {"linkURL", ""}, {"Mode", "1"}, {"PARAMETERS", {"FLIGHT", {"CanQuickSave", "True"}, {"CanQuickLoad", "True"}}}, {"SCENARIO", {"name", "ScenarioDiscoverableObjects"}, {"scene", "7, 8, 5"}, {"", "703987854"}, {"sizeCurve", {"key", "0 0 1.5 1.5"}, {"key", "0.3 0.45 0.875 0.875"}}}}"

UPDATE Reading a Stream also fails:

n = 510;
string = Table["{", {n}] <> Table["}", {n}];
stream = StringToStream[string]
Read[stream, Expression]
Close[stream]
Read::readt: Invalid input found when reading {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{\[Ellipsis]
}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
 from StringToStream[{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{\[Ellipsis]
}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}]. >>
$\endgroup$
6
  • 1
    $\begingroup$ fyi, tried it on V10 at WPC, and it failed there at 351 not 182. Not sure if this makes any difference. !Mathematica graphics $\endgroup$
    – Nasser
    Jul 4, 2014 at 23:40
  • $\begingroup$ Not true for any string, though. n = 510; ToExpression[Table["1+1+", {n}] <> Table["1+1", {n}]] $\endgroup$ Jul 4, 2014 at 23:51
  • $\begingroup$ @shrx How do you create your data? I suppose you do this in Mathematica as well? If you do create your data in Mathematica, I might have a workaround. $\endgroup$
    – halirutan
    Jul 5, 2014 at 0:08
  • $\begingroup$ I can reproduce this with V.9.0.1 on OS X. It looks like a bug to me. The string of braces is built with no problem. It's ToString that's stumbling. I've found another place where Mathematica has trouble with deeply nested lists. See this question. I would say it's a bug. $\endgroup$
    – m_goldberg
    Jul 5, 2014 at 3:45
  • $\begingroup$ @halirutan see my previous question. You can see the original structure of the file I'm trying to parse. $\endgroup$
    – shrx
    Jul 5, 2014 at 8:46

3 Answers 3

10
$\begingroup$

(All observations made in version 7.)

There seems to be a limitation for input even in the Front End (Notebook interface), in that if I enter more than 766 levels of nested lists I get a MaxFormatDepthExceeded expression and an error beep. The help text is:

A box structure with a depth exceeding the maximum allowed depth was encountered.

We can at least get this 766 level input by using the function UndocumentedTestFEParserPacket shown by John Fultz here, which I will bundle as:

parseString[s_String, prep : (True | False) : True] := 
  FrontEndExecute @ FrontEnd`UndocumentedTestFEParserPacket[s, prep]

We can then do:

n = 766;
string = Table["{", {n}] <> Table["}", {n}];
expr = ToExpression @@ parseString[string];
ToString[expr] === string
True

To extend this further would apparently require avoiding an intermediate Box structure which is an interesting problem. However it's the Fourth of July and I'll be spending my evening doing something else! :-)


Update: Using version 10, and increasing $RecursionLimit as Michael commented, we can use the method above for up to n = 5514:

$RecursionLimit = 1*^6;

n = 5514;

string = Table["{", {n}] <> Table["}", {n}];
expr = ToExpression @@ parseString[string];
ToString[expr] === string
True

However a higher value crashes Mathematica without warning. (Version 10.0.0.0 under Windows.)

$\endgroup$
1
  • 1
    $\begingroup$ FYI: This seems to work up to n = 2941 if I Block or set $RecursionLimit = 2942 or more in V9.0.1. $\endgroup$
    – Michael E2
    Jul 5, 2014 at 2:23
6
$\begingroup$

What you experience here seems to be some kind of stack limit when you have nested expressions. It doesn't seem to matter whether you nest lists or function calls. Look for instance at this example here which is nothing more than a nested call f[f[f[...f[a]]..]

Mathematica graphics

On the other hand, if the parser doesn't need to build up such a large stack, it seems to work. In an example of a+a+...+a which you can find here the Get works like a charm:

Mathematica graphics

Please note that it doesn't seem to make a difference whether you use Get or Import on a file, or ToExpression or ImportString on strings. The error stays the same here.

I'm not sure what I can propose you as workaround. Have you noticed that when you copy&paste the nested expressions directly, it works? It really seem to be a limitation of the reading from a stream.

$\endgroup$
1
$\begingroup$

I guess my solution maybe pretty easy,but it can works:

 n = 5;
 ToExpression[Table["{", {n}] <> Table["}", {n}]] == Nest[{#} &, {}, n - 1]

True

And if I set n a large number:

n=2*10^6; 
Nest[{#} &, {}, n];
Depth[%]

2000002

Also works.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.