POV-Ray : Newsgroups : povray.bugreports : Parse error: Uncategorized error thrown at parser/parsertypes.cpp line 62 : Re: Parse error: Uncategorizederrorthrownatparser/parsertypes.cppline62 Server Time
26 Jul 2024 19:36:27 EDT (-0400)
  Re: Parse error: Uncategorizederrorthrownatparser/parsertypes.cppline62  
From: William F Pokorny
Date: 26 Mar 2019 06:46:20
Message: <5c9a02fc$1@news.povray.org>
On 3/25/19 7:41 PM, clipka wrote:
> 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.

Thanks for the detailed explanations and, though I'm busy with RL 
starting in a little while today, I think you've figured it out.

I know from looking at the values the position was matching and the line 
and column were not. Further, when I look at my test cases (all some 
pretty close variation of Warren's original) the failing ones all have 
the # of the declare in just the right spot as you suggested. I'd not 
recognized this was so.

My patch, then, just avoided the assertion in the 
LexemePosition::operator== I suppose. I also didn't know the parser 
assertions were today on always and I wasn't thinking an assert could 
cause the exception.

Quick additional question. Is it the --enable-debug configure flag that 
- normally - turns on the pov asserts? I've never verified this 
assumption of mine by creating a pov assert in the code I know should 
fail.

Bill P.


Post a reply to this message

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