POV-Ray : Newsgroups : povray.bugreports : Parse error: Uncategorized error thrown at parser/parsertypes.cpp line 62 : Re: Parse error: Uncategorizederrorthrownatparser/parsertypes.cppline 62 Server Time: 20 Jun 2019 06:57:16 GMT
  Re: Parse error: Uncategorizederrorthrownatparser/parsertypes.cppline 62  
From: clipka
Date: 25 Mar 2019 23:41:39
Am 25.03.2019 um 23:55 schrieb clipka:

> If `Cond_Stack.back().PMac->endPosition == CurrentFilePosition()` throws 
> an exception, it means either of two things:
> 
> (A) The positions compared are from two different files, which means the 
> calling code has failed to check whether it is even in the right file.
> 
> (B) The line/column tracking is buggy, and yields different positions in 
> different situations.


Well, looking at the code of `IsEndOfInvokedMacro()` again, it 
_strongly_ reeks of scenario (A):

     return (Cond_Stack.back().PMac->endPosition ==
                 CurrentFilePosition()) &&
            (Cond_Stack.back().PMac->source.fileName ==
                 mTokenizer.GetInputStreamName());

should probably be swapped around, like so:

     return (Cond_Stack.back().PMac->source.fileName ==
                 mTokenizer.GetInputStreamName()) &&
            (Cond_Stack.back().PMac->endPosition ==
                 CurrentFilePosition());

so that the `LexemePosition` comparison operator is only invoked if the 
file names match.


I guess you got really lucky in your test (and the OP unlucky in their 
use case), in that you happen to have created the following scenario:

- A macro is invoked.
- That macro includes a different file.
- That included file happens to have a `#` (e.g. `#declare`) at the same 
file offset as the `#end` of the macro.
- However, the `#` happens to be in a different line and/or column.


In such a scenario, encountering the `#`, the parser would first test 
whether this is the `#end` of the macro it has been waiting for, calling 
`IsEndOfInvokedMacro()`.

`IsEndOfInvokedMacro()` in turn would checks whether the current file 
position matches that of the macro's `#end` by calling 
`LexemePostition::operator==`.

`LexemePostition::operator==` in turn would find that the file position 
does match. It would then verify that the match also reflects in line 
and column, and find that they differ, and report this inconsistency via 
an Exception.

`IsEndOfInvokedMacro()` wouldn't even get a chance to test whether it is 
looking at the right file, because its author (duh, I wonder who that 
stupid git might have been...) chose to do the two tests in the wrong order.


Now aside from the stupid git who authored `IsEndOfInvokedMacro()` 
there's someone else to blame for the situation, namely whoever thought 
it was a good idea to keep the stack of include files separate from the 
stack of pending "conditions". If they were using one and the same 
structure, having `INVOKING_MACRO_COND` on top of the stack would imply 
that we're in the file with the `#end`, and the file name test would be 
redundant.

I think it should be possible to merge the include stack into the 
"condition" stack without adverse effects, but I haven't finished work 
on that yet.


I should note that I haven't tested this hypothesis and fix for the 
error yet; I intend to do that as soon as I find the time, but of course 
you're welcome to beat me to it.


Post a reply to this message

Copyright 2003-2008 Persistence of Vision Raytracer Pty. Ltd.