#17378: Preparser gets lost with iterated ellipsis_range
----------------------------------+------------------------
       Reporter:  tmonteil        |        Owner:
           Type:  defect          |       Status:  new
       Priority:  major           |    Milestone:  sage-6.5
      Component:  user interface  |   Resolution:
       Keywords:                  |    Merged in:
        Authors:                  |    Reviewers:
Report Upstream:  N/A             |  Work issues:
         Branch:                  |       Commit:
   Dependencies:                  |     Stopgaps:
----------------------------------+------------------------

Comment (by nbruin):

 I think we're really out of our depth here. `ellipsis_range` can actually
 take multiple `..` in its arguments, so we need to distinguish between
 {{{
 [1,2..10,12..20]
 }}}
 and
 {{{
 [1,2..len([10,12..20])]
 }}}
 The code in question is presently (see sage.misc.preparser line 520)
 {{{
     ix = code.find('..')
     while ix != -1:
         if ix == 0:
             raise SyntaxError("Cannot start line with ellipsis.")
         elif code[ix-1]=='.':
             # '...' be valid Python in index slices
             code = code[:ix-1] + "Ellipsis" + code[ix+2:]
         elif len(code) >= ix+3 and code[ix+2]=='.':
             # '...' be valid Python in index slices
             code = code[:ix] + "Ellipsis" + code[ix+3:]
         else:
             start_list, end_list = containing_block(code, ix, ['()','[]'])
 (*)         arguments = code[start_list+1:end_list-1].replace('...',
 ',Ellipsis,').replace('..', ',Ellipsis,')
             arguments = re.sub(r',\s*,', ',', arguments)
             if preparse_step:
                 arguments = arguments.replace(';', ', step=')
             range_or_iter = 'range' if code[start_list]=='[' else 'iter'
             code = "%s(ellipsis_%s(%s))%s" %  (code[:start_list],
                                                range_or_iter,
                                                arguments,
                                                code[end_list:])
         ix = code.find('..')
 }}}
 The problem is in the line marked (*). It really does need to be prepared
 to make multiple substitutions, but it should leave ".." that are enclosed
 in some kind of bracket for later substitutions.

 This is really one of those cases where string-substitutions aren't really
 powerful enough. It we'd start with a '..' that has a containing block
 that isn't properly contained in a containing block of any other '..',
 rather than the first '..' we find, then we'd be ok. (because inside that
 containing block all the '..' do belong to the same `ellipsis_range`).

 I'm a little worried about cost with that approach: what happens if a
 whole ".sage" file gets preparsed that has a whole lot of '..' in it? does
 this routine then execute on that huge string? execution time quadratic
 (or worse) in the number of '..' might be problematic.

--
Ticket URL: <http://trac.sagemath.org/ticket/17378#comment:1>
Sage <http://www.sagemath.org>
Sage: Creating a Viable Open Source Alternative to Magma, Maple, Mathematica, 
and MATLAB

-- 
You received this message because you are subscribed to the Google Groups 
"sage-trac" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sage-trac.
For more options, visit https://groups.google.com/d/optout.

Reply via email to